mirror of
https://github.com/aler9/gortsplib
synced 2025-10-05 15:16:51 +08:00
rtpaac, rtph264: remove Decoder.Decode()
This commit is contained in:
@@ -5,6 +5,7 @@ import (
|
|||||||
|
|
||||||
"github.com/aler9/gortsplib"
|
"github.com/aler9/gortsplib"
|
||||||
"github.com/aler9/gortsplib/pkg/rtph264"
|
"github.com/aler9/gortsplib/pkg/rtph264"
|
||||||
|
"github.com/pion/rtp"
|
||||||
)
|
)
|
||||||
|
|
||||||
// This example shows how to
|
// This example shows how to
|
||||||
@@ -47,8 +48,15 @@ func main() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// convert RTP packets into H264 NALUs
|
// parse RTP packets
|
||||||
nalus, _, err := dec.Decode(payload)
|
var pkt rtp.Packet
|
||||||
|
err := pkt.Unmarshal(payload)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// decode H264 NALUs from RTP packets
|
||||||
|
nalus, _, err := dec.DecodeRTP(&pkt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@@ -34,21 +34,9 @@ func (d *Decoder) decodeTimestamp(ts uint32) time.Duration {
|
|||||||
return (time.Duration(ts) - time.Duration(d.initialTs)) * time.Second / d.clockRate
|
return (time.Duration(ts) - time.Duration(d.initialTs)) * time.Second / d.clockRate
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decode decodes AUs from a RTP/AAC packet.
|
// DecodeRTP decodes AUs from a RTP/AAC packet.
|
||||||
// It returns the AUs and the PTS of the first AU.
|
// It returns the AUs and the PTS of the first AU.
|
||||||
// The PTS of subsequent AUs can be calculated by adding time.Second*1000/clockRate.
|
// The PTS of subsequent AUs can be calculated by adding time.Second*1000/clockRate.
|
||||||
func (d *Decoder) Decode(byts []byte) ([][]byte, time.Duration, error) {
|
|
||||||
var pkt rtp.Packet
|
|
||||||
err := pkt.Unmarshal(byts)
|
|
||||||
if err != nil {
|
|
||||||
d.isDecodingFragmented = false
|
|
||||||
return nil, 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return d.DecodeRTP(&pkt)
|
|
||||||
}
|
|
||||||
|
|
||||||
// DecodeRTP decodes AUs from a rtp.Packet.
|
|
||||||
func (d *Decoder) DecodeRTP(pkt *rtp.Packet) ([][]byte, time.Duration, error) {
|
func (d *Decoder) DecodeRTP(pkt *rtp.Packet) ([][]byte, time.Duration, error) {
|
||||||
if len(pkt.Payload) < 2 {
|
if len(pkt.Payload) < 2 {
|
||||||
d.isDecodingFragmented = false
|
d.isDecodingFragmented = false
|
||||||
|
@@ -5,6 +5,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/pion/rtp"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -219,19 +220,26 @@ func TestDecode(t *testing.T) {
|
|||||||
d := NewDecoder(48000)
|
d := NewDecoder(48000)
|
||||||
|
|
||||||
// send an initial packet downstream
|
// send an initial packet downstream
|
||||||
// in order to compute the timestamp,
|
// in order to compute the right timestamp,
|
||||||
// which is relative to the initial packet
|
// that is relative to the initial packet
|
||||||
_, _, err := d.Decode([]byte{
|
var pkt rtp.Packet
|
||||||
|
err := pkt.Unmarshal([]byte{
|
||||||
0x80, 0xe0, 0x44, 0xed, 0x88, 0x77, 0x66, 0x55,
|
0x80, 0xe0, 0x44, 0xed, 0x88, 0x77, 0x66, 0x55,
|
||||||
0x9d, 0xbb, 0x78, 0x12, 0x00, 0x10, 0x00, 0x08, 0x0,
|
0x9d, 0xbb, 0x78, 0x12, 0x00, 0x10, 0x00, 0x08, 0x0,
|
||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
_, _, err = d.DecodeRTP(&pkt)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
var aus [][]byte
|
var aus [][]byte
|
||||||
expPTS := ca.pts
|
expPTS := ca.pts
|
||||||
|
|
||||||
for _, pkt := range ca.enc {
|
for _, byts := range ca.enc {
|
||||||
addAUs, pts, err := d.Decode(pkt)
|
var pkt rtp.Packet
|
||||||
|
err := pkt.Unmarshal(byts)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
addAUs, pts, err := d.DecodeRTP(&pkt)
|
||||||
if err == ErrMorePacketsNeeded {
|
if err == ErrMorePacketsNeeded {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -253,15 +261,6 @@ func TestDecodeErrors(t *testing.T) {
|
|||||||
pkts [][]byte
|
pkts [][]byte
|
||||||
err string
|
err string
|
||||||
}{
|
}{
|
||||||
{
|
|
||||||
"invalid rtp",
|
|
||||||
[][]byte{
|
|
||||||
{
|
|
||||||
0xaa,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"RTP header size insufficient: 1 < 4",
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"missing payload",
|
"missing payload",
|
||||||
[][]byte{
|
[][]byte{
|
||||||
@@ -402,11 +401,14 @@ func TestDecodeErrors(t *testing.T) {
|
|||||||
} {
|
} {
|
||||||
t.Run(ca.name, func(t *testing.T) {
|
t.Run(ca.name, func(t *testing.T) {
|
||||||
d := NewDecoder(48000)
|
d := NewDecoder(48000)
|
||||||
var err error
|
var lastErr error
|
||||||
for _, pkt := range ca.pkts {
|
for _, byts := range ca.pkts {
|
||||||
_, _, err = d.Decode(pkt)
|
var pkt rtp.Packet
|
||||||
|
err := pkt.Unmarshal(byts)
|
||||||
|
require.NoError(t, err)
|
||||||
|
_, _, lastErr = d.DecodeRTP(&pkt)
|
||||||
}
|
}
|
||||||
require.Equal(t, ca.err, err.Error())
|
require.Equal(t, ca.err, lastErr.Error())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -57,19 +57,6 @@ func (d *Decoder) decodeTimestamp(ts uint32) time.Duration {
|
|||||||
return (time.Duration(ts) - time.Duration(d.initialTs)) * time.Second / rtpClockRate
|
return (time.Duration(ts) - time.Duration(d.initialTs)) * time.Second / rtpClockRate
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decode decodes NALUs from a RTP/H264 packet.
|
|
||||||
// It returns the decoded NALUs and their PTS.
|
|
||||||
func (d *Decoder) Decode(byts []byte) ([][]byte, time.Duration, error) {
|
|
||||||
var pkt rtp.Packet
|
|
||||||
err := pkt.Unmarshal(byts)
|
|
||||||
if err != nil {
|
|
||||||
d.isDecodingFragmented = false
|
|
||||||
return nil, 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return d.DecodeRTP(&pkt)
|
|
||||||
}
|
|
||||||
|
|
||||||
// DecodeRTP decodes NALUs from a RTP/H264 packet.
|
// DecodeRTP decodes NALUs from a RTP/H264 packet.
|
||||||
func (d *Decoder) DecodeRTP(pkt *rtp.Packet) ([][]byte, time.Duration, error) {
|
func (d *Decoder) DecodeRTP(pkt *rtp.Packet) ([][]byte, time.Duration, error) {
|
||||||
if !d.isDecodingFragmented {
|
if !d.isDecodingFragmented {
|
||||||
@@ -213,7 +200,13 @@ func (d *Decoder) ReadSPSPPS(r io.Reader) ([]byte, []byte, error) {
|
|||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
nalus, _, err := d.Decode(buf[:n])
|
var pkt rtp.Packet
|
||||||
|
err = pkt.Unmarshal(buf[:n])
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
nalus, _, err := d.DecodeRTP(&pkt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == ErrMorePacketsNeeded {
|
if err == ErrMorePacketsNeeded {
|
||||||
continue
|
continue
|
||||||
|
@@ -6,6 +6,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/pion/rtp"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -226,18 +227,24 @@ func TestDecode(t *testing.T) {
|
|||||||
d := NewDecoder()
|
d := NewDecoder()
|
||||||
|
|
||||||
// send an initial packet downstream
|
// send an initial packet downstream
|
||||||
// in order to compute the timestamp,
|
// in order to compute the right timestamp,
|
||||||
// which is relative to the initial packet
|
// that is relative to the initial packet
|
||||||
_, _, err := d.Decode([]byte{
|
var pkt rtp.Packet
|
||||||
|
err := pkt.Unmarshal([]byte{
|
||||||
0x80, 0xe0, 0x44, 0xed, 0x88, 0x77, 0x66, 0x55,
|
0x80, 0xe0, 0x44, 0xed, 0x88, 0x77, 0x66, 0x55,
|
||||||
0x9d, 0xbb, 0x78, 0x12, 0x06, 0x00,
|
0x9d, 0xbb, 0x78, 0x12, 0x06, 0x00,
|
||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
_, _, err = d.DecodeRTP(&pkt)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
var nalus [][]byte
|
var nalus [][]byte
|
||||||
|
|
||||||
for _, pkt := range ca.enc {
|
for _, byts := range ca.enc {
|
||||||
addNALUs, pts, err := d.Decode(pkt)
|
err := pkt.Unmarshal(byts)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
addNALUs, pts, err := d.DecodeRTP(&pkt)
|
||||||
if err == ErrMorePacketsNeeded {
|
if err == ErrMorePacketsNeeded {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -255,7 +262,8 @@ func TestDecode(t *testing.T) {
|
|||||||
func TestDecodePartOfFragmentedBeforeSingle(t *testing.T) {
|
func TestDecodePartOfFragmentedBeforeSingle(t *testing.T) {
|
||||||
d := NewDecoder()
|
d := NewDecoder()
|
||||||
|
|
||||||
_, _, err := d.Decode(mergeBytes(
|
var pkt rtp.Packet
|
||||||
|
err := pkt.Unmarshal(mergeBytes(
|
||||||
[]byte{
|
[]byte{
|
||||||
0x80, 0xe0, 0x44, 0xef, 0x88, 0x77, 0x79, 0xab,
|
0x80, 0xe0, 0x44, 0xef, 0x88, 0x77, 0x79, 0xab,
|
||||||
0x9d, 0xbb, 0x78, 0x12, 0x1c, 0x45,
|
0x9d, 0xbb, 0x78, 0x12, 0x1c, 0x45,
|
||||||
@@ -263,9 +271,11 @@ func TestDecodePartOfFragmentedBeforeSingle(t *testing.T) {
|
|||||||
[]byte{0x04, 0x05, 0x06, 0x07},
|
[]byte{0x04, 0x05, 0x06, 0x07},
|
||||||
bytes.Repeat([]byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}, 147),
|
bytes.Repeat([]byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}, 147),
|
||||||
))
|
))
|
||||||
|
require.NoError(t, err)
|
||||||
|
_, _, err = d.DecodeRTP(&pkt)
|
||||||
require.Equal(t, ErrNonStartingPacketAndNoPrevious, err)
|
require.Equal(t, ErrNonStartingPacketAndNoPrevious, err)
|
||||||
|
|
||||||
_, _, err = d.Decode(mergeBytes(
|
err = pkt.Unmarshal(mergeBytes(
|
||||||
[]byte{
|
[]byte{
|
||||||
0x80, 0xe0, 0x44, 0xed, 0x88, 0x77, 0x6f, 0x1f,
|
0x80, 0xe0, 0x44, 0xed, 0x88, 0x77, 0x6f, 0x1f,
|
||||||
0x9d, 0xbb, 0x78, 0x12, 0x05,
|
0x9d, 0xbb, 0x78, 0x12, 0x05,
|
||||||
@@ -273,11 +283,15 @@ func TestDecodePartOfFragmentedBeforeSingle(t *testing.T) {
|
|||||||
bytes.Repeat([]byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}, 8),
|
bytes.Repeat([]byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}, 8),
|
||||||
))
|
))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
_, _, err = d.DecodeRTP(&pkt)
|
||||||
|
require.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDecodeSTAPAWithPadding(t *testing.T) {
|
func TestDecodeSTAPAWithPadding(t *testing.T) {
|
||||||
d := NewDecoder()
|
d := NewDecoder()
|
||||||
nalus, _, err := d.Decode([]byte{
|
|
||||||
|
var pkt rtp.Packet
|
||||||
|
err := pkt.Unmarshal([]byte{
|
||||||
0x80, 0xe0, 0x44, 0xed, 0x88, 0x77, 0x66, 0x55,
|
0x80, 0xe0, 0x44, 0xed, 0x88, 0x77, 0x66, 0x55,
|
||||||
0x9d, 0xbb, 0x78, 0x12, 0x18, 0x00, 0x02, 0xaa,
|
0x9d, 0xbb, 0x78, 0x12, 0x18, 0x00, 0x02, 0xaa,
|
||||||
0xbb, 0x00, 0x02, 0xcc, 0xdd, 0x00, 0x00, 0x00,
|
0xbb, 0x00, 0x02, 0xcc, 0xdd, 0x00, 0x00, 0x00,
|
||||||
@@ -285,6 +299,9 @@ func TestDecodeSTAPAWithPadding(t *testing.T) {
|
|||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
nalus, _, err := d.DecodeRTP(&pkt)
|
||||||
|
require.NoError(t, err)
|
||||||
require.Equal(t, [][]byte{
|
require.Equal(t, [][]byte{
|
||||||
{0xaa, 0xbb},
|
{0xaa, 0xbb},
|
||||||
{0xcc, 0xdd},
|
{0xcc, 0xdd},
|
||||||
@@ -297,15 +314,6 @@ func TestDecodeErrors(t *testing.T) {
|
|||||||
pkts [][]byte
|
pkts [][]byte
|
||||||
err string
|
err string
|
||||||
}{
|
}{
|
||||||
{
|
|
||||||
"invalid rtp",
|
|
||||||
[][]byte{
|
|
||||||
{
|
|
||||||
0xaa,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"RTP header size insufficient: 1 < 4",
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"missing payload",
|
"missing payload",
|
||||||
[][]byte{{
|
[][]byte{{
|
||||||
@@ -436,11 +444,14 @@ func TestDecodeErrors(t *testing.T) {
|
|||||||
} {
|
} {
|
||||||
t.Run(ca.name, func(t *testing.T) {
|
t.Run(ca.name, func(t *testing.T) {
|
||||||
d := NewDecoder()
|
d := NewDecoder()
|
||||||
var err error
|
var lastErr error
|
||||||
for _, pkt := range ca.pkts {
|
for _, byts := range ca.pkts {
|
||||||
_, _, err = d.Decode(pkt)
|
var pkt rtp.Packet
|
||||||
|
err := pkt.Unmarshal(byts)
|
||||||
|
require.NoError(t, err)
|
||||||
|
_, _, lastErr = d.DecodeRTP(&pkt)
|
||||||
}
|
}
|
||||||
require.Equal(t, ca.err, err.Error())
|
require.Equal(t, ca.err, lastErr.Error())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user