golanggohlsrtmpwebrtcmedia-serverobs-studiortcprtmp-proxyrtmp-serverrtprtsprtsp-proxyrtsp-relayrtsp-serversrtstreamingwebrtc-proxy
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
90 lines
1.5 KiB
90 lines
1.5 KiB
// Package h264conf contains a H264 configuration parser. |
|
package h264conf |
|
|
|
import ( |
|
"fmt" |
|
) |
|
|
|
// Conf is a RTMP H264 configuration. |
|
type Conf struct { |
|
SPS []byte |
|
PPS []byte |
|
} |
|
|
|
// Unmarshal decodes a Conf from bytes. |
|
func (c *Conf) Unmarshal(buf []byte) error { |
|
if len(buf) < 8 { |
|
return fmt.Errorf("invalid size 1") |
|
} |
|
|
|
pos := 5 |
|
|
|
spsCount := buf[pos] & 0x1F |
|
pos++ |
|
if spsCount != 1 { |
|
return fmt.Errorf("sps count != 1 is unsupported") |
|
} |
|
|
|
spsLen := int(uint16(buf[pos])<<8 | uint16(buf[pos+1])) |
|
pos += 2 |
|
if (len(buf) - pos) < spsLen { |
|
return fmt.Errorf("invalid size 2") |
|
} |
|
|
|
c.SPS = buf[pos : pos+spsLen] |
|
pos += spsLen |
|
|
|
if (len(buf) - pos) < 3 { |
|
return fmt.Errorf("invalid size 3") |
|
} |
|
|
|
ppsCount := buf[pos] |
|
pos++ |
|
if ppsCount != 1 { |
|
return fmt.Errorf("pps count != 1 is unsupported") |
|
} |
|
|
|
ppsLen := int(uint16(buf[pos])<<8 | uint16(buf[pos+1])) |
|
pos += 2 |
|
if (len(buf) - pos) < ppsLen { |
|
return fmt.Errorf("invalid size") |
|
} |
|
|
|
c.PPS = buf[pos : pos+ppsLen] |
|
|
|
return nil |
|
} |
|
|
|
// Marshal encodes a Conf into bytes. |
|
func (c Conf) Marshal() ([]byte, error) { |
|
spsLen := len(c.SPS) |
|
ppsLen := len(c.PPS) |
|
|
|
buf := make([]byte, 11+spsLen+ppsLen) |
|
|
|
buf[0] = 1 |
|
buf[1] = c.SPS[1] |
|
buf[2] = c.SPS[2] |
|
buf[3] = c.SPS[3] |
|
buf[4] = 3 | 0xFC |
|
buf[5] = 1 | 0xE0 |
|
pos := 6 |
|
|
|
buf[pos] = byte(spsLen >> 8) |
|
buf[pos+1] = byte(spsLen) |
|
pos += 2 |
|
|
|
copy(buf[pos:], c.SPS) |
|
pos += spsLen |
|
|
|
buf[pos] = 1 |
|
pos++ |
|
|
|
buf[pos] = byte(ppsLen >> 8) |
|
buf[pos+1] = byte(ppsLen) |
|
pos += 2 |
|
|
|
copy(buf[pos:], c.PPS) |
|
|
|
return buf, nil |
|
}
|
|
|