mirror of
https://github.com/aler9/rtsp-simple-server
synced 2025-10-05 15:46:58 +08:00
77 lines
1.8 KiB
Go
77 lines
1.8 KiB
Go
package message
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
)
|
|
|
|
var magicSignature = []byte{'O', 'p', 'u', 's', 'H', 'e', 'a', 'd'}
|
|
|
|
// OpusIDHeader is an Opus identification header.
|
|
// Specification: RFC7845, section 5.1
|
|
type OpusIDHeader struct {
|
|
Version uint8
|
|
ChannelCount uint8
|
|
PreSkip uint16
|
|
InputSampleRate uint32
|
|
OutputGain uint16
|
|
ChannelMappingFamily uint8
|
|
ChannelMappingTable []uint8
|
|
}
|
|
|
|
func (h *OpusIDHeader) unmarshal(buf []byte) error {
|
|
if len(buf) < 19 {
|
|
return fmt.Errorf("not enough bytes")
|
|
}
|
|
|
|
if !bytes.Equal(buf[:8], magicSignature) {
|
|
return fmt.Errorf("magic signature not corresponds")
|
|
}
|
|
|
|
h.Version = buf[8]
|
|
if h.Version != 1 {
|
|
return fmt.Errorf("invalid version: %v", h.Version)
|
|
}
|
|
|
|
h.ChannelCount = buf[9]
|
|
h.PreSkip = uint16(buf[10])<<8 | uint16(buf[11])
|
|
h.InputSampleRate = uint32(buf[12])<<24 | uint32(buf[13])<<16 | uint32(buf[14])<<8 | uint32(buf[15])
|
|
h.OutputGain = uint16(buf[16])<<8 | uint16(buf[17])
|
|
h.ChannelMappingFamily = buf[18]
|
|
h.ChannelMappingTable = buf[19:]
|
|
|
|
return nil
|
|
}
|
|
|
|
func (h OpusIDHeader) marshalSize() int {
|
|
return 19 + len(h.ChannelMappingTable)
|
|
}
|
|
|
|
func (h OpusIDHeader) marshalTo(buf []byte) (int, error) {
|
|
copy(buf[0:], magicSignature)
|
|
buf[8] = 1
|
|
buf[9] = h.ChannelCount
|
|
buf[10] = byte(h.PreSkip >> 8)
|
|
buf[11] = byte(h.PreSkip)
|
|
buf[12] = byte(h.InputSampleRate >> 24)
|
|
buf[13] = byte(h.InputSampleRate >> 16)
|
|
buf[14] = byte(h.InputSampleRate >> 8)
|
|
buf[15] = byte(h.InputSampleRate)
|
|
buf[16] = byte(h.OutputGain >> 8)
|
|
buf[17] = byte(h.OutputGain)
|
|
buf[18] = h.ChannelMappingFamily
|
|
n := copy(buf[19:], h.ChannelMappingTable)
|
|
return 19 + n, nil
|
|
}
|
|
|
|
func (h OpusIDHeader) marshal() ([]byte, error) {
|
|
buf := make([]byte, h.marshalSize())
|
|
|
|
_, err := h.marshalTo(buf)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return buf, nil
|
|
}
|