mirror of
https://github.com/aler9/gortsplib
synced 2025-10-06 23:52:46 +08:00
rtp*: remove Read(), return nalus and pts separately
This commit is contained in:
@@ -2,7 +2,6 @@ package rtph264
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@@ -25,28 +24,21 @@ func mergeBytes(vals ...[]byte) []byte {
|
||||
return res
|
||||
}
|
||||
|
||||
type readerFunc func(p []byte) (int, error)
|
||||
|
||||
func (f readerFunc) Read(p []byte) (int, error) {
|
||||
return f(p)
|
||||
}
|
||||
|
||||
var cases = []struct {
|
||||
name string
|
||||
dec []*NALUAndTimestamp
|
||||
enc [][]byte
|
||||
name string
|
||||
nalus [][]byte
|
||||
pts time.Duration
|
||||
enc [][]byte
|
||||
}{
|
||||
{
|
||||
"single",
|
||||
[]*NALUAndTimestamp{
|
||||
{
|
||||
Timestamp: 25 * time.Millisecond,
|
||||
NALU: mergeBytes(
|
||||
[]byte{0x05},
|
||||
bytes.Repeat([]byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}, 8),
|
||||
),
|
||||
},
|
||||
[][]byte{
|
||||
mergeBytes(
|
||||
[]byte{0x05},
|
||||
bytes.Repeat([]byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}, 8),
|
||||
),
|
||||
},
|
||||
25 * time.Millisecond,
|
||||
[][]byte{
|
||||
mergeBytes(
|
||||
[]byte{
|
||||
@@ -59,15 +51,13 @@ var cases = []struct {
|
||||
},
|
||||
{
|
||||
"negative timestamp",
|
||||
[]*NALUAndTimestamp{
|
||||
{
|
||||
Timestamp: -20 * time.Millisecond,
|
||||
NALU: mergeBytes(
|
||||
[]byte{0x05},
|
||||
bytes.Repeat([]byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}, 8),
|
||||
),
|
||||
},
|
||||
[][]byte{
|
||||
mergeBytes(
|
||||
[]byte{0x05},
|
||||
bytes.Repeat([]byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}, 8),
|
||||
),
|
||||
},
|
||||
-20 * time.Millisecond,
|
||||
[][]byte{
|
||||
mergeBytes(
|
||||
[]byte{
|
||||
@@ -80,15 +70,13 @@ var cases = []struct {
|
||||
},
|
||||
{
|
||||
"fragmented",
|
||||
[]*NALUAndTimestamp{
|
||||
{
|
||||
Timestamp: 55 * time.Millisecond,
|
||||
NALU: mergeBytes(
|
||||
[]byte{0x05},
|
||||
bytes.Repeat([]byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}, 256),
|
||||
),
|
||||
},
|
||||
[][]byte{
|
||||
mergeBytes(
|
||||
[]byte{0x05},
|
||||
bytes.Repeat([]byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}, 256),
|
||||
),
|
||||
},
|
||||
55 * time.Millisecond,
|
||||
[][]byte{
|
||||
mergeBytes(
|
||||
[]byte{
|
||||
@@ -110,24 +98,21 @@ var cases = []struct {
|
||||
},
|
||||
{
|
||||
"aggregated",
|
||||
[]*NALUAndTimestamp{
|
||||
[][]byte{
|
||||
{0x09, 0xF0},
|
||||
{
|
||||
NALU: []byte{0x09, 0xF0},
|
||||
},
|
||||
{
|
||||
NALU: []byte{
|
||||
0x41, 0x9a, 0x24, 0x6c, 0x41, 0x4f, 0xfe, 0xd6,
|
||||
0x8c, 0xb0, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03,
|
||||
0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00,
|
||||
0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00,
|
||||
0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03,
|
||||
0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00,
|
||||
0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00,
|
||||
0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03,
|
||||
0x00, 0x00, 0x6d, 0x40,
|
||||
},
|
||||
0x41, 0x9a, 0x24, 0x6c, 0x41, 0x4f, 0xfe, 0xd6,
|
||||
0x8c, 0xb0, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03,
|
||||
0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00,
|
||||
0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00,
|
||||
0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03,
|
||||
0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00,
|
||||
0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00,
|
||||
0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03,
|
||||
0x00, 0x00, 0x6d, 0x40,
|
||||
},
|
||||
},
|
||||
0,
|
||||
[][]byte{
|
||||
{
|
||||
0x80, 0xe0, 0x44, 0xed, 0x88, 0x77, 0x66, 0x55,
|
||||
@@ -146,30 +131,25 @@ var cases = []struct {
|
||||
},
|
||||
{
|
||||
"aggregated followed by single",
|
||||
[]*NALUAndTimestamp{
|
||||
[][]byte{
|
||||
{0x09, 0xF0},
|
||||
{
|
||||
NALU: []byte{0x09, 0xF0},
|
||||
},
|
||||
{
|
||||
NALU: []byte{
|
||||
0x41, 0x9a, 0x24, 0x6c, 0x41, 0x4f, 0xfe, 0xd6,
|
||||
0x8c, 0xb0, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03,
|
||||
0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00,
|
||||
0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00,
|
||||
0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03,
|
||||
0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00,
|
||||
0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00,
|
||||
0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03,
|
||||
0x00, 0x00, 0x6d, 0x40,
|
||||
},
|
||||
},
|
||||
{
|
||||
NALU: mergeBytes(
|
||||
[]byte{0x08},
|
||||
bytes.Repeat([]byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}, 175),
|
||||
),
|
||||
0x41, 0x9a, 0x24, 0x6c, 0x41, 0x4f, 0xfe, 0xd6,
|
||||
0x8c, 0xb0, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03,
|
||||
0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00,
|
||||
0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00,
|
||||
0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03,
|
||||
0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00,
|
||||
0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00,
|
||||
0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03,
|
||||
0x00, 0x00, 0x6d, 0x40,
|
||||
},
|
||||
mergeBytes(
|
||||
[]byte{0x08},
|
||||
bytes.Repeat([]byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}, 175),
|
||||
),
|
||||
},
|
||||
0,
|
||||
[][]byte{
|
||||
{
|
||||
0x80, 0x60, 0x44, 0xed, 0x88, 0x77, 0x66, 0x55,
|
||||
@@ -195,20 +175,15 @@ var cases = []struct {
|
||||
},
|
||||
{
|
||||
"fragmented followed by aggregated",
|
||||
[]*NALUAndTimestamp{
|
||||
{
|
||||
NALU: mergeBytes(
|
||||
[]byte{0x05},
|
||||
bytes.Repeat([]byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}, 256),
|
||||
),
|
||||
},
|
||||
{
|
||||
NALU: []byte{0x09, 0xF0},
|
||||
},
|
||||
{
|
||||
NALU: []byte{0x09, 0xF0},
|
||||
},
|
||||
[][]byte{
|
||||
mergeBytes(
|
||||
[]byte{0x05},
|
||||
bytes.Repeat([]byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}, 256),
|
||||
),
|
||||
{0x09, 0xF0},
|
||||
{0x09, 0xF0},
|
||||
},
|
||||
0,
|
||||
[][]byte{
|
||||
mergeBytes(
|
||||
[]byte{
|
||||
@@ -242,7 +217,7 @@ func TestEncode(t *testing.T) {
|
||||
ssrc := uint32(0x9dbb7812)
|
||||
initialTs := uint32(0x88776655)
|
||||
e := NewEncoder(96, &sequenceNumber, &ssrc, &initialTs)
|
||||
enc, err := e.Encode(ca.dec)
|
||||
enc, err := e.Encode(ca.nalus, ca.pts)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, ca.enc, enc)
|
||||
})
|
||||
@@ -252,35 +227,31 @@ func TestEncode(t *testing.T) {
|
||||
func TestDecode(t *testing.T) {
|
||||
for _, ca := range cases {
|
||||
t.Run(ca.name, func(t *testing.T) {
|
||||
i := 0
|
||||
r := readerFunc(func(p []byte) (int, error) {
|
||||
if i == len(ca.enc) {
|
||||
return 0, io.EOF
|
||||
}
|
||||
|
||||
i++
|
||||
return copy(p, ca.enc[i-1]), nil
|
||||
})
|
||||
|
||||
d := NewDecoder()
|
||||
|
||||
// send an initial packet downstream
|
||||
// in order to compute the timestamp,
|
||||
// which is relative to the initial packet
|
||||
_, err := d.Decode([]byte{
|
||||
_, _, err := d.Decode([]byte{
|
||||
0x80, 0xe0, 0x44, 0xed, 0x88, 0x77, 0x66, 0x55,
|
||||
0x9d, 0xbb, 0x78, 0x12, 0x06, 0x00,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
for _, dec0 := range ca.dec {
|
||||
dec, err := d.Read(r)
|
||||
var nalus [][]byte
|
||||
|
||||
for _, pkt := range ca.enc {
|
||||
addNALUs, pts, err := d.Decode(pkt)
|
||||
if err == ErrMorePacketsNeeded {
|
||||
continue
|
||||
}
|
||||
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, dec0, dec)
|
||||
require.Equal(t, ca.pts, pts)
|
||||
nalus = append(nalus, addNALUs...)
|
||||
}
|
||||
|
||||
_, err = d.Read(r)
|
||||
require.Equal(t, io.EOF, err)
|
||||
require.Equal(t, ca.nalus, nalus)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -303,7 +274,7 @@ func TestDecodeErrors(t *testing.T) {
|
||||
"STAP-A without NALUs",
|
||||
[]byte{
|
||||
0x80, 0xe0, 0x44, 0xed, 0x88, 0x77, 0x6a, 0x15,
|
||||
0x9d, 0xbb, 0x78, 0x12, byte(NALUTypeStapA),
|
||||
0x9d, 0xbb, 0x78, 0x12, byte(NALUTypeSTAPA),
|
||||
},
|
||||
"STAP-A packet doesn't contain any NALU",
|
||||
},
|
||||
@@ -311,7 +282,7 @@ func TestDecodeErrors(t *testing.T) {
|
||||
"STAP-A without size",
|
||||
[]byte{
|
||||
0x80, 0xe0, 0x44, 0xed, 0x88, 0x77, 0x6a, 0x15,
|
||||
0x9d, 0xbb, 0x78, 0x12, byte(NALUTypeStapA), 0x01,
|
||||
0x9d, 0xbb, 0x78, 0x12, byte(NALUTypeSTAPA), 0x01,
|
||||
},
|
||||
"Invalid STAP-A packet",
|
||||
},
|
||||
@@ -319,7 +290,7 @@ func TestDecodeErrors(t *testing.T) {
|
||||
"STAP-A with invalid size",
|
||||
[]byte{
|
||||
0x80, 0xe0, 0x44, 0xed, 0x88, 0x77, 0x6a, 0x15,
|
||||
0x9d, 0xbb, 0x78, 0x12, byte(NALUTypeStapA), 0x00, 0x15,
|
||||
0x9d, 0xbb, 0x78, 0x12, byte(NALUTypeSTAPA), 0x00, 0x15,
|
||||
},
|
||||
"Invalid STAP-A packet",
|
||||
},
|
||||
@@ -327,7 +298,7 @@ func TestDecodeErrors(t *testing.T) {
|
||||
"FU-A without payload",
|
||||
[]byte{
|
||||
0x80, 0xe0, 0x44, 0xed, 0x88, 0x77, 0x6a, 0x15,
|
||||
0x9d, 0xbb, 0x78, 0x12, byte(NALUTypeFuA),
|
||||
0x9d, 0xbb, 0x78, 0x12, byte(NALUTypeFUA),
|
||||
},
|
||||
"Invalid FU-A packet",
|
||||
},
|
||||
@@ -335,14 +306,22 @@ func TestDecodeErrors(t *testing.T) {
|
||||
"FU-A without start bit",
|
||||
[]byte{
|
||||
0x80, 0xe0, 0x44, 0xed, 0x88, 0x77, 0x6a, 0x15,
|
||||
0x9d, 0xbb, 0x78, 0x12, byte(NALUTypeFuA), 0x00,
|
||||
0x9d, 0xbb, 0x78, 0x12, byte(NALUTypeFUA), 0x00,
|
||||
},
|
||||
"first NALU does not contain the start bit",
|
||||
},
|
||||
{
|
||||
"MTAP",
|
||||
[]byte{
|
||||
0x80, 0xe0, 0x44, 0xed, 0x88, 0x77, 0x6a, 0x15,
|
||||
0x9d, 0xbb, 0x78, 0x12, byte(NALUTypeMTAP16),
|
||||
},
|
||||
"NALU type not supported (MTAP16)",
|
||||
},
|
||||
} {
|
||||
t.Run(ca.name, func(t *testing.T) {
|
||||
d := NewDecoder()
|
||||
_, err := d.Decode(ca.byts)
|
||||
_, _, err := d.Decode(ca.byts)
|
||||
require.NotEqual(t, ErrMorePacketsNeeded, err)
|
||||
require.Equal(t, ca.err, err.Error())
|
||||
})
|
||||
|
Reference in New Issue
Block a user