payload.go (3176B)
1 // Package jxs ... for transporting JPEG XS streams in RTP payloads 2 // as specified in RFC 9134. 3 package jxs 4 5 import "encoding/binary" 6 7 type ScanMode uint8 8 9 const ( 10 ScanModeProgressive ScanMode = 0 11 _ 12 ScanModeInterlacedFirst ScanMode = 0b00010000 13 ScanModeInterlacedSecond = 0b00011000 14 ) 15 16 /* 17 type Payload struct { 18 Header *Header 19 PacketizationUnit *PacketizationUnit 20 } 21 22 type PacketizationUnit struct { 23 VideoBox 24 ColorBox 25 // ... 26 } 27 */ 28 29 type Header struct { 30 // Sequential indicates whether packets are sent sequentially 31 // or possibly out of order. may be sent out of order. 32 Sequential bool 33 34 // PacketMode indicates the packetization mode. If true, 35 // codestream packetization is used. If false, slice 36 // packetization is used and Sequential must be false. 37 PacketMode bool 38 39 // Last indicates whether the packet is the last packet of a 40 // packetization unit. 41 Last bool 42 43 // InterlacedInfo specifies how the frame is scanned. 44 InterlacedInfo ScanMode 45 46 // FrameCount holds a 5-bit integer (modulo 32) identifying 47 // the frame to which the packet belongs. 48 FrameCount uint8 49 50 // SEPCounter (Slice and Extended Packet counter) 51 // holds an 11-bit integer which is interpreted differently 52 // depending on the value of PacketMode. 53 // 54 // If the packetization mode is codestream, then SEPCounter is 55 // incremented by 1 whenever PacketCounter overruns. 56 // 57 // If packetization mode is slice, then SEPCounter identifies 58 // the slice (modulo 2047) to which the packet contributes. 59 SEPCount uint16 60 61 // PacketCounter is an 11-bit integer identifying the packet number 62 // within the current packetization unit. 63 PacketCount uint16 64 } 65 66 func unmarshalHeader(a [4]byte, hdr Header) error { 67 hdr.Sequential = a[0]&0b10000000 > 0 68 hdr.PacketMode = a[0]&0b01000000 > 0 69 hdr.Last = a[0]&0b00100000 > 0 70 hdr.InterlacedInfo = ScanMode(a[0] & 0b00011000) 71 72 hdr.FrameCount = (a[0] & 0b00000111) << 2 73 hdr.FrameCount |= ((a[1] & 0b11000000) >> 6) 74 75 var sepc [2]byte 76 sepc[0] = a[1] & 0b00111000 >> 3 77 sepc[1] = a[1] & 0b00000111 << 5 78 sepc[1] |= a[2] & 0b11111000 >> 3 79 hdr.SEPCount = binary.BigEndian.Uint16(sepc[:]) 80 81 hdr.PacketCount = binary.BigEndian.Uint16([]byte{a[2] & 0b00000111, a[3]}) 82 return nil 83 } 84 85 func marshalHeader(hdr Header) [4]byte { 86 var a [4]byte 87 if hdr.Sequential { 88 a[0] |= (1 << 7) 89 } 90 if hdr.PacketMode { 91 a[0] |= (1 << 6) 92 } 93 if hdr.Last { 94 a[0] |= (1 << 5) 95 } 96 a[0] |= byte(hdr.InterlacedInfo) 97 98 // Need to pack the 5 bits in FrameCount across both a[0] and a[1]. 99 // Have 3 bits remaining in a[0]. 100 a[0] |= (hdr.FrameCount & 0b00011100) >> 2 101 // Pack remaining 2 bits from FrameCount into left-most bits of a[1]. 102 a[1] = (hdr.FrameCount & 0b00000011) << 6 103 104 // 6 bits remaining in a[1]. 105 // We have 11 bits in SEPCount to pack. 106 b := make([]byte, 2) 107 binary.BigEndian.PutUint16(b, hdr.SEPCount) 108 a[1] |= (b[0] & 0b00000111) << 3 109 // 3 bits remaining in a[1], so get next 3 bits from b. 110 a[1] |= (b[1] & 0b11100000) >> 5 111 112 // 5 bits remaining in b. 113 a[2] = (b[1] & 0b00011111) << 3 114 115 b[0] = 0 116 b[1] = 0 117 binary.BigEndian.PutUint16(b, hdr.PacketCount) 118 // 3 bits spare in a[2]. 119 a[2] |= (b[0] & 0b00000111) 120 a[3] = b[1] 121 return a 122 }