Make GetProfileLevelID func more smarter

This commit is contained in:
Alexey Khit
2023-02-06 20:53:55 +03:00
parent 497594f53f
commit b05cbdf3d3
2 changed files with 30 additions and 17 deletions
+26 -7
View File
@@ -3,6 +3,7 @@ package h264
import ( import (
"encoding/base64" "encoding/base64"
"encoding/binary" "encoding/binary"
"encoding/hex"
"fmt" "fmt"
"github.com/AlexxIT/go2rtc/pkg/streamer" "github.com/AlexxIT/go2rtc/pkg/streamer"
"strings" "strings"
@@ -48,21 +49,39 @@ func Join(ps, iframe []byte) []byte {
return b return b
} }
// GetProfileLevelID - get profile from fmtp line
// Some devices won't play video with high level, so limit max profile and max level.
// And return some profile even if fmtp line is empty.
func GetProfileLevelID(fmtp string) string { func GetProfileLevelID(fmtp string) string {
if fmtp == "" { // avc1.640029 - H.264 high 4.1 (Chromecast 1st and 2nd Gen)
return "" profile := byte(0x64)
} capab := byte(0)
level := byte(0x29)
if fmtp != "" {
var conf []byte
// some cameras has wrong profile-level-id // some cameras has wrong profile-level-id
// https://github.com/AlexxIT/go2rtc/issues/155 // https://github.com/AlexxIT/go2rtc/issues/155
if s := streamer.Between(fmtp, "sprop-parameter-sets=", ","); s != "" { if s := streamer.Between(fmtp, "sprop-parameter-sets=", ","); s != "" {
sps, _ := base64.StdEncoding.DecodeString(s) if sps, _ := base64.StdEncoding.DecodeString(s); len(sps) >= 4 {
if len(sps) >= 4 { conf = sps[1:4]
return fmt.Sprintf("%06X", sps[1:4]) }
} else if s = streamer.Between(fmtp, "profile-level-id=", ";"); s != "" {
conf, _ = hex.DecodeString(s)
}
if conf != nil {
if conf[0] < profile {
profile = conf[0]
capab = conf[1]
}
if conf[2] < level {
level = conf[2]
}
} }
} }
return streamer.Between(fmtp, "profile-level-id=", ";") return fmt.Sprintf("%02X%02X%02X", profile, capab, level)
} }
func GetParameterSet(fmtp string) (sps, pps []byte) { func GetParameterSet(fmtp string) (sps, pps []byte) {
-6
View File
@@ -66,13 +66,7 @@ func (c *Consumer) AddTrack(media *streamer.Media, track *streamer.Track) *strea
c.mimeType += "," c.mimeType += ","
} }
// TODO: fixme
// some devices won't play high level
if stream.RecordInfo.AVCLevelIndication <= 0x29 {
c.mimeType += "avc1." + h264.GetProfileLevelID(codec.FmtpLine) c.mimeType += "avc1." + h264.GetProfileLevelID(codec.FmtpLine)
} else {
c.mimeType += "avc1.640029"
}
c.streams = append(c.streams, stream) c.streams = append(c.streams, stream)