libpromeki 1.0.0-alpha
PROfessional MEdia toolKIt
 
Loading...
Searching...
No Matches
metadata.h
Go to the documentation of this file.
1
8#pragma once
9
10
11#if PROMEKI_ENABLE_CORE
12#include <promeki/namespace.h>
13#include <promeki/config.h>
15#include <promeki/sharedptr.h>
16#include <promeki/audiomarker.h>
17#include <promeki/enums.h>
19#include <promeki/framenumber.h>
21#include <promeki/subtitle.h>
22#include <promeki/timecode.h>
23#if PROMEKI_ENABLE_NETWORK
24#include <promeki/eui64.h>
25#endif
26
27PROMEKI_NAMESPACE_BEGIN
28
29class StringList;
30
61class Metadata : public VariantDatabase<"Metadata"> {
62 public:
64 using Base = VariantDatabase<"Metadata">;
65
66 using Base::Base;
67
68 // ============================================================
69 // Core metadata
70 // ============================================================
71
73 PROMEKI_DECLARE_ID(Timecode,
74 VariantSpec()
75 .setType(DataTypeTimecode)
76 .setDefault(promeki::Timecode())
77 .setDescription("SMPTE timecode associated with this media unit."));
78
79#if PROMEKI_ENABLE_PROAV
90 PROMEKI_DECLARE_ID(Subtitle,
91 VariantSpec()
92 .setType(DataTypeSubtitle)
93 .setDefault(promeki::Subtitle())
94 .setDescription(
95 "Subtitle cue active at this media unit (start <= ts < end)."));
96#endif
97
99 PROMEKI_DECLARE_ID(Gamma, VariantSpec()
100 .setType(DataTypeDouble)
101 .setDefault(0.0)
102 .setMin(0.0)
103 .setDescription("Gamma / transfer-function exponent."));
104
106 PROMEKI_DECLARE_ID(Title, VariantSpec()
107 .setType(DataTypeString)
108 .setDefault(String())
109 .setDescription("Title of the media."));
110
112 PROMEKI_DECLARE_ID(Copyright, VariantSpec()
113 .setType(DataTypeString)
114 .setDefault(String())
115 .setDescription("Copyright notice."));
116
118 PROMEKI_DECLARE_ID(Software, VariantSpec()
119 .setType(DataTypeString)
120 .setDefault(String())
121 .setDescription("Software that created or modified the media."));
122
124 PROMEKI_DECLARE_ID(Artist, VariantSpec()
125 .setType(DataTypeString)
126 .setDefault(String())
127 .setDescription("Artist or creator name."));
128
130 PROMEKI_DECLARE_ID(Comment, VariantSpec()
131 .setType(DataTypeString)
132 .setDefault(String())
133 .setDescription("Free-form comment."));
134
136 PROMEKI_DECLARE_ID(Date, VariantSpec()
137 .setType(DataTypeString)
138 .setDefault(String())
139 .setDescription("Creation or origination date."));
140
142 PROMEKI_DECLARE_ID(Album, VariantSpec()
143 .setType(DataTypeString)
144 .setDefault(String())
145 .setDescription("Album name (audio media)."));
146
148 PROMEKI_DECLARE_ID(License, VariantSpec()
149 .setType(DataTypeString)
150 .setDefault(String())
151 .setDescription("License information."));
152
154 PROMEKI_DECLARE_ID(TrackNumber, VariantSpec()
155 .setTypes({DataTypeInt32, DataTypeString})
156 .setDefault(String())
157 .setDescription("Track number (audio media)."));
158
160 PROMEKI_DECLARE_ID(Genre, VariantSpec()
161 .setType(DataTypeString)
162 .setDefault(String())
163 .setDescription("Genre (audio media)."));
164
166 PROMEKI_DECLARE_ID(EnableBWF, VariantSpec()
167 .setType(DataTypeBool)
168 .setDefault(false)
169 .setDescription("Enable Broadcast Wave Format metadata."));
170
172 PROMEKI_DECLARE_ID(Description, VariantSpec()
173 .setType(DataTypeString)
174 .setDefault(String())
175 .setDescription("Human-readable description of the content."));
176
178 PROMEKI_DECLARE_ID(Originator, VariantSpec()
179 .setType(DataTypeString)
180 .setDefault(String())
181 .setDescription("BWF originator name."));
182
184 PROMEKI_DECLARE_ID(OriginatorReference, VariantSpec()
185 .setTypes({DataTypeString, DataTypeUUID})
186 .setDefault(String())
187 .setDescription("BWF originator reference."));
188
190 PROMEKI_DECLARE_ID(OriginationDateTime, VariantSpec()
191 .setType(DataTypeString)
192 .setDefault(String())
193 .setDescription("BWF origination date and time."));
194
196 PROMEKI_DECLARE_ID(FrameRate, VariantSpec()
197 .setTypes({DataTypeRational, DataTypeDouble,
198 DataTypeFrameRate})
199 .setDefault(Rational<int>())
200 .setDescription("Frame rate of the associated video."));
201
206 PROMEKI_DECLARE_ID(
207 FrameRateSource,
208 VariantSpec()
209 .setType(DataTypeString)
210 .setDefault(String())
211 .setDescription("Source of the FrameRate value (file, config, or default)."));
212
214 PROMEKI_DECLARE_ID(UMID, VariantSpec()
215 .setTypes({DataTypeString, DataTypeUMID})
216 .setDefault(String())
217 .setDescription("SMPTE UMID (Unique Material Identifier)."));
218
220 PROMEKI_DECLARE_ID(CodingHistory, VariantSpec()
221 .setType(DataTypeString)
222 .setDefault(String())
223 .setDescription("BWF coding history string."));
224
225 // ============================================================
226 // Compression metadata
227 // ============================================================
228
230 PROMEKI_DECLARE_ID(CompressionLevel,
231 VariantSpec()
232 .setType(DataTypeInt32)
233 .setDefault(int32_t(0))
234 .setDescription("Compression level hint for lossy codecs."));
235
237 PROMEKI_DECLARE_ID(EnableVBR, VariantSpec()
238 .setType(DataTypeBool)
239 .setDefault(false)
240 .setDescription("Enable variable bit-rate encoding."));
241
243 PROMEKI_DECLARE_ID(VBRQuality, VariantSpec()
244 .setType(DataTypeInt32)
245 .setDefault(int32_t(0))
246 .setDescription("VBR quality setting (codec-specific)."));
247
250 PROMEKI_DECLARE_ID(CompressedSize,
251 VariantSpec()
252 .setType(DataTypeInt32)
253 .setDefault(int32_t(0))
254 .setMin(int32_t(0))
255 .setDescription("Internal allocation hint for compressed pixel formats."));
256
257 // ============================================================
258 // Streaming / frame status
259 // ============================================================
260
262 PROMEKI_DECLARE_ID(EndOfStream, VariantSpec()
263 .setType(DataTypeBool)
264 .setDefault(false)
265 .setDescription("Signals end-of-stream to downstream nodes."));
266
275 PROMEKI_DECLARE_ID(Corrupt, VariantSpec()
276 .setType(DataTypeBool)
277 .setDefault(false)
278 .setDescription("Media unit carries corrupt data."));
279
281 PROMEKI_DECLARE_ID(CorruptReason,
282 VariantSpec()
283 .setType(DataTypeString)
284 .setDefault(String())
285 .setDescription("Human-readable reason for a Corrupt marking."));
286
288 PROMEKI_DECLARE_ID(FrameNumber, VariantSpec()
289 .setType(DataTypeFrameNumber)
290 .setDefault(promeki::FrameNumber())
291 .setDescription("Frame sequence number within a stream."));
292
299 PROMEKI_DECLARE_ID(Duration,
300 VariantSpec()
301 .setType(DataTypeMediaDuration)
302 .setDefault(promeki::MediaDuration())
303 .setDescription("Clip-level duration: starting frame plus length."));
304
311 PROMEKI_DECLARE_ID(CaptureTime,
312 VariantSpec()
313 .setType(DataTypeMediaTimeStamp)
314 .setDefault(promeki::MediaTimeStamp())
315 .setDescription("Timestamp when the library or device captured this data."));
316
326 PROMEKI_DECLARE_ID(FrameBridgeTimeStamp,
327 VariantSpec()
328 .setType(DataTypeMediaTimeStamp)
329 .setDefault(promeki::MediaTimeStamp())
330 .setDescription("FrameBridge publish timestamp (SystemMonotonic)."));
331
337 PROMEKI_DECLARE_ID(RtpTimestamp, VariantSpec()
338 .setType(DataTypeUInt32)
339 .setDefault(uint32_t(0))
340 .setDescription("RTP timestamp from the packet header."));
341
343 PROMEKI_DECLARE_ID(RtpPacketCount,
344 VariantSpec()
345 .setType(DataTypeInt32)
346 .setDefault(int32_t(0))
347 .setMin(int32_t(0))
348 .setDescription("Number of RTP packets that composed this essence."));
349
350#if PROMEKI_ENABLE_PROAV
364 PROMEKI_DECLARE_ID(
365 AudioMarkers,
366 VariantSpec()
367 .setType(DataTypeAudioMarkerList)
368 .setDefault(AudioMarkerList())
369 .setDescription("Per-payload audio event markers (silence fills, "
370 "concealed loss, discontinuities, …)."));
371#endif
372
373#if PROMEKI_ENABLE_NETWORK
375 PROMEKI_DECLARE_ID(PtpGrandmasterId,
376 VariantSpec()
377 .setType(DataTypeEUI64)
378 .setDefault(EUI64())
379 .setDescription("PTP grandmaster clock identity (EUI-64)."));
380
382 PROMEKI_DECLARE_ID(PtpDomainNumber, VariantSpec()
383 .setType(DataTypeUInt8)
384 .setDefault(uint8_t(0))
385 .setMax(uint8_t(127))
386 .setDescription("PTP domain number (0-127)."));
387#endif
388
390 PROMEKI_DECLARE_ID(FrameRepeated,
391 VariantSpec()
392 .setType(DataTypeInt32)
393 .setDefault(int32_t(0))
394 .setMin(int32_t(0))
395 .setDescription("Number of times frame repeated due to underrun."));
396
398 PROMEKI_DECLARE_ID(FrameDropped, VariantSpec()
399 .setType(DataTypeInt32)
400 .setDefault(int32_t(0))
401 .setMin(int32_t(0))
402 .setDescription("Number of frames dropped before this one."));
403
414 PROMEKI_DECLARE_ID(
415 FrameSyncDrop,
416 VariantSpec()
417 .setType(DataTypeInt32)
418 .setDefault(int32_t(0))
419 .setMin(int32_t(0))
420 .setDescription(
421 "Input frames dropped between this FrameSync emit and the previous one."));
422
429 PROMEKI_DECLARE_ID(
430 FrameSyncRepeat,
431 VariantSpec()
432 .setType(DataTypeInt32)
433 .setDefault(int32_t(0))
434 .setMin(int32_t(0))
435 .setDescription("Position within a FrameSync repeat sequence (0 = fresh emit)."));
436
438 PROMEKI_DECLARE_ID(FrameLate, VariantSpec()
439 .setType(DataTypeBool)
440 .setDefault(false)
441 .setDescription("Frame arrived later than scheduled."));
442
444 PROMEKI_DECLARE_ID(FrameKeyframe, VariantSpec()
445 .setType(DataTypeBool)
446 .setDefault(false)
447 .setDescription("Frame is a keyframe / intra frame."));
448
453 PROMEKI_DECLARE_ID(ForceKeyframe,
454 VariantSpec()
455 .setType(DataTypeBool)
456 .setDefault(false)
457 .setDescription("Request encoder to emit an IDR for this frame."));
458
461 PROMEKI_DECLARE_ID(MediaDescChanged,
462 VariantSpec()
463 .setType(DataTypeBool)
464 .setDefault(false)
465 .setDescription("Frame's MediaDesc differs from previously reported."));
466
467 // ============================================================
468 // Session / capture environment
469 //
470 // These keys describe the environment a container was
471 // written in. They're populated automatically by
472 // backends whose files are meant for debugging or
473 // forensic replay (e.g. PMDF), but any writer is free
474 // to stamp them.
475 // ============================================================
476
478 PROMEKI_DECLARE_ID(SessionHostname,
479 VariantSpec()
480 .setType(DataTypeString)
481 .setDefault(String())
482 .setDescription("Runtime hostname of the machine that produced the file."));
483
485 PROMEKI_DECLARE_ID(SessionProcessId, VariantSpec()
486 .setType(DataTypeInt64)
487 .setDefault(int64_t(0))
488 .setDescription("Writer process ID at capture time."));
489
494 PROMEKI_DECLARE_ID(LibraryBuildInfo,
495 VariantSpec()
496 .setType(DataTypeString)
497 .setDefault(String())
498 .setDescription("libpromeki build identity (version, repo, date, host)."));
499
502 PROMEKI_DECLARE_ID(LibraryPlatform,
503 VariantSpec()
504 .setType(DataTypeString)
505 .setDefault(String())
506 .setDescription("Platform / compiler / C++ standard of the writer."));
507
510 PROMEKI_DECLARE_ID(LibraryFeatures,
511 VariantSpec()
512 .setType(DataTypeString)
513 .setDefault(String())
514 .setDescription("Library feature flags enabled at build time."));
515
516 // ============================================================
517 // DPX file info
518 // ============================================================
519
521 PROMEKI_DECLARE_ID(FileOrigName, VariantSpec()
522 .setType(DataTypeString)
523 .setDefault(String())
524 .setDescription("Original source filename."));
525
527 PROMEKI_DECLARE_ID(Project, VariantSpec()
528 .setType(DataTypeString)
529 .setDefault(String())
530 .setDescription("Project name."));
531
533 PROMEKI_DECLARE_ID(Reel, VariantSpec()
534 .setType(DataTypeString)
535 .setDefault(String())
536 .setDescription("Reel or input device name."));
537
538 // ============================================================
539 // DPX film info
540 // ============================================================
541
543 PROMEKI_DECLARE_ID(FilmMfgID, VariantSpec()
544 .setType(DataTypeString)
545 .setDefault(String())
546 .setDescription("Film manufacturer ID code (2 chars)."));
547
549 PROMEKI_DECLARE_ID(FilmType, VariantSpec()
550 .setType(DataTypeString)
551 .setDefault(String())
552 .setDescription("Film type (2 chars)."));
553
555 PROMEKI_DECLARE_ID(FilmOffset, VariantSpec()
556 .setType(DataTypeString)
557 .setDefault(String())
558 .setDescription("Film offset in perfs (2 chars)."));
559
561 PROMEKI_DECLARE_ID(FilmPrefix, VariantSpec()
562 .setType(DataTypeString)
563 .setDefault(String())
564 .setDescription("Film prefix (6 chars)."));
565
567 PROMEKI_DECLARE_ID(FilmCount, VariantSpec()
568 .setType(DataTypeString)
569 .setDefault(String())
570 .setDescription("Film count (4 chars)."));
571
573 PROMEKI_DECLARE_ID(FilmFormat, VariantSpec()
574 .setType(DataTypeString)
575 .setDefault(String())
576 .setDescription("Film format (e.g. Academy)."));
577
579 PROMEKI_DECLARE_ID(FilmSeqPos,
580 VariantSpec()
581 .setType(DataTypeInt32)
582 .setDefault(int32_t(0))
583 .setMin(int32_t(0))
584 .setDescription("Sequence position (frame number in sequence)."));
585
587 PROMEKI_DECLARE_ID(FilmSeqLen, VariantSpec()
588 .setType(DataTypeInt32)
589 .setDefault(int32_t(0))
590 .setMin(int32_t(0))
591 .setDescription("Sequence length (total frames in sequence)."));
592
594 PROMEKI_DECLARE_ID(FilmHoldCount,
595 VariantSpec()
596 .setType(DataTypeInt32)
597 .setDefault(int32_t(1))
598 .setMin(int32_t(1))
599 .setDescription("Held count (1 = default, >1 = repeated frame)."));
600
602 PROMEKI_DECLARE_ID(FilmShutter, VariantSpec()
603 .setType(DataTypeDouble)
604 .setDefault(0.0)
605 .setMin(0.0)
606 .setMax(360.0)
607 .setDescription("Film shutter angle in degrees."));
608
610 PROMEKI_DECLARE_ID(FilmFrameID, VariantSpec()
611 .setType(DataTypeString)
612 .setDefault(String())
613 .setDescription("Film frame identification (e.g. keycode)."));
614
616 PROMEKI_DECLARE_ID(FilmSlate, VariantSpec()
617 .setType(DataTypeString)
618 .setDefault(String())
619 .setDescription("Film slate information."));
620
621 // ============================================================
622 // DPX TV info
623 // ============================================================
624
626 PROMEKI_DECLARE_ID(FieldID,
627 VariantSpec()
628 .setType(DataTypeInt32)
629 .setDefault(int32_t(0))
630 .setRange(int32_t(0), int32_t(1))
631 .setDescription("Field number within an interlaced frame (0 or 1)."));
632
633 // ============================================================
634 // DPX image element info
635 // ============================================================
636
638 PROMEKI_DECLARE_ID(TransferCharacteristic,
639 VariantSpec()
640 .setType(DataTypeInt32)
641 .setDefault(int32_t(0))
642 .setMin(int32_t(0))
643 .setDescription("SMPTE 268M transfer characteristic code."));
644
646 PROMEKI_DECLARE_ID(Colorimetric,
647 VariantSpec()
648 .setType(DataTypeInt32)
649 .setDefault(int32_t(0))
650 .setMin(int32_t(0))
651 .setDescription("SMPTE 268M colorimetric specification code."));
652
654 PROMEKI_DECLARE_ID(
655 Orientation,
656 VariantSpec()
657 .setType(DataTypeInt32)
658 .setDefault(int32_t(0))
659 .setMin(int32_t(0))
660 .setDescription("Image orientation code (0 = left-to-right, top-to-bottom)."));
661
662 // ============================================================
663 // HDR metadata (SMPTE ST 2086 / CTA-861.3)
664 // ============================================================
665
667 PROMEKI_DECLARE_ID(MasteringDisplay,
668 VariantSpec()
669 .setType(DataTypeMasteringDisplay)
670 .setDescription("Mastering display color volume (SMPTE ST 2086)."));
671
673 PROMEKI_DECLARE_ID(ContentLightLevel,
674 VariantSpec()
675 .setType(DataTypeContentLightLevel)
676 .setDescription("Content light level info (MaxCLL / MaxFALL)."));
677
678 // ============================================================
679 // Codec VUI / color description (ISO/IEC 23091-4 / ITU-T H.273)
680 // ============================================================
681 //
682 // These mirror the @ref MediaConfig encoder-side keys, but
683 // on output: a @ref VideoDecoder parses the bitstream's VUI
684 // (H.264/HEVC) or color description (AV1) and stamps the
685 // recovered values here on every decoded @ref Image. They
686 // are distinct from the legacy DPX @c TransferCharacteristic
687 // / @c Colorimetric keys above — those carry SMPTE 268M
688 // codepoints from DPX files, while these carry H.273
689 // codepoints from a compressed bitstream.
690 //
691 // Producers should prefer picking a @ref PixelFormat that
692 // already encodes the colour space (e.g.
693 // @c YUV10_422_UYVY_LE_BT2020_PQ) when one exists — the
694 // codec / device side derives transfer / primaries /
695 // matrix / range from the @ref ColorModel via
696 // @ref ColorModel::toH273. These keys remain as the
697 // explicit override path for cases where the buffer's
698 // colour family doesn't match the wire / bitstream claim.
699
701 PROMEKI_DECLARE_ID(VideoColorPrimaries,
702 VariantSpec()
703 .setType(DataTypeEnum)
704 .setDefault(promeki::ColorPrimaries::Unspecified)
705 .setEnumType(promeki::ColorPrimaries::Type)
706 .setDescription("VUI color primaries (ISO/IEC 23091-4)."));
707
709 PROMEKI_DECLARE_ID(VideoTransferCharacteristics,
710 VariantSpec()
711 .setType(DataTypeEnum)
712 .setDefault(promeki::TransferCharacteristics::Unspecified)
713 .setEnumType(promeki::TransferCharacteristics::Type)
714 .setDescription("VUI transfer characteristics (ISO/IEC 23091-4)."));
715
717 PROMEKI_DECLARE_ID(VideoMatrixCoefficients,
718 VariantSpec()
719 .setType(DataTypeEnum)
720 .setDefault(promeki::MatrixCoefficients::Unspecified)
721 .setEnumType(promeki::MatrixCoefficients::Type)
722 .setDescription("VUI matrix coefficients (ISO/IEC 23091-4)."));
723
725 PROMEKI_DECLARE_ID(VideoRange, VariantSpec()
726 .setType(DataTypeEnum)
727 .setDefault(promeki::VideoRange::Unknown)
728 .setEnumType(promeki::VideoRange::Type)
729 .setDescription("VUI video range (Unknown / Limited / Full)."));
730
743 PROMEKI_DECLARE_ID(VideoScanMode, VariantSpec()
744 .setType(DataTypeEnum)
745 .setDefault(promeki::VideoScanMode::Unknown)
746 .setEnumType(promeki::VideoScanMode::Type)
747 .setDescription("Raster scan mode "
748 "(Progressive / Interlaced*)."));
749
750 // ============================================================
751 // Encoder per-frame statistics
752 //
753 // These keys are populated by a @ref VideoEncoder on each
754 // emitted @ref CompressedVideoPayload. They describe how
755 // the encoder coded a specific frame and are useful for
756 // rate-control tuning, quality analytics, and diagnosing
757 // bitrate / latency anomalies. A decoder will typically
758 // not repopulate them when re-decoding a stream.
759 // ============================================================
760
765 PROMEKI_DECLARE_ID(CodecFrameAvgQP, VariantSpec()
766 .setType(DataTypeInt32)
767 .setDefault(int32_t(0))
768 .setMin(int32_t(0))
769 .setDescription("Average QP of the encoded frame."));
770
774 PROMEKI_DECLARE_ID(CodecFrameSatd,
775 VariantSpec()
776 .setType(DataTypeInt32)
777 .setDefault(int32_t(0))
778 .setMin(int32_t(0))
779 .setDescription("Frame SATD (Sum of Absolute Transformed Differences)."));
780
788 PROMEKI_DECLARE_ID(CodecEncodeOrderIdx, VariantSpec()
789 .setType(DataTypeUInt32)
790 .setDefault(uint32_t(0))
791 .setDescription("Frame index in encode order."));
792
794 PROMEKI_DECLARE_ID(CodecDisplayOrderIdx, VariantSpec()
795 .setType(DataTypeUInt32)
796 .setDefault(uint32_t(0))
797 .setDescription("Frame index in display order."));
798
806 PROMEKI_DECLARE_ID(CodecTemporalId,
807 VariantSpec()
808 .setType(DataTypeInt32)
809 .setDefault(int32_t(0))
810 .setMin(int32_t(0))
811 .setDescription("Temporal scalability layer ID (0 = base layer)."));
812
820 PROMEKI_DECLARE_ID(CodecGopPosition,
821 VariantSpec()
822 .setType(DataTypeInt32)
823 .setDefault(int32_t(0))
824 .setMin(int32_t(0))
825 .setDescription("Offset from last keyframe (0 = keyframe)."));
826
834 PROMEKI_DECLARE_ID(CodecIntraBlockCount,
835 VariantSpec()
836 .setType(DataTypeInt32)
837 .setDefault(int32_t(0))
838 .setMin(int32_t(0))
839 .setDescription("Count of intra-coded blocks (codec-specific unit)."));
840
847 PROMEKI_DECLARE_ID(CodecInterBlockCount,
848 VariantSpec()
849 .setType(DataTypeInt32)
850 .setDefault(int32_t(0))
851 .setMin(int32_t(0))
852 .setDescription("Count of inter-coded blocks (codec-specific unit)."));
853
860 PROMEKI_DECLARE_ID(CodecAvgMotionVectorX,
861 VariantSpec()
862 .setType(DataTypeInt32)
863 .setDefault(int32_t(0))
864 .setDescription("Average motion vector X (codec-defined units)."));
865
868 PROMEKI_DECLARE_ID(CodecAvgMotionVectorY,
869 VariantSpec()
870 .setType(DataTypeInt32)
871 .setDefault(int32_t(0))
872 .setDescription("Average motion vector Y (codec-defined units)."));
873
898 PROMEKI_DECLARE_ID(CodecParameterSets,
899 VariantSpec()
900 .setType(DataTypeString)
901 .setDefault(String())
902 .setDescription("Out-of-band codec parameter sets "
903 "(Annex-B SPS/PPS/VPS or AV1 sequence header)."));
904
905 // ============================================================
906 // Frontend layout hints
907 //
908 // Generic per-stage layout hints for graphical editors
909 // (the promeki-pipeline demo persists Vue Flow node
910 // positions through these). Stored on
911 // @ref MediaPipelineConfig::Stage::metadata so they
912 // round-trip with the rest of the config. The wire
913 // names use the @c "Frontend." prefix to namespace UI
914 // hints away from media metadata; the C++ identifiers
915 // drop the dot because identifiers cannot contain one.
916 // ============================================================
917
919 static inline const ID FrontendX = declareID(
920 "Frontend.X", VariantSpec()
921 .setType(DataTypeDouble)
922 .setDefault(0.0)
923 .setDescription("Frontend X coordinate (pixels) for graphical editors."));
924
926 static inline const ID FrontendY = declareID(
927 "Frontend.Y", VariantSpec()
928 .setType(DataTypeDouble)
929 .setDefault(0.0)
930 .setDescription("Frontend Y coordinate (pixels) for graphical editors."));
931
932 // ============================================================
933 // Methods
934 // ============================================================
935
941 static String idToString(ID id) { return id.name(); }
942
948 static ID stringToID(const String &val) { return ID(val); }
949
956 static Metadata fromJson(const JsonObject &json, Error *err = nullptr);
957
973 String toString(unsigned int indent = 0) const;
974
992 static Metadata fromString(const String &str, Error *err = nullptr);
993
995 Metadata() = default;
996
1001 StringList dump() const;
1002
1008 bool operator==(const Metadata &other) const;
1009
1041 void applyMediaIOWriteDefaults();
1042};
1043
1044PROMEKI_NAMESPACE_END
1045
1046#endif // PROMEKI_ENABLE_CORE