mirror of
https://github.com/aler9/gortsplib
synced 2025-10-05 07:06:58 +08:00
handle additional fields of MPEG4-generic: streamtype, mode, profile-level-id (#250)
This commit is contained in:
@@ -134,6 +134,7 @@ var casesFormat = []struct {
|
|||||||
96,
|
96,
|
||||||
"mpeg4-generic/48000/2",
|
"mpeg4-generic/48000/2",
|
||||||
map[string]string{
|
map[string]string{
|
||||||
|
"streamtype": "5",
|
||||||
"profile-level-id": "1",
|
"profile-level-id": "1",
|
||||||
"mode": "AAC-hbr",
|
"mode": "AAC-hbr",
|
||||||
"sizelength": "13",
|
"sizelength": "13",
|
||||||
@@ -143,6 +144,7 @@ var casesFormat = []struct {
|
|||||||
},
|
},
|
||||||
&MPEG4Audio{
|
&MPEG4Audio{
|
||||||
PayloadTyp: 96,
|
PayloadTyp: 96,
|
||||||
|
ProfileLevelID: 1,
|
||||||
Config: &mpeg4audio.Config{
|
Config: &mpeg4audio.Config{
|
||||||
Type: mpeg4audio.ObjectTypeAACLC,
|
Type: mpeg4audio.ObjectTypeAACLC,
|
||||||
SampleRate: 48000,
|
SampleRate: 48000,
|
||||||
@@ -154,6 +156,7 @@ var casesFormat = []struct {
|
|||||||
},
|
},
|
||||||
"mpeg4-generic/48000/2",
|
"mpeg4-generic/48000/2",
|
||||||
map[string]string{
|
map[string]string{
|
||||||
|
"streamtype": "5",
|
||||||
"profile-level-id": "1",
|
"profile-level-id": "1",
|
||||||
"mode": "AAC-hbr",
|
"mode": "AAC-hbr",
|
||||||
"sizelength": "13",
|
"sizelength": "13",
|
||||||
@@ -177,6 +180,7 @@ var casesFormat = []struct {
|
|||||||
},
|
},
|
||||||
&MPEG4Audio{
|
&MPEG4Audio{
|
||||||
PayloadTyp: 96,
|
PayloadTyp: 96,
|
||||||
|
ProfileLevelID: 1,
|
||||||
Config: &mpeg4audio.Config{
|
Config: &mpeg4audio.Config{
|
||||||
Type: mpeg4audio.ObjectTypeAACLC,
|
Type: mpeg4audio.ObjectTypeAACLC,
|
||||||
SampleRate: 48000,
|
SampleRate: 48000,
|
||||||
@@ -188,6 +192,7 @@ var casesFormat = []struct {
|
|||||||
},
|
},
|
||||||
"mpeg4-generic/48000/2",
|
"mpeg4-generic/48000/2",
|
||||||
map[string]string{
|
map[string]string{
|
||||||
|
"streamtype": "5",
|
||||||
"profile-level-id": "1",
|
"profile-level-id": "1",
|
||||||
"mode": "AAC-hbr",
|
"mode": "AAC-hbr",
|
||||||
"sizelength": "13",
|
"sizelength": "13",
|
||||||
@@ -202,7 +207,7 @@ var casesFormat = []struct {
|
|||||||
96,
|
96,
|
||||||
"mpeg4-generic/48000/2",
|
"mpeg4-generic/48000/2",
|
||||||
map[string]string{
|
map[string]string{
|
||||||
"streamtype": "3",
|
"streamtype": "5",
|
||||||
"profile-level-id": "14",
|
"profile-level-id": "14",
|
||||||
"mode": "AAC-hbr",
|
"mode": "AAC-hbr",
|
||||||
"config": "1190",
|
"config": "1190",
|
||||||
@@ -210,6 +215,7 @@ var casesFormat = []struct {
|
|||||||
},
|
},
|
||||||
&MPEG4Audio{
|
&MPEG4Audio{
|
||||||
PayloadTyp: 96,
|
PayloadTyp: 96,
|
||||||
|
ProfileLevelID: 14,
|
||||||
Config: &mpeg4audio.Config{
|
Config: &mpeg4audio.Config{
|
||||||
Type: mpeg4audio.ObjectTypeAACLC,
|
Type: mpeg4audio.ObjectTypeAACLC,
|
||||||
SampleRate: 48000,
|
SampleRate: 48000,
|
||||||
@@ -219,7 +225,8 @@ var casesFormat = []struct {
|
|||||||
},
|
},
|
||||||
"mpeg4-generic/48000/2",
|
"mpeg4-generic/48000/2",
|
||||||
map[string]string{
|
map[string]string{
|
||||||
"profile-level-id": "1",
|
"streamtype": "5",
|
||||||
|
"profile-level-id": "14",
|
||||||
"mode": "AAC-hbr",
|
"mode": "AAC-hbr",
|
||||||
"config": "1190",
|
"config": "1190",
|
||||||
"sizelength": "13",
|
"sizelength": "13",
|
||||||
@@ -646,6 +653,64 @@ func TestMarshal(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestUnmarshalMPEG4AudioGenericErrors(t *testing.T) {
|
||||||
|
_, err := Unmarshal("audio", 96, "MPEG4-generic/48000/2", map[string]string{
|
||||||
|
"streamtype": "10",
|
||||||
|
})
|
||||||
|
require.Error(t, err)
|
||||||
|
|
||||||
|
_, err = Unmarshal("audio", 96, "MPEG4-generic/48000/2", map[string]string{
|
||||||
|
"mode": "asd",
|
||||||
|
})
|
||||||
|
require.Error(t, err)
|
||||||
|
|
||||||
|
_, err = Unmarshal("audio", 96, "MPEG4-generic/48000/2", map[string]string{
|
||||||
|
"profile-level-id": "aaa",
|
||||||
|
})
|
||||||
|
require.Error(t, err)
|
||||||
|
|
||||||
|
_, err = Unmarshal("audio", 96, "MPEG4-generic/48000/2", map[string]string{
|
||||||
|
"config": "aaa",
|
||||||
|
})
|
||||||
|
require.Error(t, err)
|
||||||
|
|
||||||
|
_, err = Unmarshal("audio", 96, "MPEG4-generic/48000/2", map[string]string{
|
||||||
|
"config": "0ab2",
|
||||||
|
})
|
||||||
|
require.Error(t, err)
|
||||||
|
|
||||||
|
_, err = Unmarshal("audio", 96, "MPEG4-generic/48000/2", map[string]string{
|
||||||
|
"sizelength": "aaa",
|
||||||
|
})
|
||||||
|
require.Error(t, err)
|
||||||
|
|
||||||
|
_, err = Unmarshal("audio", 96, "MPEG4-generic/48000/2", map[string]string{
|
||||||
|
"indexlength": "aaa",
|
||||||
|
})
|
||||||
|
require.Error(t, err)
|
||||||
|
|
||||||
|
_, err = Unmarshal("audio", 96, "MPEG4-generic/48000/2", map[string]string{
|
||||||
|
"indexdeltalength": "aaa",
|
||||||
|
})
|
||||||
|
require.Error(t, err)
|
||||||
|
|
||||||
|
_, err = Unmarshal("audio", 96, "MPEG4-generic/48000/2", map[string]string{
|
||||||
|
"profile-level-id": "1",
|
||||||
|
"sizelength": "13",
|
||||||
|
"indexlength": "3",
|
||||||
|
"indexdeltalength": "3",
|
||||||
|
})
|
||||||
|
require.Error(t, err)
|
||||||
|
|
||||||
|
_, err = Unmarshal("audio", 96, "MPEG4-generic/48000/2", map[string]string{
|
||||||
|
"profile-level-id": "1",
|
||||||
|
"config": "1190",
|
||||||
|
"indexlength": "3",
|
||||||
|
"indexdeltalength": "3",
|
||||||
|
})
|
||||||
|
require.Error(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
func FuzzUnmarshalH264(f *testing.F) {
|
func FuzzUnmarshalH264(f *testing.F) {
|
||||||
f.Fuzz(func(t *testing.T, sps string, pktMode string) {
|
f.Fuzz(func(t *testing.T, sps string, pktMode string) {
|
||||||
Unmarshal("video", 96, "H264/90000", map[string]string{
|
Unmarshal("video", 96, "H264/90000", map[string]string{
|
||||||
@@ -672,17 +737,6 @@ func FuzzUnmarshalLPCM(f *testing.F) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func FuzzUnmarshalMPEG4AudioGeneric(f *testing.F) {
|
|
||||||
f.Fuzz(func(t *testing.T, a, b, c, d string) {
|
|
||||||
Unmarshal("audio", 96, "MPEG4-generic/48000/2", map[string]string{
|
|
||||||
"config": a,
|
|
||||||
"sizelength": b,
|
|
||||||
"indexlength": c,
|
|
||||||
"indexdeltalength": d,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func FuzzUnmarshalMPEG4AudioLATM(f *testing.F) {
|
func FuzzUnmarshalMPEG4AudioLATM(f *testing.F) {
|
||||||
f.Fuzz(func(t *testing.T, a, b, c, d, e, f string) {
|
f.Fuzz(func(t *testing.T, a, b, c, d, e, f string) {
|
||||||
Unmarshal("audio", 96, "MP4A-LATM/48000/2", map[string]string{
|
Unmarshal("audio", 96, "MP4A-LATM/48000/2", map[string]string{
|
||||||
|
@@ -4,6 +4,7 @@ import (
|
|||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/pion/rtp"
|
"github.com/pion/rtp"
|
||||||
|
|
||||||
@@ -18,6 +19,7 @@ type MPEG4Audio = MPEG4AudioGeneric
|
|||||||
// Specification: https://datatracker.ietf.org/doc/html/rfc3640
|
// Specification: https://datatracker.ietf.org/doc/html/rfc3640
|
||||||
type MPEG4AudioGeneric struct {
|
type MPEG4AudioGeneric struct {
|
||||||
PayloadTyp uint8
|
PayloadTyp uint8
|
||||||
|
ProfileLevelID int
|
||||||
Config *mpeg4audio.Config
|
Config *mpeg4audio.Config
|
||||||
SizeLength int
|
SizeLength int
|
||||||
IndexLength int
|
IndexLength int
|
||||||
@@ -47,6 +49,24 @@ func (f *MPEG4AudioGeneric) unmarshal(
|
|||||||
|
|
||||||
for key, val := range fmtp {
|
for key, val := range fmtp {
|
||||||
switch key {
|
switch key {
|
||||||
|
case "streamtype":
|
||||||
|
if val != "5" { // AudioStream in ISO 14496-1
|
||||||
|
return fmt.Errorf("streamtype of AAC must be 5")
|
||||||
|
}
|
||||||
|
|
||||||
|
case "mode":
|
||||||
|
if strings.ToLower(val) != "aac-hbr" {
|
||||||
|
return fmt.Errorf("unsupported AAC mode: %v", val)
|
||||||
|
}
|
||||||
|
|
||||||
|
case "profile-level-id":
|
||||||
|
tmp, err := strconv.ParseInt(val, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("invalid profile-level-id: %v", val)
|
||||||
|
}
|
||||||
|
|
||||||
|
f.ProfileLevelID = int(tmp)
|
||||||
|
|
||||||
case "config":
|
case "config":
|
||||||
enc, err := hex.DecodeString(val)
|
enc, err := hex.DecodeString(val)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -105,9 +125,15 @@ func (f *MPEG4AudioGeneric) Marshal() (string, map[string]string) {
|
|||||||
sampleRate = f.Config.ExtensionSampleRate
|
sampleRate = f.Config.ExtensionSampleRate
|
||||||
}
|
}
|
||||||
|
|
||||||
|
profileLevelID := f.ProfileLevelID
|
||||||
|
if profileLevelID == 0 { // support legacy definition which didn't include profile-level-id
|
||||||
|
profileLevelID = 1
|
||||||
|
}
|
||||||
|
|
||||||
fmtp := map[string]string{
|
fmtp := map[string]string{
|
||||||
"profile-level-id": "1",
|
"streamtype": "5",
|
||||||
"mode": "AAC-hbr",
|
"mode": "AAC-hbr",
|
||||||
|
"profile-level-id": strconv.FormatInt(int64(profileLevelID), 10),
|
||||||
}
|
}
|
||||||
|
|
||||||
if f.SizeLength > 0 {
|
if f.SizeLength > 0 {
|
||||||
|
@@ -1,5 +0,0 @@
|
|||||||
go test fuzz v1
|
|
||||||
string("0")
|
|
||||||
string("\xc9u\xb9")
|
|
||||||
string("\x94\xe3ȿJ\xcai\xd5\xee\xc0\xff\xff\x00\x00O\x96a\xdb\x04\x01y\xc8@")
|
|
||||||
string("d\x00\x00\x00")
|
|
@@ -1,5 +0,0 @@
|
|||||||
go test fuzz v1
|
|
||||||
string("0")
|
|
||||||
string("")
|
|
||||||
string("")
|
|
||||||
string("0")
|
|
@@ -1,5 +0,0 @@
|
|||||||
go test fuzz v1
|
|
||||||
string("")
|
|
||||||
string("")
|
|
||||||
string("")
|
|
||||||
string("0")
|
|
@@ -1,5 +0,0 @@
|
|||||||
go test fuzz v1
|
|
||||||
string("")
|
|
||||||
string("\f3r\x05\x00\xe7\xe8")
|
|
||||||
string("2\xf5\xe13")
|
|
||||||
string("7")
|
|
Reference in New Issue
Block a user