AvTranscoder  0.9.4
C++APIforLibav/FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
FileProperties.cpp
Go to the documentation of this file.
1 #include "FileProperties.hpp"
2 
6 
7 #include <stdexcept>
8 #include <sstream>
9 
10 namespace avtranscoder
11 {
12 
14  : _formatContext(&formatContext)
15  , _avFormatContext(&formatContext.getAVFormatContext())
16  , _videoStreams()
17  , _audioStreams()
18  , _dataStreams()
19  , _subtitleStreams()
20  , _attachementStreams()
21  , _unknownStreams()
22 {
25 
26  NoDisplayProgress progress;
28 }
29 
31 {
32  // if the analysis level wiil decode some streams parts, seek at the beginning
33  if(level > eAnalyseLevelHeader && ! isRawFormat())
34  const_cast<FormatContext*>(_formatContext)->seek(0, AVSEEK_FLAG_BACKWARD);
35 
36  // clear properties
38 
39  // reload properties
40  for(size_t streamIndex = 0; streamIndex < _formatContext->getNbStreams(); ++streamIndex)
41  {
42  switch(_formatContext->getAVStream(streamIndex).codec->codec_type)
43  {
44  case AVMEDIA_TYPE_VIDEO:
45  {
46  VideoProperties properties(*_formatContext, streamIndex, progress, level);
47  _videoStreams.push_back(properties);
48  break;
49  }
50  case AVMEDIA_TYPE_AUDIO:
51  {
52  AudioProperties properties(*_formatContext, streamIndex);
53  _audioStreams.push_back(properties);
54  break;
55  }
56  case AVMEDIA_TYPE_DATA:
57  {
58  DataProperties properties(*_formatContext, streamIndex);
59  _dataStreams.push_back(properties);
60  break;
61  }
62  case AVMEDIA_TYPE_SUBTITLE:
63  {
64  SubtitleProperties properties(*_formatContext, streamIndex);
65  _subtitleStreams.push_back(properties);
66  break;
67  }
68  case AVMEDIA_TYPE_ATTACHMENT:
69  {
70  AttachementProperties properties(*_formatContext, streamIndex);
71  _attachementStreams.push_back(properties);
72  break;
73  }
74  case AVMEDIA_TYPE_UNKNOWN:
75  {
76  UnknownProperties properties(*_formatContext, streamIndex);
77  _unknownStreams.push_back(properties);
78  break;
79  }
80  case AVMEDIA_TYPE_NB:
81  {
82  break;
83  }
84  }
85  }
86 
87  // once the streams vectors are filled, add their references the base streams vector
88  for(size_t streamIndex = 0; streamIndex < _videoStreams.size(); ++streamIndex)
89  {
90  const size_t videoStreamIndex = _videoStreams.at(streamIndex).getStreamIndex();
91  _streams[videoStreamIndex] = &_videoStreams.at(streamIndex);
92  }
93 
94  for(size_t streamIndex = 0; streamIndex < _audioStreams.size(); ++streamIndex)
95  {
96  const size_t audioStreamIndex = _audioStreams.at(streamIndex).getStreamIndex();
97  _streams[audioStreamIndex] = &_audioStreams.at(streamIndex);
98  }
99 
100  for(size_t streamIndex = 0; streamIndex < _dataStreams.size(); ++streamIndex)
101  {
102  const size_t dataStreamIndex = _dataStreams.at(streamIndex).getStreamIndex();
103  _streams[dataStreamIndex] = &_dataStreams.at(streamIndex);
104  }
105 
106  for(size_t streamIndex = 0; streamIndex < _subtitleStreams.size(); ++streamIndex)
107  {
108  const size_t subtitleStreamIndex = _subtitleStreams.at(streamIndex).getStreamIndex();
109  _streams[subtitleStreamIndex] = &_subtitleStreams.at(streamIndex);
110  }
111 
112  for(size_t streamIndex = 0; streamIndex < _attachementStreams.size(); ++streamIndex)
113  {
114  const size_t attachementStreamIndex = _attachementStreams.at(streamIndex).getStreamIndex();
115  _streams[attachementStreamIndex] = &_attachementStreams.at(streamIndex);
116  }
117 
118  for(size_t streamIndex = 0; streamIndex < _unknownStreams.size(); ++streamIndex)
119  {
120  const size_t unknownStreamIndex = _unknownStreams.at(streamIndex).getStreamIndex();
121  _streams[unknownStreamIndex] = &_unknownStreams.at(streamIndex);
122  }
123 
124  // if the analysis level has decoded some streams parts, return at the beginning
125  if(level > eAnalyseLevelHeader && ! isRawFormat())
126  const_cast<FormatContext*>(_formatContext)->seek(0, AVSEEK_FLAG_BACKWARD);
127 }
128 
129 std::string FileProperties::getFilename() const
130 {
131  if(!_avFormatContext || !_avFormatContext->filename)
132  throw std::runtime_error("unknown file name");
133  return _avFormatContext->filename;
134 }
135 
136 std::string FileProperties::getFormatName() const
137 {
138  if(!_avFormatContext || !_avFormatContext->iformat || !_avFormatContext->iformat->name)
139  throw std::runtime_error("unknown format name");
140  return _avFormatContext->iformat->name;
141 }
142 
144 {
145  if(!_avFormatContext || !_avFormatContext->iformat || !_avFormatContext->iformat->long_name)
146  throw std::runtime_error("unknown format long name");
147  return _avFormatContext->iformat->long_name;
148 }
149 
151 {
152  if(getNbStreams() != 1)
153  return false;
154  // the format name should be the same as the codec name
155  if(getFormatName() == getStreamProperties().at(0)->getCodecName())
156  return true;
157  return false;
158 }
159 
161 {
162 #if LIBAVFORMAT_VERSION_MAJOR <= 55
163  throw std::runtime_error("cannot get mime type format: libavformat library has a major version <= 55.");
164 #else
165  if(_avFormatContext->iformat->mime_type == NULL)
166  throw std::runtime_error("Unknown demuxer format mime type");
167  return std::string(_avFormatContext->iformat->mime_type);
168 #endif
169 }
170 
172 {
173  if(!_avFormatContext)
174  throw std::runtime_error("unknown format context");
175  return _avFormatContext->nb_programs;
176 }
177 
179 {
180  if(!_avFormatContext)
181  throw std::runtime_error("unknown format context");
182  return 1.0 * (unsigned int)_avFormatContext->start_time / AV_TIME_BASE;
183 }
184 
186 {
187  if(!_avFormatContext)
188  throw std::runtime_error("unknown format context");
189  return 1.0 * _avFormatContext->duration / AV_TIME_BASE;
190 }
191 
193 {
194  if(!_avFormatContext)
195  throw std::runtime_error("unknown format context");
196  return _avFormatContext->bit_rate;
197 }
198 
200 {
201  if(!_avFormatContext)
202  throw std::runtime_error("unknown format context");
203  return _avFormatContext->packet_size;
204 }
205 
207 {
208  avtranscoder::StreamProperties* properties = _streams.find(streamIndex)->second;
209  if(properties)
210  return *properties;
211  std::stringstream os;
212  os << "No stream properties correspond to stream at index ";
213  os << streamIndex;
214  throw std::runtime_error(os.str());
215 }
216 
217 const std::vector<avtranscoder::StreamProperties*> FileProperties::getStreamProperties() const
218 {
219  std::vector<avtranscoder::StreamProperties*> streams;
220  for(std::map<size_t, StreamProperties*>::const_iterator it = _streams.begin(); it != _streams.end(); ++it)
221  {
222  streams.push_back(it->second);
223  }
224  return streams;
225 }
226 
228 {
229  if(!_avFormatContext)
230  throw std::runtime_error("unknown format context");
231  return _avFormatContext->nb_streams;
232 }
233 
235 {
236  PropertyVector propertyVector;
237  return fillVector(propertyVector);
238 }
239 
241 {
242  addProperty(data, "filename", &FileProperties::getFilename);
243  addProperty(data, "formatName", &FileProperties::getFormatName);
244  addProperty(data, "formatLongName", &FileProperties::getFormatLongName);
246 
247  addProperty(data, "startTime", &FileProperties::getStartTime);
248  addProperty(data, "duration", &FileProperties::getDuration);
249  addProperty(data, "bitrate", &FileProperties::getBitRate);
250  addProperty(data, "numberOfStreams", &FileProperties::getNbStreams);
251  addProperty(data, "numberOfPrograms", &FileProperties::getProgramsCount);
252 
253  detail::add(data, "numberOfVideoStreams", getNbVideoStreams());
254  detail::add(data, "numberOfAudioStreams", getNbAudioStreams());
255  detail::add(data, "numberOfDataStreams", getNbDataStreams());
256  detail::add(data, "numberOfSubtitleStreams", getNbSubtitleStreams());
257  detail::add(data, "numberOfAttachementStreams", getNbAttachementStreams());
258  detail::add(data, "numberOfUnknownStreams", getNbUnknownStreams());
259 
260  for(size_t metadataIndex = 0; metadataIndex < _metadatas.size(); ++metadataIndex)
261  {
262  detail::add(data, _metadatas.at(metadataIndex).first, _metadatas.at(metadataIndex).second);
263  }
264 
265  return data;
266 }
267 
269 {
270  PropertyMap dataMap;
271 
272  PropertyVector dataVector(asVector());
273  for(PropertyVector::const_iterator it = dataVector.begin(); it != dataVector.end(); ++it)
274  {
275  dataMap.insert(std::make_pair(it->first, it->second));
276  }
277 
278  return dataMap;
279 }
280 
281 std::string FileProperties::asJson() const
282 {
284  PropertyMap properties = asMap();
285  for(PropertyMap::iterator it = properties.begin(); it != properties.end(); ++it)
286  writer << std::make_pair(it->first.c_str(), it->second.c_str());
287  return writer.build();
288 }
289 
291 {
293  {
294  // format
296  format << asJson();
297  writer << std::make_pair("format", format.build());
298  }
299  {
300  // video streams
302  for(std::vector<avtranscoder::VideoProperties>::const_iterator it = _videoStreams.begin(); it != _videoStreams.end();
303  ++it)
304  {
305  video << it->asJson();
306  }
307  writer << std::make_pair("video", video.build());
308  }
309  {
310  // audio streams
312  for(std::vector<avtranscoder::AudioProperties>::const_iterator it = _audioStreams.begin(); it != _audioStreams.end();
313  ++it)
314  {
315  audio << it->asJson();
316  }
317  writer << std::make_pair("audio", audio.build());
318  }
319  {
320  // data streams
322  for(std::vector<avtranscoder::DataProperties>::const_iterator it = _dataStreams.begin(); it != _dataStreams.end();
323  ++it)
324  {
325  data << it->asJson();
326  }
327  writer << std::make_pair("data", data.build());
328  }
329  {
330  // subtitle streams
332  for(std::vector<avtranscoder::SubtitleProperties>::const_iterator it = _subtitleStreams.begin();
333  it != _subtitleStreams.end(); ++it)
334  {
335  subtitle << it->asJson();
336  }
337  writer << std::make_pair("subtitle", subtitle.build());
338  }
339  {
340  // attachement streams
341  json::JsonArrayStreamWriter attachement;
342  for(std::vector<avtranscoder::AttachementProperties>::const_iterator it = _attachementStreams.begin();
343  it != _attachementStreams.end(); ++it)
344  {
345  attachement << it->asJson();
346  }
347  writer << std::make_pair("attachement", attachement.build());
348  }
349  {
350  // unknown streams
352  for(std::vector<avtranscoder::UnknownProperties>::const_iterator it = _unknownStreams.begin();
353  it != _unknownStreams.end(); ++it)
354  {
355  unknown << it->asJson();
356  }
357  writer << std::make_pair("unknown", unknown.build());
358  }
359  return writer.build();
360 }
361 
363 {
364  _streams.clear();
365 
366  _videoStreams.clear();
367  _audioStreams.clear();
368  _dataStreams.clear();
369  _subtitleStreams.clear();
370  _attachementStreams.clear();
371  _unknownStreams.clear();
372 }
373 
374 std::ostream& operator<<(std::ostream& flux, const FileProperties& fileProperties)
375 {
376  flux << std::left;
377  flux << detail::separator << " Wrapper " << detail::separator << std::endl;
378 
379  PropertyVector properties = fileProperties.asVector();
380  for(PropertyVector::iterator it = properties.begin(); it != properties.end(); ++it)
381  {
382  flux << std::setw(detail::keyWidth) << it->first << ": " << it->second << std::endl;
383  }
384 
385  return flux;
386 }
387 }
size_t getBitRate() const
total stream bitrate in bit/s, 0 if not available (result of a computation by ffmpeg) ...
Base class of Progress. Inherit this class to have your own way to manage a progress bar...
Definition: IProgress.hpp:23
std::vector< std::pair< std::string, std::string > > PropertyVector
PropertyVector is a vector of pair, because the order of properties matters to us.
Definition: util.hpp:23
EAnalyseLevel
Level of file analysis.
Definition: util.hpp:10
std::vector< DataProperties > _dataStreams
Array of properties per data stream.
PropertyMap asMap() const
Return format properties as a map (name of property, value)
bool isRawFormat() const
Is there a container, or a raw bitstreams without access to timing information.
void extractStreamProperties(IProgress &progress, const EAnalyseLevel level)
Relaunch streams analysis with a specific level.
Write an array to a stream.
Definition: JsonWriter.hpp:106
const size_t keyWidth
Definition: util.hpp:32
std::vector< AttachementProperties > _attachementStreams
Array of properties per attachement stream.
const std::string separator
Definition: util.hpp:33
void add(PropertyVector &propertyVector, const std::string &key, const size_t &value)
Definition: util.cpp:16
std::string getFilename() const
size_t getNbSubtitleStreams() const
std::vector< SubtitleProperties > _subtitleStreams
Array of properties per subtitle stream.
void fillMetadataDictionnary(AVDictionary *avdictionnary, PropertyVector &metadata)
Fill metadata parameter with the given AVDictionary.
Definition: util.cpp:55
std::string allPropertiesAsJson() const
Return all properties as a json format.
std::string getFormatLongName() const
Descriptive name for the format, meant to be more human-readable than name, or empty if unknown...
const std::vector< avtranscoder::StreamProperties * > getStreamProperties() const
std::map< size_t, StreamProperties * > _streams
Map of properties per stream index (of all types) - only references to the following properties...
const avtranscoder::StreamProperties & getStreamPropertiesWithIndex(const size_t streamIndex) const
void addProperty(PropertyVector &data, const std::string &key, T(FileProperties::*getter)(void) const) const
std::map< std::string, std::string > PropertyMap
Definition: util.hpp:24
std::string getFormatMimeType() const
Comma-separated list of mime types, or empty if unknown.
std::vector< AudioProperties > _audioStreams
Array of properties per audio stream.
PropertyVector asVector() const
Return format properties as a vector (name of property: value)
Wrapper of an AVFormatContext.
std::string getFormatName() const
A comma separated list of short names for the format, or empty if unknown.
std::vector< UnknownProperties > _unknownStreams
Array of properties per unknown stream.
std::vector< VideoProperties > _videoStreams
Array of properties per video stream.
size_t getNbAttachementStreams() const
Virtual based class of properties for all types of stream.
std::string asJson() const
Return all format properties as a json format.
Write an object to a stream.
Definition: JsonWriter.hpp:84
size_t getNbUnknownStreams() const
std::ostream & operator<<(std::ostream &flux, const InputFile &input)
Definition: InputFile.cpp:171
const AVFormatContext * _avFormatContext
Has link (no ownership)
PropertyVector & fillVector(PropertyVector &data) const
To avoid copy of the vector.
const FormatContext * _formatContext
Has link (no ownership)
float getDuration() const
in seconds
Implementation of IProgress, to manage cases when we need an IProgress but don't care of a progress b...
FileProperties(const FormatContext &formatContext)
Analayse a file from its FormatContext.
AVStream & getAVStream(size_t index) const
void clearStreamProperties()
Clear all array of stream properties.
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy