diff --git a/pkg/formatdecenc/rtph264/decoder_test.go b/pkg/formatdecenc/rtph264/decoder_test.go index 93031bfa..92024e45 100644 --- a/pkg/formatdecenc/rtph264/decoder_test.go +++ b/pkg/formatdecenc/rtph264/decoder_test.go @@ -419,6 +419,39 @@ func TestDecodeAnnexB(t *testing.T) { } } +func TestDecodeUntilMarker(t *testing.T) { + d := &Decoder{} + d.Init() + + nalus, _, err := d.DecodeUntilMarker(&rtp.Packet{ + Header: rtp.Header{ + Version: 2, + Marker: false, + PayloadType: 96, + SequenceNumber: 17647, + Timestamp: 2289531307, + SSRC: 0x9dbb7812, + }, + Payload: []byte{0x01, 0x02}, + }) + require.Equal(t, ErrMorePacketsNeeded, err) + require.Equal(t, [][]byte(nil), nalus) + + nalus, _, err = d.DecodeUntilMarker(&rtp.Packet{ + Header: rtp.Header{ + Version: 2, + Marker: true, + PayloadType: 96, + SequenceNumber: 17647, + Timestamp: 2289531307, + SSRC: 0x9dbb7812, + }, + Payload: []byte{0x01, 0x02}, + }) + require.NoError(t, err) + require.Equal(t, [][]byte{{0x01, 0x02}, {0x01, 0x02}}, nalus) +} + func TestDecodeErrors(t *testing.T) { for _, ca := range []struct { name string @@ -527,7 +560,24 @@ func TestDecodeErrors(t *testing.T) { "invalid FU-A packet (can't contain both a start and end bit)", }, { - "FU-A non-starting", + "FU-A non-starting 1", + []*rtp.Packet{ + { + Header: rtp.Header{ + Version: 2, + Marker: true, + PayloadType: 96, + SequenceNumber: 17646, + Timestamp: 2289527317, + SSRC: 0x9dbb7812, + }, + Payload: []byte{0x1c, 0b01000000}, + }, + }, + "received a non-starting FU-A packet without any previous FU-A starting packet", + }, + { + "FU-A non-starting 2", []*rtp.Packet{ { Header: rtp.Header{ diff --git a/pkg/formatdecenc/rtph265/decoder_test.go b/pkg/formatdecenc/rtph265/decoder_test.go index f890f3d4..bff05d6a 100644 --- a/pkg/formatdecenc/rtph265/decoder_test.go +++ b/pkg/formatdecenc/rtph265/decoder_test.go @@ -77,7 +77,7 @@ var cases = []struct { { "fragmented", [][]byte{ - bytes.Repeat([]byte{0x01, 0x02, 0x03, 0x04}, 512), + bytes.Repeat([]byte{0x01, 0x02, 0x03, 0x04}, 1024), }, 55 * time.Millisecond, []*rtp.Packet{ @@ -99,15 +99,29 @@ var cases = []struct { { Header: rtp.Header{ Version: 2, - Marker: true, + Marker: false, PayloadType: 96, SequenceNumber: 17646, Timestamp: 2289531307, SSRC: 0x9dbb7812, }, Payload: mergeBytes( - []byte{0x63, 0x02, 0x40, 0x04}, - bytes.Repeat([]byte{0x01, 0x02, 0x03, 0x04}, 147), + []byte{0x63, 0x02, 0x00, 0x04}, + bytes.Repeat([]byte{0x01, 0x02, 0x03, 0x04}, 364), + ), + }, + { + Header: rtp.Header{ + Version: 2, + Marker: true, + PayloadType: 96, + SequenceNumber: 17647, + Timestamp: 2289531307, + SSRC: 0x9dbb7812, + }, + Payload: mergeBytes( + []byte{0x63, 0x02, 0x40}, + bytes.Repeat([]byte{0x01, 0x02, 0x03, 0x04}, 295), ), }, }, @@ -159,3 +173,186 @@ func TestDecode(t *testing.T) { }) } } + +func TestDecodeErrors(t *testing.T) { + for _, ca := range []struct { + name string + pkts []*rtp.Packet + err string + }{ + { + "missing payload", + []*rtp.Packet{ + { + Header: rtp.Header{ + Version: 2, + Marker: true, + PayloadType: 96, + SequenceNumber: 17645, + Timestamp: 2289527317, + SSRC: 0x9dbb7812, + }, + }, + }, + "payload is too short", + }, + { + "aggregation unit no size", + []*rtp.Packet{ + { + Header: rtp.Header{ + Version: 2, + Marker: true, + PayloadType: 96, + SequenceNumber: 17645, + Timestamp: 2289527317, + SSRC: 0x9dbb7812, + }, + Payload: []byte{48 << 1, 0x00, 0x01}, + }, + }, + "invalid aggregation unit (invalid size)", + }, + { + "aggregation unit invalid size", + []*rtp.Packet{ + { + Header: rtp.Header{ + Version: 2, + Marker: true, + PayloadType: 96, + SequenceNumber: 17645, + Timestamp: 2289527317, + SSRC: 0x9dbb7812, + }, + Payload: []byte{48 << 1, 0x00, 0x00, 0x05, 0x00}, + }, + }, + "invalid aggregation unit (invalid size)", + }, + { + "aggregation unit no NALUs", + []*rtp.Packet{ + { + Header: rtp.Header{ + Version: 2, + Marker: true, + PayloadType: 96, + SequenceNumber: 17645, + Timestamp: 2289527317, + SSRC: 0x9dbb7812, + }, + Payload: []byte{48 << 1, 0x00, 0x00, 0x00}, + }, + }, + "aggregation unit doesn't contain any NALU", + }, + { + "fragmentation unit invalid", + []*rtp.Packet{ + { + Header: rtp.Header{ + Version: 2, + Marker: true, + PayloadType: 96, + SequenceNumber: 17645, + Timestamp: 2289527317, + SSRC: 0x9dbb7812, + }, + Payload: []byte{49 << 1, 0x00}, + }, + }, + "payload is too short", + }, + { + "fragmentation unit start and end bit", + []*rtp.Packet{ + { + Header: rtp.Header{ + Version: 2, + Marker: true, + PayloadType: 96, + SequenceNumber: 17645, + Timestamp: 2289527317, + SSRC: 0x9dbb7812, + }, + Payload: []byte{49 << 1, 0x00, 0b11000000}, + }, + }, + "invalid fragmentation unit (can't contain both a start and end bit)", + }, + { + "fragmentation unit non-starting 1", + []*rtp.Packet{ + { + Header: rtp.Header{ + Version: 2, + Marker: true, + PayloadType: 96, + SequenceNumber: 17645, + Timestamp: 2289527317, + SSRC: 0x9dbb7812, + }, + Payload: []byte{49 << 1, 0x00, 0b01000000}, + }, + }, + "received a non-starting fragmentation unit without any previous fragmentation units", + }, + { + "fragmentation unit non-starting 2", + []*rtp.Packet{ + { + Header: rtp.Header{ + Version: 2, + Marker: true, + PayloadType: 96, + SequenceNumber: 17645, + Timestamp: 2289527317, + SSRC: 0x9dbb7812, + }, + Payload: []byte{0x01, 0x00}, + }, + { + Header: rtp.Header{ + Version: 2, + Marker: true, + PayloadType: 96, + SequenceNumber: 17645, + Timestamp: 2289527317, + SSRC: 0x9dbb7812, + }, + Payload: []byte{49 << 1, 0x00, 0b00000000}, + }, + }, + "invalid fragmentation unit (non-starting)", + }, + { + "paci", + []*rtp.Packet{ + { + Header: rtp.Header{ + Version: 2, + Marker: true, + PayloadType: 96, + SequenceNumber: 17645, + Timestamp: 2289527317, + SSRC: 0x9dbb7812, + }, + Payload: []byte{50 << 1, 0x00}, + }, + }, + "PACI packets are not supported (yet)", + }, + } { + t.Run(ca.name, func(t *testing.T) { + d := &Decoder{} + d.Init() + + var lastErr error + for _, pkt := range ca.pkts { + _, _, lastErr = d.Decode(pkt) + } + require.EqualError(t, lastErr, ca.err) + }) + } +}