Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

discard invalid video tracks (#381) #383

Merged
merged 1 commit into from
Aug 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions pkg/formats/av1.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ type AV1 struct {
Tier *int
}

func (f *AV1) unmarshal(payloadType uint8, _ string, _ string, _ string, fmtp map[string]string) error {
f.PayloadTyp = payloadType
func (f *AV1) unmarshal(ctx *unmarshalContext) error {
f.PayloadTyp = ctx.payloadType

for key, val := range fmtp {
for key, val := range ctx.fmtp {
switch key {
case "level-idx":
n, err := strconv.ParseUint(val, 10, 31)
Expand Down
120 changes: 67 additions & 53 deletions pkg/formats/format.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,19 @@ func getCodecAndClock(rtpMap string) (string, string) {
return strings.ToLower(parts2[0]), parts2[1]
}

type unmarshalContext struct {
mediaType string
payloadType uint8
clock string
codec string
rtpMap string
fmtp map[string]string
}

// Format is a media format.
// It defines the payload type of RTP packets and how to encode/decode them.
type Format interface {
unmarshal(payloadType uint8, clock string, codec string, rtpmap string, fmtp map[string]string) error
unmarshal(ctx *unmarshalContext) error

// Codec returns the codec name.
Codec() string
Expand Down Expand Up @@ -49,81 +58,86 @@ func Unmarshal(mediaType string, payloadType uint8, rtpMap string, fmtp map[stri

format := func() Format {
switch {
case mediaType == "video":
switch {
case payloadType == 26:
return &MJPEG{}
// video

case payloadType == 26:
return &MJPEG{}

case payloadType == 32:
return &MPEG1Video{}

case payloadType == 32:
return &MPEG1Video{}
case payloadType == 33:
return &MPEGTS{}

case payloadType == 33:
return &MPEGTS{}
case codec == "mp4v-es" && clock == "90000":
return &MPEG4Video{}

case codec == "mp4v-es" && clock == "90000":
return &MPEG4Video{}
case codec == "h264" && clock == "90000":
return &H264{}

case codec == "h264" && clock == "90000":
return &H264{}
case codec == "h265" && clock == "90000":
return &H265{}

case codec == "h265" && clock == "90000":
return &H265{}
case codec == "vp8" && clock == "90000":
return &VP8{}

case codec == "vp8" && clock == "90000":
return &VP8{}
case codec == "vp9" && clock == "90000":
return &VP9{}

case codec == "vp9" && clock == "90000":
return &VP9{}
case codec == "av1" && clock == "90000":
return &AV1{}

case codec == "av1" && clock == "90000":
return &AV1{}
}
// audio

case mediaType == "audio":
switch {
case payloadType == 0, payloadType == 8:
return &G711{}
case payloadType == 0, payloadType == 8:
return &G711{}

case payloadType == 9:
return &G722{}
case payloadType == 9:
return &G722{}

case (codec == "g726-16" ||
codec == "g726-24" ||
codec == "g726-32" ||
codec == "g726-40" ||
codec == "aal2-g726-16" ||
codec == "aal2-g726-24" ||
codec == "aal2-g726-32" ||
codec == "aal2-g726-40") && clock == "8000":
return &G726{}
case (codec == "g726-16" ||
codec == "g726-24" ||
codec == "g726-32" ||
codec == "g726-40" ||
codec == "aal2-g726-16" ||
codec == "aal2-g726-24" ||
codec == "aal2-g726-32" ||
codec == "aal2-g726-40") && clock == "8000":
return &G726{}

case payloadType == 14:
return &MPEG1Audio{}
case payloadType == 14:
return &MPEG1Audio{}

case codec == "l8", codec == "l16", codec == "l24":
return &LPCM{}
case codec == "l8", codec == "l16", codec == "l24":
return &LPCM{}

case codec == "mpeg4-generic":
return &MPEG4AudioGeneric{}
case codec == "mpeg4-generic":
return &MPEG4AudioGeneric{}

case codec == "mp4a-latm":
return &MPEG4AudioLATM{}
case codec == "mp4a-latm":
return &MPEG4AudioLATM{}

case codec == "speex":
return &Speex{}
case codec == "speex":
return &Speex{}

case codec == "vorbis":
return &Vorbis{}
case codec == "vorbis":
return &Vorbis{}

case codec == "opus":
return &Opus{}
}
case codec == "opus":
return &Opus{}
}

return &Generic{}
}()

err := format.unmarshal(payloadType, clock, codec, rtpMap, fmtp)
err := format.unmarshal(&unmarshalContext{
mediaType: mediaType,
payloadType: payloadType,
clock: clock,
codec: codec,
rtpMap: rtpMap,
fmtp: fmtp,
})
if err != nil {
return nil, err
}
Expand Down
171 changes: 89 additions & 82 deletions pkg/formats/format_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -912,109 +912,116 @@ func TestMarshal(t *testing.T) {
}
}

func TestUnmarshalMPEG4AudioGenericErrors(t *testing.T) {
_, err := Unmarshal("audio", 96, "MPEG4-generic/48000/2", map[string]string{
"streamtype": "10",
func TestUnmarshalErrors(t *testing.T) {
t.Run("invalid video", func(t *testing.T) {
_, err := Unmarshal("video", 96, "", map[string]string{})
require.Error(t, err)
})
require.Error(t, err)

_, err = Unmarshal("audio", 96, "MPEG4-generic/48000/2", map[string]string{
"mode": "asd",
})
require.Error(t, err)
t.Run("mpeg-4 audio generic", func(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{
"profile-level-id": "aaa",
})
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{
"config": "aaa",
})
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": "0ab2",
})
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{
"sizelength": "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{
"indexlength": "aaa",
})
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{
"indexdeltalength": "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{
"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{
"indexdeltalength": "aaa",
})
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)
}
_, 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)

func TestUnmarshalMPEG4AudioLATMErrors(t *testing.T) {
_, err := Unmarshal("audio", 96, "MP4A-LATM/48000/2", map[string]string{
"profile-level-id": "aaa",
_, 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)
})
require.Error(t, err)

_, err = Unmarshal("audio", 96, "MP4A-LATM/48000/2", map[string]string{
"bitrate": "aaa",
})
require.Error(t, err)
t.Run("mpeg-4 audio latm", func(t *testing.T) {
_, err := Unmarshal("audio", 96, "MP4A-LATM/48000/2", map[string]string{
"profile-level-id": "aaa",
})
require.Error(t, err)

_, err = Unmarshal("audio", 96, "MP4A-LATM/48000/2", map[string]string{
"cpresent": "0",
})
require.Error(t, err)
_, err = Unmarshal("audio", 96, "MP4A-LATM/48000/2", map[string]string{
"bitrate": "aaa",
})
require.Error(t, err)

_, err = Unmarshal("audio", 96, "MP4A-LATM/48000/2", map[string]string{
"config": "aaa",
})
require.Error(t, err)
_, err = Unmarshal("audio", 96, "MP4A-LATM/48000/2", map[string]string{
"cpresent": "0",
})
require.Error(t, err)

_, err = Unmarshal("audio", 96, "MP4A-LATM/48000/2", map[string]string{
"profile-level-id": "15",
"object": "2",
"cpresent": "0",
"sbr-enabled": "1",
})
require.Error(t, err)
}
_, err = Unmarshal("audio", 96, "MP4A-LATM/48000/2", map[string]string{
"config": "aaa",
})
require.Error(t, err)

func TestUnmarshalAV1Errors(t *testing.T) {
_, err := Unmarshal("video", 96, "AV1/90000", map[string]string{
"level-idx": "aaa",
_, err = Unmarshal("audio", 96, "MP4A-LATM/48000/2", map[string]string{
"profile-level-id": "15",
"object": "2",
"cpresent": "0",
"sbr-enabled": "1",
})
require.Error(t, err)
})
require.Error(t, err)

_, err = Unmarshal("video", 96, "AV1/90000", map[string]string{
"profile": "aaa",
})
require.Error(t, err)
t.Run("av1", func(t *testing.T) {
_, err := Unmarshal("video", 96, "AV1/90000", map[string]string{
"level-idx": "aaa",
})
require.Error(t, err)

_, err = Unmarshal("video", 96, "AV1/90000", map[string]string{
"tier": "aaa",
_, err = Unmarshal("video", 96, "AV1/90000", map[string]string{
"profile": "aaa",
})
require.Error(t, err)

_, err = Unmarshal("video", 96, "AV1/90000", map[string]string{
"tier": "aaa",
})
require.Error(t, err)
})
require.Error(t, err)
}

func FuzzUnmarshalH264(f *testing.F) {
Expand Down
4 changes: 2 additions & 2 deletions pkg/formats/g711.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ type G711 struct {
MULaw bool
}

func (f *G711) unmarshal(payloadType uint8, _ string, _ string, _ string, _ map[string]string) error {
f.MULaw = (payloadType == 0)
func (f *G711) unmarshal(ctx *unmarshalContext) error {
f.MULaw = (ctx.payloadType == 0)
return nil
}

Expand Down
2 changes: 1 addition & 1 deletion pkg/formats/g722.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
// Specification: https://datatracker.ietf.org/doc/html/rfc3551
type G722 struct{}

func (f *G722) unmarshal(_ uint8, _ string, _ string, _ string, _ map[string]string) error {
func (f *G722) unmarshal(_ *unmarshalContext) error {
return nil
}

Expand Down
Loading