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/audiodesc.h>
26#include <promeki/mediadesc.h>
27#include <promeki/metadata.h>
28#include <promeki/timecode.h>
29#include <promeki/iodevice.h>
30
31PROMEKI_NAMESPACE_BEGIN
32
67class QuickTime {
68 public:
70 using Ptr = SharedPtr<QuickTime>;
71
73 enum Operation {
74 InvalidOperation = 0,
75 Reader,
76 Writer
77 };
78
84 enum TrackType {
85 InvalidTrack = 0,
86 Video,
87 Audio,
88 TimecodeTrack,
89 Subtitle,
90 Data
91 };
92
94 enum Layout {
101 LayoutClassic = 0,
109 LayoutFragmented = 1
110 };
111
121 class Track {
122 public:
124 Track() = default;
125
127 bool isValid() const { return _type != InvalidTrack; }
128
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; }
171
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; }
202
203 private:
204 TrackType _type = InvalidTrack;
205 uint32_t _id = 0;
206 uint32_t _timescale = 0;
207 uint64_t _duration = 0;
208 FrameRate _frameRate;
209 uint64_t _sampleCount = 0;
210 String _language;
211 String _name;
212 PixelFormat _pixelFormat;
213 Size2Du32 _size;
214 AudioDesc _audioDesc;
215 Metadata _metadata;
216 int64_t _editStartOffset = 0;
217 Buffer _codecConfig;
218 FourCC _codecConfigType{'\0', '\0', '\0', '\0'};
219 };
220
222 using TrackList = ::promeki::List<Track>;
223
232 struct Sample {
233 uint32_t trackId = 0;
234 uint64_t index = 0;
235 int64_t dts = 0;
236 int64_t pts = 0;
237 uint64_t duration = 0;
238 bool keyframe = false;
239 Buffer data;
240 };
241
250 class Impl {
251 PROMEKI_SHARED_BASE(Impl)
252 public:
254 explicit Impl(Operation op) : _operation(op) {}
255
257 virtual ~Impl();
258
260 Operation operation() const { return _operation; }
261
263 const String &filename() const { return _filename; }
264
266 void setFilename(const String &fn) { _filename = fn; }
267
269 IODevice *device() const { return _device; }
270
275 void setDevice(IODevice *dev, bool takeOwnership = false) {
276 _device = dev;
277 _ownsDevice = takeOwnership;
278 }
279
281 virtual Error open();
282
284 virtual void close();
285
287 virtual bool isOpen() const;
288
299 virtual Error readSample(size_t trackIndex, uint64_t sampleIndex, Sample &out);
300
317 virtual Error readSampleRange(size_t trackIndex, uint64_t startSampleIndex,
318 uint64_t count, Sample &out);
319
329 virtual Error addVideoTrack(const PixelFormat &codec, const Size2Du32 &size,
330 const FrameRate &frameRate, uint32_t *outTrackId);
331
339 virtual Error addAudioTrack(const AudioDesc &desc, uint32_t *outTrackId);
340
350 virtual Error addTimecodeTrack(const Timecode &startTimecode,
351 const FrameRate &frameRate, uint32_t *outTrackId);
352
366 virtual Error writeSample(uint32_t trackId, const Sample &sample);
367
369 virtual void setContainerMetadata(const Metadata &meta);
370
372 Layout layout() const { return _layout; }
373
379 virtual Error setLayout(Layout layout);
380
382 bool flushSync() const { return _flushSync; }
383
398 void setFlushSync(bool enable) { _flushSync = enable; }
399
414 virtual Error flush();
415
421 virtual Error finalize();
422
424 const TrackList &tracks() const { return _tracks; }
425
427 const MediaDesc &mediaDesc() const { return _mediaDesc; }
428
430 const Metadata &containerMetadata() const { return _containerMetadata; }
431
442 const Timecode &startTimecode() const { return _startTimecode; }
443
444 protected:
445 Operation _operation;
446 Layout _layout = LayoutClassic;
447 bool _flushSync = false;
448 String _filename;
449 IODevice *_device = nullptr;
450 bool _ownsDevice = false;
451 TrackList _tracks;
452 MediaDesc _mediaDesc;
453 Metadata _containerMetadata;
454 Timecode _startTimecode;
455 };
456
458 static QuickTime createReader(const String &filename);
459
461 static QuickTime createWriter(const String &filename);
462
470 static Result<QuickTime> createForOperation(Operation op, IODevice *device);
471
473 QuickTime() : d(SharedPtr<Impl>::create(InvalidOperation)) {}
474
476 explicit QuickTime(Impl *impl) : d(SharedPtr<Impl>::takeOwnership(impl)) {}
477
479 bool isValid() const { return d->operation() != InvalidOperation; }
480
482 Operation operation() const { return d->operation(); }
483
485 const String &filename() const { return d->filename(); }
486
488 void setFilename(const String &fn) { d.modify()->setFilename(fn); }
489
491 IODevice *device() const { return d->device(); }
492
494 Error open() { return d.modify()->open(); }
495
497 void close() { d.modify()->close(); }
498
500 bool isOpen() const { return d->isOpen(); }
501
503 Error readSample(size_t trackIndex, uint64_t sampleIndex, Sample &out) {
504 return d.modify()->readSample(trackIndex, sampleIndex, out);
505 }
506
509 Error readSampleRange(size_t trackIndex, uint64_t startSampleIndex, uint64_t count, Sample &out) {
510 return d.modify()->readSampleRange(trackIndex, startSampleIndex, count, out);
511 }
512
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);
517 }
518
520 Error addAudioTrack(const AudioDesc &desc, uint32_t *outTrackId = nullptr) {
521 return d.modify()->addAudioTrack(desc, outTrackId);
522 }
523
525 Error addTimecodeTrack(const Timecode &startTimecode, const FrameRate &frameRate,
526 uint32_t *outTrackId = nullptr) {
527 return d.modify()->addTimecodeTrack(startTimecode, frameRate, outTrackId);
528 }
529
531 Error writeSample(uint32_t trackId, const Sample &sample) {
532 return d.modify()->writeSample(trackId, sample);
533 }
534
536 void setContainerMetadata(const Metadata &meta) { d.modify()->setContainerMetadata(meta); }
537
539 Layout layout() const { return d->layout(); }
540
542 Error setLayout(Layout layout) { return d.modify()->setLayout(layout); }
543
545 bool flushSync() const { return d->flushSync(); }
546
548 void setFlushSync(bool enable) { d.modify()->setFlushSync(enable); }
549
551 Error flush() { return d.modify()->flush(); }
552
554 Error finalize() { return d.modify()->finalize(); }
555
557 const TrackList &tracks() const { return d->tracks(); }
558
560 const MediaDesc &mediaDesc() const { return d->mediaDesc(); }
561
563 const Metadata &containerMetadata() const { return d->containerMetadata(); }
564
566 const Timecode &startTimecode() const { return d->startTimecode(); }
567
568 private:
569 SharedPtr<Impl> d;
570};
571
572PROMEKI_NAMESPACE_END
573
574#endif // PROMEKI_ENABLE_PROAV