libpromeki 1.0.0-alpha
PROfessional MEdia toolKIt
 
Loading...
Searching...
No Matches
quicktime.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 <cstdint>
14#include <promeki/namespace.h>
15#include <promeki/sharedptr.h>
16#include <promeki/string.h>
17#include <promeki/error.h>
18#include <promeki/result.h>
19#include <promeki/list.h>
20#include <promeki/buffer.h>
21#include <promeki/fourcc.h>
22#include <promeki/framerate.h>
23#include <promeki/size2d.h>
24#include <promeki/pixelformat.h>
25#include <promeki/enums_video.h>
26#include <promeki/audiodesc.h>
27#include <promeki/ancdesc.h>
28#include <promeki/mediadesc.h>
29#include <promeki/metadata.h>
30#include <promeki/timecode.h>
31#include <promeki/iodevice.h>
32
33PROMEKI_NAMESPACE_BEGIN
34
69class QuickTime {
70 public:
72 using Ptr = SharedPtr<QuickTime>;
73
75 enum Operation {
76 InvalidOperation = 0,
77 Reader,
78 Writer
79 };
80
86 enum TrackType {
87 InvalidTrack = 0,
88 Video,
89 Audio,
90 TimecodeTrack,
91 Subtitle,
92 Data,
96 AncData,
101 Caption
102 };
103
105 enum Layout {
112 LayoutClassic = 0,
120 LayoutFragmented = 1
121 };
122
135 enum Profile {
137 ProfileMov = 0,
139 ProfileMp4 = 1
140 };
141
151 class Track {
152 public:
154 Track() = default;
155
157 bool isValid() const { return _type != InvalidTrack; }
158
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; }
205
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; }
240
241 private:
242 TrackType _type = InvalidTrack;
243 uint32_t _id = 0;
244 uint32_t _timescale = 0;
245 uint64_t _duration = 0;
246 FrameRate _frameRate;
247 uint64_t _sampleCount = 0;
248 String _language;
249 String _name;
250 PixelFormat _pixelFormat;
251 Size2Du32 _size;
252 VideoScanMode _videoScanMode = VideoScanMode::Unknown;
253 AudioDesc _audioDesc;
254 AncDesc _ancDesc;
255 Metadata _metadata;
256 int64_t _editStartOffset = 0;
257 Buffer _codecConfig;
258 FourCC _codecConfigType{'\0', '\0', '\0', '\0'};
259 };
260
262 using TrackList = ::promeki::List<Track>;
263
272 struct Sample {
273 uint32_t trackId = 0;
274 uint64_t index = 0;
275 int64_t dts = 0;
276 int64_t pts = 0;
277 uint64_t duration = 0;
278 bool keyframe = false;
279 Buffer data;
280 };
281
290 class Impl {
291 PROMEKI_SHARED_BASE(Impl)
292 public:
294 explicit Impl(Operation op) : _operation(op) {}
295
297 virtual ~Impl();
298
300 Operation operation() const { return _operation; }
301
303 const String &filename() const { return _filename; }
304
306 void setFilename(const String &fn) { _filename = fn; }
307
309 IODevice *device() const { return _device; }
310
315 void setDevice(IODevice *dev, bool takeOwnership = false) {
316 _device = dev;
317 _ownsDevice = takeOwnership;
318 }
319
321 virtual Error open();
322
324 virtual void close();
325
327 virtual bool isOpen() const;
328
339 virtual Error readSample(size_t trackIndex, uint64_t sampleIndex, Sample &out);
340
357 virtual Error readSampleRange(size_t trackIndex, uint64_t startSampleIndex,
358 uint64_t count, Sample &out);
359
369 virtual Error addVideoTrack(const PixelFormat &codec, const Size2Du32 &size,
370 const FrameRate &frameRate, uint32_t *outTrackId);
371
379 virtual Error addAudioTrack(const AudioDesc &desc, uint32_t *outTrackId);
380
399 virtual Error addAncTrack(const AncDesc &desc, const FrameRate &frameRate,
400 uint32_t *outTrackId);
401
417 virtual Error addCaptionTrack(const FrameRate &frameRate, uint32_t *outTrackId);
418
428 virtual Error addTimecodeTrack(const Timecode &startTimecode,
429 const FrameRate &frameRate, uint32_t *outTrackId);
430
444 virtual Error writeSample(uint32_t trackId, const Sample &sample);
445
447 virtual void setContainerMetadata(const Metadata &meta);
448
455 virtual void setVideoScanMode(VideoScanMode) {}
456
458 Layout layout() const { return _layout; }
459
465 virtual Error setLayout(Layout layout);
466
468 Profile profile() const { return _profile; }
469
475 void setProfile(Profile profile) { _profile = profile; }
476
478 bool flushSync() const { return _flushSync; }
479
494 void setFlushSync(bool enable) { _flushSync = enable; }
495
510 virtual Error flush();
511
517 virtual Error finalize();
518
520 const TrackList &tracks() const { return _tracks; }
521
523 const MediaDesc &mediaDesc() const { return _mediaDesc; }
524
526 const Metadata &containerMetadata() const { return _containerMetadata; }
527
538 const Timecode &startTimecode() const { return _startTimecode; }
539
540 protected:
541 Operation _operation;
542 Layout _layout = LayoutClassic;
543 Profile _profile = ProfileMov;
544 bool _flushSync = false;
545 String _filename;
546 IODevice *_device = nullptr;
547 bool _ownsDevice = false;
548 TrackList _tracks;
549 MediaDesc _mediaDesc;
550 Metadata _containerMetadata;
551 Timecode _startTimecode;
552 };
553
555 static QuickTime createReader(const String &filename);
556
558 static QuickTime createWriter(const String &filename);
559
567 static Result<QuickTime> createForOperation(Operation op, IODevice *device);
568
570 QuickTime() : d(SharedPtr<Impl>::create(InvalidOperation)) {}
571
573 explicit QuickTime(Impl *impl) : d(SharedPtr<Impl>::takeOwnership(impl)) {}
574
576 bool isValid() const { return d->operation() != InvalidOperation; }
577
579 Operation operation() const { return d->operation(); }
580
582 const String &filename() const { return d->filename(); }
583
585 void setFilename(const String &fn) { d.modify()->setFilename(fn); }
586
588 IODevice *device() const { return d->device(); }
589
591 Error open() { return d.modify()->open(); }
592
594 void close() { d.modify()->close(); }
595
597 bool isOpen() const { return d->isOpen(); }
598
600 Error readSample(size_t trackIndex, uint64_t sampleIndex, Sample &out) {
601 return d.modify()->readSample(trackIndex, sampleIndex, out);
602 }
603
606 Error readSampleRange(size_t trackIndex, uint64_t startSampleIndex, uint64_t count, Sample &out) {
607 return d.modify()->readSampleRange(trackIndex, startSampleIndex, count, out);
608 }
609
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);
614 }
615
617 Error addAudioTrack(const AudioDesc &desc, uint32_t *outTrackId = nullptr) {
618 return d.modify()->addAudioTrack(desc, outTrackId);
619 }
620
622 Error addAncTrack(const AncDesc &desc, const FrameRate &frameRate, uint32_t *outTrackId = nullptr) {
623 return d.modify()->addAncTrack(desc, frameRate, outTrackId);
624 }
625
627 Error addCaptionTrack(const FrameRate &frameRate, uint32_t *outTrackId = nullptr) {
628 return d.modify()->addCaptionTrack(frameRate, outTrackId);
629 }
630
632 Error addTimecodeTrack(const Timecode &startTimecode, const FrameRate &frameRate,
633 uint32_t *outTrackId = nullptr) {
634 return d.modify()->addTimecodeTrack(startTimecode, frameRate, outTrackId);
635 }
636
638 Error writeSample(uint32_t trackId, const Sample &sample) {
639 return d.modify()->writeSample(trackId, sample);
640 }
641
643 void setContainerMetadata(const Metadata &meta) { d.modify()->setContainerMetadata(meta); }
644
646 void setVideoScanMode(VideoScanMode mode) { d.modify()->setVideoScanMode(mode); }
647
649 Layout layout() const { return d->layout(); }
650
652 Error setLayout(Layout layout) { return d.modify()->setLayout(layout); }
653
655 Profile profile() const { return d->profile(); }
656
658 void setProfile(Profile profile) { d.modify()->setProfile(profile); }
659
661 bool flushSync() const { return d->flushSync(); }
662
664 void setFlushSync(bool enable) { d.modify()->setFlushSync(enable); }
665
667 Error flush() { return d.modify()->flush(); }
668
670 Error finalize() { return d.modify()->finalize(); }
671
673 const TrackList &tracks() const { return d->tracks(); }
674
676 const MediaDesc &mediaDesc() const { return d->mediaDesc(); }
677
679 const Metadata &containerMetadata() const { return d->containerMetadata(); }
680
682 const Timecode &startTimecode() const { return d->startTimecode(); }
683
684 private:
685 SharedPtr<Impl> d;
686};
687
688PROMEKI_NAMESPACE_END
689
690#endif // PROMEKI_ENABLE_PROAV