libpromeki 1.0.0-alpha
PROfessional MEdia toolKIt
 
Loading...
Searching...
No Matches
ffmpegmediaio.h
Go to the documentation of this file.
1
8#pragma once
9
10
11#include <promeki/config.h>
12#if PROMEKI_ENABLE_PROAV && PROMEKI_ENABLE_FFMPEG
13#include <promeki/audiodesc.h>
15#include <promeki/deque.h>
16#include <promeki/framecount.h>
17#include <promeki/framenumber.h>
18#include <promeki/framerate.h>
20#include <promeki/namespace.h>
21#include <promeki/string.h>
22
23// Forward-declare the libav* types we hold by pointer so this promeki
24// header never pulls in the libavformat / libavcodec headers — they live
25// only in the .cpp.
26struct AVFormatContext;
27struct AVBSFContext;
28struct AVStream;
29struct AVPacket;
30
31PROMEKI_NAMESPACE_BEGIN
32
101class FfmpegMediaIO : public DedicatedThreadMediaIO {
102 PROMEKI_OBJECT(FfmpegMediaIO, DedicatedThreadMediaIO)
103 public:
105 FfmpegMediaIO(ObjectBase *parent = nullptr);
106
108 ~FfmpegMediaIO() override;
109
110 Error proposeInput(const MediaDesc &offered, MediaDesc *preferred) const override;
111
112 protected:
113 Error executeCmd(MediaIOCommandOpen &cmd) override;
114 Error executeCmd(MediaIOCommandClose &cmd) override;
115 Error executeCmd(MediaIOCommandRead &cmd) override;
116 Error executeCmd(MediaIOCommandWrite &cmd) override;
117 Error executeCmd(MediaIOCommandSeek &cmd) override;
118
119 private:
120 Error openReader(const MediaIOCommandOpen &cmd, MediaIOCommandOpen &out);
121 Error openWriter(const MediaIOCommandOpen &cmd, MediaIOCommandOpen &out);
122 Error setupWriterFromFrame(const Frame &frame);
123 void closeContexts();
124
125 // Rewrites @p desc's image / audio descriptors to the compressed
126 // formats named by MediaConfig::FfmpegVideoCodec /
127 // FfmpegAudioCodec, so the planner splices encoders. Invalid /
128 // already-compressed streams are left untouched.
129 void rewriteVideoForCodec(MediaDesc &desc) const;
130 void rewriteAudioForCodec(MediaDesc &desc) const;
131
132 // ---- Shared state ----
133 bool _isOpen = false;
134 bool _isWrite = false;
135 String _filename;
136
137 // ---- Reader state ----
138 AVFormatContext *_inFmt = nullptr;
139 AVBSFContext *_bsf = nullptr; // h264/hevc mp4toannexb, or null
140 int _videoStream = -1;
141 int _audioStream = -1;
142 FrameRate _frameRate;
143 FrameCount _frameCount{FrameCount::unknown()};
144 FrameNumber _currentFrame{0};
145 AudioDesc _audioDesc;
146 bool _eof = false;
147
148 // ---- Writer state ----
149 AVFormatContext *_outFmt = nullptr;
150 AVStream *_outVideo = nullptr;
151 AVStream *_outAudio = nullptr;
152 bool _headerWritten = false;
153 bool _writerTracksRegistered = false;
154 int64_t _writerVideoPts = 0;
155 int64_t _writerAudioPts = 0;
156};
157
165class FfmpegFactory : public MediaIOFactory {
166 public:
167 FfmpegFactory() = default;
168
169 String name() const override { return String("FFmpeg"); }
170 String displayName() const override { return String("FFmpeg (libavformat)"); }
171 String description() const override {
172 return String("Generic FFmpeg container backend (Matroska/WebM, AVI, FLV, …)");
173 }
174
175 // The fallback extension list deliberately covers only
176 // containers no native backend claims; .mov / .mp4 / .wav
177 // etc. are intentionally absent so the native backends win
178 // the auto-dispatch. (isFallback() makes the order moot,
179 // but keeping the list narrow keeps probe behaviour clear.)
180 StringList extensions() const override {
181 return {String("mkv"), String("webm"), String("avi"), String("flv"),
182 String("wmv"), String("asf"), String("ogv"), String("ogg"),
183 String("mpg"), String("mpeg"), String("vob"), String("3gp"),
184 String("rm"), String("rmvb"), String("nut"), String("mxf")};
185 }
186
187 bool canBeSource() const override { return true; }
188 bool canBeSink() const override { return true; }
189 bool isFallback() const override { return true; }
190
191 bool canHandleDevice(IODevice *device) const override;
192 Config::SpecMap configSpecs() const override;
193
194 MediaIO *create(const Config &config, ObjectBase *parent = nullptr) const override;
195};
196
197PROMEKI_NAMESPACE_END
198
199#endif // PROMEKI_ENABLE_PROAV && PROMEKI_ENABLE_FFMPEG