diff --git a/pkg/h264/h264.go b/pkg/h264/h264.go index 8d0ef9a9..12239536 100644 --- a/pkg/h264/h264.go +++ b/pkg/h264/h264.go @@ -5,8 +5,9 @@ import ( "encoding/binary" "encoding/hex" "fmt" - "github.com/AlexxIT/go2rtc/pkg/core" "strings" + + "github.com/AlexxIT/go2rtc/pkg/core" ) const ( @@ -49,14 +50,23 @@ func Join(ps, iframe []byte) []byte { return b } +// https://developers.google.com/cast/docs/media +const ( + ProfileBaseline = 0x42 + ProfileMain = 0x4D + ProfileHigh = 0x64 + CapabilityBaseline = 0xE0 + CapabilityMain = 0x40 +) + // 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 { // avc1.640029 - H.264 high 4.1 (Chromecast 1st and 2nd Gen) - profile := byte(0x64) + profile := byte(ProfileHigh) capab := byte(0) - level := byte(0x29) + level := byte(41) if fmtp != "" { var conf []byte @@ -70,12 +80,18 @@ func GetProfileLevelID(fmtp string) string { conf, _ = hex.DecodeString(s) } - if conf != nil { - if conf[0] < profile { + if len(conf) == 3 { + // sanitize profile, capab and level to supported values + switch conf[0] { + case ProfileBaseline, ProfileMain: profile = conf[0] + } + switch conf[1] { + case CapabilityBaseline, CapabilityMain: capab = conf[1] } - if conf[2] < level { + switch conf[2] { + case 30, 31, 40: level = conf[2] } } diff --git a/pkg/h264/h264_test.go b/pkg/h264/h264_test.go index 542c3dde..cf159c32 100644 --- a/pkg/h264/h264_test.go +++ b/pkg/h264/h264_test.go @@ -39,3 +39,15 @@ func TestDecodeSPS(t *testing.T) { require.Equal(t, uint16(1920), sps.Width()) require.Equal(t, uint16(1080), sps.Height()) } + +func TestGetProfileLevelID(t *testing.T) { + // OpenIPC https://github.com/OpenIPC + s := "profile-level-id=0033e7; packetization-mode=1; " + profile := GetProfileLevelID(s) + require.Equal(t, "640029", profile) + + // Eufy T8400 https://github.com/AlexxIT/go2rtc/issues/155 + s = "packetization-mode=1;profile-level-id=276400" + profile = GetProfileLevelID(s) + require.Equal(t, "640029", profile) +}