UNPKG

@astronautlabs/rfc8331

Version:

Implementation of RFC 8331, RTP Payload for SMPTE ST 291-1 Ancillary Data

221 lines (204 loc) 10.4 kB
import { BitstreamElement, Field, Marker } from "@astronautlabs/bitstream"; import * as ST291 from '@astronautlabs/st291'; export const ANC_MIMETYPE = 'video/smpte291'; export class AncillaryMessage extends BitstreamElement { /** * This flag, when set to "1", indicates that the ANC data * corresponds to the color-difference data channel (C). When * set to "0", this flag indicates either that the ANC data * corresponds to the luma (Y) data channel, that the ANC data * source is from an SD signal, or that the ANC data source has * no specific luma or color-difference data channels. For ANC * data from a multi-stream interface source, the C flag SHALL * refer to the channel of the stream used to transport the ANC * data packet. For situations where there is no SDI source, if * the ANC data type definition specifically requires the use of * the C or Y data channel, the C flag SHALL reflect that * requirement. */ @Field(1) c : number; /** * This field contains the digital interface line number that * corresponds to the location of the ANC data packet as an * unsigned integer in network byte order. * The following special Line_Number values indicate that the * location of the ANC data packet is in certain generic * vertical regions of the SDI raster: * * - 0x7FF: Without specific line location within the field or * frame * - 0x7FE: On any line in the range from the second line after * the line specified for switching, as defined in SMPTE * RP 168 [RP168], to the last line before active video, * inclusive * - 0x7FD: On a line number larger than can be represented in 11 * bits of this field (if needed for future formats) * * Note that the lines that are available to convey ANC data are * as defined in the applicable sample structure specification * (e.g., SMPTE ST 274 [ST274], SMPTE ST 296 [ST296], ITU-R * BT.656 [BT656]) and are possibly further restricted per SMPTE * RP 168 [RP168]. * In multi-stream interfaces, this field refers to the line * number that an ANC data packet is carried on within a * particular data stream in the interface. */ @Field(11) lineNumber : number; /** * This field defines the location of the ANC data packet in an * SDI raster relative to the start of active video (SAV; a * digital synchronizing signal present in SDI interfaces) as an * unsigned integer in network byte order. A value of 0 means * that the ADF of the ANC data packet begins immediately * following SAV. The horizontal offset from SAV is measured in * terms of 10-bit words of the indicated data stream and data * channel. * The following special Horizontal_Offset values indicate that * the location of the ANC data packet is in certain generic * horizontal regions of the SDI raster: * * - 0xFFF: Without specific horizontal location * - 0xFFE: Within horizontal ancillary data space (HANC) as * defined in SMPTE ST 291-1 [ST291] * - 0xFFD: Within the ancillary data space located between SAV * (Start of Active Video) and EAV (End of Active Video) * markers of the serial digital interface * - 0xFFC: Horizontal offset is larger than can be represented in * the 12 bits of this field (if needed for future * formats or for certain low frame rate 720p formats) * * In multi-stream interfaces, this field refers to the * horizontal location where an ANC data packet is placed on a * line carried within a particular data stream in the * interface. * * Note that HANC data space will generally have higher luma * sample numbers than any samples in the active digital line. * Also note that SMPTE ST 296 [ST296] (1280 x 720 progressive * active images) image sampling systems 7 and 8 (1280 x 720 * progressive @ 24 fps and 1280 x 720 progressive @ 23.98 fps * respectively) have a luma sample number maximum of 4124. It * is unlikely that an actual implementation would have an ANC * data packet begin at a Horizontal_Offset beyond 4091 (0xFFB) * in these formats; should that occur, the Horizontal_Offset * value 0xFFC can be used to signal a horizontal offset larger * than can be represented in the field. Further note that the * 12-bit field of Horizontal_Offset is kept that size in this * memo to maintain easy conversion to/from SMPTE ST 2038 * [ST2038], which also has a 12-bit Horizontal_Offset field. * */ @Field(12) horizontalOffset : number; /** * This field indicates whether the data stream number of a * multi-stream data mapping used to transport the ANC data * packet is specified. If the S bit is ’0’, then the StreamNum * field provides no guidance regarding the source data stream * number of the ANC data packet. If the S bit is ’1’, then the * StreamNum field carries information regarding the source data * stream number of the ANC data packet. */ @Field(1) dataStreamFlag : number; /** * If the S bit (Data Stream Flag) is ’1’, then the StreamNum * field MUST carry identification of the source data stream * number of the ANC data packet. If the data stream is * numbered, then the StreamNum field SHALL carry the number of * the source data stream minus one. If the source multi-stream * interface does not have numbered data streams, the following * numbers SHALL be used in this field: ’0’ for link A data * stream and ’1’ for link B data stream. For stereoscopic * multi-stream interface formats that do not have numbered * streams, the following numbers SHALL be used in this field: * ’0’ for left eye stream and ’1’ for right eye stream. * Note that in multi-link SDI connections, the physical link * that a particular stream utilizes is typically specified by * the interface standard. Also note that numbering of data * streams is across the interface as a whole. For example, in * the SMPTE ST 425-3 dual-link 3 Gb/s interface, the data * streams are numbered 1-4 with data streams 1 and 2 on link 1 * and data streams 3 and 4 on link 2. */ @Field(7) streamNum : number; @Marker() $packetStart; @Field(0, { skip: ['ancillaryDataFlag']}) packet : ST291.Packet; @Marker() $packetEnd; @Field(i => 32 - (i.measure(i => i.$packetStart, i => i.$packetEnd) % 32)) wordAlign : number = 0; } export class AncillaryPacket extends BitstreamElement { @Field(8, { writtenValue: i => i.messages.length }) ancCount : number = 0; /** * These two bits relate to signaling the field specified by the * RTP timestamp in an interlaced SDI raster. A value of 0b00 * indicates that either the video format is progressive or that * no field is specified. A value of 0b10 indicates that the * timestamp refers to the first field of an interlaced video * signal. A value of 0b11 indicates that the timestamp refers * to the second field of an interlaced video signal. The value * 0b01 is not valid. Receivers SHOULD ignore an ANC data * packet with an F field value of 0b01 and SHOULD process any * other ANC data packets with valid F field values that are * present in the RTP payload. * Note that some multi-stream SDI interfaces might use multiple * interlaced signal streams to transmit progressive images, in * which case the "F" bits would refer to the field of the * interlaced stream used for transport of the ANC data packet. */ @Field(2) field : number; /** * The 22 reserved bits of value "0" follow the F field to * ensure that the first ANC data packet header field in the * payload begins 32-bit word-aligned with the start of the RTP * header to ease implementation. */ @Field(22) reserved : number = 0; /** * ancCount (8 bits): * This field is the count of the total number of ANC data * packets carried in the RTP payload, as an unsigned integer. * A single ANC data RTP packet payload cannot carry more than * 255 ANC data packets. * If more than 255 ANC data packets need to be carried in a * field or frame, additional RTP packets carrying ANC data MAY * be sent with the same RTP timestamp but with different * sequence numbers. ANC_Count of 0 indicates that there are no * ANC data packets in the payload (for example, an RTP packet * that carries no actual ANC data packets even though its * marker bit indicates the last ANC data RTP packet in a field/ * frame). If the ANC_Count is 0, the Length will also be 0. */ @Field(0, { array: { count: i => i.ancCount, type: AncillaryMessage } }) messages : AncillaryMessage[]; } export class RTPPacketHeader extends BitstreamElement { @Field(2) version : number; @Field(1) p : number; @Field(1) x : Number; @Field(4) cc : number; /** * The marker bit set to "1" indicates the last ANC data RTP packet * for a frame (for progressive scan video) or the last ANC data RTP * packet for a field (for interlaced video). */ @Field(1) marker : number; @Field(7) pt : number; @Field(16) sequenceNumber : number; @Field(32) timestamp : number; @Field(32) ssrc : number; /** * The high-order bits of the extended 32-bit sequence number, * in network byte order. This is the same as the Extended * Sequence Number field in RFC 4175 [RFC4175]. */ @Field(16) extendedSequenceNumber : number; /** * Number of octets of the ANC data RTP payload, beginning with * the "C" bit of the first ANC packet data header, as an * unsigned integer in network byte order. Note that all * word_align fields contribute to the calculation of the Length * field. */ @Field(16) length : number; }