11#include <promeki/config.h>
12#if PROMEKI_ENABLE_PROAV
33PROMEKI_NAMESPACE_BEGIN
72 using Ptr = SharedPtr<QuickTime>;
157 bool isValid()
const {
return _type != InvalidTrack; }
160 TrackType type()
const {
return _type; }
162 uint32_t id()
const {
return _id; }
164 uint32_t timescale()
const {
return _timescale; }
166 uint64_t duration()
const {
return _duration; }
168 const FrameRate &frameRate()
const {
return _frameRate; }
170 uint64_t sampleCount()
const {
return _sampleCount; }
172 const String &language()
const {
return _language; }
174 const String &name()
const {
return _name; }
176 const PixelFormat &pixelFormat()
const {
return _pixelFormat; }
178 const Size2Du32 &size()
const {
return _size; }
180 VideoScanMode videoScanMode()
const {
return _videoScanMode; }
182 const AudioDesc &audioDesc()
const {
return _audioDesc; }
184 const AncDesc &ancDesc()
const {
return _ancDesc; }
186 const Metadata &metadata()
const {
return _metadata; }
188 int64_t editStartOffset()
const {
return _editStartOffset; }
197 const Buffer &codecConfig()
const {
return _codecConfig; }
204 FourCC codecConfigType()
const {
return _codecConfigType; }
207 void setType(TrackType t) { _type = t; }
209 void setId(uint32_t
id) { _id = id; }
211 void setTimescale(uint32_t ts) { _timescale = ts; }
213 void setDuration(uint64_t d) { _duration = d; }
215 void setFrameRate(
const FrameRate &r) { _frameRate = r; }
217 void setSampleCount(uint64_t n) { _sampleCount = n; }
219 void setLanguage(
const String &s) { _language = s; }
221 void setName(
const String &s) { _name = s; }
223 void setPixelFormat(
const PixelFormat &pd) { _pixelFormat = pd; }
225 void setSize(
const Size2Du32 &s) { _size = s; }
227 void setVideoScanMode(
const VideoScanMode &m) { _videoScanMode = m; }
229 void setAudioDesc(
const AudioDesc &ad) { _audioDesc = ad; }
231 void setAncDesc(
const AncDesc &ad) { _ancDesc = ad; }
233 Metadata &metadata() {
return _metadata; }
235 void setEditStartOffset(int64_t v) { _editStartOffset = v; }
237 void setCodecConfig(
const Buffer &b) { _codecConfig = b; }
239 void setCodecConfigType(FourCC t) { _codecConfigType = t; }
242 TrackType _type = InvalidTrack;
244 uint32_t _timescale = 0;
245 uint64_t _duration = 0;
246 FrameRate _frameRate;
247 uint64_t _sampleCount = 0;
250 PixelFormat _pixelFormat;
252 VideoScanMode _videoScanMode = VideoScanMode::Unknown;
253 AudioDesc _audioDesc;
256 int64_t _editStartOffset = 0;
258 FourCC _codecConfigType{
'\0',
'\0',
'\0',
'\0'};
262 using TrackList = ::promeki::List<Track>;
273 uint32_t trackId = 0;
277 uint64_t duration = 0;
278 bool keyframe =
false;
291 PROMEKI_SHARED_BASE(Impl)
294 explicit Impl(Operation op) : _operation(op) {}
300 Operation operation()
const {
return _operation; }
303 const String &filename()
const {
return _filename; }
306 void setFilename(
const String &fn) { _filename = fn; }
309 IODevice *device()
const {
return _device; }
315 void setDevice(IODevice *dev,
bool takeOwnership =
false) {
317 _ownsDevice = takeOwnership;
321 virtual Error open();
324 virtual void close();
327 virtual bool isOpen()
const;
339 virtual Error readSample(
size_t trackIndex, uint64_t sampleIndex, Sample &out);
357 virtual Error readSampleRange(
size_t trackIndex, uint64_t startSampleIndex,
358 uint64_t count, Sample &out);
369 virtual Error addVideoTrack(
const PixelFormat &codec,
const Size2Du32 &size,
370 const FrameRate &frameRate, uint32_t *outTrackId);
379 virtual Error addAudioTrack(
const AudioDesc &desc, uint32_t *outTrackId);
399 virtual Error addAncTrack(
const AncDesc &desc,
const FrameRate &frameRate,
400 uint32_t *outTrackId);
417 virtual Error addCaptionTrack(
const FrameRate &frameRate, uint32_t *outTrackId);
428 virtual Error addTimecodeTrack(
const Timecode &startTimecode,
429 const FrameRate &frameRate, uint32_t *outTrackId);
444 virtual Error writeSample(uint32_t trackId,
const Sample &sample);
447 virtual void setContainerMetadata(
const Metadata &meta);
455 virtual void setVideoScanMode(VideoScanMode) {}
458 Layout layout()
const {
return _layout; }
465 virtual Error setLayout(Layout layout);
468 Profile profile()
const {
return _profile; }
475 void setProfile(Profile profile) { _profile = profile; }
478 bool flushSync()
const {
return _flushSync; }
494 void setFlushSync(
bool enable) { _flushSync = enable; }
510 virtual Error flush();
517 virtual Error finalize();
520 const TrackList &tracks()
const {
return _tracks; }
523 const MediaDesc &mediaDesc()
const {
return _mediaDesc; }
526 const Metadata &containerMetadata()
const {
return _containerMetadata; }
538 const Timecode &startTimecode()
const {
return _startTimecode; }
541 Operation _operation;
542 Layout _layout = LayoutClassic;
543 Profile _profile = ProfileMov;
544 bool _flushSync =
false;
546 IODevice *_device =
nullptr;
547 bool _ownsDevice =
false;
549 MediaDesc _mediaDesc;
550 Metadata _containerMetadata;
551 Timecode _startTimecode;
555 static QuickTime createReader(
const String &filename);
558 static QuickTime createWriter(
const String &filename);
567 static Result<QuickTime> createForOperation(Operation op, IODevice *device);
570 QuickTime() : d(SharedPtr<Impl>::create(InvalidOperation)) {}
573 explicit QuickTime(Impl *impl) : d(SharedPtr<Impl>::takeOwnership(impl)) {}
576 bool isValid()
const {
return d->operation() != InvalidOperation; }
579 Operation operation()
const {
return d->operation(); }
582 const String &filename()
const {
return d->filename(); }
585 void setFilename(
const String &fn) { d.modify()->setFilename(fn); }
588 IODevice *device()
const {
return d->device(); }
591 Error open() {
return d.modify()->open(); }
594 void close() { d.modify()->close(); }
597 bool isOpen()
const {
return d->isOpen(); }
600 Error readSample(
size_t trackIndex, uint64_t sampleIndex, Sample &out) {
601 return d.modify()->readSample(trackIndex, sampleIndex, out);
606 Error readSampleRange(
size_t trackIndex, uint64_t startSampleIndex, uint64_t count, Sample &out) {
607 return d.modify()->readSampleRange(trackIndex, startSampleIndex, count, out);
611 Error addVideoTrack(
const PixelFormat &codec,
const Size2Du32 &size,
const FrameRate &frameRate,
612 uint32_t *outTrackId =
nullptr) {
613 return d.modify()->addVideoTrack(codec, size, frameRate, outTrackId);
617 Error addAudioTrack(
const AudioDesc &desc, uint32_t *outTrackId =
nullptr) {
618 return d.modify()->addAudioTrack(desc, outTrackId);
622 Error addAncTrack(
const AncDesc &desc,
const FrameRate &frameRate, uint32_t *outTrackId =
nullptr) {
623 return d.modify()->addAncTrack(desc, frameRate, outTrackId);
627 Error addCaptionTrack(
const FrameRate &frameRate, uint32_t *outTrackId =
nullptr) {
628 return d.modify()->addCaptionTrack(frameRate, outTrackId);
632 Error addTimecodeTrack(
const Timecode &startTimecode,
const FrameRate &frameRate,
633 uint32_t *outTrackId =
nullptr) {
634 return d.modify()->addTimecodeTrack(startTimecode, frameRate, outTrackId);
638 Error writeSample(uint32_t trackId,
const Sample &sample) {
639 return d.modify()->writeSample(trackId, sample);
643 void setContainerMetadata(
const Metadata &meta) { d.modify()->setContainerMetadata(meta); }
646 void setVideoScanMode(VideoScanMode mode) { d.modify()->setVideoScanMode(mode); }
649 Layout layout()
const {
return d->layout(); }
652 Error setLayout(Layout layout) {
return d.modify()->setLayout(layout); }
655 Profile profile()
const {
return d->profile(); }
658 void setProfile(Profile profile) { d.modify()->setProfile(profile); }
661 bool flushSync()
const {
return d->flushSync(); }
664 void setFlushSync(
bool enable) { d.modify()->setFlushSync(enable); }
667 Error flush() {
return d.modify()->flush(); }
670 Error finalize() {
return d.modify()->finalize(); }
673 const TrackList &tracks()
const {
return d->tracks(); }
676 const MediaDesc &mediaDesc()
const {
return d->mediaDesc(); }
679 const Metadata &containerMetadata()
const {
return d->containerMetadata(); }
682 const Timecode &startTimecode()
const {
return d->startTimecode(); }