11#include <promeki/config.h>
12#if PROMEKI_ENABLE_PROAV
31PROMEKI_NAMESPACE_BEGIN
70 using Ptr = SharedPtr<QuickTime>;
127 bool isValid()
const {
return _type != InvalidTrack; }
130 TrackType type()
const {
return _type; }
132 uint32_t id()
const {
return _id; }
134 uint32_t timescale()
const {
return _timescale; }
136 uint64_t duration()
const {
return _duration; }
138 const FrameRate &frameRate()
const {
return _frameRate; }
140 uint64_t sampleCount()
const {
return _sampleCount; }
142 const String &language()
const {
return _language; }
144 const String &name()
const {
return _name; }
146 const PixelFormat &pixelFormat()
const {
return _pixelFormat; }
148 const Size2Du32 &size()
const {
return _size; }
150 const AudioDesc &audioDesc()
const {
return _audioDesc; }
152 const Metadata &metadata()
const {
return _metadata; }
154 int64_t editStartOffset()
const {
return _editStartOffset; }
163 const Buffer &codecConfig()
const {
return _codecConfig; }
170 FourCC codecConfigType()
const {
return _codecConfigType; }
173 void setType(TrackType t) { _type = t; }
175 void setId(uint32_t
id) { _id = id; }
177 void setTimescale(uint32_t ts) { _timescale = ts; }
179 void setDuration(uint64_t d) { _duration = d; }
181 void setFrameRate(
const FrameRate &r) { _frameRate = r; }
183 void setSampleCount(uint64_t n) { _sampleCount = n; }
185 void setLanguage(
const String &s) { _language = s; }
187 void setName(
const String &s) { _name = s; }
189 void setPixelFormat(
const PixelFormat &pd) { _pixelFormat = pd; }
191 void setSize(
const Size2Du32 &s) { _size = s; }
193 void setAudioDesc(
const AudioDesc &ad) { _audioDesc = ad; }
195 Metadata &metadata() {
return _metadata; }
197 void setEditStartOffset(int64_t v) { _editStartOffset = v; }
199 void setCodecConfig(
const Buffer &b) { _codecConfig = b; }
201 void setCodecConfigType(FourCC t) { _codecConfigType = t; }
204 TrackType _type = InvalidTrack;
206 uint32_t _timescale = 0;
207 uint64_t _duration = 0;
208 FrameRate _frameRate;
209 uint64_t _sampleCount = 0;
212 PixelFormat _pixelFormat;
214 AudioDesc _audioDesc;
216 int64_t _editStartOffset = 0;
218 FourCC _codecConfigType{
'\0',
'\0',
'\0',
'\0'};
222 using TrackList = ::promeki::List<Track>;
233 uint32_t trackId = 0;
237 uint64_t duration = 0;
238 bool keyframe =
false;
251 PROMEKI_SHARED_BASE(Impl)
254 explicit Impl(Operation op) : _operation(op) {}
260 Operation operation()
const {
return _operation; }
263 const String &filename()
const {
return _filename; }
266 void setFilename(
const String &fn) { _filename = fn; }
269 IODevice *device()
const {
return _device; }
275 void setDevice(IODevice *dev,
bool takeOwnership =
false) {
277 _ownsDevice = takeOwnership;
281 virtual Error open();
284 virtual void close();
287 virtual bool isOpen()
const;
299 virtual Error readSample(
size_t trackIndex, uint64_t sampleIndex, Sample &out);
317 virtual Error readSampleRange(
size_t trackIndex, uint64_t startSampleIndex,
318 uint64_t count, Sample &out);
329 virtual Error addVideoTrack(
const PixelFormat &codec,
const Size2Du32 &size,
330 const FrameRate &frameRate, uint32_t *outTrackId);
339 virtual Error addAudioTrack(
const AudioDesc &desc, uint32_t *outTrackId);
350 virtual Error addTimecodeTrack(
const Timecode &startTimecode,
351 const FrameRate &frameRate, uint32_t *outTrackId);
366 virtual Error writeSample(uint32_t trackId,
const Sample &sample);
369 virtual void setContainerMetadata(
const Metadata &meta);
372 Layout layout()
const {
return _layout; }
379 virtual Error setLayout(Layout layout);
382 bool flushSync()
const {
return _flushSync; }
398 void setFlushSync(
bool enable) { _flushSync = enable; }
414 virtual Error flush();
421 virtual Error finalize();
424 const TrackList &tracks()
const {
return _tracks; }
427 const MediaDesc &mediaDesc()
const {
return _mediaDesc; }
430 const Metadata &containerMetadata()
const {
return _containerMetadata; }
442 const Timecode &startTimecode()
const {
return _startTimecode; }
445 Operation _operation;
446 Layout _layout = LayoutClassic;
447 bool _flushSync =
false;
449 IODevice *_device =
nullptr;
450 bool _ownsDevice =
false;
452 MediaDesc _mediaDesc;
453 Metadata _containerMetadata;
454 Timecode _startTimecode;
458 static QuickTime createReader(
const String &filename);
461 static QuickTime createWriter(
const String &filename);
470 static Result<QuickTime> createForOperation(Operation op, IODevice *device);
473 QuickTime() : d(SharedPtr<Impl>::create(InvalidOperation)) {}
476 explicit QuickTime(Impl *impl) : d(SharedPtr<Impl>::takeOwnership(impl)) {}
479 bool isValid()
const {
return d->operation() != InvalidOperation; }
482 Operation operation()
const {
return d->operation(); }
485 const String &filename()
const {
return d->filename(); }
488 void setFilename(
const String &fn) { d.modify()->setFilename(fn); }
491 IODevice *device()
const {
return d->device(); }
494 Error open() {
return d.modify()->open(); }
497 void close() { d.modify()->close(); }
500 bool isOpen()
const {
return d->isOpen(); }
503 Error readSample(
size_t trackIndex, uint64_t sampleIndex, Sample &out) {
504 return d.modify()->readSample(trackIndex, sampleIndex, out);
509 Error readSampleRange(
size_t trackIndex, uint64_t startSampleIndex, uint64_t count, Sample &out) {
510 return d.modify()->readSampleRange(trackIndex, startSampleIndex, count, out);
514 Error addVideoTrack(
const PixelFormat &codec,
const Size2Du32 &size,
const FrameRate &frameRate,
515 uint32_t *outTrackId =
nullptr) {
516 return d.modify()->addVideoTrack(codec, size, frameRate, outTrackId);
520 Error addAudioTrack(
const AudioDesc &desc, uint32_t *outTrackId =
nullptr) {
521 return d.modify()->addAudioTrack(desc, outTrackId);
525 Error addTimecodeTrack(
const Timecode &startTimecode,
const FrameRate &frameRate,
526 uint32_t *outTrackId =
nullptr) {
527 return d.modify()->addTimecodeTrack(startTimecode, frameRate, outTrackId);
531 Error writeSample(uint32_t trackId,
const Sample &sample) {
532 return d.modify()->writeSample(trackId, sample);
536 void setContainerMetadata(
const Metadata &meta) { d.modify()->setContainerMetadata(meta); }
539 Layout layout()
const {
return d->layout(); }
542 Error setLayout(Layout layout) {
return d.modify()->setLayout(layout); }
545 bool flushSync()
const {
return d->flushSync(); }
548 void setFlushSync(
bool enable) { d.modify()->setFlushSync(enable); }
551 Error flush() {
return d.modify()->flush(); }
554 Error finalize() {
return d.modify()->finalize(); }
557 const TrackList &tracks()
const {
return d->tracks(); }
560 const MediaDesc &mediaDesc()
const {
return d->mediaDesc(); }
563 const Metadata &containerMetadata()
const {
return d->containerMetadata(); }
566 const Timecode &startTimecode()
const {
return d->startTimecode(); }