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  }