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_color.h>
16#include <promeki/enums_video.h>
17#include <promeki/error.h>
18#include <promeki/namespace.h>
19#include <promeki/result.h>
20#include <promeki/string.h>
21#include <cstdint>
22
23PROMEKI_NAMESPACE_BEGIN
24
25class DataStream;
26class FrameRate;
27class St291Packet;
28class VideoFormat;
29
136class SdiVpid {
137 public:
138 PROMEKI_DATATYPE(SdiVpid, DataTypeSdiVpid, 1)
139
140
141 using ByteArray = ::promeki::Array<uint8_t, 4>;
142
143 // ------------------------------------------------------------
144 // Well-known byte 1 payload identification codes
145 // ------------------------------------------------------------
146
148 static constexpr uint8_t Byte1_Unknown = 0x00;
149
150 // Annex C — Historical pre-2008 payload identifier codes
151 // (byte 1 bit 7 = 0). These codes are recognised by
152 // @ref isValid / @ref linkStandard for decoder
153 // round-trip but their byte 2 / 3 / 4 layouts differ
154 // from the modern Table 1b schema — Annex C carries
155 // the picture rate in byte 2 @c [3:0] (same as
156 // Table 1b) but moves the scan flag to byte 3 @c [4]
157 // and uses byte 4 differently. The library's field
158 // decoders apply the Table 1b layout regardless, so
159 // for a legacy payload the field accessors may report
160 // misleading values. Callers seeing @ref isAnnexC
161 // return @c true should consult the raw bytes and
162 // decode per Annex C tables themselves.
163
166 static constexpr uint8_t Byte1_AnnexC_BT601 = 0x01;
169 static constexpr uint8_t Byte1_AnnexC_BT1358 = 0x02;
172 static constexpr uint8_t Byte1_AnnexC_ST347 = 0x03;
175 static constexpr uint8_t Byte1_AnnexC_ST274 = 0x04;
178 static constexpr uint8_t Byte1_AnnexC_ST296 = 0x05;
181 static constexpr uint8_t Byte1_AnnexC_ST349 = 0x06;
182
184 static constexpr uint8_t Byte1_SL_SD = 0x81;
186 static constexpr uint8_t Byte1_SL_HD_720 = 0x84;
188 static constexpr uint8_t Byte1_SL_HD_1080 = 0x85;
190 static constexpr uint8_t Byte1_DL_HD = 0x87;
192 static constexpr uint8_t Byte1_SL_3GA_720 = 0x88;
194 static constexpr uint8_t Byte1_SL_3GA_1080 = 0x89;
197 static constexpr uint8_t Byte1_SL_3GB = 0x8A;
200 static constexpr uint8_t Byte1_SL_6G_2160 = 0xC0;
203 static constexpr uint8_t Byte1_SL_6G_1080 = 0xC1;
206 static constexpr uint8_t Byte1_SL_12G_2160 = 0xCE;
209 static constexpr uint8_t Byte1_SL_12G_1080 = 0xCF;
210
211 // ------------------------------------------------------------
212 // Well-known byte 2 picture-rate codes ([3:0] field, Table 2)
213 // ------------------------------------------------------------
214
216 static constexpr uint8_t Rate_Unknown = 0x0;
219 static constexpr uint8_t Rate_95_90 = 0x1;
221 static constexpr uint8_t Rate_23_98 = 0x2;
223 static constexpr uint8_t Rate_24 = 0x3;
225 static constexpr uint8_t Rate_47_95 = 0x4;
227 static constexpr uint8_t Rate_25 = 0x5;
229 static constexpr uint8_t Rate_29_97 = 0x6;
231 static constexpr uint8_t Rate_30 = 0x7;
233 static constexpr uint8_t Rate_48 = 0x8;
235 static constexpr uint8_t Rate_50 = 0x9;
237 static constexpr uint8_t Rate_59_94 = 0xA;
239 static constexpr uint8_t Rate_60 = 0xB;
241 static constexpr uint8_t Rate_96 = 0xC;
243 static constexpr uint8_t Rate_100 = 0xD;
246 static constexpr uint8_t Rate_119_88 = 0xE;
248 static constexpr uint8_t Rate_120 = 0xF;
249
250 // ------------------------------------------------------------
251 // Byte 3 sampling-structure codes ([3:0] field, Table 3)
252 // ------------------------------------------------------------
253 //
254 // The well-known sampling-structure codes are modelled by
255 // the @ref VpidSampling enum (its integer values are the
256 // on-wire ST 352:2013 Table 3 nibbles). Use @ref sampling
257 // / @ref setSampling for the decoded structure and
258 // @ref samplingCode for the raw nibble.
259
260 // ------------------------------------------------------------
261 // Well-known byte 4 bit-depth codes ([1:0] field)
262 // ------------------------------------------------------------
263 //
264 // The meaning of the bit-depth field depends on the
265 // schema named by byte 1:
266 //
267 // - ST 352:2013 (SD/HD/3G payloads): 0=8-bit, 1=10-bit,
268 // 2=12-bit, 3=Reserved.
269 // - ST 2081-10 / ST 2082-10 (6G/12G payloads):
270 // 0=10-bit Full Range, 1=10-bit, 2=12-bit, 3=12-bit
271 // Full Range.
272 //
273 // The @c BitDepth_* constants below name the raw codes;
274 // @ref bitDepth and @ref isFullRange interpret them
275 // against the appropriate schema based on byte 1.
276
280 static constexpr uint8_t BitDepth_8 = 0x0;
285 static constexpr uint8_t BitDepth_10_Full = 0x0;
287 static constexpr uint8_t BitDepth_10 = 0x1;
289 static constexpr uint8_t BitDepth_12 = 0x2;
293 static constexpr uint8_t BitDepth_12_Full = 0x3;
294
295 // ------------------------------------------------------------
296 // ST 2081-10 / ST 2082-10 extended byte 2 transfer codes
297 // (byte 2 [5:4])
298 // ------------------------------------------------------------
299
302 static constexpr uint8_t Transfer_SDR = 0x0;
304 static constexpr uint8_t Transfer_HLG = 0x1;
307 static constexpr uint8_t Transfer_PQ = 0x2;
311 static constexpr uint8_t Transfer_Unspecified = 0x3;
312
313 // ------------------------------------------------------------
314 // ST 2081-10 / ST 2082-10 extended byte 3 colorimetry
315 // codes (byte 3 [5:4])
316 // ------------------------------------------------------------
317
320 static constexpr uint8_t Colorimetry_Rec709 = 0x0;
323 static constexpr uint8_t Colorimetry_VANC = 0x1;
325 static constexpr uint8_t Colorimetry_UHDTV = 0x2;
327 static constexpr uint8_t Colorimetry_Unknown = 0x3;
328
329 // ============================================================
330 // Construction
331 // ============================================================
332
339 SdiVpid() = default;
340
349 SdiVpid(uint8_t b1, uint8_t b2, uint8_t b3, uint8_t b4);
350
354 explicit SdiVpid(const ByteArray &bytes);
355
356 // ============================================================
357 // Validity and raw accessors
358 // ============================================================
359
373 bool isValid() const;
374
390 bool isCurrentVersion() const { return (_bytes[0] & 0x80) != 0; }
391
405 bool isAnnexC() const;
406
429 Error validate() const;
430
432 uint8_t byte1() const { return _bytes[0]; }
434 uint8_t byte2() const { return _bytes[1]; }
436 uint8_t byte3() const { return _bytes[2]; }
438 uint8_t byte4() const { return _bytes[3]; }
439
441 const ByteArray &bytes() const { return _bytes; }
442
444 void setByte1(uint8_t b) { _bytes[0] = b; }
446 void setByte2(uint8_t b) { _bytes[1] = b; }
448 void setByte3(uint8_t b) { _bytes[2] = b; }
450 void setByte4(uint8_t b) { _bytes[3] = b; }
451
452 // ============================================================
453 // Decoded field accessors
454 // ============================================================
455
468 SdiLinkStandard linkStandard() const;
469
483 String payloadDescription() const;
484
504 SdiWireFormat wireFormat() const;
505
511 uint8_t pictureRateCode() const { return static_cast<uint8_t>(_bytes[1] & 0x0F); }
512
528 FrameRate pictureRate() const;
529
540 bool isProgressiveTransport() const { return (_bytes[1] & 0x80) != 0; }
541
554 bool isProgressivePicture() const { return (_bytes[1] & 0x40) != 0; }
555
568 bool isSdSchema() const { return _bytes[0] == Byte1_SL_SD; }
569
582 bool sdHas960Samples() const { return (_bytes[2] & 0x40) != 0; }
583
595 bool has2048Samples() const { return (_bytes[2] & 0x40) != 0; }
596
601 bool is16x9() const { return (_bytes[2] & 0x80) != 0; }
602
617 VideoScanMode videoScanMode() const;
618
626 uint8_t samplingCode() const { return static_cast<uint8_t>(_bytes[2] & 0x0F); }
627
638 VpidSampling sampling() const;
639
651 void setSampling(const VpidSampling &sampling);
652
666 uint8_t bitDepthCode() const { return static_cast<uint8_t>(_bytes[3] & 0x03); }
667
677 int bitDepth() const;
678
690 bool isFullRange() const;
691
704 bool isExtendedSchema() const;
705
718 uint8_t transferCode() const { return static_cast<uint8_t>((_bytes[1] >> 4) & 0x03); }
719
733 TransferCharacteristics transferCharacteristic() const;
734
743 uint8_t colorimetryCode() const { return static_cast<uint8_t>((_bytes[2] >> 4) & 0x03); }
744
758 ColorPrimaries colorimetry() const;
759
769 bool isIctcp() const { return (_bytes[3] & 0x10) != 0; }
770
776 uint8_t channelAssignment() const { return static_cast<uint8_t>((_bytes[3] >> 5) & 0x07); }
777
791 void setChannelAssignment(uint8_t ch) {
792 _bytes[3] = static_cast<uint8_t>((_bytes[3] & 0x1F) | ((ch & 0x07) << 5));
793 }
794
804 void setTransferCode(uint8_t code) {
805 _bytes[1] = static_cast<uint8_t>((_bytes[1] & 0xCF) | ((code & 0x03) << 4));
806 }
807
812 void setColorimetryCode(uint8_t code) {
813 _bytes[2] = static_cast<uint8_t>((_bytes[2] & 0xCF) | ((code & 0x03) << 4));
814 }
815
820 void setIctcp(bool ictcp) {
821 if (ictcp) _bytes[3] = static_cast<uint8_t>(_bytes[3] | 0x10);
822 else _bytes[3] = static_cast<uint8_t>(_bytes[3] & ~0x10);
823 }
824
829 void setBitDepthCode(uint8_t code) {
830 _bytes[3] = static_cast<uint8_t>((_bytes[3] & 0xFC) | (code & 0x03));
831 }
832
833 // ============================================================
834 // Encoders
835 // ============================================================
836
870 static SdiVpid encode(const VideoFormat &videoFormat,
871 const SdiWireFormat &wireFormat,
872 const SdiLinkStandard &standard);
873
893 static SdiVpid encode(const VideoFormat &videoFormat,
894 const SdiWireFormat &wireFormat,
895 const SdiLinkStandard &standard,
896 int channelIndex);
897
904 static uint8_t encodePictureRateCode(const FrameRate &rate);
905
906 // ============================================================
907 // Integer conversion
908 // ============================================================
909
919 uint32_t toUint32BE() const;
920
927 static SdiVpid fromUint32BE(uint32_t v);
928
929 // ============================================================
930 // ANC packet round-trip (SMPTE ST 291-1 carriage)
931 // ============================================================
932
961 St291Packet toSt291Packet(uint16_t line = 0, bool fieldB = false, bool cBit = false) const;
962
981 static Result<SdiVpid> fromSt291Packet(const St291Packet &pkt);
982
1018 static int recommendedAncLine(const VideoFormat &fmt, int field = 1);
1019
1020 // ============================================================
1021 // String form, equality, DataStream
1022 // ============================================================
1023
1027 String toString() const;
1028
1038 static Result<SdiVpid> fromString(const String &s);
1039
1041 bool operator==(const SdiVpid &other) const { return _bytes == other._bytes; }
1042
1044 bool operator!=(const SdiVpid &other) const { return !(*this == other); }
1045
1052 Error writeToStream(DataStream &s) const;
1053
1058 template <uint32_t V> static Result<SdiVpid> readFromStream(DataStream &s);
1059
1060 private:
1061 ByteArray _bytes{};
1062};
1063
1064PROMEKI_NAMESPACE_END
1065
1066#endif // PROMEKI_ENABLE_PROAV