github.com/bluenviron/mediacommon@v1.9.3/pkg/formats/mpegts/opus_control_header.go (about) 1 package mpegts 2 3 import ( 4 "fmt" 5 6 "github.com/bluenviron/mediacommon/pkg/bits" 7 ) 8 9 func unmarshalPayloadSize(buf []byte, pos *int) (int, error) { 10 res := 0 11 12 for { 13 next, err := bits.ReadBits(buf, pos, 8) 14 if err != nil { 15 return 0, err 16 } 17 18 res += int(next) 19 20 if next != 255 { 21 break 22 } 23 } 24 25 return res, nil 26 } 27 28 func marshalPayloadSizeSize(v int) int { 29 return v/255 + 1 30 } 31 32 func marshalPayloadSize(v int, ss int, buf []byte) { 33 for i := 0; i < (ss - 1); i++ { 34 buf[i] = 255 35 } 36 buf[ss-1] = byte(v % 255) 37 } 38 39 type opusControlHeader struct { 40 PayloadSize int 41 StartTrimFlag bool 42 EndTrimFlag bool 43 ControlExtensionFlag bool 44 StartTrim uint16 45 EndTrim uint16 46 ControlExtensionLength uint8 47 } 48 49 func (h *opusControlHeader) unmarshal(buf []byte) (int, error) { 50 pos := 0 51 52 err := bits.HasSpace(buf, pos, 16) 53 if err != nil { 54 return 0, err 55 } 56 57 prefix := bits.ReadBitsUnsafe(buf, &pos, 11) 58 if prefix != 0x3ff { 59 return 0, fmt.Errorf("invalid prefix") 60 } 61 62 h.StartTrimFlag = bits.ReadFlagUnsafe(buf, &pos) 63 h.EndTrimFlag = bits.ReadFlagUnsafe(buf, &pos) 64 h.ControlExtensionFlag = bits.ReadFlagUnsafe(buf, &pos) 65 66 pos += 2 // reserved 67 68 h.PayloadSize, err = unmarshalPayloadSize(buf, &pos) 69 if err != nil { 70 return 0, err 71 } 72 73 if h.StartTrimFlag { 74 err := bits.HasSpace(buf, pos, 16) 75 if err != nil { 76 return 0, err 77 } 78 79 pos += 3 // reserved 80 h.StartTrim = uint16(bits.ReadBitsUnsafe(buf, &pos, 13)) 81 } 82 83 if h.EndTrimFlag { 84 err := bits.HasSpace(buf, pos, 16) 85 if err != nil { 86 return 0, err 87 } 88 89 pos += 3 // reserved 90 h.EndTrim = uint16(bits.ReadBitsUnsafe(buf, &pos, 13)) 91 } 92 93 if h.ControlExtensionFlag { 94 tmp, err := bits.ReadBits(buf, &pos, 8) 95 if err != nil { 96 return 0, err 97 } 98 h.ControlExtensionLength = uint8(tmp) 99 100 space := 8 * int(h.ControlExtensionLength) 101 err = bits.HasSpace(buf, pos, space) 102 if err != nil { 103 return 0, err 104 } 105 106 pos += space // reserved 107 } 108 109 return pos / 8, nil 110 } 111 112 func (h *opusControlHeader) marshalSize() int { 113 n := 2 + marshalPayloadSizeSize(h.PayloadSize) 114 if h.StartTrimFlag { 115 n += 2 116 } 117 if h.EndTrimFlag { 118 n += 2 119 } 120 if h.ControlExtensionFlag { 121 n++ 122 n += int(h.ControlExtensionLength) 123 } 124 return n 125 } 126 127 func (h *opusControlHeader) marshalTo(buf []byte) (int, error) { 128 buf[0] = 0b01111111 129 130 buf[1] = 0b111 << 5 131 if h.StartTrimFlag { 132 buf[1] |= 1 << 4 133 } 134 if h.EndTrimFlag { 135 buf[1] |= 1 << 3 136 } 137 if h.ControlExtensionFlag { 138 buf[1] |= 1 << 2 139 } 140 141 ss := marshalPayloadSizeSize(h.PayloadSize) 142 marshalPayloadSize(h.PayloadSize, ss, buf[2:]) 143 pos := 2 + ss 144 145 if h.StartTrimFlag { 146 buf[pos] = uint8(h.StartTrim >> 8) 147 buf[pos+1] = uint8(h.StartTrim) 148 pos += 2 149 } 150 151 if h.EndTrimFlag { 152 buf[pos] = uint8(h.EndTrim >> 8) 153 buf[pos+1] = uint8(h.EndTrim) 154 pos += 2 155 } 156 157 if h.ControlExtensionFlag { 158 buf[pos] = h.ControlExtensionLength 159 pos++ 160 pos += int(h.ControlExtensionLength) 161 } 162 163 return pos, nil 164 }