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 #if AVCPP_HAS_AVFORMAT
18 
19 extern "C" {
20 #include <libavformat/avformat.h>
21 }
22 
23 namespace av {
24 
25 using AvioInterruptCb = std::function<int()>;
26 
27 struct CustomIO
28 {
29  virtual ~CustomIO() {}
30  virtual int write(const uint8_t *data, size_t size)
31  {
32  static_cast<void>(data);
33  static_cast<void>(size);
34  return -1;
35  }
36  virtual int read(uint8_t *data, size_t size)
37  {
38  static_cast<void>(data);
39  static_cast<void>(size);
40  return -1;
41  }
43  virtual int64_t seek(int64_t offset, int whence)
44  {
45  static_cast<void>(offset);
46  static_cast<void>(whence);
47  return -1;
48  }
50  virtual int seekable() const { return 0; }
51  virtual const char* name() const { return ""; }
52 };
53 
54 class FormatContext : public FFWrapperPtr<AVFormatContext>, public noncopyable
55 {
56 public:
57  FormatContext();
58  ~FormatContext();
59 
60  void setSocketTimeout(int64_t timeout);
61  void setInterruptCallback(const AvioInterruptCb& cb);
62 
63  void setFormat(const InputFormat& format);
64  void setFormat(const OutputFormat& format);
65 
66  InputFormat inputFormat() const;
67  OutputFormat outputFormat() const;
68 
69  bool isOutput() const;
70  bool isOpened() const;
71 
72  void flush();
73  void close();
74  void dump() const;
75 
76  //
77  // Streams
78  //
79  size_t streamsCount() const;
80  Stream stream(size_t idx);
81  Stream stream(size_t idx, OptionalErrorCode ec);
82  [[deprecated("Codec is not used by the FFmpeg API. Use addStream() without codec and point configured codec context after")]]
83  Stream addStream(const Codec &codec, OptionalErrorCode ec = throws());
84  Stream addStream(OptionalErrorCode ec = throws());
85  Stream addStream(const class VideoEncoderContext& encCtx, OptionalErrorCode ec = throws());
86  Stream addStream(const class AudioEncoderContext& encCtx, OptionalErrorCode ec = throws());
87 
88  //
89  // Seeking
90  //
91  bool seekable() const noexcept;
92  void seek(const Timestamp& timestamp, OptionalErrorCode ec = throws());
93  void seek(const Timestamp& timestamp, size_t streamIndex, OptionalErrorCode ec = throws());
94  void seek(const Timestamp& timestamp, bool anyFrame, OptionalErrorCode ec = throws());
95  void seek(const Timestamp& timestamp, size_t streamIndex, bool anyFrame, OptionalErrorCode ec = throws());
96 
97  void seek(int64_t position, int streamIndex, int flags, OptionalErrorCode ec = throws());
98 
99  //
100  // Other tools
101  //
102  Timestamp startTime() const noexcept;
103  Timestamp duration() const noexcept;
104  void substractStartTime(bool enable);
105 
112  int eventFlags() const noexcept;
113  bool eventFlags(int flags) const noexcept;
114  void eventFlagsClear(int flags) noexcept;
115 
116  //
117  // Input
118  //
119  void openInput(const std::string& uri, OptionalErrorCode ec = throws());
120  void openInput(const std::string& uri, Dictionary &formatOptions, OptionalErrorCode ec = throws());
121  void openInput(const std::string& uri, Dictionary &&formatOptions, OptionalErrorCode ec = throws());
122 
123  void openInput(const std::string& uri, InputFormat format, OptionalErrorCode ec = throws());
124  void openInput(const std::string& uri, Dictionary &formatOptions, InputFormat format, OptionalErrorCode ec = throws());
125  void openInput(const std::string& uri, Dictionary &&formatOptions, InputFormat format, OptionalErrorCode ec = throws());
126 
127  static constexpr size_t CUSTOM_IO_DEFAULT_BUFFER_SIZE = 200000;
128 
129  void openInput(CustomIO *io,
130  OptionalErrorCode ec = throws(),
131  size_t internalBufferSize = CUSTOM_IO_DEFAULT_BUFFER_SIZE)
132  {
133  return openInput(io, InputFormat(), ec, internalBufferSize);
134  }
135  void openInput(CustomIO *io,
136  Dictionary &formatOptions,
137  OptionalErrorCode ec = throws(),
138  size_t internalBufferSize = CUSTOM_IO_DEFAULT_BUFFER_SIZE)
139  {
140  return openInput(io, formatOptions, InputFormat(), ec, internalBufferSize);
141  }
142  void openInput(CustomIO *io,
143  Dictionary &&formatOptions,
144  OptionalErrorCode ec = throws(),
145  size_t internalBufferSize = CUSTOM_IO_DEFAULT_BUFFER_SIZE)
146  {
147  return openInput(io, std::move(formatOptions), InputFormat(), ec, internalBufferSize);
148  }
149 
150  void openInput(CustomIO *io,
151  InputFormat format,
152  OptionalErrorCode ec = throws(),
153  size_t internalBufferSize = CUSTOM_IO_DEFAULT_BUFFER_SIZE);
154  void openInput(CustomIO *io,
155  Dictionary &formatOptions,
156  InputFormat format,
157  OptionalErrorCode ec = throws(),
158  size_t internalBufferSize = CUSTOM_IO_DEFAULT_BUFFER_SIZE);
159  void openInput(CustomIO *io,
160  Dictionary &&formatOptions,
161  InputFormat format,
162  OptionalErrorCode ec = throws(),
163  size_t internalBufferSize = CUSTOM_IO_DEFAULT_BUFFER_SIZE);
164 
165  void findStreamInfo(OptionalErrorCode ec = throws());
166  void findStreamInfo(DictionaryArray &streamsOptions, OptionalErrorCode ec = throws());
167  void findStreamInfo(DictionaryArray &&streamsOptions, OptionalErrorCode ec = throws());
168 
169  Packet readPacket(OptionalErrorCode ec = throws());
170 
171  //
172  // Output
173  //
174  void openOutput(const std::string& uri, OptionalErrorCode ec = throws());
175  void openOutput(const std::string& uri, Dictionary &options, OptionalErrorCode ec = throws());
176  void openOutput(const std::string& uri, Dictionary &&options, OptionalErrorCode ec = throws());
177 
178  // TBD
179  //void openOutput(const std::string& uri, OutputFormat format, OptionalErrorCode ec = throws());
180  //void openOutput(const std::string& uri, Dictionary &options, OutputFormat format, OptionalErrorCode ec = throws());
181  //void openOutput(const std::string& uri, Dictionary &&options, OutputFormat format, OptionalErrorCode ec = throws());
182 
183  void openOutput(CustomIO *io, OptionalErrorCode ec = throws(), size_t internalBufferSize = CUSTOM_IO_DEFAULT_BUFFER_SIZE);
184 
185  void writeHeader(OptionalErrorCode ec = throws());
186  void writeHeader(Dictionary &options, OptionalErrorCode ec = throws());
187  void writeHeader(Dictionary &&options, OptionalErrorCode ec = throws());
188 
189  void writePacket(OptionalErrorCode ec = throws());
190  void writePacket(const Packet &pkt, OptionalErrorCode ec = throws());
191  void writePacketDirect(OptionalErrorCode ec = throws());
192  void writePacketDirect(const Packet &pkt, OptionalErrorCode ec = throws());
193 
194  bool checkUncodedFrameWriting(size_t streamIndex, std::error_code &ec) noexcept;
195  bool checkUncodedFrameWriting(size_t streamIndex) noexcept;
196 
197  void writeUncodedFrame(class VideoFrame &frame, size_t streamIndex, OptionalErrorCode ec = throws());
198  void writeUncodedFrameDirect(class VideoFrame &frame, size_t streamIndex, OptionalErrorCode ec = throws());
199  void writeUncodedFrame(class AudioSamples &frame, size_t streamIndex, OptionalErrorCode ec = throws());
200  void writeUncodedFrameDirect(class AudioSamples &frame, size_t streamIndex, OptionalErrorCode ec = throws());
201 
202  void writeTrailer(OptionalErrorCode ec = throws());
203 
204 private:
205  void openInput(const std::string& uri, InputFormat format, AVDictionary **options, OptionalErrorCode ec);
206  void openOutput(const std::string& uri, OutputFormat format, AVDictionary **options, OptionalErrorCode ec);
207  void writeHeader(AVDictionary **options, OptionalErrorCode ec = throws());
208  void writePacket(const Packet &pkt, OptionalErrorCode ec, int(*write_proc)(AVFormatContext *, AVPacket *));
209  void writeFrame(AVFrame *frame, int streamIndex, OptionalErrorCode ec, int(*write_proc)(AVFormatContext*,int,AVFrame*));
210 
211  Stream addStream(const class CodecContext2 &ctx, OptionalErrorCode ec);
212 
213  static int avioInterruptCb(void *opaque);
214  int avioInterruptCb();
215  void setupInterruptHandling();
216  void resetSocketAccess();
217  void findStreamInfo(AVDictionary **options, size_t optionsCount, OptionalErrorCode ec);
218  void closeCodecContexts();
219  int checkPbError(int stat);
220 
221  void openCustomIO(CustomIO *io, size_t internalBufferSize, bool isWritable, OptionalErrorCode ec);
222  void openCustomIOInput(CustomIO *io, size_t internalBufferSize, OptionalErrorCode ec);
223  void openCustomIOOutput(CustomIO *io, size_t internalBufferSize, OptionalErrorCode ec);
224 
225 private:
226  std::shared_ptr<char> m_monitor {new char};
227  std::chrono::time_point<std::chrono::system_clock> m_lastSocketAccess;
228  int64_t m_socketTimeout = -1;
229  AvioInterruptCb m_interruptCb;
230 
231  bool m_isOpened = false;
232  bool m_customIO = false;
233  bool m_streamsInfoFound = false;
234  bool m_headerWriten = false;
235  bool m_substractStartTime = false;
236 };
237 
238 } // namespace av
239 
240 #endif // if AVCPP_HAS_AVFORMAT
Definition: audioresampler.cpp:8
OptionalErrorCode throws()
Helper to construct null OptionalErrorCode object.
Definition: averror.h:179
Definition: averror.h:228
Definition: ffmpeg.h:22