AvTranscoder  0.9.4
C++APIforLibav/FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
FormatContext.cpp
Go to the documentation of this file.
1 #include "FormatContext.hpp"
2 
3 #include <stdexcept>
4 #include <sstream>
5 
6 namespace avtranscoder
7 {
8 
9 FormatContext::FormatContext(const std::string& filename, int req_flags, AVDictionary** options)
10  : _avFormatContext(NULL)
11  , _flags(req_flags)
12  , _options()
13  , _isOpen(false)
14 {
15  int ret = avformat_open_input(&_avFormatContext, filename.c_str(), NULL, options);
16  if(ret < 0)
17  {
18  std::string msg = "Unable to open file ";
19  msg += filename;
20  msg += ": ";
21  msg += getDescriptionFromErrorCode(ret);
22  throw std::ios_base::failure(msg);
23  }
24  _isOpen = true;
25 
27  // when demuxing, priv_data of AVFormatContext is set by avformat_open_input()
28  if(_avFormatContext->iformat->priv_class)
29  loadOptions(_options, _avFormatContext->priv_data, req_flags);
30 }
31 
33  : _avFormatContext(NULL)
34  , _flags(req_flags)
35  , _options()
36  , _isOpen(false)
37 {
38  _avFormatContext = avformat_alloc_context();
40 }
41 
43 {
44  if(!_avFormatContext)
45  return;
46 
47  if(_isOpen)
48  avformat_close_input(&_avFormatContext);
49  else
50  avformat_free_context(_avFormatContext);
51  _avFormatContext = NULL;
52 }
53 
54 void FormatContext::findStreamInfo(AVDictionary** options)
55 {
56  const int err = avformat_find_stream_info(_avFormatContext, options);
57  if(err < 0)
58  {
59  throw std::ios_base::failure("Unable to find stream informations: " + getDescriptionFromErrorCode(err));
60  }
61 }
62 
63 void FormatContext::openRessource(const std::string& url, int flags)
64 {
65  if((_avFormatContext->flags & AVFMT_NOFILE) == AVFMT_NOFILE)
66  return;
67 
68  const int err = avio_open2(&_avFormatContext->pb, url.c_str(), flags, NULL, NULL);
69  if(err < 0)
70  {
71  throw std::ios_base::failure("Error when opening output format: " + getDescriptionFromErrorCode(err));
72  }
73 }
74 
76 {
77  if((_avFormatContext->flags & AVFMT_NOFILE) == AVFMT_NOFILE)
78  return;
79 
80  const int err = avio_close(_avFormatContext->pb);
81  if(err < 0)
82  {
83  throw std::ios_base::failure("Error when close output format: " + getDescriptionFromErrorCode(err));
84  }
85 }
86 
87 void FormatContext::writeHeader(AVDictionary** options)
88 {
89  const int ret = avformat_write_header(_avFormatContext, options);
90  if(ret != 0)
91  {
92  throw std::runtime_error("Could not write header: " + getDescriptionFromErrorCode(ret));
93  }
94  // when muxing, priv_data of AVFormatContext is set by avformat_write_header()
95  if(_avFormatContext->oformat->priv_class)
97 }
98 
99 void FormatContext::writeFrame(AVPacket& packet, bool interleaved)
100 {
101  int ret = 0;
102  if(interleaved)
103  ret = av_interleaved_write_frame(_avFormatContext, &packet);
104  else
105  {
106  // returns 1 if flushed and there is no more data to flush
107  ret = av_write_frame(_avFormatContext, &packet);
108  }
109 
110  if(ret < 0)
111  {
112  throw std::runtime_error("Error when writting packet in stream: " + getDescriptionFromErrorCode(ret));
113  }
114 }
115 
117 {
118  const int ret = av_write_trailer(_avFormatContext);
119  if(ret != 0)
120  {
121  throw std::runtime_error("Could not write trailer: " + getDescriptionFromErrorCode(ret));
122  }
123 }
124 
125 void FormatContext::addMetaData(const std::string& key, const std::string& value)
126 {
127  const int ret = av_dict_set(&_avFormatContext->metadata, key.c_str(), value.c_str(), 0);
128  if(ret < 0)
129  {
131  }
132 }
133 
134 AVStream& FormatContext::addAVStream(const AVCodec& avCodec)
135 {
136  // Need const_cast<AVCodec*> for libav versions < 54.34.
137  AVStream* stream = avformat_new_stream(_avFormatContext, const_cast<AVCodec*>(&avCodec));
138  if(stream == NULL)
139  {
140  throw std::runtime_error("Unable to add new video stream");
141  }
142  return *stream;
143 }
144 
145 bool FormatContext::seek(const uint64_t position, const int flag)
146 {
147  LOG_INFO("Seek in '" << _avFormatContext->filename << "' at " << position << " with flag '"<< flag << "'")
148  const int err = av_seek_frame(_avFormatContext, -1, position, flag);
149  if(err < 0)
150  {
151  LOG_ERROR("Error when seek at " << position << " (in AV_TIME_BASE units) in file")
153  return false;
154  }
155  return true;
156 }
157 
158 std::vector<Option> FormatContext::getOptions()
159 {
160  std::vector<Option> optionsArray;
161  for(OptionMap::iterator it = _options.begin(); it != _options.end(); ++it)
162  {
163  optionsArray.push_back(it->second);
164  }
165  return optionsArray;
166 }
167 
168 AVStream& FormatContext::getAVStream(size_t index) const
169 {
170  if(index >= getNbStreams())
171  {
172  std::stringstream msg;
173  msg << "Can't acces stream at index ";
174  msg << index;
175  throw std::runtime_error(msg.str());
176  }
177  return *_avFormatContext->streams[index];
178 }
179 
180 void FormatContext::setFilename(const std::string& filename)
181 {
182  strcpy(&_avFormatContext->filename[0], filename.c_str());
183 }
184 
185 void FormatContext::setOutputFormat(const std::string& filename, const std::string& shortName, const std::string& mimeType)
186 {
187  AVOutputFormat* oformat = av_guess_format(shortName.c_str(), filename.c_str(), mimeType.c_str());
188  if(!oformat)
189  {
190  std::string msg("Unable to find format for ");
191  msg += filename;
192  if(!shortName.empty())
193  {
194  msg += ", formatName = ";
195  msg += shortName;
196  }
197  if(!mimeType.empty())
198  {
199  msg += ", mimeType = ";
200  msg += mimeType;
201  }
202  throw std::ios_base::failure(msg);
203  }
204 
205  _avFormatContext->oformat = oformat;
206 }
207 }
#define LOG_ERROR(...)
Definition: log.hpp:35
const int _flags
Flags with which the options are loaded (see AV_OPT_FLAG_xxx)
void closeRessource()
Close the resource accessed by the AVIOContext and free it.
void loadOptions(OptionMap &outOptions, void *av_class, int req_flags)
Definition: Option.cpp:227
bool seek(const uint64_t position, const int flag)
Seek at a specific position.
void setOutputFormat(const std::string &filename, const std::string &shortName="", const std::string &mimeType="")
std::string getDescriptionFromErrorCode(const int code)
Get the string description corresponding to the error code provided by ffmpeg/libav.
Definition: common.cpp:22
void addMetaData(const std::string &key, const std::string &value)
AVStream & addAVStream(const AVCodec &avCodec)
#define LOG_INFO(...)
Definition: log.hpp:23
void writeTrailer()
Write the stream trailer to an output media file.
OptionArray getOptions()
Get options as array.
void writeHeader(AVDictionary **options=NULL)
Write the stream header to an output media file.
bool _isOpen
Is the AVFormatContext open (in constructor with a filename)
void findStreamInfo(AVDictionary **options=NULL)
Read packets of a media file to get stream information.
void writeFrame(AVPacket &packet, bool interleaved=true)
Write a packet to an output media file.
AVFormatContext * _avFormatContext
Has ownership.
void openRessource(const std::string &url, int flags)
Create and initialize a AVIOContext for accessing the resource indicated by url.
FormatContext(const FormatContext &formatContext)
AVStream & getAVStream(size_t index) const
void setFilename(const std::string &filename)
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