streaming

Media streaming and broadcast systems in Go
Log | Files | Refs | README | LICENSE

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 }