libpromeki 1.0.0-alpha
PROfessional MEdia toolKIt
 
Loading...
Searching...
No Matches
mediapayload.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 <optional>
15#include <promeki/optional.h>
16#include <promeki/namespace.h>
17#include <promeki/sharedptr.h>
18#include <promeki/buffer.h>
19#include <promeki/bufferview.h>
21#include <promeki/duration.h>
22#include <promeki/metadata.h>
23#include <promeki/string.h>
24#include <promeki/list.h>
25#include <promeki/enums.h>
26#include <promeki/variant.h>
27#include <promeki/error.h>
28
29#include <promeki/fourcc.h>
30
31PROMEKI_NAMESPACE_BEGIN
32
33class DataStream;
34class VariantSpec;
35
105class MediaPayload {
106 public:
107 RefCount _promeki_refct;
108 virtual MediaPayload *_promeki_clone() const = 0;
109
111 using Ptr = SharedPtr<MediaPayload, /*CopyOnWrite=*/true, MediaPayload>;
112
114 using PtrList = ::promeki::List<Ptr>;
115
133 enum Flag : uint64_t {
134 None = 0,
135 Keyframe =
136 1ull
137 << 0,
138 Discardable = 1ull
139 << 1,
140 Corrupt =
141 1ull
142 << 2,
143 EndOfStream = 1ull << 3,
144 IntraRefresh =
145 1ull
146 << 4,
147 };
148
150 MediaPayload() = default;
151
160 explicit MediaPayload(const BufferView &data) : _data(data) {}
161
162 MediaPayload(const MediaPayload &) = default;
163 MediaPayload(MediaPayload &&) = default;
164 MediaPayload &operator=(const MediaPayload &) = default;
165 MediaPayload &operator=(MediaPayload &&) = default;
166
168 virtual ~MediaPayload() = default;
169
171 virtual const MediaPayloadKind &kind() const = 0;
172
184 virtual bool isCompressed() const = 0;
185
194 virtual bool isValid() const {
195 if (_data.isEmpty()) return false;
196 for (auto v : _data) {
197 if (v.isValid()) return true;
198 }
199 return false;
200 }
201
202 // ---- Plane data -------------------------------------------
203
205 const BufferView &data() const { return _data; }
206
208 BufferView &data() { return _data; }
209
211 void setData(const BufferView &d) { _data = d; }
212
214 size_t planeCount() const { return _data.count(); }
215
217 BufferView::Entry plane(size_t index) const { return _data[index]; }
218
220 size_t size() const { return _data.totalSize(); }
221
222 // ---- Stream index -----------------------------------------
223
231 int streamIndex() const { return _streamIndex; }
232
234 void setStreamIndex(int idx) { _streamIndex = idx; }
235
236 // ---- Timing -----------------------------------------------
237
239 const MediaTimeStamp &pts() const { return _pts; }
240
242 void setPts(const MediaTimeStamp &ts) { _pts = ts; }
243
252 const MediaTimeStamp &dts() const { return _dts; }
253
255 void setDts(const MediaTimeStamp &ts) { _dts = ts; }
256
280 virtual Duration duration() const { return Duration(); }
281
295 virtual Error setDuration(const Duration &val) {
296 (void)val;
297 return Error::NotSupported;
298 }
299
315 virtual bool hasDuration() const { return false; }
316
317 // ---- Flags ------------------------------------------------
318
320 uint64_t flags() const { return _flags; }
321
323 void setFlags(uint64_t f) { _flags = f; }
324
326 void addFlag(Flag f) { _flags |= static_cast<uint64_t>(f); }
327
329 void removeFlag(Flag f) { _flags &= ~static_cast<uint64_t>(f); }
330
339 void setFlag(Flag f, bool on) {
340 if (on)
341 addFlag(f);
342 else
343 removeFlag(f);
344 }
345
347 bool hasFlag(Flag f) const { return (_flags & static_cast<uint64_t>(f)) != 0; }
348
362 static const char *flagName(Flag f);
363
373 virtual bool isKeyframe() const { return hasFlag(Keyframe); }
374
395 virtual bool isSafeCutPoint() const { return isKeyframe(); }
396
398 bool isDiscardable() const { return hasFlag(Discardable); }
399
401 bool isCorrupt() const { return hasFlag(Corrupt); }
402
404 bool isEndOfStream() const { return hasFlag(EndOfStream); }
405
418 bool isIntraRefresh() const { return hasFlag(IntraRefresh); }
419
421 void markEndOfStream(bool v = true) {
422 if (v)
423 addFlag(EndOfStream);
424 else
425 removeFlag(EndOfStream);
426 }
427
437 void markCorrupt(const String &reason = String()) {
438 addFlag(Corrupt);
439 if (!reason.isEmpty()) metadata().set(Metadata::CorruptReason, reason);
440 }
441
443 String corruptReason() const { return metadata().getAs<String>(Metadata::CorruptReason); }
444
445 // ---- Metadata ---------------------------------------------
446
471 virtual const Metadata &metadata() const = 0;
472
474 virtual Metadata &metadata() = 0;
475
476 // ---- Safe downcast ----------------------------------------
477
485 template <typename T> const T *as() const { return dynamic_cast<const T *>(this); }
486
488 template <typename T> T *as() { return dynamic_cast<T *>(this); }
489
490 // ---- Exclusive ownership ----------------------------------
491
505 bool isExclusive() const { return _data.isExclusive() && isExclusiveExtras(); }
506
507 // ---- DataStream serialisation ------------------------------
508
520 virtual uint32_t subclassFourCC() const = 0;
521
531 virtual void serialisePayload(DataStream &s) const = 0;
532
540 virtual void deserialisePayload(DataStream &s) = 0;
541
543 using Factory = Ptr (*)();
544
554 static void registerSubclass(uint32_t fourcc, Factory factory);
555
565 static Ptr createEmpty(uint32_t fourcc);
566
584 void ensureExclusive() {
585 _data.ensureExclusive();
586 ensureExclusiveExtras();
587 }
588
589 // ---- VariantLookup polymorphic dispatch -------------------
590
606 virtual Optional<Variant> variantLookupResolve(const String &key, Error *err = nullptr) const = 0;
607
613 virtual bool variantLookupAssign(const String &key, const Variant &value, Error *err = nullptr) = 0;
614
621 virtual const VariantSpec *variantLookupSpecFor(const String &key, Error *err = nullptr) const = 0;
622
639 virtual StringList variantLookupScalarNames() const = 0;
640
655 virtual StringList variantLookupDump(const String &indent = String()) const = 0;
656
657 protected:
668 virtual bool isExclusiveExtras() const { return true; }
669
678 virtual void ensureExclusiveExtras() {}
679
680 public:
681 private:
682 BufferView _data;
683 MediaTimeStamp _pts;
684 MediaTimeStamp _dts;
685 int _streamIndex = 0;
686 uint64_t _flags = 0;
687};
688
690DataStream &operator<<(DataStream &s, const MediaPayload::Ptr &p);
691
693DataStream &operator>>(DataStream &s, MediaPayload::Ptr &p);
694
706#define PROMEKI_REGISTER_MEDIAPAYLOAD(Cls, fourccStr) \
707 namespace { \
708 struct Cls##_MediaPayloadRegistrar { \
709 Cls##_MediaPayloadRegistrar() { \
710 ::promeki::MediaPayload::registerSubclass( \
711 ::promeki::FourCC(fourccStr).value(), \
712 []() -> ::promeki::MediaPayload::Ptr { \
713 return ::promeki::Cls::Ptr::create(); \
714 }); \
715 } \
716 }; \
717 static Cls##_MediaPayloadRegistrar s_##Cls##_mediaPayloadRegistrar; \
718 }
719
746#define PROMEKI_MEDIAPAYLOAD_LOOKUP_DISPATCH(Self) \
747 Optional<::promeki::Variant> variantLookupResolve(const ::promeki::String &key, \
748 ::promeki::Error *err = nullptr) const override { \
749 return ::promeki::VariantLookup<Self>::resolveDirect(*this, key, err); \
750 } \
751 bool variantLookupAssign(const ::promeki::String &key, const ::promeki::Variant &value, \
752 ::promeki::Error *err = nullptr) override { \
753 return ::promeki::VariantLookup<Self>::assignDirect(*this, key, value, err); \
754 } \
755 const ::promeki::VariantSpec *variantLookupSpecFor(const ::promeki::String &key, \
756 ::promeki::Error *err = nullptr) const override { \
757 return ::promeki::VariantLookup<Self>::specForDirect(key, err); \
758 } \
759 ::promeki::StringList variantLookupScalarNames() const override { \
760 return ::promeki::VariantLookup<Self>::registeredScalars(); \
761 } \
762 ::promeki::StringList variantLookupDump(const ::promeki::String &indent = ::promeki::String()) \
763 const override { \
764 return ::promeki::VariantLookup<Self>::dump(*this, indent); \
765 }
766
767PROMEKI_NAMESPACE_END
768
769#endif // PROMEKI_ENABLE_PROAV