11#include <promeki/config.h>
12#if PROMEKI_ENABLE_PROAV
28PROMEKI_NAMESPACE_BEGIN
70class QuickTimeMediaIO :
public DedicatedThreadMediaIO {
71 PROMEKI_OBJECT(QuickTimeMediaIO, DedicatedThreadMediaIO)
74 static inline constexpr int DefaultFragmentFrames = 30;
77 QuickTimeMediaIO(ObjectBase *parent =
nullptr);
80 ~QuickTimeMediaIO()
override;
82 Error proposeInput(
const MediaDesc &offered, MediaDesc *preferred)
const override;
85 Error executeCmd(MediaIOCommandOpen &cmd)
override;
86 Error executeCmd(MediaIOCommandClose &cmd)
override;
87 Error executeCmd(MediaIOCommandRead &cmd)
override;
88 Error executeCmd(MediaIOCommandWrite &cmd)
override;
89 Error executeCmd(MediaIOCommandSeek &cmd)
override;
96 static bool isSupportedPixelFormat(
const PixelFormat &pd);
102 static PixelFormat pickSupportedPixelFormat(
const PixelFormat &offered);
108 void rewriteAudioForCodec(MediaDesc &desc)
const;
115 void rewriteVideoForCodec(MediaDesc &desc)
const;
121 VideoScanMode resolveWriteScanMode(
const VideoScanMode &descScanMode)
const;
123 Error readVideoFrame(
const FrameNumber &frameIndex, Frame &outFrame);
124 Error readAudioSlice(uint64_t startSample,
size_t samples, MediaPayload::Ptr &out);
125 Error setupWriterFromFrame(
const Frame &frame);
126 Error drainWriterAudio(
bool flush);
129 bool _isOpen =
false;
130 bool _isWrite =
false;
132 int _videoTrackIndex = -1;
133 int _audioTrackIndex = -1;
134 int _ancTrackIndex = -1;
135 int _captionTrackIndex = -1;
136 QuickTimeCaptionReadPolicy _captionReadPolicy{QuickTimeCaptionReadPolicy::Auto};
137 FrameNumber _currentFrame{0};
138 FrameCount _frameCount{0};
139 FrameRate _frameRate;
140 Timecode _anchorTimecode;
141 uint64_t _audioSampleCursor = 0;
146 uint64_t _audioCompressedFrameSamples = 0;
147 AudioDesc _audioDesc;
150 bool _writerTracksRegistered =
false;
151 uint32_t _writerVideoTrackId = 0;
152 uint32_t _writerAudioTrackId = 0;
153 uint32_t _writerAncTrackId = 0;
154 uint32_t _writerCaptionTrackId = 0;
155 uint32_t _writerTimecodeTrackId = 0;
156 FrameCount _writerFrameCount{0};
157 int _writerFragmentFrames = DefaultFragmentFrames;
158 FrameCount _writerFramesSinceFlush{0};
159 AudioBuffer _writerAudioFifo;
160 AudioDesc _writerAudioStorage;
167class QuickTimeFactory :
public MediaIOFactory {
169 QuickTimeFactory() =
default;
171 String name()
const override {
return String(
"QuickTime"); }
172 String displayName()
const override {
return String(
"QuickTime / MOV"); }
173 String description()
const override {
174 return String(
"QuickTime / ISO-BMFF container files (.mov, .mp4, .m4v)");
176 StringList extensions()
const override {
177 return {String(
"mov"), String(
"qt"), String(
"mp4"), String(
"m4v")};
180 bool canBeSource()
const override {
return true; }
181 bool canBeSink()
const override {
return true; }
183 bool canHandleDevice(IODevice *device)
const override;
184 Config::SpecMap configSpecs()
const override;
185 Metadata defaultMetadata()
const override;
187 MediaIO *create(
const Config &config, ObjectBase *parent =
nullptr)
const override;