diff --git a/pkg/format/format_test.go b/pkg/format/format_test.go index d2fca531..45111fad 100644 --- a/pkg/format/format_test.go +++ b/pkg/format/format_test.go @@ -629,7 +629,41 @@ func TestNewFromMediaDescriptionErrors(t *testing.T) { err string }{ { - "aac missing fmtp", + "audio lpcm invalid clock", + &psdp.MediaDescription{ + MediaName: psdp.MediaName{ + Media: "audio", + Protos: []string{"RTP", "AVP"}, + Formats: []string{"97"}, + }, + Attributes: []psdp.Attribute{ + { + Key: "rtpmap", + Value: "97 L8/", + }, + }, + }, + "strconv.ParseInt: parsing \"\": invalid syntax", + }, + { + "audio lpcm invalid channels", + &psdp.MediaDescription{ + MediaName: psdp.MediaName{ + Media: "audio", + Protos: []string{"RTP", "AVP"}, + Formats: []string{"97"}, + }, + Attributes: []psdp.Attribute{ + { + Key: "rtpmap", + Value: "97 L8/48000/", + }, + }, + }, + "strconv.ParseInt: parsing \"\": invalid syntax", + }, + { + "audio aac missing fmtp", &psdp.MediaDescription{ MediaName: psdp.MediaName{ Media: "audio", @@ -646,7 +680,7 @@ func TestNewFromMediaDescriptionErrors(t *testing.T) { "fmtp attribute is missing", }, { - "aac invalid fmtp", + "audio aac invalid fmtp", &psdp.MediaDescription{ MediaName: psdp.MediaName{ Media: "audio", @@ -667,7 +701,7 @@ func TestNewFromMediaDescriptionErrors(t *testing.T) { "fmtp attribute is missing", }, { - "aac fmtp without key", + "audio aac fmtp without key", &psdp.MediaDescription{ MediaName: psdp.MediaName{ Media: "audio", @@ -688,7 +722,7 @@ func TestNewFromMediaDescriptionErrors(t *testing.T) { "invalid fmtp (profile-level-id)", }, { - "aac missing config", + "audio aac missing config", &psdp.MediaDescription{ MediaName: psdp.MediaName{ Media: "audio", @@ -709,7 +743,7 @@ func TestNewFromMediaDescriptionErrors(t *testing.T) { "config is missing (profile-level-id=1)", }, { - "aac invalid config 1", + "audio aac invalid config 1", &psdp.MediaDescription{ MediaName: psdp.MediaName{ Media: "audio", @@ -730,7 +764,7 @@ func TestNewFromMediaDescriptionErrors(t *testing.T) { "invalid AAC config (zz)", }, { - "aac invalid config 2", + "audio aac invalid config 2", &psdp.MediaDescription{ MediaName: psdp.MediaName{ Media: "audio", @@ -751,7 +785,7 @@ func TestNewFromMediaDescriptionErrors(t *testing.T) { "invalid AAC config (aa)", }, { - "aac missing sizelength", + "audio aac missing sizelength", &psdp.MediaDescription{ MediaName: psdp.MediaName{ Media: "audio", @@ -772,7 +806,70 @@ func TestNewFromMediaDescriptionErrors(t *testing.T) { "sizelength is missing (profile-level-id=1; config=1190)", }, { - "opus invalid 1", + "audio aac invalid sizelength", + &psdp.MediaDescription{ + MediaName: psdp.MediaName{ + Media: "audio", + Protos: []string{"RTP", "AVP"}, + Formats: []string{"96"}, + }, + Attributes: []psdp.Attribute{ + { + Key: "rtpmap", + Value: "96 mpeg4-generic/48000/2", + }, + { + Key: "fmtp", + Value: "96 profile-level-id=1; sizelength=aaa", + }, + }, + }, + "invalid AAC SizeLength (aaa)", + }, + { + "audio aac invalid indexlength", + &psdp.MediaDescription{ + MediaName: psdp.MediaName{ + Media: "audio", + Protos: []string{"RTP", "AVP"}, + Formats: []string{"96"}, + }, + Attributes: []psdp.Attribute{ + { + Key: "rtpmap", + Value: "96 mpeg4-generic/48000/2", + }, + { + Key: "fmtp", + Value: "96 profile-level-id=1; indexlength=aaa", + }, + }, + }, + "invalid AAC IndexLength (aaa)", + }, + { + "audio aac invalid indexdeltalength", + &psdp.MediaDescription{ + MediaName: psdp.MediaName{ + Media: "audio", + Protos: []string{"RTP", "AVP"}, + Formats: []string{"96"}, + }, + Attributes: []psdp.Attribute{ + { + Key: "rtpmap", + Value: "96 mpeg4-generic/48000/2", + }, + { + Key: "fmtp", + Value: "96 profile-level-id=1; indexdeltalength=aaa", + }, + }, + }, + "invalid AAC IndexDeltaLength (aaa)", + }, + { + "audio opus invalid 1", &psdp.MediaDescription{ MediaName: psdp.MediaName{ Media: "audio", @@ -789,7 +886,7 @@ func TestNewFromMediaDescriptionErrors(t *testing.T) { "invalid clock (48000)", }, { - "opus invalid 2", + "audio opus invalid 2", &psdp.MediaDescription{ MediaName: psdp.MediaName{ Media: "audio", @@ -806,7 +903,7 @@ func TestNewFromMediaDescriptionErrors(t *testing.T) { "strconv.ParseInt: parsing \"aa\": invalid syntax", }, { - "opus invalid 3", + "audio opus invalid 3", &psdp.MediaDescription{ MediaName: psdp.MediaName{ Media: "audio", diff --git a/pkg/format/g711.go b/pkg/format/g711.go index 59521dea..9cc090ec 100644 --- a/pkg/format/g711.go +++ b/pkg/format/g711.go @@ -1,9 +1,6 @@ package format import ( - "fmt" - "strings" - "github.com/pion/rtp" "github.com/aler9/gortsplib/v2/pkg/formatdecenc/rtpsimpleaudio" @@ -34,13 +31,7 @@ func (t *G711) PayloadType() uint8 { } func (t *G711) unmarshal(payloadType uint8, clock string, codec string, rtpmap string, fmtp string) error { - tmp := strings.Split(clock, "/") - if len(tmp) == 2 && tmp[1] != "1" { - return fmt.Errorf("G711 formats can have only one channel") - } - t.MULaw = (payloadType == 0) - return nil } diff --git a/pkg/format/g711_test.go b/pkg/format/g711_test.go index 682365eb..4ed4f94a 100644 --- a/pkg/format/g711_test.go +++ b/pkg/format/g711_test.go @@ -41,3 +41,17 @@ func TestG711MediaDescription(t *testing.T) { require.Equal(t, "", fmtp) }) } + +func TestG711DecEncoder(t *testing.T) { + format := &G711{} + + enc := format.CreateEncoder() + pkt, err := enc.Encode([]byte{0x01, 0x02, 0x03, 0x04}, 0) + require.NoError(t, err) + require.Equal(t, format.PayloadType(), pkt.PayloadType) + + dec := format.CreateDecoder() + byts, _, err := dec.Decode(pkt) + require.NoError(t, err) + require.Equal(t, []byte{0x01, 0x02, 0x03, 0x04}, byts) +} diff --git a/pkg/format/g722.go b/pkg/format/g722.go index beee8006..474acb6a 100644 --- a/pkg/format/g722.go +++ b/pkg/format/g722.go @@ -1,9 +1,6 @@ package format import ( - "fmt" - "strings" - "github.com/pion/rtp" "github.com/aler9/gortsplib/v2/pkg/formatdecenc/rtpsimpleaudio" @@ -28,11 +25,6 @@ func (t *G722) PayloadType() uint8 { } func (t *G722) unmarshal(payloadType uint8, clock string, codec string, rtpmap string, fmtp string) error { - tmp := strings.Split(clock, "/") - if len(tmp) == 2 && tmp[1] != "1" { - return fmt.Errorf("G722 formats can have only one channel") - } - return nil } diff --git a/pkg/format/g722_test.go b/pkg/format/g722_test.go index 9823bb58..d08006fc 100644 --- a/pkg/format/g722_test.go +++ b/pkg/format/g722_test.go @@ -22,3 +22,17 @@ func TestG722MediaDescription(t *testing.T) { require.Equal(t, "G722/8000", rtpmap) require.Equal(t, "", fmtp) } + +func TestG722DecEncoder(t *testing.T) { + format := &G722{} + + enc := format.CreateEncoder() + pkt, err := enc.Encode([]byte{0x01, 0x02, 0x03, 0x04}, 0) + require.NoError(t, err) + require.Equal(t, format.PayloadType(), pkt.PayloadType) + + dec := format.CreateDecoder() + byts, _, err := dec.Decode(pkt) + require.NoError(t, err) + require.Equal(t, []byte{0x01, 0x02, 0x03, 0x04}, byts) +} diff --git a/pkg/format/h264_test.go b/pkg/format/h264_test.go index f7202def..b5c3bcad 100644 --- a/pkg/format/h264_test.go +++ b/pkg/format/h264_test.go @@ -74,3 +74,17 @@ func TestH264MediaDescription(t *testing.T) { require.Equal(t, "packetization-mode=1", fmtp) }) } + +func TestH264DecEncoder(t *testing.T) { + format := &H264{} + + enc := format.CreateEncoder() + pkts, err := enc.Encode([][]byte{{0x01, 0x02, 0x03, 0x04}}, 0) + require.NoError(t, err) + require.Equal(t, format.PayloadType(), pkts[0].PayloadType) + + dec := format.CreateDecoder() + byts, _, err := dec.Decode(pkts[0]) + require.NoError(t, err) + require.Equal(t, [][]byte{{0x01, 0x02, 0x03, 0x04}}, byts) +} diff --git a/pkg/format/h265_test.go b/pkg/format/h265_test.go index ce58930f..472cb01b 100644 --- a/pkg/format/h265_test.go +++ b/pkg/format/h265_test.go @@ -42,3 +42,17 @@ func TestH265MediaDescription(t *testing.T) { require.Equal(t, "H265/90000", rtpmap) require.Equal(t, "sprop-vps=AQI=; sprop-sps=AwQ=; sprop-pps=BQY=", fmtp) } + +func TestH265DecEncoder(t *testing.T) { + format := &H265{} + + enc := format.CreateEncoder() + pkts, err := enc.Encode([][]byte{{0x01, 0x02, 0x03, 0x04}}, 0) + require.NoError(t, err) + require.Equal(t, format.PayloadType(), pkts[0].PayloadType) + + dec := format.CreateDecoder() + byts, _, err := dec.Decode(pkts[0]) + require.NoError(t, err) + require.Equal(t, [][]byte{{0x01, 0x02, 0x03, 0x04}}, byts) +} diff --git a/pkg/format/lpcm.go b/pkg/format/lpcm.go index b97cdbc1..939de55c 100644 --- a/pkg/format/lpcm.go +++ b/pkg/format/lpcm.go @@ -1,7 +1,6 @@ package format import ( - "fmt" "strconv" "strings" @@ -48,9 +47,6 @@ func (t *LPCM) unmarshal(payloadType uint8, clock string, codec string, rtpmap s } tmp := strings.SplitN(clock, "/", 2) - if len(tmp) < 1 { - return fmt.Errorf("invalid clock (%v)", clock) - } tmp1, err := strconv.ParseInt(tmp[0], 10, 64) if err != nil { diff --git a/pkg/format/lpcm_test.go b/pkg/format/lpcm_test.go index 21ecf758..47cbefc9 100644 --- a/pkg/format/lpcm_test.go +++ b/pkg/format/lpcm_test.go @@ -1,6 +1,8 @@ package format import ( + "fmt" + "strconv" "testing" "github.com/pion/rtp" @@ -21,14 +23,37 @@ func TestLPCMAttributes(t *testing.T) { } func TestLPCMMediaDescription(t *testing.T) { + for _, ca := range []int{8, 16, 24} { + t.Run(strconv.FormatInt(int64(ca), 10), func(t *testing.T) { + format := &LPCM{ + PayloadTyp: 96, + BitDepth: ca, + SampleRate: 96000, + ChannelCount: 2, + } + + rtpmap, fmtp := format.Marshal() + require.Equal(t, fmt.Sprintf("L%d/96000/2", ca), rtpmap) + require.Equal(t, "", fmtp) + }) + } +} + +func TestLPCMDecEncoder(t *testing.T) { format := &LPCM{ PayloadTyp: 96, - BitDepth: 24, + BitDepth: 16, SampleRate: 96000, ChannelCount: 2, } - rtpmap, fmtp := format.Marshal() - require.Equal(t, "L24/96000/2", rtpmap) - require.Equal(t, "", fmtp) + enc := format.CreateEncoder() + pkts, err := enc.Encode([]byte{0x01, 0x02, 0x03, 0x04}, 0) + require.NoError(t, err) + require.Equal(t, format.PayloadType(), pkts[0].PayloadType) + + dec := format.CreateDecoder() + byts, _, err := dec.Decode(pkts[0]) + require.NoError(t, err) + require.Equal(t, []byte{0x01, 0x02, 0x03, 0x04}, byts) } diff --git a/pkg/format/opus.go b/pkg/format/opus.go index 3b07ebd5..11462ddd 100644 --- a/pkg/format/opus.go +++ b/pkg/format/opus.go @@ -35,7 +35,7 @@ func (t *Opus) PayloadType() uint8 { func (t *Opus) unmarshal(payloadType uint8, clock string, codec string, rtpmap string, fmtp string) error { t.PayloadTyp = payloadType - tmp := strings.SplitN(clock, "/", 32) + tmp := strings.SplitN(clock, "/", 2) if len(tmp) != 2 { return fmt.Errorf("invalid clock (%v)", clock) } diff --git a/pkg/format/opus_test.go b/pkg/format/opus_test.go index 7d6aca52..2535dd7f 100644 --- a/pkg/format/opus_test.go +++ b/pkg/format/opus_test.go @@ -30,3 +30,17 @@ func TestOpusMediaDescription(t *testing.T) { require.Equal(t, "opus/48000/2", rtpmap) require.Equal(t, "sprop-stereo=1", fmtp) } + +func TestOpusDecEncoder(t *testing.T) { + format := &Opus{} + + enc := format.CreateEncoder() + pkt, err := enc.Encode([]byte{0x01, 0x02, 0x03, 0x04}, 0) + require.NoError(t, err) + require.Equal(t, format.PayloadType(), pkt.PayloadType) + + dec := format.CreateDecoder() + byts, _, err := dec.Decode(pkt) + require.NoError(t, err) + require.Equal(t, []byte{0x01, 0x02, 0x03, 0x04}, byts) +} diff --git a/pkg/format/vorbis.go b/pkg/format/vorbis.go index 0df1f421..63c16711 100644 --- a/pkg/format/vorbis.go +++ b/pkg/format/vorbis.go @@ -35,7 +35,7 @@ func (t *Vorbis) PayloadType() uint8 { func (t *Vorbis) unmarshal(payloadType uint8, clock string, codec string, rtpmap string, fmtp string) error { t.PayloadTyp = payloadType - tmp := strings.SplitN(clock, "/", 32) + tmp := strings.SplitN(clock, "/", 2) if len(tmp) != 2 { return fmt.Errorf("invalid clock (%v)", clock) } diff --git a/pkg/format/vp8_test.go b/pkg/format/vp8_test.go index b59c268c..b1b6b4c4 100644 --- a/pkg/format/vp8_test.go +++ b/pkg/format/vp8_test.go @@ -30,3 +30,17 @@ func TestVP8MediaDescription(t *testing.T) { require.Equal(t, "VP8/90000", rtpmap) require.Equal(t, "max-fr=123;max-fs=456", fmtp) } + +func TestVP8DecEncoder(t *testing.T) { + format := &VP8{} + + enc := format.CreateEncoder() + pkts, err := enc.Encode([]byte{0x01, 0x02, 0x03, 0x04}, 0) + require.NoError(t, err) + require.Equal(t, format.PayloadType(), pkts[0].PayloadType) + + dec := format.CreateDecoder() + byts, _, err := dec.Decode(pkts[0]) + require.NoError(t, err) + require.Equal(t, []byte{0x01, 0x02, 0x03, 0x04}, byts) +} diff --git a/pkg/format/vp9_test.go b/pkg/format/vp9_test.go index 135832a9..77297151 100644 --- a/pkg/format/vp9_test.go +++ b/pkg/format/vp9_test.go @@ -32,3 +32,17 @@ func TestVP9MediaDescription(t *testing.T) { require.Equal(t, "VP9/90000", rtpmap) require.Equal(t, "max-fr=123;max-fs=456;profile-id=789", fmtp) } + +func TestVP9DecEncoder(t *testing.T) { + format := &VP9{} + + enc := format.CreateEncoder() + pkts, err := enc.Encode([]byte{0x01, 0x02, 0x03, 0x04}, 0) + require.NoError(t, err) + require.Equal(t, format.PayloadType(), pkts[0].PayloadType) + + dec := format.CreateDecoder() + byts, _, err := dec.Decode(pkts[0]) + require.NoError(t, err) + require.Equal(t, []byte{0x01, 0x02, 0x03, 0x04}, byts) +} diff --git a/pkg/formatdecenc/rtpmpeg4audio/decoder.go b/pkg/formatdecenc/rtpmpeg4audio/decoder.go index 064fd9ee..1424d0a7 100644 --- a/pkg/formatdecenc/rtpmpeg4audio/decoder.go +++ b/pkg/formatdecenc/rtpmpeg4audio/decoder.go @@ -20,13 +20,13 @@ type Decoder struct { // sample rate of input packets. SampleRate int - // The number of bits on which the AU-size field is encoded in the AU-header. + // The number of bits in which the AU-size field is encoded in the AU-header. SizeLength int - // The number of bits on which the AU-Index is encoded in the first AU-header. + // The number of bits in which the AU-Index is encoded in the first AU-header. IndexLength int - // The number of bits on which the AU-Index-delta field is encoded in any non-first AU-header. + // The number of bits in which the AU-Index-delta field is encoded in any non-first AU-header. IndexDeltaLength int timeDecoder *rtptimedec.Decoder diff --git a/pkg/formatdecenc/rtpmpeg4audio/encoder.go b/pkg/formatdecenc/rtpmpeg4audio/encoder.go index 62dbbd2a..d12c1a22 100644 --- a/pkg/formatdecenc/rtpmpeg4audio/encoder.go +++ b/pkg/formatdecenc/rtpmpeg4audio/encoder.go @@ -44,13 +44,13 @@ type Encoder struct { // sample rate of packets. SampleRate int - // The number of bits on which the AU-size field is encoded in the AU-header. + // The number of bits in which the AU-size field is encoded in the AU-header. SizeLength int - // The number of bits on which the AU-Index is encoded in the first AU-header. + // The number of bits in which the AU-Index is encoded in the first AU-header. IndexLength int - // The number of bits on which the AU-Index-delta field is encoded in any non-first AU-header. + // The number of bits in which the AU-Index-delta field is encoded in any non-first AU-header. IndexDeltaLength int sequenceNumber uint16