mirror of
https://github.com/AlexxIT/go2rtc.git
synced 2025-10-03 23:46:27 +08:00
99 lines
2.1 KiB
Go
99 lines
2.1 KiB
Go
// Package h265 - MPEG4 format related functions
|
|
package h265
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/base64"
|
|
"encoding/binary"
|
|
|
|
"github.com/AlexxIT/go2rtc/pkg/core"
|
|
)
|
|
|
|
func DecodeConfig(conf []byte) (profile, vps, sps, pps []byte) {
|
|
profile = conf[1:4]
|
|
|
|
b := conf[23:]
|
|
if binary.BigEndian.Uint16(b[1:]) != 1 {
|
|
return
|
|
}
|
|
vpsSize := binary.BigEndian.Uint16(b[3:])
|
|
vps = b[5 : 5+vpsSize]
|
|
|
|
b = conf[23+5+vpsSize:]
|
|
if binary.BigEndian.Uint16(b[1:]) != 1 {
|
|
return
|
|
}
|
|
spsSize := binary.BigEndian.Uint16(b[3:])
|
|
sps = b[5 : 5+spsSize]
|
|
|
|
b = conf[23+5+vpsSize+5+spsSize:]
|
|
if binary.BigEndian.Uint16(b[1:]) != 1 {
|
|
return
|
|
}
|
|
ppsSize := binary.BigEndian.Uint16(b[3:])
|
|
pps = b[5 : 5+ppsSize]
|
|
|
|
return
|
|
}
|
|
|
|
func EncodeConfig(vps, sps, pps []byte) []byte {
|
|
vpsSize := uint16(len(vps))
|
|
spsSize := uint16(len(sps))
|
|
ppsSize := uint16(len(pps))
|
|
|
|
buf := make([]byte, 23+5+vpsSize+5+spsSize+5+ppsSize)
|
|
|
|
buf[0] = 1
|
|
copy(buf[1:], sps[3:6]) // profile
|
|
buf[21] = 3 // ?
|
|
buf[22] = 3 // ?
|
|
|
|
b := buf[23:]
|
|
_ = b[5]
|
|
b[0] = (vps[0] >> 1) & 0x3F
|
|
binary.BigEndian.PutUint16(b[1:], 1) // VPS count
|
|
binary.BigEndian.PutUint16(b[3:], vpsSize)
|
|
copy(b[5:], vps)
|
|
|
|
b = buf[23+5+vpsSize:]
|
|
_ = b[5]
|
|
b[0] = (sps[0] >> 1) & 0x3F
|
|
binary.BigEndian.PutUint16(b[1:], 1) // SPS count
|
|
binary.BigEndian.PutUint16(b[3:], spsSize)
|
|
copy(b[5:], sps)
|
|
|
|
b = buf[23+5+vpsSize+5+spsSize:]
|
|
_ = b[5]
|
|
b[0] = (pps[0] >> 1) & 0x3F
|
|
binary.BigEndian.PutUint16(b[1:], 1) // PPS count
|
|
binary.BigEndian.PutUint16(b[3:], ppsSize)
|
|
copy(b[5:], pps)
|
|
|
|
return buf
|
|
}
|
|
|
|
func ConfigToCodec(conf []byte) *core.Codec {
|
|
buf := bytes.NewBufferString("profile-id=1")
|
|
|
|
_, vps, sps, pps := DecodeConfig(conf)
|
|
if vps != nil {
|
|
buf.WriteString(";sprop-vps=")
|
|
buf.WriteString(base64.StdEncoding.EncodeToString(vps))
|
|
}
|
|
if sps != nil {
|
|
buf.WriteString(";sprop-sps=")
|
|
buf.WriteString(base64.StdEncoding.EncodeToString(sps))
|
|
}
|
|
if pps != nil {
|
|
buf.WriteString(";sprop-pps=")
|
|
buf.WriteString(base64.StdEncoding.EncodeToString(pps))
|
|
}
|
|
|
|
return &core.Codec{
|
|
Name: core.CodecH265,
|
|
ClockRate: 90000,
|
|
FmtpLine: buf.String(),
|
|
PayloadType: core.PayloadTypeRAW,
|
|
}
|
|
}
|