libpromeki 1.0.0-alpha
PROfessional MEdia toolKIt
 
Loading...
Searching...
No Matches
quicktimemediaio.h
Go to the documentation of this file.
1
8#pragma once
9
10
11#include <promeki/config.h>
12#if PROMEKI_ENABLE_PROAV
13#include <promeki/audiobuffer.h>
14#include <promeki/audiodesc.h>
16#include <promeki/framecount.h>
17#include <promeki/framenumber.h>
18#include <promeki/framerate.h>
21#include <promeki/namespace.h>
22#include <promeki/quicktime.h>
23#include <promeki/string.h>
24#include <promeki/timecode.h>
25
26PROMEKI_NAMESPACE_BEGIN
27
68class QuickTimeMediaIO : public DedicatedThreadMediaIO {
69 PROMEKI_OBJECT(QuickTimeMediaIO, DedicatedThreadMediaIO)
70 public:
72 static inline constexpr int DefaultFragmentFrames = 30;
73
75 QuickTimeMediaIO(ObjectBase *parent = nullptr);
76
78 ~QuickTimeMediaIO() override;
79
80 Error proposeInput(const MediaDesc &offered, MediaDesc *preferred) const override;
81
82 protected:
83 Error executeCmd(MediaIOCommandOpen &cmd) override;
84 Error executeCmd(MediaIOCommandClose &cmd) override;
85 Error executeCmd(MediaIOCommandRead &cmd) override;
86 Error executeCmd(MediaIOCommandWrite &cmd) override;
87 Error executeCmd(MediaIOCommandSeek &cmd) override;
88
89 private:
90 // True when @p pd is a PixelFormat this writer knows how
91 // to serialise into a valid QuickTime sample entry plus
92 // mdat payload. See proposeInput() for the supported
93 // set and the rationale for each omission.
94 static bool isSupportedPixelFormat(const PixelFormat &pd);
95
96 // Picks the closest writer-supported PixelFormat for an
97 // offered shape, preserving bit depth, chroma
98 // subsampling, and YUV / RGB family where possible so
99 // the planner-inserted CSC stays cheap.
100 static PixelFormat pickSupportedPixelFormat(const PixelFormat &offered);
101
102 Error readVideoFrame(const FrameNumber &frameIndex, Frame &outFrame);
103 Error readAudioSlice(uint64_t startSample, size_t samples, MediaPayload::Ptr &out);
104 Error setupWriterFromFrame(const Frame &frame);
105 Error drainWriterAudio(bool flush);
106
107 QuickTime _qt;
108 bool _isOpen = false;
109 bool _isWrite = false;
110 String _filename;
111 int _videoTrackIndex = -1;
112 int _audioTrackIndex = -1;
113 FrameNumber _currentFrame{0};
114 FrameCount _frameCount{0};
115 FrameRate _frameRate;
116 Timecode _anchorTimecode;
117 uint64_t _audioSampleCursor = 0;
118 AudioDesc _audioDesc;
119
120 bool _writerTracksRegistered = false;
121 uint32_t _writerVideoTrackId = 0;
122 uint32_t _writerAudioTrackId = 0;
123 uint32_t _writerTimecodeTrackId = 0;
124 FrameCount _writerFrameCount{0};
125 int _writerFragmentFrames = DefaultFragmentFrames;
126 FrameCount _writerFramesSinceFlush{0};
127 AudioBuffer _writerAudioFifo;
128 AudioDesc _writerAudioStorage;
129};
130
135class QuickTimeFactory : public MediaIOFactory {
136 public:
137 QuickTimeFactory() = default;
138
139 String name() const override { return String("QuickTime"); }
140 String displayName() const override { return String("QuickTime / MOV"); }
141 String description() const override {
142 return String("QuickTime / ISO-BMFF container files (.mov, .mp4, .m4v)");
143 }
144 StringList extensions() const override {
145 return {String("mov"), String("qt"), String("mp4"), String("m4v")};
146 }
147
148 bool canBeSource() const override { return true; }
149 bool canBeSink() const override { return true; }
150
151 bool canHandleDevice(IODevice *device) const override;
152 Config::SpecMap configSpecs() const override;
153 Metadata defaultMetadata() const override;
154
155 MediaIO *create(const Config &config, ObjectBase *parent = nullptr) const override;
156};
157
158PROMEKI_NAMESPACE_END
159
160#endif // PROMEKI_ENABLE_PROAV