avcpp  2.0
Wrapper for the FFmpeg that simplify usage from C++ projects.
formatcontext.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <memory>
4 #include <chrono>
5 #include <functional>
6 #include <vector>
7 
8 #include "ffmpeg.h"
9 #include "format.h"
10 #include "avutils.h"
11 #include "stream.h"
12 #include "packet.h"
13 #include "codec.h"
14 #include "dictionary.h"
15 #include "averror.h"
16 
17 extern "C" {
18 #include <libavformat/avformat.h>
19 //#include <libavformat/avio.h>
20 }
21 
22 namespace av {
23 
24 using AvioInterruptCb = std::function<int()>;
25 
26 struct CustomIO
27 {
28  virtual ~CustomIO() {}
29  virtual int write(const uint8_t *data, size_t size)
30  {
31  static_cast<void>(data);
32  static_cast<void>(size);
33  return -1;
34  }
35  virtual int read(uint8_t *data, size_t size)
36  {
37  static_cast<void>(data);
38  static_cast<void>(size);
39  return -1;
40  }
42  virtual int64_t seek(int64_t offset, int whence)
43  {
44  static_cast<void>(offset);
45  static_cast<void>(whence);
46  return -1;
47  }
49  virtual int seekable() const { return 0; }
50  virtual const char* name() const { return ""; }
51 };
52 
53 class FormatContext : public FFWrapperPtr<AVFormatContext>, public noncopyable
54 {
55 public:
56  FormatContext();
58 
59  void setSocketTimeout(int64_t timeout);
60  void setInterruptCallback(const AvioInterruptCb& cb);
61 
62  void setFormat(const InputFormat& format);
63  void setFormat(const OutputFormat& format);
64 
65  InputFormat inputFormat() const;
66  OutputFormat outputFormat() const;
67 
68  bool isOutput() const;
69  bool isOpened() const;
70 
71  void flush();
72  void close();
73  void dump() const;
74 
75  //
76  // Streams
77  //
78  size_t streamsCount() const;
79  Stream stream(size_t idx);
80  Stream stream(size_t idx, OptionalErrorCode ec);
81  [[deprecated("Codec is not used by the FFmpeg API. Use addStream() without codec and point configured codec context after")]]
82  Stream addStream(const Codec &codec, OptionalErrorCode ec = throws());
83  Stream addStream(OptionalErrorCode ec = throws());
84  Stream addStream(const class VideoEncoderContext& encCtx, OptionalErrorCode ec = throws());
85  Stream addStream(const class AudioEncoderContext& encCtx, OptionalErrorCode ec = throws());
86 
87  //
88  // Seeking
89  //
90  bool seekable() const noexcept;
91  void seek(const Timestamp& timestamp, OptionalErrorCode ec = throws());
92  void seek(const Timestamp& timestamp, size_t streamIndex, OptionalErrorCode ec = throws());
93  void seek(const Timestamp& timestamp, bool anyFrame, OptionalErrorCode ec = throws());
94  void seek(const Timestamp& timestamp, size_t streamIndex, bool anyFrame, OptionalErrorCode ec = throws());
95 
96  void seek(int64_t position, int streamIndex, int flags, OptionalErrorCode ec = throws());
97 
98  //
99  // Other tools
100  //
101  Timestamp startTime() const noexcept;
102  Timestamp duration() const noexcept;
103  void substractStartTime(bool enable);
104 
111  int eventFlags() const noexcept;
112  bool eventFlags(int flags) const noexcept;
113  void eventFlagsClear(int flags) noexcept;
114 
115  //
116  // Input
117  //
118  void openInput(const std::string& uri, OptionalErrorCode ec = throws());
119  void openInput(const std::string& uri, Dictionary &formatOptions, OptionalErrorCode ec = throws());
120  void openInput(const std::string& uri, Dictionary &&formatOptions, OptionalErrorCode ec = throws());
121 
122  void openInput(const std::string& uri, InputFormat format, OptionalErrorCode ec = throws());
123  void openInput(const std::string& uri, Dictionary &formatOptions, InputFormat format, OptionalErrorCode ec = throws());
124  void openInput(const std::string& uri, Dictionary &&formatOptions, InputFormat format, OptionalErrorCode ec = throws());
125 
126  static constexpr size_t CUSTOM_IO_DEFAULT_BUFFER_SIZE = 200000;
127 
128  void openInput(CustomIO *io,
129  OptionalErrorCode ec = throws(),
130  size_t internalBufferSize = CUSTOM_IO_DEFAULT_BUFFER_SIZE)
131  {
132  return openInput(io, InputFormat(), ec, internalBufferSize);
133  }
134  void openInput(CustomIO *io,
135  Dictionary &formatOptions,
136  OptionalErrorCode ec = throws(),
137  size_t internalBufferSize = CUSTOM_IO_DEFAULT_BUFFER_SIZE)
138  {
139  return openInput(io, formatOptions, InputFormat(), ec, internalBufferSize);
140  }
141  void openInput(CustomIO *io,
142  Dictionary &&formatOptions,
143  OptionalErrorCode ec = throws(),
144  size_t internalBufferSize = CUSTOM_IO_DEFAULT_BUFFER_SIZE)
145  {
146  return openInput(io, std::move(formatOptions), InputFormat(), ec, internalBufferSize);
147  }
148 
149  void openInput(CustomIO *io,
150  InputFormat format,
151  OptionalErrorCode ec = throws(),
152  size_t internalBufferSize = CUSTOM_IO_DEFAULT_BUFFER_SIZE);
153  void openInput(CustomIO *io,
154  Dictionary &formatOptions,
155  InputFormat format,
156  OptionalErrorCode ec = throws(),
157  size_t internalBufferSize = CUSTOM_IO_DEFAULT_BUFFER_SIZE);
158  void openInput(CustomIO *io,
159  Dictionary &&formatOptions,
160  InputFormat format,
161  OptionalErrorCode ec = throws(),
162  size_t internalBufferSize = CUSTOM_IO_DEFAULT_BUFFER_SIZE);
163 
164  void findStreamInfo(OptionalErrorCode ec = throws());
165  void findStreamInfo(DictionaryArray &streamsOptions, OptionalErrorCode ec = throws());
166  void findStreamInfo(DictionaryArray &&streamsOptions, OptionalErrorCode ec = throws());
167 
168  Packet readPacket(OptionalErrorCode ec = throws());
169 
170  //
171  // Output
172  //
173  void openOutput(const std::string& uri, OptionalErrorCode ec = throws());
174  void openOutput(const std::string& uri, Dictionary &options, OptionalErrorCode ec = throws());
175  void openOutput(const std::string& uri, Dictionary &&options, OptionalErrorCode ec = throws());
176 
177  // TBD
178  //void openOutput(const std::string& uri, OutputFormat format, OptionalErrorCode ec = throws());
179  //void openOutput(const std::string& uri, Dictionary &options, OutputFormat format, OptionalErrorCode ec = throws());
180  //void openOutput(const std::string& uri, Dictionary &&options, OutputFormat format, OptionalErrorCode ec = throws());
181 
182  void openOutput(CustomIO *io, OptionalErrorCode ec = throws(), size_t internalBufferSize = CUSTOM_IO_DEFAULT_BUFFER_SIZE);
183 
184  void writeHeader(OptionalErrorCode ec = throws());
185  void writeHeader(Dictionary &options, OptionalErrorCode ec = throws());
186  void writeHeader(Dictionary &&options, OptionalErrorCode ec = throws());
187 
188  void writePacket(OptionalErrorCode ec = throws());
189  void writePacket(const Packet &pkt, OptionalErrorCode ec = throws());
190  void writePacketDirect(OptionalErrorCode ec = throws());
191  void writePacketDirect(const Packet &pkt, OptionalErrorCode ec = throws());
192 
193  bool checkUncodedFrameWriting(size_t streamIndex, std::error_code &ec) noexcept;
194  bool checkUncodedFrameWriting(size_t streamIndex) noexcept;
195 
196  void writeUncodedFrame(class VideoFrame &frame, size_t streamIndex, OptionalErrorCode ec = throws());
197  void writeUncodedFrameDirect(class VideoFrame &frame, size_t streamIndex, OptionalErrorCode ec = throws());
198  void writeUncodedFrame(class AudioSamples &frame, size_t streamIndex, OptionalErrorCode ec = throws());
199  void writeUncodedFrameDirect(class AudioSamples &frame, size_t streamIndex, OptionalErrorCode ec = throws());
200 
201  void writeTrailer(OptionalErrorCode ec = throws());
202 
203 private:
204  void openInput(const std::string& uri, InputFormat format, AVDictionary **options, OptionalErrorCode ec);
205  void openOutput(const std::string& uri, OutputFormat format, AVDictionary **options, OptionalErrorCode ec);
206  void writeHeader(AVDictionary **options, OptionalErrorCode ec = throws());
207  void writePacket(const Packet &pkt, OptionalErrorCode ec, int(*write_proc)(AVFormatContext *, AVPacket *));
208  void writeFrame(AVFrame *frame, int streamIndex, OptionalErrorCode ec, int(*write_proc)(AVFormatContext*,int,AVFrame*));
209 
210  Stream addStream(const class CodecContext2 &ctx, OptionalErrorCode ec);
211 
212  static int avioInterruptCb(void *opaque);
213  int avioInterruptCb();
214  void setupInterruptHandling();
215  void resetSocketAccess();
216  void findStreamInfo(AVDictionary **options, size_t optionsCount, OptionalErrorCode ec);
217  void closeCodecContexts();
218  int checkPbError(int stat);
219 
220  void openCustomIO(CustomIO *io, size_t internalBufferSize, bool isWritable, OptionalErrorCode ec);
221  void openCustomIOInput(CustomIO *io, size_t internalBufferSize, OptionalErrorCode ec);
222  void openCustomIOOutput(CustomIO *io, size_t internalBufferSize, OptionalErrorCode ec);
223 
224 private:
225  std::shared_ptr<char> m_monitor {new char};
226  std::chrono::time_point<std::chrono::system_clock> m_lastSocketAccess;
227  int64_t m_socketTimeout = -1;
228  AvioInterruptCb m_interruptCb;
229 
230  bool m_isOpened = false;
231  bool m_customIO = false;
232  bool m_streamsInfoFound = false;
233  bool m_headerWriten = false;
234  bool m_substractStartTime = false;
235 };
236 
237 } // namespace av
238 
av::FormatContext::dump
void dump() const
Definition: formatcontext.cpp:196
av::FormatContext::stream
Stream stream(size_t idx)
Definition: formatcontext.cpp:209
av::FormatContext::flush
void flush()
Definition: formatcontext.cpp:149
av::DictionaryArray
Array of Dictinaries wrapper.
Definition: dictionary.h:588
av::Dictionary
Implements interface to access to the AVDictionary entity.
Definition: dictionary.h:30
av::OutputFormat
Definition: format.h:86
av::FormatContext::openInput
void openInput(CustomIO *io, Dictionary &formatOptions, OptionalErrorCode ec=throws(), size_t internalBufferSize=CUSTOM_IO_DEFAULT_BUFFER_SIZE)
Definition: formatcontext.h:134
av::CustomIO::~CustomIO
virtual ~CustomIO()
Definition: formatcontext.h:28
av::InputFormat
Definition: format.h:71
averror.h
av::FormatContext::close
void close()
Definition: formatcontext.cpp:157
ffmpeg.h
av::FormatContext::inputFormat
InputFormat inputFormat() const
Definition: formatcontext.cpp:123
FFWrapperPtr
Definition: ffmpeg.h:68
av::FormatContext::writeUncodedFrame
void writeUncodedFrame(class VideoFrame &frame, size_t streamIndex, OptionalErrorCode ec=throws())
Definition: formatcontext.cpp:791
format.h
av::CustomIO::read
virtual int read(uint8_t *data, size_t size)
Definition: formatcontext.h:35
av::FormatContext::eventFlagsClear
void eventFlagsClear(int flags) noexcept
Definition: formatcontext.cpp:357
av::FormatContext::addStream
Stream addStream(const Codec &codec, OptionalErrorCode ec=throws())
Definition: formatcontext.cpp:232
av::FormatContext::setSocketTimeout
void setSocketTimeout(int64_t timeout)
Definition: formatcontext.cpp:89
av::FormatContext::setInterruptCallback
void setInterruptCallback(const AvioInterruptCb &cb)
Definition: formatcontext.cpp:94
codec.h
av::FormatContext::openInput
void openInput(const std::string &uri, OptionalErrorCode ec=throws())
av::FormatContext::CUSTOM_IO_DEFAULT_BUFFER_SIZE
static constexpr size_t CUSTOM_IO_DEFAULT_BUFFER_SIZE
Definition: formatcontext.h:126
av::OptionalErrorCode
Definition: averror.h:63
av::FormatContext::writePacket
void writePacket(OptionalErrorCode ec=throws())
Definition: formatcontext.cpp:734
av::FormatContext::duration
Timestamp duration() const noexcept
Definition: formatcontext.cpp:370
av::FormatContext::findStreamInfo
void findStreamInfo(OptionalErrorCode ec=throws())
Definition: formatcontext.cpp:477
avutils.h
av::FormatContext::openOutput
void openOutput(const std::string &uri, OptionalErrorCode ec=throws())
av::FormatContext::checkUncodedFrameWriting
bool checkUncodedFrameWriting(size_t streamIndex, std::error_code &ec) noexcept
stream.h
av::FormatContext::writePacketDirect
void writePacketDirect(OptionalErrorCode ec=throws())
Definition: formatcontext.cpp:744
av::CustomIO::seek
virtual int64_t seek(int64_t offset, int whence)
whence is a one of SEEK_* from stdio.h
Definition: formatcontext.h:42
av::CustomIO
Definition: formatcontext.h:26
av::CodecContext2
Definition: codeccontext.h:28
av::AudioSamples
Definition: frame.h:391
av::VideoEncoderContext
Definition: codeccontext.h:442
av::FormatContext::eventFlags
int eventFlags() const noexcept
Flags to the user to detect events happening on the file.
Definition: formatcontext.cpp:343
av::CustomIO::seekable
virtual int seekable() const
Return combination of AVIO_SEEKABLE_* flags or zero.
Definition: formatcontext.h:49
av::FormatContext::~FormatContext
~FormatContext()
Definition: formatcontext.cpp:80
av::CustomIO::name
virtual const char * name() const
Definition: formatcontext.h:50
packet.h
dictionary.h
av::Packet
Definition: packet.h:18
av::VideoFrame
Definition: frame.h:354
av::FormatContext::seek
void seek(const Timestamp &timestamp, OptionalErrorCode ec=throws())
Definition: formatcontext.cpp:300
av
Definition: audioresampler.cpp:8
av::AudioEncoderContext
Definition: codeccontext.h:588
av::FormatContext::isOutput
bool isOutput() const
Definition: formatcontext.cpp:139
av::FormatContext::FormatContext
FormatContext()
Definition: formatcontext.cpp:74
av::CustomIO::write
virtual int write(const uint8_t *data, size_t size)
Definition: formatcontext.h:29
av::FormatContext::readPacket
Packet readPacket(OptionalErrorCode ec=throws())
Definition: formatcontext.cpp:499
av::FormatContext::writeUncodedFrameDirect
void writeUncodedFrameDirect(class VideoFrame &frame, size_t streamIndex, OptionalErrorCode ec=throws())
Definition: formatcontext.cpp:796
av::FormatContext::isOpened
bool isOpened() const
Definition: formatcontext.cpp:144
av::AvioInterruptCb
std::function< int()> AvioInterruptCb
Definition: formatcontext.h:24
av::noncopyable
Definition: avutils.h:69
av::FormatContext::substractStartTime
void substractStartTime(bool enable)
Definition: formatcontext.cpp:364
av::FormatContext::outputFormat
OutputFormat outputFormat() const
Definition: formatcontext.cpp:131
av::FormatContext
Definition: formatcontext.h:53
av::FormatContext::startTime
Timestamp startTime() const noexcept
Definition: formatcontext.cpp:334
av::Timestamp
The Timestamp class represents timestamp value and it timebase.
Definition: timestamp.h:13
av::FormatContext::writeTrailer
void writeTrailer(OptionalErrorCode ec=throws())
Definition: formatcontext.cpp:915
av::FormatContext::openInput
void openInput(CustomIO *io, OptionalErrorCode ec=throws(), size_t internalBufferSize=CUSTOM_IO_DEFAULT_BUFFER_SIZE)
Definition: formatcontext.h:128
av::Codec
Definition: codec.h:17
av::FormatContext::streamsCount
size_t streamsCount() const
Definition: formatcontext.cpp:204
av::FormatContext::setFormat
void setFormat(const InputFormat &format)
Definition: formatcontext.cpp:99
av::FormatContext::writeHeader
void writeHeader(OptionalErrorCode ec=throws())
Definition: formatcontext.cpp:686
av::Stream
Definition: stream.h:22
av::FormatContext::seekable
bool seekable() const noexcept
Definition: formatcontext.cpp:292
av::FormatContext::openInput
void openInput(CustomIO *io, Dictionary &&formatOptions, OptionalErrorCode ec=throws(), size_t internalBufferSize=CUSTOM_IO_DEFAULT_BUFFER_SIZE)
Definition: formatcontext.h:141