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 
Definition: codeccontext.h:593
Definition: frame.h:446
Definition: codeccontext.h:33
Definition: codec.h:18
Array of Dictinaries wrapper.
Definition: dictionary.h:589
Implements interface to access to the AVDictionary entity.
Definition: dictionary.h:31
Definition: formatcontext.h:54
void setInterruptCallback(const AvioInterruptCb &cb)
Definition: formatcontext.cpp:94
~FormatContext()
Definition: formatcontext.cpp:80
void close()
Definition: formatcontext.cpp:157
void writeUncodedFrameDirect(class VideoFrame &frame, size_t streamIndex, OptionalErrorCode ec=throws())
Definition: formatcontext.cpp:796
void openInput(CustomIO *io, Dictionary &formatOptions, OptionalErrorCode ec=throws(), size_t internalBufferSize=CUSTOM_IO_DEFAULT_BUFFER_SIZE)
Definition: formatcontext.h:134
OutputFormat outputFormat() const
Definition: formatcontext.cpp:131
void setSocketTimeout(int64_t timeout)
Definition: formatcontext.cpp:89
Stream addStream(const class VideoEncoderContext &encCtx, OptionalErrorCode ec=throws())
void openInput(const std::string &uri, OptionalErrorCode ec=throws())
Stream addStream(const Codec &codec, OptionalErrorCode ec=throws())
Definition: formatcontext.cpp:232
void openInput(CustomIO *io, Dictionary &&formatOptions, OptionalErrorCode ec=throws(), size_t internalBufferSize=CUSTOM_IO_DEFAULT_BUFFER_SIZE)
Definition: formatcontext.h:141
void writeUncodedFrame(class VideoFrame &frame, size_t streamIndex, OptionalErrorCode ec=throws())
Definition: formatcontext.cpp:791
InputFormat inputFormat() const
Definition: formatcontext.cpp:123
void writeTrailer(OptionalErrorCode ec=throws())
Definition: formatcontext.cpp:915
void writeHeader(OptionalErrorCode ec=throws())
Definition: formatcontext.cpp:686
void openOutput(const std::string &uri, OptionalErrorCode ec=throws())
Timestamp duration() const noexcept
Definition: formatcontext.cpp:370
Timestamp startTime() const noexcept
Definition: formatcontext.cpp:334
bool isOpened() const
Definition: formatcontext.cpp:144
static constexpr size_t CUSTOM_IO_DEFAULT_BUFFER_SIZE
Definition: formatcontext.h:126
void eventFlagsClear(int flags) noexcept
Definition: formatcontext.cpp:357
void substractStartTime(bool enable)
Definition: formatcontext.cpp:364
int eventFlags() const noexcept
Flags to the user to detect events happening on the file.
Definition: formatcontext.cpp:343
Stream addStream(const class AudioEncoderContext &encCtx, OptionalErrorCode ec=throws())
bool checkUncodedFrameWriting(size_t streamIndex, std::error_code &ec) noexcept
void writePacket(OptionalErrorCode ec=throws())
Definition: formatcontext.cpp:734
bool isOutput() const
Definition: formatcontext.cpp:139
void openOutput(const std::string &uri, Dictionary &&options, OptionalErrorCode ec=throws())
void dump() const
Definition: formatcontext.cpp:196
void flush()
Definition: formatcontext.cpp:149
void setFormat(const InputFormat &format)
Definition: formatcontext.cpp:99
void findStreamInfo(OptionalErrorCode ec=throws())
Definition: formatcontext.cpp:477
FormatContext()
Definition: formatcontext.cpp:74
void writePacketDirect(OptionalErrorCode ec=throws())
Definition: formatcontext.cpp:744
bool seekable() const noexcept
Definition: formatcontext.cpp:292
void seek(const Timestamp &timestamp, OptionalErrorCode ec=throws())
Definition: formatcontext.cpp:300
size_t streamsCount() const
Definition: formatcontext.cpp:204
Stream stream(size_t idx)
Definition: formatcontext.cpp:209
Packet readPacket(OptionalErrorCode ec=throws())
Definition: formatcontext.cpp:499
void openOutput(const std::string &uri, Dictionary &options, OptionalErrorCode ec=throws())
Definition: format.h:72
Definition: averror.h:64
Definition: format.h:87
Definition: packet.h:24
Definition: stream.h:23
The Timestamp class represents timestamp value and it timebase.
Definition: timestamp.h:14
Definition: codeccontext.h:447
Definition: frame.h:359
Definition: avutils.h:85
Definition: audioresampler.cpp:8
OptionalErrorCode throws()
Helper to construct null OptionalErrorCode object.
Definition: averror.h:179
std::function< int()> AvioInterruptCb
Definition: formatcontext.h:24
Definition: averror.h:228
Definition: ffmpeg.h:67
Definition: formatcontext.h:27
virtual int write(const uint8_t *data, size_t size)
Definition: formatcontext.h:29
virtual ~CustomIO()
Definition: formatcontext.h:28
virtual int seekable() const
Return combination of AVIO_SEEKABLE_* flags or zero.
Definition: formatcontext.h:49
virtual const char * name() const
Definition: formatcontext.h:50
virtual int read(uint8_t *data, size_t size)
Definition: formatcontext.h:35
virtual int64_t seek(int64_t offset, int whence)
whence is a one of SEEK_* from stdio.h
Definition: formatcontext.h:42