libpromeki 1.0.0-alpha
PROfessional MEdia toolKIt
 
Loading...
Searching...
No Matches
sdivpid.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 <promeki/array.h>
14#include <promeki/datatype.h>
15#include <promeki/enums.h>
16#include <promeki/error.h>
17#include <promeki/namespace.h>
18#include <promeki/result.h>
19#include <promeki/string.h>
20#include <cstdint>
21
22PROMEKI_NAMESPACE_BEGIN
23
24class DataStream;
25class FrameRate;
26class St291Packet;
27class VideoFormat;
28
135class SdiVpid {
136 public:
137 PROMEKI_DATATYPE(SdiVpid, DataTypeSdiVpid, 1)
138
139
140 using ByteArray = ::promeki::Array<uint8_t, 4>;
141
142 // ------------------------------------------------------------
143 // Well-known byte 1 payload identification codes
144 // ------------------------------------------------------------
145
147 static constexpr uint8_t Byte1_Unknown = 0x00;
148
149 // Annex C — Historical pre-2008 payload identifier codes
150 // (byte 1 bit 7 = 0). These codes are recognised by
151 // @ref isValid / @ref linkStandard for decoder
152 // round-trip but their byte 2 / 3 / 4 layouts differ
153 // from the modern Table 1b schema — Annex C carries
154 // the picture rate in byte 2 @c [3:0] (same as
155 // Table 1b) but moves the scan flag to byte 3 @c [4]
156 // and uses byte 4 differently. The library's field
157 // decoders apply the Table 1b layout regardless, so
158 // for a legacy payload the field accessors may report
159 // misleading values. Callers seeing @ref isAnnexC
160 // return @c true should consult the raw bytes and
161 // decode per Annex C tables themselves.
162
165 static constexpr uint8_t Byte1_AnnexC_BT601 = 0x01;
168 static constexpr uint8_t Byte1_AnnexC_BT1358 = 0x02;
171 static constexpr uint8_t Byte1_AnnexC_ST347 = 0x03;
174 static constexpr uint8_t Byte1_AnnexC_ST274 = 0x04;
177 static constexpr uint8_t Byte1_AnnexC_ST296 = 0x05;
180 static constexpr uint8_t Byte1_AnnexC_ST349 = 0x06;
181
183 static constexpr uint8_t Byte1_SL_SD = 0x81;
185 static constexpr uint8_t Byte1_SL_HD_720 = 0x84;
187 static constexpr uint8_t Byte1_SL_HD_1080 = 0x85;
189 static constexpr uint8_t Byte1_DL_HD = 0x87;
191 static constexpr uint8_t Byte1_SL_3GA_720 = 0x88;
193 static constexpr uint8_t Byte1_SL_3GA_1080 = 0x89;
196 static constexpr uint8_t Byte1_SL_3GB = 0x8A;
199 static constexpr uint8_t Byte1_SL_6G_2160 = 0xC0;
202 static constexpr uint8_t Byte1_SL_6G_1080 = 0xC1;
205 static constexpr uint8_t Byte1_SL_12G_2160 = 0xCE;
208 static constexpr uint8_t Byte1_SL_12G_1080 = 0xCF;
209
210 // ------------------------------------------------------------
211 // Well-known byte 2 picture-rate codes ([3:0] field, Table 2)
212 // ------------------------------------------------------------
213
215 static constexpr uint8_t Rate_Unknown = 0x0;
218 static constexpr uint8_t Rate_95_90 = 0x1;
220 static constexpr uint8_t Rate_23_98 = 0x2;
222 static constexpr uint8_t Rate_24 = 0x3;
224 static constexpr uint8_t Rate_47_95 = 0x4;
226 static constexpr uint8_t Rate_25 = 0x5;
228 static constexpr uint8_t Rate_29_97 = 0x6;
230 static constexpr uint8_t Rate_30 = 0x7;
232 static constexpr uint8_t Rate_48 = 0x8;
234 static constexpr uint8_t Rate_50 = 0x9;
236 static constexpr uint8_t Rate_59_94 = 0xA;
238 static constexpr uint8_t Rate_60 = 0xB;
240 static constexpr uint8_t Rate_96 = 0xC;
242 static constexpr uint8_t Rate_100 = 0xD;
245 static constexpr uint8_t Rate_119_88 = 0xE;
247 static constexpr uint8_t Rate_120 = 0xF;
248
249 // ------------------------------------------------------------
250 // Well-known byte 3 sampling-structure codes ([3:0] field, Table 3)
251 // ------------------------------------------------------------
252
254 static constexpr uint8_t Sampling_YCbCr_422 = 0x0;
256 static constexpr uint8_t Sampling_YCbCr_444 = 0x1;
258 static constexpr uint8_t Sampling_RGB_444 = 0x2;
260 static constexpr uint8_t Sampling_YCbCr_420 = 0x3;
262 static constexpr uint8_t Sampling_YCbCrA_4224 = 0x4;
264 static constexpr uint8_t Sampling_YCbCrA_4444 = 0x5;
266 static constexpr uint8_t Sampling_RGBA_4444 = 0x6;
267
268 // ------------------------------------------------------------
269 // Well-known byte 4 bit-depth codes ([1:0] field)
270 // ------------------------------------------------------------
271 //
272 // The meaning of the bit-depth field depends on the
273 // schema named by byte 1:
274 //
275 // - ST 352:2013 (SD/HD/3G payloads): 0=8-bit, 1=10-bit,
276 // 2=12-bit, 3=Reserved.
277 // - ST 2081-10 / ST 2082-10 (6G/12G payloads):
278 // 0=10-bit Full Range, 1=10-bit, 2=12-bit, 3=12-bit
279 // Full Range.
280 //
281 // The @c BitDepth_* constants below name the raw codes;
282 // @ref bitDepth and @ref isFullRange interpret them
283 // against the appropriate schema based on byte 1.
284
288 static constexpr uint8_t BitDepth_8 = 0x0;
293 static constexpr uint8_t BitDepth_10_Full = 0x0;
295 static constexpr uint8_t BitDepth_10 = 0x1;
297 static constexpr uint8_t BitDepth_12 = 0x2;
301 static constexpr uint8_t BitDepth_12_Full = 0x3;
302
303 // ------------------------------------------------------------
304 // ST 2081-10 / ST 2082-10 extended byte 2 transfer codes
305 // (byte 2 [5:4])
306 // ------------------------------------------------------------
307
310 static constexpr uint8_t Transfer_SDR = 0x0;
312 static constexpr uint8_t Transfer_HLG = 0x1;
315 static constexpr uint8_t Transfer_PQ = 0x2;
319 static constexpr uint8_t Transfer_Unspecified = 0x3;
320
321 // ------------------------------------------------------------
322 // ST 2081-10 / ST 2082-10 extended byte 3 colorimetry
323 // codes (byte 3 [5:4])
324 // ------------------------------------------------------------
325
328 static constexpr uint8_t Colorimetry_Rec709 = 0x0;
331 static constexpr uint8_t Colorimetry_VANC = 0x1;
333 static constexpr uint8_t Colorimetry_UHDTV = 0x2;
335 static constexpr uint8_t Colorimetry_Unknown = 0x3;
336
337 // ============================================================
338 // Construction
339 // ============================================================
340
347 SdiVpid() = default;
348
357 SdiVpid(uint8_t b1, uint8_t b2, uint8_t b3, uint8_t b4);
358
362 explicit SdiVpid(const ByteArray &bytes);
363
364 // ============================================================
365 // Validity and raw accessors
366 // ============================================================
367
381 bool isValid() const;
382
398 bool isCurrentVersion() const { return (_bytes[0] & 0x80) != 0; }
399
413 bool isAnnexC() const;
414
437 Error validate() const;
438
440 uint8_t byte1() const { return _bytes[0]; }
442 uint8_t byte2() const { return _bytes[1]; }
444 uint8_t byte3() const { return _bytes[2]; }
446 uint8_t byte4() const { return _bytes[3]; }
447
449 const ByteArray &bytes() const { return _bytes; }
450
452 void setByte1(uint8_t b) { _bytes[0] = b; }
454 void setByte2(uint8_t b) { _bytes[1] = b; }
456 void setByte3(uint8_t b) { _bytes[2] = b; }
458 void setByte4(uint8_t b) { _bytes[3] = b; }
459
460 // ============================================================
461 // Decoded field accessors
462 // ============================================================
463
476 SdiLinkStandard linkStandard() const;
477
497 SdiWireFormat wireFormat() const;
498
504 uint8_t pictureRateCode() const { return static_cast<uint8_t>(_bytes[1] & 0x0F); }
505
521 FrameRate pictureRate() const;
522
533 bool isProgressiveTransport() const { return (_bytes[1] & 0x80) != 0; }
534
547 bool isProgressivePicture() const { return (_bytes[1] & 0x40) != 0; }
548
561 bool isSdSchema() const { return _bytes[0] == Byte1_SL_SD; }
562
575 bool sdHas960Samples() const { return (_bytes[2] & 0x40) != 0; }
576
588 bool has2048Samples() const { return (_bytes[2] & 0x40) != 0; }
589
594 bool is16x9() const { return (_bytes[2] & 0x80) != 0; }
595
610 VideoScanMode videoScanMode() const;
611
617 uint8_t samplingCode() const { return static_cast<uint8_t>(_bytes[2] & 0x0F); }
618
632 uint8_t bitDepthCode() const { return static_cast<uint8_t>(_bytes[3] & 0x03); }
633
643 int bitDepth() const;
644
656 bool isFullRange() const;
657
670 bool isExtendedSchema() const;
671
684 uint8_t transferCode() const { return static_cast<uint8_t>((_bytes[1] >> 4) & 0x03); }
685
699 TransferCharacteristics transferCharacteristic() const;
700
709 uint8_t colorimetryCode() const { return static_cast<uint8_t>((_bytes[2] >> 4) & 0x03); }
710
724 ColorPrimaries colorimetry() const;
725
735 bool isIctcp() const { return (_bytes[3] & 0x10) != 0; }
736
742 uint8_t channelAssignment() const { return static_cast<uint8_t>((_bytes[3] >> 5) & 0x07); }
743
757 void setChannelAssignment(uint8_t ch) {
758 _bytes[3] = static_cast<uint8_t>((_bytes[3] & 0x1F) | ((ch & 0x07) << 5));
759 }
760
770 void setTransferCode(uint8_t code) {
771 _bytes[1] = static_cast<uint8_t>((_bytes[1] & 0xCF) | ((code & 0x03) << 4));
772 }
773
778 void setColorimetryCode(uint8_t code) {
779 _bytes[2] = static_cast<uint8_t>((_bytes[2] & 0xCF) | ((code & 0x03) << 4));
780 }
781
786 void setIctcp(bool ictcp) {
787 if (ictcp) _bytes[3] = static_cast<uint8_t>(_bytes[3] | 0x10);
788 else _bytes[3] = static_cast<uint8_t>(_bytes[3] & ~0x10);
789 }
790
795 void setBitDepthCode(uint8_t code) {
796 _bytes[3] = static_cast<uint8_t>((_bytes[3] & 0xFC) | (code & 0x03));
797 }
798
799 // ============================================================
800 // Encoders
801 // ============================================================
802
836 static SdiVpid encode(const VideoFormat &videoFormat,
837 const SdiWireFormat &wireFormat,
838 const SdiLinkStandard &standard);
839
859 static SdiVpid encode(const VideoFormat &videoFormat,
860 const SdiWireFormat &wireFormat,
861 const SdiLinkStandard &standard,
862 int channelIndex);
863
870 static uint8_t encodePictureRateCode(const FrameRate &rate);
871
872 // ============================================================
873 // Integer conversion
874 // ============================================================
875
885 uint32_t toUint32BE() const;
886
893 static SdiVpid fromUint32BE(uint32_t v);
894
895 // ============================================================
896 // ANC packet round-trip (SMPTE ST 291-1 carriage)
897 // ============================================================
898
927 St291Packet toSt291Packet(uint16_t line = 0, bool fieldB = false, bool cBit = false) const;
928
947 static Result<SdiVpid> fromSt291Packet(const St291Packet &pkt);
948
984 static int recommendedAncLine(const VideoFormat &fmt, int field = 1);
985
986 // ============================================================
987 // String form, equality, DataStream
988 // ============================================================
989
993 String toString() const;
994
1004 static Result<SdiVpid> fromString(const String &s);
1005
1007 bool operator==(const SdiVpid &other) const { return _bytes == other._bytes; }
1008
1010 bool operator!=(const SdiVpid &other) const { return !(*this == other); }
1011
1018 Error writeToStream(DataStream &s) const;
1019
1024 template <uint32_t V> static Result<SdiVpid> readFromStream(DataStream &s);
1025
1026 private:
1027 ByteArray _bytes{};
1028};
1029
1030PROMEKI_NAMESPACE_END
1031
1032#endif // PROMEKI_ENABLE_PROAV