Skip to content

Commit

Permalink
discard invalid video tracks (#381) (#383)
Browse files Browse the repository at this point in the history
  • Loading branch information
aler9 authored Aug 25, 2023
1 parent 608f149 commit dffc241
Show file tree
Hide file tree
Showing 22 changed files with 233 additions and 214 deletions.
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

0 comments on commit dffc241

Please sign in to comment.