Files
go2rtc/pkg/h264/mpeg4.go
T
Sergey Krashevich 2b7682cdb3 refactor(dvrip): simplify broadcast loop structure
- replace traditional for loop with range-based for loop for clarity

refactor(ffmpeg): simplify cut function loop
- utilize range-based for loop instead of traditional for loop

refactor(ring): update API response mapping type
- change map type from `interface{}` to `any` for better type safety

refactor(stream): handle nil source in NewStream
- add nil check for source elements before processing

refactor(webrtc): unify payload handling in GetToken
- change map type from `interface{}` to `any` for consistency

refactor(ascii): optimize nested loops in Write function
- replace traditional for loops with range-based for loops for readability

refactor(bits): enhance readability in Reader methods
- replace traditional for loops with range-based for loops in Read functions

refactor(h264): modernize loop structures in DecodeConfig
- switch to range-based for loops for cleaner code

refactor(h265): streamline profile_tier_level loops
- utilize range-based for loops instead of traditional for loops

chore(core): remove commented-out test function for clarity

refactor(core): simplify RandString function loop
- change traditional for loop to range-based for loop

refactor(flvt): optimize timestamp handling in TestTimeToRTP
- switch to range-based for loop for iterating frames

refactor(nest): improve error handling in ExchangeSDP
- format error message with printf-style formatting for clarity

refactor(tapo): enhance securityEncode function
- change traditional for loop to range-based for loop for readability

fix(tcp): correct masking in websocket Write method
- replace traditional for loop with range-based for loop

refactor(tutk): modernize encoding loops in crypto functions
- utilize range-based for loops for better readability

refactor(tuya): unify data types in MQTT message struct
- change map type from `interface{}` to `any` for consistency

refactor(webrtc): standardize codec registration
- change map type from `interface{}` to `any` for type safety

refactor(yaml): simplify Unmarshal function signature
- update parameter type from `interface{}` to `any` for better clarity
2026-03-10 23:26:45 +03:00

102 lines
2.0 KiB
Go

// Package h264 - MPEG4 format related functions
package h264
import (
"bytes"
"encoding/base64"
"encoding/binary"
"encoding/hex"
"github.com/AlexxIT/go2rtc/pkg/core"
)
// DecodeConfig - extract profile, SPS and PPS from MPEG4 config
func DecodeConfig(conf []byte) (profile []byte, sps []byte, pps []byte) {
if len(conf) < 6 || conf[0] != 1 {
return
}
profile = conf[1:4]
count := conf[5] & 0x1F
conf = conf[6:]
for range count {
if len(conf) < 2 {
return
}
size := 2 + int(binary.BigEndian.Uint16(conf))
if len(conf) < size {
return
}
if sps == nil {
sps = conf[2:size]
}
conf = conf[size:]
}
count = conf[0]
conf = conf[1:]
for range count {
if len(conf) < 2 {
return
}
size := 2 + int(binary.BigEndian.Uint16(conf))
if len(conf) < size {
return
}
if pps == nil {
pps = conf[2:size]
}
conf = conf[size:]
}
return
}
func EncodeConfig(sps, pps []byte) []byte {
spsSize := uint16(len(sps))
ppsSize := uint16(len(pps))
buf := make([]byte, 5+3+spsSize+3+ppsSize)
buf[0] = 1
copy(buf[1:], sps[1:4]) // profile
buf[4] = 3 | 0xFC // ? LengthSizeMinusOne
b := buf[5:]
_ = b[3]
b[0] = 1 | 0xE0 // ? sps count
binary.BigEndian.PutUint16(b[1:], spsSize)
copy(b[3:], sps)
b = buf[5+3+spsSize:]
_ = b[3]
b[0] = 1 // pps count
binary.BigEndian.PutUint16(b[1:], ppsSize)
copy(b[3:], pps)
return buf
}
func ConfigToCodec(conf []byte) *core.Codec {
buf := bytes.NewBufferString("packetization-mode=1")
profile, sps, pps := DecodeConfig(conf)
if profile != nil {
buf.WriteString(";profile-level-id=")
buf.WriteString(hex.EncodeToString(profile))
}
if sps != nil && pps != nil {
buf.WriteString(";sprop-parameter-sets=")
buf.WriteString(base64.StdEncoding.EncodeToString(sps))
buf.WriteString(",")
buf.WriteString(base64.StdEncoding.EncodeToString(pps))
}
return &core.Codec{
Name: core.CodecH264,
ClockRate: 90000,
FmtpLine: buf.String(),
PayloadType: core.PayloadTypeRAW,
}
}