add AC-3 decoder and encoder (#427)

This commit is contained in:
Alessandro Ros
2023-09-19 22:15:39 +02:00
committed by GitHub
parent 747de35cbc
commit fc2a10a499
26 changed files with 1670 additions and 81 deletions

View File

@@ -121,6 +121,7 @@ In RTSP, media streams are routed between server and clients by using RTP packet
|MPEG-4 Audio (AAC)|Generic (RFC3640)|[link](https://pkg.go.dev/github.com/bluenviron/gortsplib/v4/pkg/format#MPEG4AudioGeneric)|:heavy_check_mark:|
|MPEG-4 Audio (AAC)|LATM (RFC6416)|[link](https://pkg.go.dev/github.com/bluenviron/gortsplib/v4/pkg/format#MPEG4AudioLATM)|:heavy_check_mark:|
|MPEG-1/2 Audio (MP3)||[link](https://pkg.go.dev/github.com/bluenviron/gortsplib/v4/pkg/format#MPEG1Audio)|:heavy_check_mark:|
|AC-3||[link](https://pkg.go.dev/github.com/bluenviron/gortsplib/v4/pkg/format#AC3)|:heavy_check_mark:|
|Speex||[link](https://pkg.go.dev/github.com/bluenviron/gortsplib/v4/pkg/format#Speex)||
|G726||[link](https://pkg.go.dev/github.com/bluenviron/gortsplib/v4/pkg/format#G726)||
|G722||[link](https://pkg.go.dev/github.com/bluenviron/gortsplib/v4/pkg/format#G722)|:heavy_check_mark:|
@@ -140,20 +141,21 @@ In RTSP, media streams are routed between server and clients by using RTP packet
|[RFC2326, RTSP 1.0](https://datatracker.ietf.org/doc/html/rfc2326)|protocol|
|[RFC7826, RTSP 2.0](https://datatracker.ietf.org/doc/html/rfc7826)|protocol|
|[RFC8866, SDP: Session Description Protocol](https://datatracker.ietf.org/doc/html/rfc8866)|SDP|
|[RFC3551, RTP Profile for Audio and Video Conferences with Minimal Control](https://datatracker.ietf.org/doc/html/rfc3551)|G726, G722, G711 payload formats|
|[RTP Payload Format For AV1 (v1.0)](https://aomediacodec.github.io/av1-rtp-spec/)|AV1 payload format|
|[RTP Payload Format for VP9 Video](https://datatracker.ietf.org/doc/html/draft-ietf-payload-vp9-16)|VP9 payload format|
|[RFC7741, RTP Payload Format for VP8 Video](https://datatracker.ietf.org/doc/html/rfc7741)|VP8 payload format|
|[RFC7798, RTP Payload Format for High Efficiency Video Coding (HEVC)](https://datatracker.ietf.org/doc/html/rfc7798)|H265 payload format|
|[RFC6184, RTP Payload Format for H.264 Video](https://datatracker.ietf.org/doc/html/rfc6184)|H264 payload format|
|[RFC3640, RTP Payload Format for Transport of MPEG-4 Elementary Streams](https://datatracker.ietf.org/doc/html/rfc3640)|MPEG-4 audio, MPEG-4 video payload formats|
|[RFC2250, RTP Payload Format for MPEG1/MPEG2 Video](https://datatracker.ietf.org/doc/html/rfc2250)|MPEG-1 video, MPEG-2 audio, MPEG-TS payload formats|
|[RFC2435, RTP Payload Format for JPEG-compressed Video](https://datatracker.ietf.org/doc/html/rfc2435)|M-JPEG payload format|
|[RFC6416, RTP Payload Format for MPEG-4 Audio/Visual Streams](https://datatracker.ietf.org/doc/html/rfc6416)|MPEG-4 audio payload format|
|[RFC6184, RTP Payload Format for H.264 Video](https://datatracker.ietf.org/doc/html/rfc6184)|H264 payload format|
|[RFC7798, RTP Payload Format for High Efficiency Video Coding (HEVC)](https://datatracker.ietf.org/doc/html/rfc7798)|H265 payload format|
|[RFC7741, RTP Payload Format for VP8 Video](https://datatracker.ietf.org/doc/html/rfc7741)|VP8 payload format|
|[RTP Payload Format for VP9 Video](https://datatracker.ietf.org/doc/html/draft-ietf-payload-vp9-16)|VP9 payload format|
|[RFC3190, RTP Payload Format for 12-bit DAT Audio and 20- and 24-bit Linear Sampled Audio](https://datatracker.ietf.org/doc/html/rfc3190)|LPCM payload format|
|[RFC5215, RTP Payload Format for Vorbis Encoded Audio](https://datatracker.ietf.org/doc/html/rfc5215)|Vorbis payload format|
|[RFC7587, RTP Payload Format for the Opus Speech and Audio Codec](https://datatracker.ietf.org/doc/html/rfc7587)|Opus payload format|
|[RFC3640, RTP Payload Format for Transport of MPEG-4 Elementary Streams](https://datatracker.ietf.org/doc/html/rfc3640)|MPEG-4 audio, MPEG-4 video payload formats|
|[RFC5215, RTP Payload Format for Vorbis Encoded Audio](https://datatracker.ietf.org/doc/html/rfc5215)|Vorbis payload format|
|[RFC4184, RTP Payload Format for AC-3 Audio](https://datatracker.ietf.org/doc/html/rfc4184)|AC-3 payload format|
|[RFC6416, RTP Payload Format for MPEG-4 Audio/Visual Streams](https://datatracker.ietf.org/doc/html/rfc6416)|MPEG-4 audio payload format|
|[RFC5574, RTP Payload Format for the Speex Codec](https://datatracker.ietf.org/doc/html/rfc5574)|Speex payload format|
|[RTP Payload Format For AV1 (v1.0)](https://aomediacodec.github.io/av1-rtp-spec/)|AV1 payload format|
|[RFC3551, RTP Profile for Audio and Video Conferences with Minimal Control](https://datatracker.ietf.org/doc/html/rfc3551)|G726, G722, G711 payload formats|
|[RFC3190, RTP Payload Format for 12-bit DAT Audio and 20- and 24-bit Linear Sampled Audio](https://datatracker.ietf.org/doc/html/rfc3190)|LPCM payload format|
|[Codec specifications](https://github.com/bluenviron/mediacommon#specifications)|codecs|
|[Golang project layout](https://github.com/golang-standards/project-layout)|project layout|

2
go.mod
View File

@@ -3,7 +3,7 @@ module github.com/bluenviron/gortsplib/v4
go 1.19
require (
github.com/bluenviron/mediacommon v1.3.0
github.com/bluenviron/mediacommon v1.3.1-0.20230919191723-607668055ebe
github.com/google/uuid v1.3.1
github.com/pion/rtcp v1.2.10
github.com/pion/rtp v1.8.1

4
go.sum
View File

@@ -2,8 +2,8 @@ github.com/asticode/go-astikit v0.30.0 h1:DkBkRQRIxYcknlaU7W7ksNfn4gMFsB0tqMJflx
github.com/asticode/go-astikit v0.30.0/go.mod h1:h4ly7idim1tNhaVkdVBeXQZEE3L0xblP7fCWbgwipF0=
github.com/asticode/go-astits v1.13.0 h1:XOgkaadfZODnyZRR5Y0/DWkA9vrkLLPLeeOvDwfKZ1c=
github.com/asticode/go-astits v1.13.0/go.mod h1:QSHmknZ51pf6KJdHKZHJTLlMegIrhega3LPWz3ND/iI=
github.com/bluenviron/mediacommon v1.3.0 h1:2ttKdlvEXJSzHTd1+7x4TmJDTqEhLAAPP9QfdnYWo8U=
github.com/bluenviron/mediacommon v1.3.0/go.mod h1:/vlOVSebDwzdRtQONOKLua0fOSJg1tUDHpP+h9a0uqM=
github.com/bluenviron/mediacommon v1.3.1-0.20230919191723-607668055ebe h1:8kvIJfRXvv1Za1hdArKjvd/l8WCHJF+d+oLtANdFbr8=
github.com/bluenviron/mediacommon v1.3.1-0.20230919191723-607668055ebe/go.mod h1:/vlOVSebDwzdRtQONOKLua0fOSJg1tUDHpP+h9a0uqM=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=

101
pkg/format/ac3.go Normal file
View File

@@ -0,0 +1,101 @@
package format
import (
"strconv"
"strings"
"github.com/pion/rtp"
"github.com/bluenviron/gortsplib/v4/pkg/format/rtpac3"
)
// AC3 is a RTP format for the AC-3 codec.
// Specification: https://datatracker.ietf.org/doc/html/rfc4184
type AC3 struct {
PayloadTyp uint8
SampleRate int
ChannelCount int
}
func (f *AC3) unmarshal(ctx *unmarshalContext) error {
f.PayloadTyp = ctx.payloadType
tmp := strings.SplitN(ctx.clock, "/", 2)
tmp1, err := strconv.ParseUint(tmp[0], 10, 31)
if err != nil {
return err
}
f.SampleRate = int(tmp1)
if len(tmp) >= 2 {
tmp1, err := strconv.ParseUint(tmp[1], 10, 31)
if err != nil {
return err
}
f.ChannelCount = int(tmp1)
} else {
// RFC4184: If the "channels" parameter
// is omitted, a default maximum value of 6 is implied.
f.ChannelCount = 6
}
return nil
}
// Codec implements Format.
func (f *AC3) Codec() string {
return "AC-3"
}
// ClockRate implements Format.
func (f *AC3) ClockRate() int {
return f.SampleRate
}
// PayloadType implements Format.
func (f *AC3) PayloadType() uint8 {
return f.PayloadTyp
}
// RTPMap implements Format.
func (f *AC3) RTPMap() string {
return "AC3/" + strconv.FormatInt(int64(f.SampleRate), 10) +
"/" + strconv.FormatInt(int64(f.ChannelCount), 10)
}
// FMTP implements Format.
func (f *AC3) FMTP() map[string]string {
return nil
}
// PTSEqualsDTS implements Format.
func (f *AC3) PTSEqualsDTS(*rtp.Packet) bool {
return true
}
// CreateDecoder creates a decoder able to decode the content of the format.
func (f *AC3) CreateDecoder() (*rtpac3.Decoder, error) {
d := &rtpac3.Decoder{}
err := d.Init()
if err != nil {
return nil, err
}
return d, nil
}
// CreateEncoder creates an encoder able to encode the content of the format.
func (f *AC3) CreateEncoder() (*rtpac3.Encoder, error) {
e := &rtpac3.Encoder{
PayloadType: f.PayloadTyp,
}
err := e.Init()
if err != nil {
return nil, err
}
return e, nil
}

139
pkg/format/ac3_test.go Normal file
View File

@@ -0,0 +1,139 @@
package format
import (
"testing"
"github.com/pion/rtp"
"github.com/stretchr/testify/require"
)
func TestAC3Attributes(t *testing.T) {
format := &AC3{
PayloadTyp: 96,
SampleRate: 44100,
ChannelCount: 2,
}
require.Equal(t, "AC-3", format.Codec())
require.Equal(t, 44100, format.ClockRate())
require.Equal(t, true, format.PTSEqualsDTS(&rtp.Packet{}))
}
func TestAC3DecEncoder(t *testing.T) {
format := &AC3{
PayloadTyp: 96,
SampleRate: 44100,
ChannelCount: 2,
}
enc, err := format.CreateEncoder()
require.NoError(t, err)
pkts, err := enc.Encode([][]byte{{ //nolint:dupl
0x0b, 0x77, 0x47, 0x11, 0x0c, 0x40, 0x2f, 0x84,
0x2b, 0xc1, 0x07, 0x7a, 0xb0, 0xfa, 0xbb, 0xea,
0xef, 0x9f, 0x57, 0x7c, 0xf9, 0xf3, 0xf7, 0xcf,
0x9f, 0x3e, 0x32, 0xfe, 0xd5, 0xc1, 0x50, 0xde,
0xc5, 0x1e, 0x73, 0xd2, 0x6c, 0xa6, 0x94, 0x46,
0x4e, 0x92, 0x8c, 0x0f, 0xb9, 0xcf, 0xad, 0x07,
0x54, 0x4a, 0x2e, 0xf3, 0x7d, 0x07, 0x2e, 0xa4,
0x2f, 0xba, 0xbf, 0x39, 0xb5, 0xc9, 0x92, 0xa6,
0xe1, 0xb4, 0x70, 0xc5, 0xc4, 0xb5, 0xe6, 0x5d,
0x0f, 0xa8, 0x71, 0xa4, 0xcc, 0xc5, 0xbc, 0x75,
0x67, 0x92, 0x52, 0x4f, 0x7e, 0x62, 0x1c, 0xa9,
0xd9, 0xb5, 0x19, 0x6a, 0xd7, 0xb0, 0x44, 0x92,
0x30, 0x3b, 0xf7, 0x61, 0xd6, 0x49, 0x96, 0x66,
0x98, 0x28, 0x1a, 0x95, 0xa9, 0x42, 0xad, 0xb7,
0x50, 0x90, 0xad, 0x1c, 0x34, 0x80, 0xe2, 0xef,
0xcd, 0x41, 0x0b, 0xf0, 0x9d, 0x57, 0x62, 0x78,
0xfd, 0xc6, 0xc2, 0x19, 0x9e, 0x26, 0x31, 0xca,
0x1e, 0x75, 0xb1, 0x7a, 0x8e, 0xb5, 0x51, 0x3a,
0xfe, 0xe4, 0xf1, 0x0b, 0x4f, 0x14, 0x90, 0xdb,
0x9f, 0x44, 0x50, 0xbb, 0xef, 0x74, 0x00, 0x8c,
0x1f, 0x97, 0xa1, 0xa2, 0xfa, 0x72, 0x16, 0x47,
0xc6, 0xc0, 0xe5, 0xfe, 0x67, 0x03, 0x9c, 0xfe,
0x62, 0x01, 0xa1, 0x00, 0x5d, 0xff, 0xa5, 0x03,
0x59, 0xfa, 0xa8, 0x25, 0x5f, 0x6b, 0x83, 0x51,
0xf2, 0xc0, 0x44, 0xff, 0x2d, 0x05, 0x4b, 0xee,
0xe0, 0x54, 0x9e, 0xae, 0x86, 0x45, 0xf3, 0xbd,
0x0e, 0x42, 0xf2, 0xbf, 0x0f, 0x7f, 0xc6, 0x09,
0x07, 0xdc, 0x22, 0x11, 0x77, 0xbe, 0x31, 0x27,
0x5b, 0xa4, 0x13, 0x47, 0x07, 0x32, 0x9f, 0x1f,
0xcb, 0xb0, 0xdf, 0x3e, 0x7d, 0x0d, 0xf3, 0xe7,
0xcf, 0x9f, 0x3e, 0xae, 0xf9, 0xf3, 0xe7, 0xcf,
0x9f, 0x3e, 0x85, 0x5d, 0xf3, 0xe7, 0xcf, 0x9f,
0x3e, 0x7c, 0xf9, 0xf3, 0xe7, 0xcf, 0x9f, 0x3f,
0x53, 0x5d, 0xf3, 0xe7, 0xcf, 0x9f, 0x3e, 0x7c,
0xf9, 0xf3, 0xe7, 0xcf, 0x9f, 0x3e, 0x7c, 0xf9,
0xf3, 0xe7, 0xcf, 0x9f, 0x3e, 0x7c, 0xf9, 0xf3,
0xe7, 0xcf, 0x9f, 0x3e, 0x00, 0x46, 0x28, 0x26,
0x20, 0x4a, 0x5a, 0xc0, 0x8a, 0xc5, 0xae, 0xa0,
0x55, 0x78, 0x82, 0x7a, 0x38, 0x10, 0x09, 0xc9,
0xb8, 0x0c, 0xfa, 0x5b, 0xc9, 0xd2, 0xec, 0x44,
0x25, 0xf8, 0x20, 0xf2, 0xc8, 0x8a, 0xe9, 0x40,
0x18, 0x06, 0xc6, 0x2b, 0xc8, 0xed, 0x8f, 0x33,
0x09, 0x92, 0x28, 0x1e, 0xc4, 0x24, 0xd8, 0x33,
0xa5, 0x00, 0xf5, 0xea, 0x18, 0xfa, 0x90, 0x97,
0x97, 0xe8, 0x39, 0x6a, 0xcf, 0xf1, 0xdd, 0xff,
0x9e, 0x8e, 0x04, 0x02, 0xae, 0x65, 0x87, 0x5c,
0x4e, 0x72, 0xfd, 0x3c, 0x01, 0x86, 0xfe, 0x56,
0x59, 0x74, 0x44, 0x3a, 0x40, 0x00, 0xec, 0xfc,
}})
require.NoError(t, err)
require.Equal(t, format.PayloadType(), pkts[0].PayloadType)
dec, err := format.CreateDecoder()
require.NoError(t, err)
byts, err := dec.Decode(pkts[0])
require.NoError(t, err)
require.Equal(t, [][]byte{{ //nolint:dupl
0x0b, 0x77, 0x47, 0x11, 0x0c, 0x40, 0x2f, 0x84,
0x2b, 0xc1, 0x07, 0x7a, 0xb0, 0xfa, 0xbb, 0xea,
0xef, 0x9f, 0x57, 0x7c, 0xf9, 0xf3, 0xf7, 0xcf,
0x9f, 0x3e, 0x32, 0xfe, 0xd5, 0xc1, 0x50, 0xde,
0xc5, 0x1e, 0x73, 0xd2, 0x6c, 0xa6, 0x94, 0x46,
0x4e, 0x92, 0x8c, 0x0f, 0xb9, 0xcf, 0xad, 0x07,
0x54, 0x4a, 0x2e, 0xf3, 0x7d, 0x07, 0x2e, 0xa4,
0x2f, 0xba, 0xbf, 0x39, 0xb5, 0xc9, 0x92, 0xa6,
0xe1, 0xb4, 0x70, 0xc5, 0xc4, 0xb5, 0xe6, 0x5d,
0x0f, 0xa8, 0x71, 0xa4, 0xcc, 0xc5, 0xbc, 0x75,
0x67, 0x92, 0x52, 0x4f, 0x7e, 0x62, 0x1c, 0xa9,
0xd9, 0xb5, 0x19, 0x6a, 0xd7, 0xb0, 0x44, 0x92,
0x30, 0x3b, 0xf7, 0x61, 0xd6, 0x49, 0x96, 0x66,
0x98, 0x28, 0x1a, 0x95, 0xa9, 0x42, 0xad, 0xb7,
0x50, 0x90, 0xad, 0x1c, 0x34, 0x80, 0xe2, 0xef,
0xcd, 0x41, 0x0b, 0xf0, 0x9d, 0x57, 0x62, 0x78,
0xfd, 0xc6, 0xc2, 0x19, 0x9e, 0x26, 0x31, 0xca,
0x1e, 0x75, 0xb1, 0x7a, 0x8e, 0xb5, 0x51, 0x3a,
0xfe, 0xe4, 0xf1, 0x0b, 0x4f, 0x14, 0x90, 0xdb,
0x9f, 0x44, 0x50, 0xbb, 0xef, 0x74, 0x00, 0x8c,
0x1f, 0x97, 0xa1, 0xa2, 0xfa, 0x72, 0x16, 0x47,
0xc6, 0xc0, 0xe5, 0xfe, 0x67, 0x03, 0x9c, 0xfe,
0x62, 0x01, 0xa1, 0x00, 0x5d, 0xff, 0xa5, 0x03,
0x59, 0xfa, 0xa8, 0x25, 0x5f, 0x6b, 0x83, 0x51,
0xf2, 0xc0, 0x44, 0xff, 0x2d, 0x05, 0x4b, 0xee,
0xe0, 0x54, 0x9e, 0xae, 0x86, 0x45, 0xf3, 0xbd,
0x0e, 0x42, 0xf2, 0xbf, 0x0f, 0x7f, 0xc6, 0x09,
0x07, 0xdc, 0x22, 0x11, 0x77, 0xbe, 0x31, 0x27,
0x5b, 0xa4, 0x13, 0x47, 0x07, 0x32, 0x9f, 0x1f,
0xcb, 0xb0, 0xdf, 0x3e, 0x7d, 0x0d, 0xf3, 0xe7,
0xcf, 0x9f, 0x3e, 0xae, 0xf9, 0xf3, 0xe7, 0xcf,
0x9f, 0x3e, 0x85, 0x5d, 0xf3, 0xe7, 0xcf, 0x9f,
0x3e, 0x7c, 0xf9, 0xf3, 0xe7, 0xcf, 0x9f, 0x3f,
0x53, 0x5d, 0xf3, 0xe7, 0xcf, 0x9f, 0x3e, 0x7c,
0xf9, 0xf3, 0xe7, 0xcf, 0x9f, 0x3e, 0x7c, 0xf9,
0xf3, 0xe7, 0xcf, 0x9f, 0x3e, 0x7c, 0xf9, 0xf3,
0xe7, 0xcf, 0x9f, 0x3e, 0x00, 0x46, 0x28, 0x26,
0x20, 0x4a, 0x5a, 0xc0, 0x8a, 0xc5, 0xae, 0xa0,
0x55, 0x78, 0x82, 0x7a, 0x38, 0x10, 0x09, 0xc9,
0xb8, 0x0c, 0xfa, 0x5b, 0xc9, 0xd2, 0xec, 0x44,
0x25, 0xf8, 0x20, 0xf2, 0xc8, 0x8a, 0xe9, 0x40,
0x18, 0x06, 0xc6, 0x2b, 0xc8, 0xed, 0x8f, 0x33,
0x09, 0x92, 0x28, 0x1e, 0xc4, 0x24, 0xd8, 0x33,
0xa5, 0x00, 0xf5, 0xea, 0x18, 0xfa, 0x90, 0x97,
0x97, 0xe8, 0x39, 0x6a, 0xcf, 0xf1, 0xdd, 0xff,
0x9e, 0x8e, 0x04, 0x02, 0xae, 0x65, 0x87, 0x5c,
0x4e, 0x72, 0xfd, 0x3c, 0x01, 0x86, 0xfe, 0x56,
0x59, 0x74, 0x44, 0x3a, 0x40, 0x00, 0xec, 0xfc,
}}, byts)
}

View File

@@ -57,40 +57,55 @@ func Unmarshal(mediaType string, payloadType uint8, rtpMap string, fmtp map[stri
switch {
// video
case payloadType == 26:
return &MJPEG{}
case payloadType == 32:
return &MPEG1Video{}
case payloadType == 33:
return &MPEGTS{}
case codec == "mp4v-es" && clock == "90000":
return &MPEG4Video{}
case codec == "h264" && clock == "90000":
return &H264{}
case codec == "h265" && clock == "90000":
return &H265{}
case codec == "vp8" && clock == "90000":
return &VP8{}
case codec == "av1" && clock == "90000":
return &AV1{}
case codec == "vp9" && clock == "90000":
return &VP9{}
case codec == "av1" && clock == "90000":
return &AV1{}
case codec == "vp8" && clock == "90000":
return &VP8{}
case codec == "h265" && clock == "90000":
return &H265{}
case codec == "h264" && clock == "90000":
return &H264{}
case codec == "mp4v-es" && clock == "90000":
return &MPEG4Video{}
case payloadType == 32:
return &MPEG1Video{}
case payloadType == 26:
return &MJPEG{}
case payloadType == 33:
return &MPEGTS{}
// audio
case payloadType == 0, payloadType == 8:
return &G711{}
case codec == "opus":
return &Opus{}
case payloadType == 9:
return &G722{}
case codec == "vorbis":
return &Vorbis{}
case codec == "mpeg4-generic":
return &MPEG4AudioGeneric{}
case codec == "mp4a-latm":
return &MPEG4AudioLATM{}
case payloadType == 14:
return &MPEG1Audio{}
case codec == "ac3":
return &AC3{}
case codec == "speex":
return &Speex{}
case (codec == "g726-16" ||
codec == "g726-24" ||
@@ -102,26 +117,14 @@ func Unmarshal(mediaType string, payloadType uint8, rtpMap string, fmtp map[stri
codec == "aal2-g726-40") && clock == "8000":
return &G726{}
case payloadType == 14:
return &MPEG1Audio{}
case payloadType == 9:
return &G722{}
case payloadType == 0, payloadType == 8:
return &G711{}
case codec == "l8", codec == "l16", codec == "l24":
return &LPCM{}
case codec == "mpeg4-generic":
return &MPEG4AudioGeneric{}
case codec == "mp4a-latm":
return &MPEG4AudioLATM{}
case codec == "speex":
return &Speex{}
case codec == "vorbis":
return &Vorbis{}
case codec == "opus":
return &Opus{}
}
return &Generic{}

View File

@@ -580,6 +580,34 @@ var casesFormat = []struct {
"sprop-stereo": "1",
},
},
{
"audio ac3",
"audio",
96,
"AC3/48000/2",
nil,
&AC3{
PayloadTyp: 96,
SampleRate: 48000,
ChannelCount: 2,
},
"AC3/48000/2",
nil,
},
{
"audio ac3 implicit channels",
"audio",
97,
"AC3/48000",
nil,
&AC3{
PayloadTyp: 97,
SampleRate: 48000,
ChannelCount: 6,
},
"AC3/48000/6",
nil,
},
{
"video jpeg",
"video",

View File

@@ -15,7 +15,7 @@ import (
"github.com/bluenviron/mediacommon/pkg/codecs/h264"
)
// H264 is a RTP format for the H264 codec, defined in MPEG-4 part 10.
// H264 is a RTP format for the H264 codec.
// Specification: https://datatracker.ietf.org/doc/html/rfc6184
type H264 struct {
PayloadTyp uint8

View File

@@ -0,0 +1,142 @@
package rtpac3
import (
"errors"
"fmt"
"github.com/pion/rtp"
"github.com/bluenviron/mediacommon/pkg/codecs/ac3"
)
// ErrMorePacketsNeeded is returned when more packets are needed.
var ErrMorePacketsNeeded = errors.New("need more packets")
// ErrNonStartingPacketAndNoPrevious is returned when we received a non-starting
// packet of a fragmented frame and we didn't received anything before.
// It's normal to receive this when decoding a stream that has been already
// running for some time.
var ErrNonStartingPacketAndNoPrevious = errors.New(
"received a non-starting fragment without any previous starting fragment")
func joinFragments(fragments [][]byte, size int) []byte {
ret := make([]byte, size)
n := 0
for _, p := range fragments {
n += copy(ret[n:], p)
}
return ret
}
// Decoder is a AC-3 decoder.
// Specification: https://datatracker.ietf.org/doc/html/rfc4184
type Decoder struct {
firstPacketReceived bool
fragments [][]byte
fragmentsSize int
fragmentsExpected int
}
// Init initializes the decoder.
func (d *Decoder) Init() error {
return nil
}
// Decode decodes frames from a RTP packet.
// It returns the frames and the PTS of the first frame.
func (d *Decoder) Decode(pkt *rtp.Packet) ([][]byte, error) {
if len(pkt.Payload) < 2 {
d.fragments = d.fragments[:0] // discard pending fragments
d.fragmentsSize = 0
return nil, fmt.Errorf("payload is too short")
}
mbz := pkt.Payload[0] >> 2
ft := pkt.Payload[0] & 0b11
if mbz != 0 {
d.fragments = d.fragments[:0] // discard pending fragments
d.fragmentsSize = 0
return nil, fmt.Errorf("invalid MBZ: %v", mbz)
}
var frames [][]byte
switch ft {
case 0:
d.fragments = d.fragments[:0] // discard pending fragments
d.fragmentsSize = 0
d.firstPacketReceived = true
buf := pkt.Payload[2:]
for {
var syncInfo ac3.SyncInfo
err := syncInfo.Unmarshal(buf)
if err != nil {
return nil, err
}
size := syncInfo.FrameSize()
if len(buf) < size {
return nil, fmt.Errorf("payload is too short")
}
frames = append(frames, buf[:size])
buf = buf[size:]
if len(buf) == 0 {
break
}
}
case 1, 2:
d.fragments = d.fragments[:0] // discard pending fragments
d.fragmentsSize = 0
var syncInfo ac3.SyncInfo
err := syncInfo.Unmarshal(pkt.Payload[2:])
if err != nil {
return nil, err
}
size := syncInfo.FrameSize()
le := len(pkt.Payload[2:])
d.fragmentsSize = le
d.fragmentsExpected = size - le
d.fragments = append(d.fragments, pkt.Payload[2:])
d.firstPacketReceived = true
return nil, ErrMorePacketsNeeded
case 3:
if d.fragmentsSize == 0 {
if !d.firstPacketReceived {
return nil, ErrNonStartingPacketAndNoPrevious
}
return nil, fmt.Errorf("received a subsequent fragment without previous fragments")
}
le := len(pkt.Payload[2:])
d.fragmentsSize += le
d.fragmentsExpected -= le
if d.fragmentsExpected < 0 {
d.fragments = d.fragments[:0] // discard pending fragments
d.fragmentsSize = 0
return nil, fmt.Errorf("fragment is too big")
}
d.fragments = append(d.fragments, pkt.Payload[2:])
if d.fragmentsExpected > 0 {
return nil, ErrMorePacketsNeeded
}
frames = [][]byte{joinFragments(d.fragments, d.fragmentsSize)}
d.fragments = d.fragments[:0]
d.fragmentsSize = 0
}
return frames, nil
}

View File

@@ -0,0 +1,70 @@
package rtpac3
import (
"testing"
"github.com/pion/rtp"
"github.com/stretchr/testify/require"
)
func TestDecode(t *testing.T) {
for _, ca := range cases {
t.Run(ca.name, func(t *testing.T) {
d := &Decoder{}
err := d.Init()
require.NoError(t, err)
var frames [][]byte
for _, pkt := range ca.pkts {
clone := pkt.Clone()
addFrames, err := d.Decode(pkt)
// test input integrity
require.Equal(t, clone, pkt)
if err == ErrMorePacketsNeeded {
continue
}
require.NoError(t, err)
frames = append(frames, addFrames...)
}
require.Equal(t, ca.frames, frames)
})
}
}
func FuzzDecoder(f *testing.F) {
f.Fuzz(func(t *testing.T, a []byte, am bool, b []byte, bm bool) {
d := &Decoder{}
err := d.Init()
require.NoError(t, err)
d.Decode(&rtp.Packet{ //nolint:errcheck
Header: rtp.Header{
Version: 2,
Marker: am,
PayloadType: 96,
SequenceNumber: 17645,
Timestamp: 2289527317,
SSRC: 0x9dbb7812,
},
Payload: a,
})
d.Decode(&rtp.Packet{ //nolint:errcheck
Header: rtp.Header{
Version: 2,
Marker: bm,
PayloadType: 96,
SequenceNumber: 17646,
Timestamp: 2289527317,
SSRC: 0x9dbb7812,
},
Payload: b,
})
})
}

View File

@@ -0,0 +1,201 @@
package rtpac3
import (
"crypto/rand"
"github.com/pion/rtp"
"github.com/bluenviron/mediacommon/pkg/codecs/ac3"
)
const (
rtpVersion = 2
defaultPayloadMaxSize = 1460 // 1500 (UDP MTU) - 20 (IP header) - 8 (UDP header) - 12 (RTP header)
)
func randUint32() (uint32, error) {
var b [4]byte
_, err := rand.Read(b[:])
if err != nil {
return 0, err
}
return uint32(b[0])<<24 | uint32(b[1])<<16 | uint32(b[2])<<8 | uint32(b[3]), nil
}
func packetCount(avail, le int) int {
n := le / avail
if (le % avail) != 0 {
n++
}
return n
}
// Encoder is a AC-3 encoder.
// Specification: https://datatracker.ietf.org/doc/html/rfc4184
type Encoder struct {
// payload type of packets.
PayloadType uint8
// SSRC of packets (optional).
// It defaults to a random value.
SSRC *uint32
// initial sequence number of packets (optional).
// It defaults to a random value.
InitialSequenceNumber *uint16
// maximum size of packet payloads (optional).
// It defaults to 1460.
PayloadMaxSize int
sequenceNumber uint16
}
// Init initializes the encoder.
func (e *Encoder) Init() error {
if e.SSRC == nil {
v, err := randUint32()
if err != nil {
return err
}
e.SSRC = &v
}
if e.InitialSequenceNumber == nil {
v, err := randUint32()
if err != nil {
return err
}
v2 := uint16(v)
e.InitialSequenceNumber = &v2
}
if e.PayloadMaxSize == 0 {
e.PayloadMaxSize = defaultPayloadMaxSize
}
e.sequenceNumber = *e.InitialSequenceNumber
return nil
}
// Encode encodes frames into RTP packets.
func (e *Encoder) Encode(frames [][]byte) ([]*rtp.Packet, error) {
var rets []*rtp.Packet
var batch [][]byte
timestamp := uint32(0)
// split frames into batches
for _, frame := range frames {
if e.lenAggregated(batch, frame) <= e.PayloadMaxSize {
// add to existing batch
batch = append(batch, frame)
} else {
// write current batch
if batch != nil {
pkts, err := e.writeBatch(batch, timestamp)
if err != nil {
return nil, err
}
rets = append(rets, pkts...)
timestamp += uint32(len(batch)) * ac3.SamplesPerFrame
}
// initialize new batch
batch = [][]byte{frame}
}
}
// write last batch
pkts, err := e.writeBatch(batch, timestamp)
if err != nil {
return nil, err
}
rets = append(rets, pkts...)
return rets, nil
}
func (e *Encoder) writeBatch(frames [][]byte, timestamp uint32) ([]*rtp.Packet, error) {
if len(frames) != 1 || e.lenAggregated(frames, nil) < e.PayloadMaxSize {
return e.writeAggregated(frames, timestamp)
}
return e.writeFragmented(frames[0], timestamp)
}
func (e *Encoder) writeFragmented(frame []byte, timestamp uint32) ([]*rtp.Packet, error) {
avail := e.PayloadMaxSize - 4
le := len(frame)
packetCount := packetCount(avail, le)
ret := make([]*rtp.Packet, packetCount)
le = avail
ft := uint8(2)
if avail >= (len(frame) * 5 / 8) {
ft = 1
}
for i := range ret {
if i == (packetCount - 1) {
le = len(frame)
}
payload := make([]byte, 2+le)
payload[0] = ft
payload[1] = uint8(packetCount)
n := copy(payload[2:], frame)
frame = frame[n:]
ret[i] = &rtp.Packet{
Header: rtp.Header{
Version: rtpVersion,
PayloadType: e.PayloadType,
SequenceNumber: e.sequenceNumber,
Timestamp: timestamp,
SSRC: *e.SSRC,
Marker: i == (packetCount - 1),
},
Payload: payload,
}
e.sequenceNumber++
ft = 3
}
return ret, nil
}
func (e *Encoder) lenAggregated(frames [][]byte, addFrame []byte) int {
n := 2 + len(addFrame)
for _, frame := range frames {
n += len(frame)
}
return n
}
func (e *Encoder) writeAggregated(frames [][]byte, timestamp uint32) ([]*rtp.Packet, error) {
payload := make([]byte, e.lenAggregated(frames, nil))
payload[1] = uint8(len(frames))
n := 2
for _, frame := range frames {
n += copy(payload[n:], frame)
}
pkt := &rtp.Packet{
Header: rtp.Header{
Version: rtpVersion,
PayloadType: e.PayloadType,
SequenceNumber: e.sequenceNumber,
Timestamp: timestamp,
SSRC: *e.SSRC,
Marker: true,
},
Payload: payload,
}
e.sequenceNumber++
return []*rtp.Packet{pkt}, nil
}

View File

@@ -0,0 +1,861 @@
//nolint:dupl
package rtpac3
import (
"testing"
"github.com/pion/rtp"
"github.com/stretchr/testify/require"
)
func uint16Ptr(v uint16) *uint16 {
return &v
}
func uint32Ptr(v uint32) *uint32 {
return &v
}
var cases = []struct {
name string
frames [][]byte
pkts []*rtp.Packet
}{
{
"single",
[][]byte{{
0x0b, 0x77, 0x47, 0x11, 0x0c, 0x40, 0x2f, 0x84,
0x2b, 0xc1, 0x07, 0x7a, 0xb0, 0xfa, 0xbb, 0xea,
0xef, 0x9f, 0x57, 0x7c, 0xf9, 0xf3, 0xf7, 0xcf,
0x9f, 0x3e, 0x32, 0xfe, 0xd5, 0xc1, 0x50, 0xde,
0xc5, 0x1e, 0x73, 0xd2, 0x6c, 0xa6, 0x94, 0x46,
0x4e, 0x92, 0x8c, 0x0f, 0xb9, 0xcf, 0xad, 0x07,
0x54, 0x4a, 0x2e, 0xf3, 0x7d, 0x07, 0x2e, 0xa4,
0x2f, 0xba, 0xbf, 0x39, 0xb5, 0xc9, 0x92, 0xa6,
0xe1, 0xb4, 0x70, 0xc5, 0xc4, 0xb5, 0xe6, 0x5d,
0x0f, 0xa8, 0x71, 0xa4, 0xcc, 0xc5, 0xbc, 0x75,
0x67, 0x92, 0x52, 0x4f, 0x7e, 0x62, 0x1c, 0xa9,
0xd9, 0xb5, 0x19, 0x6a, 0xd7, 0xb0, 0x44, 0x92,
0x30, 0x3b, 0xf7, 0x61, 0xd6, 0x49, 0x96, 0x66,
0x98, 0x28, 0x1a, 0x95, 0xa9, 0x42, 0xad, 0xb7,
0x50, 0x90, 0xad, 0x1c, 0x34, 0x80, 0xe2, 0xef,
0xcd, 0x41, 0x0b, 0xf0, 0x9d, 0x57, 0x62, 0x78,
0xfd, 0xc6, 0xc2, 0x19, 0x9e, 0x26, 0x31, 0xca,
0x1e, 0x75, 0xb1, 0x7a, 0x8e, 0xb5, 0x51, 0x3a,
0xfe, 0xe4, 0xf1, 0x0b, 0x4f, 0x14, 0x90, 0xdb,
0x9f, 0x44, 0x50, 0xbb, 0xef, 0x74, 0x00, 0x8c,
0x1f, 0x97, 0xa1, 0xa2, 0xfa, 0x72, 0x16, 0x47,
0xc6, 0xc0, 0xe5, 0xfe, 0x67, 0x03, 0x9c, 0xfe,
0x62, 0x01, 0xa1, 0x00, 0x5d, 0xff, 0xa5, 0x03,
0x59, 0xfa, 0xa8, 0x25, 0x5f, 0x6b, 0x83, 0x51,
0xf2, 0xc0, 0x44, 0xff, 0x2d, 0x05, 0x4b, 0xee,
0xe0, 0x54, 0x9e, 0xae, 0x86, 0x45, 0xf3, 0xbd,
0x0e, 0x42, 0xf2, 0xbf, 0x0f, 0x7f, 0xc6, 0x09,
0x07, 0xdc, 0x22, 0x11, 0x77, 0xbe, 0x31, 0x27,
0x5b, 0xa4, 0x13, 0x47, 0x07, 0x32, 0x9f, 0x1f,
0xcb, 0xb0, 0xdf, 0x3e, 0x7d, 0x0d, 0xf3, 0xe7,
0xcf, 0x9f, 0x3e, 0xae, 0xf9, 0xf3, 0xe7, 0xcf,
0x9f, 0x3e, 0x85, 0x5d, 0xf3, 0xe7, 0xcf, 0x9f,
0x3e, 0x7c, 0xf9, 0xf3, 0xe7, 0xcf, 0x9f, 0x3f,
0x53, 0x5d, 0xf3, 0xe7, 0xcf, 0x9f, 0x3e, 0x7c,
0xf9, 0xf3, 0xe7, 0xcf, 0x9f, 0x3e, 0x7c, 0xf9,
0xf3, 0xe7, 0xcf, 0x9f, 0x3e, 0x7c, 0xf9, 0xf3,
0xe7, 0xcf, 0x9f, 0x3e, 0x00, 0x46, 0x28, 0x26,
0x20, 0x4a, 0x5a, 0xc0, 0x8a, 0xc5, 0xae, 0xa0,
0x55, 0x78, 0x82, 0x7a, 0x38, 0x10, 0x09, 0xc9,
0xb8, 0x0c, 0xfa, 0x5b, 0xc9, 0xd2, 0xec, 0x44,
0x25, 0xf8, 0x20, 0xf2, 0xc8, 0x8a, 0xe9, 0x40,
0x18, 0x06, 0xc6, 0x2b, 0xc8, 0xed, 0x8f, 0x33,
0x09, 0x92, 0x28, 0x1e, 0xc4, 0x24, 0xd8, 0x33,
0xa5, 0x00, 0xf5, 0xea, 0x18, 0xfa, 0x90, 0x97,
0x97, 0xe8, 0x39, 0x6a, 0xcf, 0xf1, 0xdd, 0xff,
0x9e, 0x8e, 0x04, 0x02, 0xae, 0x65, 0x87, 0x5c,
0x4e, 0x72, 0xfd, 0x3c, 0x01, 0x86, 0xfe, 0x56,
0x59, 0x74, 0x44, 0x3a, 0x40, 0x00, 0xec, 0xfc,
}},
[]*rtp.Packet{
{
Header: rtp.Header{
Version: 2,
Marker: true,
PayloadType: 96,
SequenceNumber: 17645,
SSRC: 0x9dbb7812,
},
Payload: []byte{
0x00, 0x01, 0x0b, 0x77, 0x47, 0x11, 0x0c, 0x40,
0x2f, 0x84, 0x2b, 0xc1, 0x07, 0x7a, 0xb0, 0xfa,
0xbb, 0xea, 0xef, 0x9f, 0x57, 0x7c, 0xf9, 0xf3,
0xf7, 0xcf, 0x9f, 0x3e, 0x32, 0xfe, 0xd5, 0xc1,
0x50, 0xde, 0xc5, 0x1e, 0x73, 0xd2, 0x6c, 0xa6,
0x94, 0x46, 0x4e, 0x92, 0x8c, 0x0f, 0xb9, 0xcf,
0xad, 0x07, 0x54, 0x4a, 0x2e, 0xf3, 0x7d, 0x07,
0x2e, 0xa4, 0x2f, 0xba, 0xbf, 0x39, 0xb5, 0xc9,
0x92, 0xa6, 0xe1, 0xb4, 0x70, 0xc5, 0xc4, 0xb5,
0xe6, 0x5d, 0x0f, 0xa8, 0x71, 0xa4, 0xcc, 0xc5,
0xbc, 0x75, 0x67, 0x92, 0x52, 0x4f, 0x7e, 0x62,
0x1c, 0xa9, 0xd9, 0xb5, 0x19, 0x6a, 0xd7, 0xb0,
0x44, 0x92, 0x30, 0x3b, 0xf7, 0x61, 0xd6, 0x49,
0x96, 0x66, 0x98, 0x28, 0x1a, 0x95, 0xa9, 0x42,
0xad, 0xb7, 0x50, 0x90, 0xad, 0x1c, 0x34, 0x80,
0xe2, 0xef, 0xcd, 0x41, 0x0b, 0xf0, 0x9d, 0x57,
0x62, 0x78, 0xfd, 0xc6, 0xc2, 0x19, 0x9e, 0x26,
0x31, 0xca, 0x1e, 0x75, 0xb1, 0x7a, 0x8e, 0xb5,
0x51, 0x3a, 0xfe, 0xe4, 0xf1, 0x0b, 0x4f, 0x14,
0x90, 0xdb, 0x9f, 0x44, 0x50, 0xbb, 0xef, 0x74,
0x00, 0x8c, 0x1f, 0x97, 0xa1, 0xa2, 0xfa, 0x72,
0x16, 0x47, 0xc6, 0xc0, 0xe5, 0xfe, 0x67, 0x03,
0x9c, 0xfe, 0x62, 0x01, 0xa1, 0x00, 0x5d, 0xff,
0xa5, 0x03, 0x59, 0xfa, 0xa8, 0x25, 0x5f, 0x6b,
0x83, 0x51, 0xf2, 0xc0, 0x44, 0xff, 0x2d, 0x05,
0x4b, 0xee, 0xe0, 0x54, 0x9e, 0xae, 0x86, 0x45,
0xf3, 0xbd, 0x0e, 0x42, 0xf2, 0xbf, 0x0f, 0x7f,
0xc6, 0x09, 0x07, 0xdc, 0x22, 0x11, 0x77, 0xbe,
0x31, 0x27, 0x5b, 0xa4, 0x13, 0x47, 0x07, 0x32,
0x9f, 0x1f, 0xcb, 0xb0, 0xdf, 0x3e, 0x7d, 0x0d,
0xf3, 0xe7, 0xcf, 0x9f, 0x3e, 0xae, 0xf9, 0xf3,
0xe7, 0xcf, 0x9f, 0x3e, 0x85, 0x5d, 0xf3, 0xe7,
0xcf, 0x9f, 0x3e, 0x7c, 0xf9, 0xf3, 0xe7, 0xcf,
0x9f, 0x3f, 0x53, 0x5d, 0xf3, 0xe7, 0xcf, 0x9f,
0x3e, 0x7c, 0xf9, 0xf3, 0xe7, 0xcf, 0x9f, 0x3e,
0x7c, 0xf9, 0xf3, 0xe7, 0xcf, 0x9f, 0x3e, 0x7c,
0xf9, 0xf3, 0xe7, 0xcf, 0x9f, 0x3e, 0x00, 0x46,
0x28, 0x26, 0x20, 0x4a, 0x5a, 0xc0, 0x8a, 0xc5,
0xae, 0xa0, 0x55, 0x78, 0x82, 0x7a, 0x38, 0x10,
0x09, 0xc9, 0xb8, 0x0c, 0xfa, 0x5b, 0xc9, 0xd2,
0xec, 0x44, 0x25, 0xf8, 0x20, 0xf2, 0xc8, 0x8a,
0xe9, 0x40, 0x18, 0x06, 0xc6, 0x2b, 0xc8, 0xed,
0x8f, 0x33, 0x09, 0x92, 0x28, 0x1e, 0xc4, 0x24,
0xd8, 0x33, 0xa5, 0x00, 0xf5, 0xea, 0x18, 0xfa,
0x90, 0x97, 0x97, 0xe8, 0x39, 0x6a, 0xcf, 0xf1,
0xdd, 0xff, 0x9e, 0x8e, 0x04, 0x02, 0xae, 0x65,
0x87, 0x5c, 0x4e, 0x72, 0xfd, 0x3c, 0x01, 0x86,
0xfe, 0x56, 0x59, 0x74, 0x44, 0x3a, 0x40, 0x00,
0xec, 0xfc,
},
},
},
},
{
"aggregated",
[][]byte{
{
0x0b, 0x77, 0x47, 0x11, 0x0c, 0x40, 0x2f, 0x84,
0x2b, 0xc1, 0x07, 0x7a, 0xb0, 0xfa, 0xbb, 0xea,
0xef, 0x9f, 0x57, 0x7c, 0xf9, 0xf3, 0xf7, 0xcf,
0x9f, 0x3e, 0x32, 0xfe, 0xd5, 0xc1, 0x50, 0xde,
0xc5, 0x1e, 0x73, 0xd2, 0x6c, 0xa6, 0x94, 0x46,
0x4e, 0x92, 0x8c, 0x0f, 0xb9, 0xcf, 0xad, 0x07,
0x54, 0x4a, 0x2e, 0xf3, 0x7d, 0x07, 0x2e, 0xa4,
0x2f, 0xba, 0xbf, 0x39, 0xb5, 0xc9, 0x92, 0xa6,
0xe1, 0xb4, 0x70, 0xc5, 0xc4, 0xb5, 0xe6, 0x5d,
0x0f, 0xa8, 0x71, 0xa4, 0xcc, 0xc5, 0xbc, 0x75,
0x67, 0x92, 0x52, 0x4f, 0x7e, 0x62, 0x1c, 0xa9,
0xd9, 0xb5, 0x19, 0x6a, 0xd7, 0xb0, 0x44, 0x92,
0x30, 0x3b, 0xf7, 0x61, 0xd6, 0x49, 0x96, 0x66,
0x98, 0x28, 0x1a, 0x95, 0xa9, 0x42, 0xad, 0xb7,
0x50, 0x90, 0xad, 0x1c, 0x34, 0x80, 0xe2, 0xef,
0xcd, 0x41, 0x0b, 0xf0, 0x9d, 0x57, 0x62, 0x78,
0xfd, 0xc6, 0xc2, 0x19, 0x9e, 0x26, 0x31, 0xca,
0x1e, 0x75, 0xb1, 0x7a, 0x8e, 0xb5, 0x51, 0x3a,
0xfe, 0xe4, 0xf1, 0x0b, 0x4f, 0x14, 0x90, 0xdb,
0x9f, 0x44, 0x50, 0xbb, 0xef, 0x74, 0x00, 0x8c,
0x1f, 0x97, 0xa1, 0xa2, 0xfa, 0x72, 0x16, 0x47,
0xc6, 0xc0, 0xe5, 0xfe, 0x67, 0x03, 0x9c, 0xfe,
0x62, 0x01, 0xa1, 0x00, 0x5d, 0xff, 0xa5, 0x03,
0x59, 0xfa, 0xa8, 0x25, 0x5f, 0x6b, 0x83, 0x51,
0xf2, 0xc0, 0x44, 0xff, 0x2d, 0x05, 0x4b, 0xee,
0xe0, 0x54, 0x9e, 0xae, 0x86, 0x45, 0xf3, 0xbd,
0x0e, 0x42, 0xf2, 0xbf, 0x0f, 0x7f, 0xc6, 0x09,
0x07, 0xdc, 0x22, 0x11, 0x77, 0xbe, 0x31, 0x27,
0x5b, 0xa4, 0x13, 0x47, 0x07, 0x32, 0x9f, 0x1f,
0xcb, 0xb0, 0xdf, 0x3e, 0x7d, 0x0d, 0xf3, 0xe7,
0xcf, 0x9f, 0x3e, 0xae, 0xf9, 0xf3, 0xe7, 0xcf,
0x9f, 0x3e, 0x85, 0x5d, 0xf3, 0xe7, 0xcf, 0x9f,
0x3e, 0x7c, 0xf9, 0xf3, 0xe7, 0xcf, 0x9f, 0x3f,
0x53, 0x5d, 0xf3, 0xe7, 0xcf, 0x9f, 0x3e, 0x7c,
0xf9, 0xf3, 0xe7, 0xcf, 0x9f, 0x3e, 0x7c, 0xf9,
0xf3, 0xe7, 0xcf, 0x9f, 0x3e, 0x7c, 0xf9, 0xf3,
0xe7, 0xcf, 0x9f, 0x3e, 0x00, 0x46, 0x28, 0x26,
0x20, 0x4a, 0x5a, 0xc0, 0x8a, 0xc5, 0xae, 0xa0,
0x55, 0x78, 0x82, 0x7a, 0x38, 0x10, 0x09, 0xc9,
0xb8, 0x0c, 0xfa, 0x5b, 0xc9, 0xd2, 0xec, 0x44,
0x25, 0xf8, 0x20, 0xf2, 0xc8, 0x8a, 0xe9, 0x40,
0x18, 0x06, 0xc6, 0x2b, 0xc8, 0xed, 0x8f, 0x33,
0x09, 0x92, 0x28, 0x1e, 0xc4, 0x24, 0xd8, 0x33,
0xa5, 0x00, 0xf5, 0xea, 0x18, 0xfa, 0x90, 0x97,
0x97, 0xe8, 0x39, 0x6a, 0xcf, 0xf1, 0xdd, 0xff,
0x9e, 0x8e, 0x04, 0x02, 0xae, 0x65, 0x87, 0x5c,
0x4e, 0x72, 0xfd, 0x3c, 0x01, 0x86, 0xfe, 0x56,
0x59, 0x74, 0x44, 0x3a, 0x40, 0x00, 0xec, 0xfc,
},
{
0x0b, 0x77, 0x47, 0x11, 0x0c, 0x40, 0x2f, 0x84,
0x2b, 0xc1, 0x07, 0x7a, 0xb0, 0xfa, 0xbb, 0xea,
0xef, 0x9f, 0x57, 0x7c, 0xf9, 0xf3, 0xf7, 0xcf,
0x9f, 0x3e, 0x32, 0xfe, 0xd5, 0xc1, 0x50, 0xde,
0xc5, 0x1e, 0x73, 0xd2, 0x6c, 0xa6, 0x94, 0x46,
0x4e, 0x92, 0x8c, 0x0f, 0xb9, 0xcf, 0xad, 0x07,
0x54, 0x4a, 0x2e, 0xf3, 0x7d, 0x07, 0x2e, 0xa4,
0x2f, 0xba, 0xbf, 0x39, 0xb5, 0xc9, 0x92, 0xa6,
0xe1, 0xb4, 0x70, 0xc5, 0xc4, 0xb5, 0xe6, 0x5d,
0x0f, 0xa8, 0x71, 0xa4, 0xcc, 0xc5, 0xbc, 0x75,
0x67, 0x92, 0x52, 0x4f, 0x7e, 0x62, 0x1c, 0xa9,
0xd9, 0xb5, 0x19, 0x6a, 0xd7, 0xb0, 0x44, 0x92,
0x30, 0x3b, 0xf7, 0x61, 0xd6, 0x49, 0x96, 0x66,
0x98, 0x28, 0x1a, 0x95, 0xa9, 0x42, 0xad, 0xb7,
0x50, 0x90, 0xad, 0x1c, 0x34, 0x80, 0xe2, 0xef,
0xcd, 0x41, 0x0b, 0xf0, 0x9d, 0x57, 0x62, 0x78,
0xfd, 0xc6, 0xc2, 0x19, 0x9e, 0x26, 0x31, 0xca,
0x1e, 0x75, 0xb1, 0x7a, 0x8e, 0xb5, 0x51, 0x3a,
0xfe, 0xe4, 0xf1, 0x0b, 0x4f, 0x14, 0x90, 0xdb,
0x9f, 0x44, 0x50, 0xbb, 0xef, 0x74, 0x00, 0x8c,
0x1f, 0x97, 0xa1, 0xa2, 0xfa, 0x72, 0x16, 0x47,
0xc6, 0xc0, 0xe5, 0xfe, 0x67, 0x03, 0x9c, 0xfe,
0x62, 0x01, 0xa1, 0x00, 0x5d, 0xff, 0xa5, 0x03,
0x59, 0xfa, 0xa8, 0x25, 0x5f, 0x6b, 0x83, 0x51,
0xf2, 0xc0, 0x44, 0xff, 0x2d, 0x05, 0x4b, 0xee,
0xe0, 0x54, 0x9e, 0xae, 0x86, 0x45, 0xf3, 0xbd,
0x0e, 0x42, 0xf2, 0xbf, 0x0f, 0x7f, 0xc6, 0x09,
0x07, 0xdc, 0x22, 0x11, 0x77, 0xbe, 0x31, 0x27,
0x5b, 0xa4, 0x13, 0x47, 0x07, 0x32, 0x9f, 0x1f,
0xcb, 0xb0, 0xdf, 0x3e, 0x7d, 0x0d, 0xf3, 0xe7,
0xcf, 0x9f, 0x3e, 0xae, 0xf9, 0xf3, 0xe7, 0xcf,
0x9f, 0x3e, 0x85, 0x5d, 0xf3, 0xe7, 0xcf, 0x9f,
0x3e, 0x7c, 0xf9, 0xf3, 0xe7, 0xcf, 0x9f, 0x3f,
0x53, 0x5d, 0xf3, 0xe7, 0xcf, 0x9f, 0x3e, 0x7c,
0xf9, 0xf3, 0xe7, 0xcf, 0x9f, 0x3e, 0x7c, 0xf9,
0xf3, 0xe7, 0xcf, 0x9f, 0x3e, 0x7c, 0xf9, 0xf3,
0xe7, 0xcf, 0x9f, 0x3e, 0x00, 0x46, 0x28, 0x26,
0x20, 0x4a, 0x5a, 0xc0, 0x8a, 0xc5, 0xae, 0xa0,
0x55, 0x78, 0x82, 0x7a, 0x38, 0x10, 0x09, 0xc9,
0xb8, 0x0c, 0xfa, 0x5b, 0xc9, 0xd2, 0xec, 0x44,
0x25, 0xf8, 0x20, 0xf2, 0xc8, 0x8a, 0xe9, 0x40,
0x18, 0x06, 0xc6, 0x2b, 0xc8, 0xed, 0x8f, 0x33,
0x09, 0x92, 0x28, 0x1e, 0xc4, 0x24, 0xd8, 0x33,
0xa5, 0x00, 0xf5, 0xea, 0x18, 0xfa, 0x90, 0x97,
0x97, 0xe8, 0x39, 0x6a, 0xcf, 0xf1, 0xdd, 0xff,
0x9e, 0x8e, 0x04, 0x02, 0xae, 0x65, 0x87, 0x5c,
0x4e, 0x72, 0xfd, 0x3c, 0x01, 0x86, 0xfe, 0x56,
0x59, 0x74, 0x44, 0x3a, 0x40, 0x00, 0xec, 0xfc,
},
},
[]*rtp.Packet{
{
Header: rtp.Header{
Version: 2,
Marker: true,
PayloadType: 96,
SequenceNumber: 17645,
SSRC: 0x9dbb7812,
},
Payload: []byte{
0x00, 0x02, 0x0b, 0x77, 0x47, 0x11, 0x0c, 0x40,
0x2f, 0x84, 0x2b, 0xc1, 0x07, 0x7a, 0xb0, 0xfa,
0xbb, 0xea, 0xef, 0x9f, 0x57, 0x7c, 0xf9, 0xf3,
0xf7, 0xcf, 0x9f, 0x3e, 0x32, 0xfe, 0xd5, 0xc1,
0x50, 0xde, 0xc5, 0x1e, 0x73, 0xd2, 0x6c, 0xa6,
0x94, 0x46, 0x4e, 0x92, 0x8c, 0x0f, 0xb9, 0xcf,
0xad, 0x07, 0x54, 0x4a, 0x2e, 0xf3, 0x7d, 0x07,
0x2e, 0xa4, 0x2f, 0xba, 0xbf, 0x39, 0xb5, 0xc9,
0x92, 0xa6, 0xe1, 0xb4, 0x70, 0xc5, 0xc4, 0xb5,
0xe6, 0x5d, 0x0f, 0xa8, 0x71, 0xa4, 0xcc, 0xc5,
0xbc, 0x75, 0x67, 0x92, 0x52, 0x4f, 0x7e, 0x62,
0x1c, 0xa9, 0xd9, 0xb5, 0x19, 0x6a, 0xd7, 0xb0,
0x44, 0x92, 0x30, 0x3b, 0xf7, 0x61, 0xd6, 0x49,
0x96, 0x66, 0x98, 0x28, 0x1a, 0x95, 0xa9, 0x42,
0xad, 0xb7, 0x50, 0x90, 0xad, 0x1c, 0x34, 0x80,
0xe2, 0xef, 0xcd, 0x41, 0x0b, 0xf0, 0x9d, 0x57,
0x62, 0x78, 0xfd, 0xc6, 0xc2, 0x19, 0x9e, 0x26,
0x31, 0xca, 0x1e, 0x75, 0xb1, 0x7a, 0x8e, 0xb5,
0x51, 0x3a, 0xfe, 0xe4, 0xf1, 0x0b, 0x4f, 0x14,
0x90, 0xdb, 0x9f, 0x44, 0x50, 0xbb, 0xef, 0x74,
0x00, 0x8c, 0x1f, 0x97, 0xa1, 0xa2, 0xfa, 0x72,
0x16, 0x47, 0xc6, 0xc0, 0xe5, 0xfe, 0x67, 0x03,
0x9c, 0xfe, 0x62, 0x01, 0xa1, 0x00, 0x5d, 0xff,
0xa5, 0x03, 0x59, 0xfa, 0xa8, 0x25, 0x5f, 0x6b,
0x83, 0x51, 0xf2, 0xc0, 0x44, 0xff, 0x2d, 0x05,
0x4b, 0xee, 0xe0, 0x54, 0x9e, 0xae, 0x86, 0x45,
0xf3, 0xbd, 0x0e, 0x42, 0xf2, 0xbf, 0x0f, 0x7f,
0xc6, 0x09, 0x07, 0xdc, 0x22, 0x11, 0x77, 0xbe,
0x31, 0x27, 0x5b, 0xa4, 0x13, 0x47, 0x07, 0x32,
0x9f, 0x1f, 0xcb, 0xb0, 0xdf, 0x3e, 0x7d, 0x0d,
0xf3, 0xe7, 0xcf, 0x9f, 0x3e, 0xae, 0xf9, 0xf3,
0xe7, 0xcf, 0x9f, 0x3e, 0x85, 0x5d, 0xf3, 0xe7,
0xcf, 0x9f, 0x3e, 0x7c, 0xf9, 0xf3, 0xe7, 0xcf,
0x9f, 0x3f, 0x53, 0x5d, 0xf3, 0xe7, 0xcf, 0x9f,
0x3e, 0x7c, 0xf9, 0xf3, 0xe7, 0xcf, 0x9f, 0x3e,
0x7c, 0xf9, 0xf3, 0xe7, 0xcf, 0x9f, 0x3e, 0x7c,
0xf9, 0xf3, 0xe7, 0xcf, 0x9f, 0x3e, 0x00, 0x46,
0x28, 0x26, 0x20, 0x4a, 0x5a, 0xc0, 0x8a, 0xc5,
0xae, 0xa0, 0x55, 0x78, 0x82, 0x7a, 0x38, 0x10,
0x09, 0xc9, 0xb8, 0x0c, 0xfa, 0x5b, 0xc9, 0xd2,
0xec, 0x44, 0x25, 0xf8, 0x20, 0xf2, 0xc8, 0x8a,
0xe9, 0x40, 0x18, 0x06, 0xc6, 0x2b, 0xc8, 0xed,
0x8f, 0x33, 0x09, 0x92, 0x28, 0x1e, 0xc4, 0x24,
0xd8, 0x33, 0xa5, 0x00, 0xf5, 0xea, 0x18, 0xfa,
0x90, 0x97, 0x97, 0xe8, 0x39, 0x6a, 0xcf, 0xf1,
0xdd, 0xff, 0x9e, 0x8e, 0x04, 0x02, 0xae, 0x65,
0x87, 0x5c, 0x4e, 0x72, 0xfd, 0x3c, 0x01, 0x86,
0xfe, 0x56, 0x59, 0x74, 0x44, 0x3a, 0x40, 0x00,
0xec, 0xfc, 0x0b, 0x77, 0x47, 0x11, 0x0c, 0x40,
0x2f, 0x84, 0x2b, 0xc1, 0x07, 0x7a, 0xb0, 0xfa,
0xbb, 0xea, 0xef, 0x9f, 0x57, 0x7c, 0xf9, 0xf3,
0xf7, 0xcf, 0x9f, 0x3e, 0x32, 0xfe, 0xd5, 0xc1,
0x50, 0xde, 0xc5, 0x1e, 0x73, 0xd2, 0x6c, 0xa6,
0x94, 0x46, 0x4e, 0x92, 0x8c, 0x0f, 0xb9, 0xcf,
0xad, 0x07, 0x54, 0x4a, 0x2e, 0xf3, 0x7d, 0x07,
0x2e, 0xa4, 0x2f, 0xba, 0xbf, 0x39, 0xb5, 0xc9,
0x92, 0xa6, 0xe1, 0xb4, 0x70, 0xc5, 0xc4, 0xb5,
0xe6, 0x5d, 0x0f, 0xa8, 0x71, 0xa4, 0xcc, 0xc5,
0xbc, 0x75, 0x67, 0x92, 0x52, 0x4f, 0x7e, 0x62,
0x1c, 0xa9, 0xd9, 0xb5, 0x19, 0x6a, 0xd7, 0xb0,
0x44, 0x92, 0x30, 0x3b, 0xf7, 0x61, 0xd6, 0x49,
0x96, 0x66, 0x98, 0x28, 0x1a, 0x95, 0xa9, 0x42,
0xad, 0xb7, 0x50, 0x90, 0xad, 0x1c, 0x34, 0x80,
0xe2, 0xef, 0xcd, 0x41, 0x0b, 0xf0, 0x9d, 0x57,
0x62, 0x78, 0xfd, 0xc6, 0xc2, 0x19, 0x9e, 0x26,
0x31, 0xca, 0x1e, 0x75, 0xb1, 0x7a, 0x8e, 0xb5,
0x51, 0x3a, 0xfe, 0xe4, 0xf1, 0x0b, 0x4f, 0x14,
0x90, 0xdb, 0x9f, 0x44, 0x50, 0xbb, 0xef, 0x74,
0x00, 0x8c, 0x1f, 0x97, 0xa1, 0xa2, 0xfa, 0x72,
0x16, 0x47, 0xc6, 0xc0, 0xe5, 0xfe, 0x67, 0x03,
0x9c, 0xfe, 0x62, 0x01, 0xa1, 0x00, 0x5d, 0xff,
0xa5, 0x03, 0x59, 0xfa, 0xa8, 0x25, 0x5f, 0x6b,
0x83, 0x51, 0xf2, 0xc0, 0x44, 0xff, 0x2d, 0x05,
0x4b, 0xee, 0xe0, 0x54, 0x9e, 0xae, 0x86, 0x45,
0xf3, 0xbd, 0x0e, 0x42, 0xf2, 0xbf, 0x0f, 0x7f,
0xc6, 0x09, 0x07, 0xdc, 0x22, 0x11, 0x77, 0xbe,
0x31, 0x27, 0x5b, 0xa4, 0x13, 0x47, 0x07, 0x32,
0x9f, 0x1f, 0xcb, 0xb0, 0xdf, 0x3e, 0x7d, 0x0d,
0xf3, 0xe7, 0xcf, 0x9f, 0x3e, 0xae, 0xf9, 0xf3,
0xe7, 0xcf, 0x9f, 0x3e, 0x85, 0x5d, 0xf3, 0xe7,
0xcf, 0x9f, 0x3e, 0x7c, 0xf9, 0xf3, 0xe7, 0xcf,
0x9f, 0x3f, 0x53, 0x5d, 0xf3, 0xe7, 0xcf, 0x9f,
0x3e, 0x7c, 0xf9, 0xf3, 0xe7, 0xcf, 0x9f, 0x3e,
0x7c, 0xf9, 0xf3, 0xe7, 0xcf, 0x9f, 0x3e, 0x7c,
0xf9, 0xf3, 0xe7, 0xcf, 0x9f, 0x3e, 0x00, 0x46,
0x28, 0x26, 0x20, 0x4a, 0x5a, 0xc0, 0x8a, 0xc5,
0xae, 0xa0, 0x55, 0x78, 0x82, 0x7a, 0x38, 0x10,
0x09, 0xc9, 0xb8, 0x0c, 0xfa, 0x5b, 0xc9, 0xd2,
0xec, 0x44, 0x25, 0xf8, 0x20, 0xf2, 0xc8, 0x8a,
0xe9, 0x40, 0x18, 0x06, 0xc6, 0x2b, 0xc8, 0xed,
0x8f, 0x33, 0x09, 0x92, 0x28, 0x1e, 0xc4, 0x24,
0xd8, 0x33, 0xa5, 0x00, 0xf5, 0xea, 0x18, 0xfa,
0x90, 0x97, 0x97, 0xe8, 0x39, 0x6a, 0xcf, 0xf1,
0xdd, 0xff, 0x9e, 0x8e, 0x04, 0x02, 0xae, 0x65,
0x87, 0x5c, 0x4e, 0x72, 0xfd, 0x3c, 0x01, 0x86,
0xfe, 0x56, 0x59, 0x74, 0x44, 0x3a, 0x40, 0x00,
0xec, 0xfc,
},
},
},
},
{
"fragmented",
[][]byte{{
0x0b, 0x77, 0x1a, 0x01, 0x1e, 0x40, 0xeb, 0xf8,
0x40, 0x3e, 0xff, 0x99, 0xc5, 0x98, 0xb3, 0x16,
0x62, 0xcc, 0x59, 0xff, 0xfa, 0xd7, 0xae, 0xf9,
0x07, 0x7a, 0xb0, 0xfa, 0xbb, 0xea, 0xef, 0x9f,
0x57, 0x7c, 0xf9, 0xf3, 0xf7, 0xc2, 0x0e, 0xf5,
0x61, 0xf5, 0x77, 0xd5, 0xdf, 0x3e, 0xae, 0xf9,
0xf3, 0xe7, 0xef, 0x84, 0x1d, 0xea, 0xc3, 0xea,
0xef, 0xab, 0xbe, 0x7d, 0x5d, 0xf3, 0xe7, 0xcf,
0xdf, 0x08, 0x3b, 0xd5, 0x87, 0xd5, 0xdf, 0x57,
0x7c, 0xfa, 0xbb, 0xe7, 0xcf, 0x9f, 0xbe, 0x10,
0x77, 0xab, 0x0f, 0xab, 0xbe, 0xae, 0xf9, 0xf5,
0x77, 0xcf, 0x9f, 0x3f, 0x7c, 0x23, 0xc4, 0xf9,
0x7f, 0x66, 0xa5, 0x4a, 0x95, 0x2a, 0x54, 0xa9,
0x00, 0x54, 0x37, 0xb1, 0x4e, 0x73, 0xc9, 0xb3,
0x69, 0x45, 0x93, 0xa2, 0x8c, 0x3e, 0xe7, 0xfa,
0xd0, 0x75, 0x44, 0xa2, 0xef, 0x37, 0xd0, 0x72,
0xea, 0x42, 0xfb, 0xad, 0xce, 0x6d, 0x72, 0x65,
0x53, 0xe1, 0xa8, 0xe1, 0x8b, 0x89, 0x6b, 0xcc,
0xb4, 0x3e, 0xa1, 0xc6, 0xa6, 0x8c, 0x57, 0x8d,
0x5b, 0xca, 0x52, 0x4f, 0x7e, 0x62, 0x1c, 0xa9,
0xd9, 0xb5, 0x19, 0x6a, 0xd7, 0xb0, 0x44, 0x92,
0x30, 0x3b, 0xf7, 0x63, 0xb9, 0x2c, 0xb6, 0x73,
0x0a, 0x0d, 0x45, 0xa2, 0x8a, 0xbd, 0xc5, 0x02,
0x1b, 0x4e, 0x24, 0x81, 0xcb, 0xce, 0x74, 0x11,
0x7c, 0x2e, 0xb7, 0x65, 0x24, 0x6e, 0x6c, 0x46,
0x67, 0x89, 0x8c, 0x72, 0x87, 0x9d, 0x70, 0xca,
0x9d, 0x55, 0x0a, 0xaf, 0xdd, 0x38, 0x8b, 0x5e,
0x52, 0x87, 0xbb, 0xe9, 0x10, 0x5b, 0xfe, 0xd0,
0x04, 0xc3, 0xf1, 0xe8, 0x68, 0xbe, 0x9c, 0x85,
0x91, 0xf1, 0xb0, 0x39, 0x7f, 0x99, 0x82, 0x9d,
0xfd, 0x88, 0x0a, 0x00, 0x17, 0x7f, 0xa6, 0x05,
0x67, 0xea, 0xa0, 0x95, 0x7d, 0xae, 0x0d, 0x47,
0xcb, 0x01, 0x13, 0xfc, 0xb4, 0x15, 0x2f, 0xbb,
0x81, 0x52, 0x7a, 0xba, 0x19, 0x17, 0xab, 0xc1,
0xd0, 0xf9, 0xc0, 0x1d, 0xfe, 0x21, 0x21, 0xfe,
0x22, 0x21, 0xed, 0xe3, 0x25, 0xdd, 0xe4, 0x26,
0xa3, 0x2a, 0x32, 0xa3, 0x34, 0xe0, 0x26, 0x72,
0x58, 0x40, 0x95, 0x0d, 0xec, 0x53, 0x9c, 0xf2,
0x6c, 0xda, 0x51, 0x64, 0xe8, 0xa3, 0x0f, 0xb9,
0xfe, 0xb4, 0x1d, 0x51, 0x28, 0xbb, 0xcd, 0xf4,
0x1c, 0xba, 0x90, 0xbe, 0xeb, 0x73, 0x9b, 0x5c,
0x99, 0x54, 0xf8, 0x6a, 0x38, 0x62, 0xe2, 0x5a,
0xf3, 0x2d, 0x0f, 0xa8, 0x71, 0xa9, 0xa3, 0x15,
0xe3, 0x56, 0xf2, 0x94, 0x93, 0xdf, 0x98, 0x87,
0x2a, 0x76, 0x6d, 0x46, 0x5a, 0xb5, 0xec, 0x11,
0x24, 0x8c, 0x0e, 0xfd, 0xd8, 0xee, 0x4b, 0x2d,
0x9c, 0xc2, 0x83, 0x51, 0x68, 0xa2, 0xaf, 0x71,
0x40, 0x86, 0xd3, 0x89, 0x20, 0x72, 0xf3, 0x9d,
0x04, 0x5f, 0x0b, 0xad, 0xd9, 0x49, 0x1b, 0x9b,
0x11, 0x99, 0xe2, 0x63, 0x1c, 0xa1, 0xe7, 0x5c,
0x32, 0xa7, 0x55, 0x42, 0xab, 0xf7, 0x4e, 0x22,
0xd7, 0x94, 0xa1, 0xee, 0xfa, 0x44, 0x16, 0xff,
0xb4, 0x01, 0x30, 0xfc, 0x7a, 0x1a, 0x2f, 0xa7,
0x21, 0x64, 0x7c, 0x6c, 0x0e, 0x5f, 0xe6, 0x60,
0xa7, 0x7f, 0x62, 0x02, 0x80, 0x05, 0xdf, 0xe9,
0x81, 0x59, 0xfa, 0xa8, 0x25, 0x5f, 0x6b, 0x83,
0x51, 0xf2, 0xc0, 0x44, 0xff, 0x2d, 0x05, 0x4b,
0xee, 0xe0, 0x54, 0x9e, 0xae, 0x86, 0x45, 0xea,
0xf0, 0x74, 0x3e, 0x70, 0x07, 0x7f, 0x88, 0x48,
0x7f, 0x88, 0x88, 0x7b, 0x78, 0xc9, 0x77, 0x79,
0x09, 0x54, 0x37, 0xb1, 0x4e, 0x73, 0xc9, 0xb3,
0x69, 0x45, 0x93, 0xa2, 0x8c, 0x3e, 0xe7, 0xfa,
0xd0, 0x75, 0x44, 0xa2, 0xef, 0x37, 0xd0, 0x72,
0xea, 0x42, 0xfb, 0xad, 0xce, 0x6d, 0x72, 0x65,
0x53, 0xe1, 0xa8, 0xe1, 0x8b, 0x89, 0x6b, 0xcc,
0xb4, 0x3e, 0xa1, 0xc6, 0xa6, 0x8c, 0x57, 0x8d,
0x5b, 0xca, 0x52, 0x4f, 0x7e, 0x62, 0x1c, 0xa9,
0xd9, 0xb5, 0x19, 0x6a, 0xd7, 0xb0, 0x44, 0x92,
0x30, 0x3b, 0xf7, 0x63, 0xb9, 0x2c, 0xb6, 0x73,
0x0a, 0x0d, 0x45, 0xa2, 0x8a, 0xbd, 0xc5, 0x02,
0x1b, 0x4e, 0x24, 0x81, 0xcb, 0xce, 0x74, 0x11,
0x7c, 0x2e, 0xb7, 0x65, 0x24, 0x6e, 0x6c, 0x46,
0x67, 0x89, 0x8c, 0x72, 0x87, 0x9d, 0x70, 0xca,
0x9d, 0x55, 0x0a, 0xaf, 0xdd, 0x38, 0x8b, 0x5e,
0x52, 0x87, 0xbb, 0xe9, 0x10, 0x5b, 0xfe, 0xd0,
0x04, 0xc3, 0xf1, 0xe8, 0x68, 0xbe, 0x9c, 0x85,
0x91, 0xf1, 0xb0, 0x39, 0x7f, 0x99, 0x82, 0x9d,
0xfd, 0x88, 0x0a, 0x00, 0x17, 0x7f, 0xa6, 0x05,
0x67, 0xea, 0xa0, 0x95, 0x7d, 0xae, 0x0d, 0x47,
0xcb, 0x01, 0x13, 0xfc, 0xb4, 0x15, 0x2f, 0xbb,
0x81, 0x52, 0x7a, 0xba, 0x19, 0x17, 0xab, 0xc1,
0xd0, 0xf9, 0xc0, 0x1d, 0xfe, 0x21, 0x21, 0xfe,
0x22, 0x21, 0xed, 0xe3, 0x25, 0xdd, 0xe4, 0x25,
0x50, 0xde, 0xc5, 0x39, 0xcf, 0x26, 0xcd, 0xa5,
0x16, 0x4e, 0x8a, 0x30, 0xfb, 0x9f, 0xeb, 0x41,
0xd5, 0x12, 0x8b, 0xbc, 0xdf, 0x41, 0xcb, 0xa9,
0x0b, 0xee, 0xb7, 0x39, 0xb5, 0xc9, 0x95, 0x4f,
0x86, 0xa3, 0x86, 0x2e, 0x25, 0xaf, 0x32, 0xd0,
0xfa, 0x87, 0x1a, 0x9a, 0x31, 0x5e, 0x35, 0x6f,
0x29, 0x49, 0x3d, 0xf9, 0x88, 0x72, 0xa7, 0x66,
0xd4, 0x65, 0xab, 0x5e, 0xc1, 0x12, 0x48, 0xc0,
0xef, 0xdd, 0x8e, 0xe4, 0xb2, 0xd9, 0xcc, 0x28,
0x35, 0x16, 0x8a, 0x2a, 0xf7, 0x14, 0x08, 0x6d,
0x38, 0x92, 0x07, 0x2f, 0x39, 0xd0, 0x45, 0xf0,
0xba, 0xdd, 0x94, 0x91, 0xb9, 0xb1, 0x19, 0x9e,
0x26, 0x31, 0xca, 0x1e, 0x75, 0xc3, 0x2a, 0x75,
0x54, 0x2a, 0xbf, 0x74, 0xe2, 0x2d, 0x79, 0x4a,
0x1e, 0xef, 0xa4, 0x41, 0x6f, 0xfb, 0x40, 0x13,
0x0f, 0xc7, 0xa1, 0xa2, 0xfa, 0x72, 0x16, 0x47,
0xc6, 0xc0, 0xe5, 0xfe, 0x66, 0x0a, 0x77, 0xf6,
0x20, 0x28, 0x00, 0x5d, 0xfe, 0x98, 0x15, 0x9f,
0xaa, 0x82, 0x55, 0xf6, 0xb8, 0x35, 0x1f, 0x2c,
0x04, 0x4f, 0xf2, 0xd0, 0x54, 0xbe, 0xee, 0x05,
0x49, 0xea, 0xe8, 0x64, 0x5e, 0xaf, 0x07, 0x43,
0xe7, 0x00, 0x77, 0xf8, 0x84, 0x87, 0xf8, 0x88,
0x87, 0xb7, 0x8c, 0x97, 0x77, 0x90, 0x95, 0x43,
0x7b, 0x14, 0xe7, 0x3c, 0x9b, 0x36, 0x94, 0x59,
0x3a, 0x28, 0xc3, 0xee, 0x7f, 0xad, 0x07, 0x54,
0x4a, 0x2e, 0xf3, 0x7d, 0x07, 0x2e, 0xa4, 0x2f,
0xba, 0xdc, 0xe6, 0xd7, 0x26, 0x55, 0x3e, 0x1a,
0x8e, 0x18, 0xb8, 0x96, 0xbc, 0xcb, 0x43, 0xea,
0x1c, 0x6a, 0x68, 0xc5, 0x78, 0xd5, 0xbc, 0xa5,
0x24, 0xf7, 0xe6, 0x21, 0xca, 0x9d, 0x9b, 0x51,
0x96, 0xad, 0x7b, 0x04, 0x49, 0x23, 0x03, 0xbf,
0x76, 0x3b, 0x92, 0xcb, 0x67, 0x30, 0xa0, 0xd4,
0x5a, 0x28, 0xab, 0xdc, 0x50, 0x21, 0xb4, 0xe2,
0x48, 0x1c, 0xbc, 0xe7, 0x41, 0x17, 0xc2, 0xeb,
0x76, 0x52, 0x46, 0xe6, 0xc4, 0x66, 0x78, 0x98,
0xc7, 0x28, 0x79, 0xd7, 0x0c, 0xa9, 0xd5, 0x50,
0xaa, 0xfd, 0xd3, 0x88, 0xb5, 0xe5, 0x28, 0x7b,
0xbe, 0x91, 0x05, 0xbf, 0xed, 0x00, 0x4c, 0x3f,
0x1e, 0x86, 0x8b, 0xe9, 0xc8, 0x59, 0x1f, 0x1b,
0x03, 0x97, 0xf9, 0x98, 0x29, 0xdf, 0xd8, 0x80,
0xa0, 0x01, 0x77, 0xfa, 0x60, 0x56, 0x7e, 0xaa,
0x09, 0x57, 0xda, 0xe0, 0xd4, 0x7c, 0xb0, 0x11,
0x3f, 0xcb, 0x41, 0x52, 0xfb, 0xb8, 0x15, 0x27,
0xab, 0xa1, 0x91, 0x7a, 0xbc, 0x1d, 0x0f, 0x9c,
0x01, 0xdf, 0xe2, 0x12, 0x1f, 0xe2, 0x22, 0x1e,
0xde, 0x32, 0x5d, 0xde, 0x42, 0x55, 0x15, 0x8a,
0x9c, 0xf4, 0x9b, 0x33, 0x4a, 0x0c, 0x9d, 0x51,
0x80, 0x7c, 0x04, 0xaa, 0xa9, 0xf3, 0xe7, 0xcf,
0x9f, 0x3e, 0x73, 0x29, 0xf1, 0xfc, 0xbb, 0x0d,
0xf3, 0xe7, 0xd0, 0xdf, 0x3e, 0x7c, 0xf9, 0xf3,
0xea, 0xef, 0x9f, 0x3e, 0x7c, 0xf9, 0xf3, 0xe8,
0x55, 0xdf, 0x3e, 0x7c, 0xf9, 0xf3, 0xe7, 0xcf,
0x9f, 0x3e, 0x7c, 0xf9, 0xf3, 0xf5, 0x35, 0xdf,
0x3e, 0x7c, 0xf9, 0xf3, 0xe7, 0xcf, 0x9f, 0x3e,
0x7c, 0xf9, 0xf3, 0xe7, 0xcf, 0x9f, 0x3e, 0x1c,
0xca, 0x7c, 0x7f, 0x2e, 0xc3, 0x7c, 0xf9, 0xf4,
0x37, 0xcf, 0x9f, 0x3e, 0x7c, 0xfa, 0xbb, 0xe7,
0xcf, 0x9f, 0x3e, 0x7c, 0xfa, 0x15, 0x77, 0xcf,
0x9f, 0x3e, 0x7c, 0xf9, 0xf3, 0xe7, 0xcf, 0x9f,
0x3e, 0x7c, 0xfd, 0x4d, 0x77, 0xcf, 0x9f, 0x3e,
0x7c, 0xf9, 0xf3, 0xe7, 0xcf, 0x9f, 0x3e, 0x7c,
0xf9, 0xf3, 0xe7, 0xcf, 0x87, 0x32, 0x9f, 0x1f,
0xcb, 0xb0, 0xdf, 0x3e, 0x7d, 0x0d, 0xf3, 0xe7,
0xcf, 0x9f, 0x3e, 0xae, 0xf9, 0xf3, 0xe7, 0xcf,
0x9f, 0x3e, 0x85, 0x5d, 0xf3, 0xe7, 0xcf, 0x9f,
0x3e, 0x7c, 0xf9, 0xf3, 0xe7, 0xcf, 0x9f, 0x3f,
0x53, 0x5d, 0xf3, 0xe7, 0xcf, 0x9f, 0x3e, 0x7c,
0xf9, 0xf3, 0xe7, 0xcf, 0x9f, 0x3e, 0x7c, 0xf9,
0xf3, 0xe1, 0xcc, 0xa7, 0xc7, 0xf2, 0xec, 0x37,
0xcf, 0x9f, 0x43, 0x7c, 0xf9, 0xf3, 0xe7, 0xcf,
0xab, 0xbe, 0x7c, 0xf9, 0xf3, 0xe7, 0xcf, 0xa1,
0x57, 0x7c, 0xf9, 0xf3, 0xe7, 0xcf, 0x9f, 0x3e,
0x7c, 0xf9, 0xf3, 0xe7, 0xcf, 0xd4, 0xd7, 0x7c,
0xf9, 0xf3, 0xe7, 0xcf, 0x9f, 0x3e, 0x7c, 0xf9,
0xf3, 0xe7, 0xcf, 0x9f, 0x3e, 0x7c, 0xf8, 0x73,
0x29, 0xf1, 0xfc, 0xbb, 0x0d, 0xf3, 0xe7, 0xd0,
0xdf, 0x3e, 0x7c, 0xf9, 0xf3, 0xea, 0xef, 0x9f,
0x3e, 0x7c, 0xf9, 0xf3, 0xe8, 0x55, 0xdf, 0x3e,
0x7c, 0xf9, 0xf3, 0xe7, 0xcf, 0x9f, 0x3e, 0x7c,
0xf9, 0xf3, 0xf5, 0x35, 0xdf, 0x3e, 0x7c, 0xf9,
0xf3, 0xe7, 0xcf, 0x9f, 0x3e, 0x7c, 0xf9, 0xf3,
0xe7, 0xcf, 0x9f, 0x3e, 0x00, 0x23, 0x28, 0x26,
0x20, 0x4a, 0x5a, 0xc2, 0x2b, 0x5a, 0xea, 0x05,
0x57, 0x88, 0x27, 0x47, 0x80, 0x11, 0x94, 0x13,
0x10, 0x25, 0x2d, 0x61, 0x15, 0xad, 0x75, 0x02,
0xab, 0xc4, 0x13, 0xa0, 0x8c, 0xa0, 0x98, 0x81,
0x29, 0x6b, 0x08, 0xad, 0x6b, 0xa8, 0x15, 0x5e,
0x20, 0x9d, 0x1e, 0x08, 0xca, 0x09, 0x88, 0x12,
0x96, 0xb0, 0x8a, 0xd6, 0xba, 0x81, 0x55, 0xe2,
0x09, 0xd0, 0x02, 0x32, 0x82, 0x62, 0x04, 0xa5,
0xac, 0x22, 0xb5, 0xae, 0xa0, 0x55, 0x78, 0x82,
0x74, 0x6e, 0x04, 0x85, 0x08, 0x81, 0x29, 0x6b,
0x08, 0xad, 0x6b, 0xa8, 0x15, 0x03, 0xe0, 0x00,
0x00, 0x09, 0xcb, 0x70, 0x19, 0xf4, 0xb7, 0x94,
0x97, 0x60, 0x84, 0xbf, 0x04, 0x1e, 0x59, 0x02,
0xbc, 0x6c, 0xe5, 0xb8, 0x0c, 0xfa, 0x5b, 0xca,
0x4b, 0xb0, 0x42, 0x5f, 0x82, 0x0f, 0x2c, 0x81,
0x67, 0x2d, 0xc0, 0x67, 0xd2, 0xde, 0x52, 0x5d,
0x82, 0x12, 0xfc, 0x10, 0x79, 0x64, 0x0a, 0xf2,
0x72, 0xdc, 0x06, 0x7d, 0x2d, 0xe5, 0x25, 0xd8,
0x21, 0x2f, 0xc1, 0x07, 0x96, 0x40, 0xac, 0x9c,
0xb7, 0x01, 0x9f, 0x4b, 0x79, 0x49, 0x76, 0x08,
0x4b, 0xf0, 0x41, 0xe5, 0x90, 0x2b, 0x7f, 0x3b,
0xee, 0x27, 0xd2, 0xde, 0x52, 0x5d, 0x82, 0x12,
0xfc, 0x10, 0x1f, 0x01, 0x80, 0x0a, 0xae, 0xf9,
0xf0, 0x18, 0x0d, 0x8c, 0x57, 0x91, 0xdb, 0x1d,
0x98, 0x52, 0x45, 0x03, 0xd8, 0x84, 0x9b, 0x0c,
0xf1, 0xac, 0x06, 0xc6, 0x2b, 0xc8, 0xed, 0x8e,
0xcc, 0x29, 0x22, 0x81, 0xec, 0x42, 0x4d, 0x86,
0x60, 0x36, 0x31, 0x5e, 0x47, 0x6c, 0x76, 0x61,
0x49, 0x14, 0x0f, 0x62, 0x12, 0x6c, 0x33, 0xc6,
0x03, 0x63, 0x15, 0xe4, 0x76, 0xc7, 0x66, 0x14,
0x91, 0x40, 0xf6, 0x21, 0x26, 0xc3, 0x31, 0x80,
0xd8, 0xc5, 0x79, 0x1d, 0xb1, 0xd9, 0x85, 0x24,
0x50, 0x3d, 0x88, 0x49, 0xb0, 0xcd, 0xc3, 0x07,
0xb2, 0x5e, 0x47, 0x6c, 0x76, 0x61, 0x49, 0x14,
0x0f, 0x60, 0x7c, 0x04, 0x00, 0x29, 0xf3, 0xe7,
0xcf, 0x9f, 0x3e, 0x07, 0xae, 0xa1, 0x8f, 0xa9,
0x09, 0x79, 0xfa, 0x0f, 0x6a, 0xcf, 0xf1, 0xdd,
0xff, 0xad, 0x1e, 0x03, 0xd7, 0x50, 0xc7, 0xd4,
0x84, 0xbc, 0xfd, 0x07, 0xb5, 0x67, 0xf8, 0xee,
0xff, 0xd6, 0x9e, 0xba, 0x86, 0x3e, 0xa4, 0x25,
0xe7, 0xe8, 0x3d, 0xab, 0x3f, 0xc7, 0x77, 0xfe,
0xb4, 0x79, 0xeb, 0xa8, 0x63, 0xea, 0x42, 0x5e,
0x7e, 0x83, 0xda, 0xb3, 0xfc, 0x77, 0x7f, 0xeb,
0x40, 0x7a, 0xea, 0x18, 0xfa, 0x90, 0x97, 0x9f,
0xa0, 0xf6, 0xac, 0xff, 0x1d, 0xdf, 0xfa, 0xd1,
0xbf, 0xf6, 0x14, 0x5e, 0xa4, 0x25, 0xe7, 0xe8,
0x3d, 0xab, 0x3f, 0xc6, 0x0f, 0x80, 0x00, 0x00,
0x2a, 0xec, 0xb0, 0xeb, 0x89, 0xce, 0x62, 0x9e,
0x03, 0x0d, 0xfc, 0xac, 0xb2, 0xe8, 0x90, 0xf1,
0xb5, 0x76, 0x58, 0x75, 0xc4, 0xe7, 0x31, 0x4f,
0x01, 0x86, 0xfe, 0x56, 0x59, 0x74, 0x48, 0xab,
0xb2, 0xc3, 0xae, 0x27, 0x39, 0x8a, 0x78, 0x0c,
0x37, 0xf2, 0xb2, 0xcb, 0xa2, 0x43, 0xca, 0xbb,
0x2c, 0x3a, 0xe2, 0x73, 0x98, 0xa7, 0x80, 0xc3,
0x7f, 0x2b, 0x2c, 0xba, 0x24, 0x32, 0xae, 0xcb,
0x0e, 0xb8, 0x9c, 0xe6, 0x29, 0xe0, 0x30, 0xdf,
0xca, 0xcb, 0x2e, 0x89, 0x0d, 0xfd, 0x67, 0x96,
0xae, 0x27, 0x39, 0x8a, 0x78, 0x0c, 0x37, 0xf2,
0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0xa2,
}},
[]*rtp.Packet{
{
Header: rtp.Header{
Version: 2,
Marker: false,
PayloadType: 96,
SequenceNumber: 17645,
SSRC: 0x9dbb7812,
},
Payload: []byte{
0x01, 0x02, 0x0b, 0x77, 0x1a, 0x01, 0x1e, 0x40,
0xeb, 0xf8, 0x40, 0x3e, 0xff, 0x99, 0xc5, 0x98,
0xb3, 0x16, 0x62, 0xcc, 0x59, 0xff, 0xfa, 0xd7,
0xae, 0xf9, 0x07, 0x7a, 0xb0, 0xfa, 0xbb, 0xea,
0xef, 0x9f, 0x57, 0x7c, 0xf9, 0xf3, 0xf7, 0xc2,
0x0e, 0xf5, 0x61, 0xf5, 0x77, 0xd5, 0xdf, 0x3e,
0xae, 0xf9, 0xf3, 0xe7, 0xef, 0x84, 0x1d, 0xea,
0xc3, 0xea, 0xef, 0xab, 0xbe, 0x7d, 0x5d, 0xf3,
0xe7, 0xcf, 0xdf, 0x08, 0x3b, 0xd5, 0x87, 0xd5,
0xdf, 0x57, 0x7c, 0xfa, 0xbb, 0xe7, 0xcf, 0x9f,
0xbe, 0x10, 0x77, 0xab, 0x0f, 0xab, 0xbe, 0xae,
0xf9, 0xf5, 0x77, 0xcf, 0x9f, 0x3f, 0x7c, 0x23,
0xc4, 0xf9, 0x7f, 0x66, 0xa5, 0x4a, 0x95, 0x2a,
0x54, 0xa9, 0x00, 0x54, 0x37, 0xb1, 0x4e, 0x73,
0xc9, 0xb3, 0x69, 0x45, 0x93, 0xa2, 0x8c, 0x3e,
0xe7, 0xfa, 0xd0, 0x75, 0x44, 0xa2, 0xef, 0x37,
0xd0, 0x72, 0xea, 0x42, 0xfb, 0xad, 0xce, 0x6d,
0x72, 0x65, 0x53, 0xe1, 0xa8, 0xe1, 0x8b, 0x89,
0x6b, 0xcc, 0xb4, 0x3e, 0xa1, 0xc6, 0xa6, 0x8c,
0x57, 0x8d, 0x5b, 0xca, 0x52, 0x4f, 0x7e, 0x62,
0x1c, 0xa9, 0xd9, 0xb5, 0x19, 0x6a, 0xd7, 0xb0,
0x44, 0x92, 0x30, 0x3b, 0xf7, 0x63, 0xb9, 0x2c,
0xb6, 0x73, 0x0a, 0x0d, 0x45, 0xa2, 0x8a, 0xbd,
0xc5, 0x02, 0x1b, 0x4e, 0x24, 0x81, 0xcb, 0xce,
0x74, 0x11, 0x7c, 0x2e, 0xb7, 0x65, 0x24, 0x6e,
0x6c, 0x46, 0x67, 0x89, 0x8c, 0x72, 0x87, 0x9d,
0x70, 0xca, 0x9d, 0x55, 0x0a, 0xaf, 0xdd, 0x38,
0x8b, 0x5e, 0x52, 0x87, 0xbb, 0xe9, 0x10, 0x5b,
0xfe, 0xd0, 0x04, 0xc3, 0xf1, 0xe8, 0x68, 0xbe,
0x9c, 0x85, 0x91, 0xf1, 0xb0, 0x39, 0x7f, 0x99,
0x82, 0x9d, 0xfd, 0x88, 0x0a, 0x00, 0x17, 0x7f,
0xa6, 0x05, 0x67, 0xea, 0xa0, 0x95, 0x7d, 0xae,
0x0d, 0x47, 0xcb, 0x01, 0x13, 0xfc, 0xb4, 0x15,
0x2f, 0xbb, 0x81, 0x52, 0x7a, 0xba, 0x19, 0x17,
0xab, 0xc1, 0xd0, 0xf9, 0xc0, 0x1d, 0xfe, 0x21,
0x21, 0xfe, 0x22, 0x21, 0xed, 0xe3, 0x25, 0xdd,
0xe4, 0x26, 0xa3, 0x2a, 0x32, 0xa3, 0x34, 0xe0,
0x26, 0x72, 0x58, 0x40, 0x95, 0x0d, 0xec, 0x53,
0x9c, 0xf2, 0x6c, 0xda, 0x51, 0x64, 0xe8, 0xa3,
0x0f, 0xb9, 0xfe, 0xb4, 0x1d, 0x51, 0x28, 0xbb,
0xcd, 0xf4, 0x1c, 0xba, 0x90, 0xbe, 0xeb, 0x73,
0x9b, 0x5c, 0x99, 0x54, 0xf8, 0x6a, 0x38, 0x62,
0xe2, 0x5a, 0xf3, 0x2d, 0x0f, 0xa8, 0x71, 0xa9,
0xa3, 0x15, 0xe3, 0x56, 0xf2, 0x94, 0x93, 0xdf,
0x98, 0x87, 0x2a, 0x76, 0x6d, 0x46, 0x5a, 0xb5,
0xec, 0x11, 0x24, 0x8c, 0x0e, 0xfd, 0xd8, 0xee,
0x4b, 0x2d, 0x9c, 0xc2, 0x83, 0x51, 0x68, 0xa2,
0xaf, 0x71, 0x40, 0x86, 0xd3, 0x89, 0x20, 0x72,
0xf3, 0x9d, 0x04, 0x5f, 0x0b, 0xad, 0xd9, 0x49,
0x1b, 0x9b, 0x11, 0x99, 0xe2, 0x63, 0x1c, 0xa1,
0xe7, 0x5c, 0x32, 0xa7, 0x55, 0x42, 0xab, 0xf7,
0x4e, 0x22, 0xd7, 0x94, 0xa1, 0xee, 0xfa, 0x44,
0x16, 0xff, 0xb4, 0x01, 0x30, 0xfc, 0x7a, 0x1a,
0x2f, 0xa7, 0x21, 0x64, 0x7c, 0x6c, 0x0e, 0x5f,
0xe6, 0x60, 0xa7, 0x7f, 0x62, 0x02, 0x80, 0x05,
0xdf, 0xe9, 0x81, 0x59, 0xfa, 0xa8, 0x25, 0x5f,
0x6b, 0x83, 0x51, 0xf2, 0xc0, 0x44, 0xff, 0x2d,
0x05, 0x4b, 0xee, 0xe0, 0x54, 0x9e, 0xae, 0x86,
0x45, 0xea, 0xf0, 0x74, 0x3e, 0x70, 0x07, 0x7f,
0x88, 0x48, 0x7f, 0x88, 0x88, 0x7b, 0x78, 0xc9,
0x77, 0x79, 0x09, 0x54, 0x37, 0xb1, 0x4e, 0x73,
0xc9, 0xb3, 0x69, 0x45, 0x93, 0xa2, 0x8c, 0x3e,
0xe7, 0xfa, 0xd0, 0x75, 0x44, 0xa2, 0xef, 0x37,
0xd0, 0x72, 0xea, 0x42, 0xfb, 0xad, 0xce, 0x6d,
0x72, 0x65, 0x53, 0xe1, 0xa8, 0xe1, 0x8b, 0x89,
0x6b, 0xcc, 0xb4, 0x3e, 0xa1, 0xc6, 0xa6, 0x8c,
0x57, 0x8d, 0x5b, 0xca, 0x52, 0x4f, 0x7e, 0x62,
0x1c, 0xa9, 0xd9, 0xb5, 0x19, 0x6a, 0xd7, 0xb0,
0x44, 0x92, 0x30, 0x3b, 0xf7, 0x63, 0xb9, 0x2c,
0xb6, 0x73, 0x0a, 0x0d, 0x45, 0xa2, 0x8a, 0xbd,
0xc5, 0x02, 0x1b, 0x4e, 0x24, 0x81, 0xcb, 0xce,
0x74, 0x11, 0x7c, 0x2e, 0xb7, 0x65, 0x24, 0x6e,
0x6c, 0x46, 0x67, 0x89, 0x8c, 0x72, 0x87, 0x9d,
0x70, 0xca, 0x9d, 0x55, 0x0a, 0xaf, 0xdd, 0x38,
0x8b, 0x5e, 0x52, 0x87, 0xbb, 0xe9, 0x10, 0x5b,
0xfe, 0xd0, 0x04, 0xc3, 0xf1, 0xe8, 0x68, 0xbe,
0x9c, 0x85, 0x91, 0xf1, 0xb0, 0x39, 0x7f, 0x99,
0x82, 0x9d, 0xfd, 0x88, 0x0a, 0x00, 0x17, 0x7f,
0xa6, 0x05, 0x67, 0xea, 0xa0, 0x95, 0x7d, 0xae,
0x0d, 0x47, 0xcb, 0x01, 0x13, 0xfc, 0xb4, 0x15,
0x2f, 0xbb, 0x81, 0x52, 0x7a, 0xba, 0x19, 0x17,
0xab, 0xc1, 0xd0, 0xf9, 0xc0, 0x1d, 0xfe, 0x21,
0x21, 0xfe, 0x22, 0x21, 0xed, 0xe3, 0x25, 0xdd,
0xe4, 0x25, 0x50, 0xde, 0xc5, 0x39, 0xcf, 0x26,
0xcd, 0xa5, 0x16, 0x4e, 0x8a, 0x30, 0xfb, 0x9f,
0xeb, 0x41, 0xd5, 0x12, 0x8b, 0xbc, 0xdf, 0x41,
0xcb, 0xa9, 0x0b, 0xee, 0xb7, 0x39, 0xb5, 0xc9,
0x95, 0x4f, 0x86, 0xa3, 0x86, 0x2e, 0x25, 0xaf,
0x32, 0xd0, 0xfa, 0x87, 0x1a, 0x9a, 0x31, 0x5e,
0x35, 0x6f, 0x29, 0x49, 0x3d, 0xf9, 0x88, 0x72,
0xa7, 0x66, 0xd4, 0x65, 0xab, 0x5e, 0xc1, 0x12,
0x48, 0xc0, 0xef, 0xdd, 0x8e, 0xe4, 0xb2, 0xd9,
0xcc, 0x28, 0x35, 0x16, 0x8a, 0x2a, 0xf7, 0x14,
0x08, 0x6d, 0x38, 0x92, 0x07, 0x2f, 0x39, 0xd0,
0x45, 0xf0, 0xba, 0xdd, 0x94, 0x91, 0xb9, 0xb1,
0x19, 0x9e, 0x26, 0x31, 0xca, 0x1e, 0x75, 0xc3,
0x2a, 0x75, 0x54, 0x2a, 0xbf, 0x74, 0xe2, 0x2d,
0x79, 0x4a, 0x1e, 0xef, 0xa4, 0x41, 0x6f, 0xfb,
0x40, 0x13, 0x0f, 0xc7, 0xa1, 0xa2, 0xfa, 0x72,
0x16, 0x47, 0xc6, 0xc0, 0xe5, 0xfe, 0x66, 0x0a,
0x77, 0xf6, 0x20, 0x28, 0x00, 0x5d, 0xfe, 0x98,
0x15, 0x9f, 0xaa, 0x82, 0x55, 0xf6, 0xb8, 0x35,
0x1f, 0x2c, 0x04, 0x4f, 0xf2, 0xd0, 0x54, 0xbe,
0xee, 0x05, 0x49, 0xea, 0xe8, 0x64, 0x5e, 0xaf,
0x07, 0x43, 0xe7, 0x00, 0x77, 0xf8, 0x84, 0x87,
0xf8, 0x88, 0x87, 0xb7, 0x8c, 0x97, 0x77, 0x90,
0x95, 0x43, 0x7b, 0x14, 0xe7, 0x3c, 0x9b, 0x36,
0x94, 0x59, 0x3a, 0x28, 0xc3, 0xee, 0x7f, 0xad,
0x07, 0x54, 0x4a, 0x2e, 0xf3, 0x7d, 0x07, 0x2e,
0xa4, 0x2f, 0xba, 0xdc, 0xe6, 0xd7, 0x26, 0x55,
0x3e, 0x1a, 0x8e, 0x18, 0xb8, 0x96, 0xbc, 0xcb,
0x43, 0xea, 0x1c, 0x6a, 0x68, 0xc5, 0x78, 0xd5,
0xbc, 0xa5, 0x24, 0xf7, 0xe6, 0x21, 0xca, 0x9d,
0x9b, 0x51, 0x96, 0xad, 0x7b, 0x04, 0x49, 0x23,
0x03, 0xbf, 0x76, 0x3b, 0x92, 0xcb, 0x67, 0x30,
0xa0, 0xd4, 0x5a, 0x28, 0xab, 0xdc, 0x50, 0x21,
0xb4, 0xe2, 0x48, 0x1c, 0xbc, 0xe7, 0x41, 0x17,
0xc2, 0xeb, 0x76, 0x52, 0x46, 0xe6, 0xc4, 0x66,
0x78, 0x98, 0xc7, 0x28, 0x79, 0xd7, 0x0c, 0xa9,
0xd5, 0x50, 0xaa, 0xfd, 0xd3, 0x88, 0xb5, 0xe5,
0x28, 0x7b, 0xbe, 0x91, 0x05, 0xbf, 0xed, 0x00,
0x4c, 0x3f, 0x1e, 0x86, 0x8b, 0xe9, 0xc8, 0x59,
0x1f, 0x1b, 0x03, 0x97, 0xf9, 0x98, 0x29, 0xdf,
0xd8, 0x80, 0xa0, 0x01, 0x77, 0xfa, 0x60, 0x56,
0x7e, 0xaa, 0x09, 0x57, 0xda, 0xe0, 0xd4, 0x7c,
0xb0, 0x11, 0x3f, 0xcb, 0x41, 0x52, 0xfb, 0xb8,
0x15, 0x27, 0xab, 0xa1, 0x91, 0x7a, 0xbc, 0x1d,
0x0f, 0x9c, 0x01, 0xdf, 0xe2, 0x12, 0x1f, 0xe2,
0x22, 0x1e, 0xde, 0x32, 0x5d, 0xde, 0x42, 0x55,
0x15, 0x8a, 0x9c, 0xf4, 0x9b, 0x33, 0x4a, 0x0c,
0x9d, 0x51, 0x80, 0x7c, 0x04, 0xaa, 0xa9, 0xf3,
0xe7, 0xcf, 0x9f, 0x3e, 0x73, 0x29, 0xf1, 0xfc,
0xbb, 0x0d, 0xf3, 0xe7, 0xd0, 0xdf, 0x3e, 0x7c,
0xf9, 0xf3, 0xea, 0xef, 0x9f, 0x3e, 0x7c, 0xf9,
0xf3, 0xe8, 0x55, 0xdf, 0x3e, 0x7c, 0xf9, 0xf3,
0xe7, 0xcf, 0x9f, 0x3e, 0x7c, 0xf9, 0xf3, 0xf5,
0x35, 0xdf, 0x3e, 0x7c, 0xf9, 0xf3, 0xe7, 0xcf,
0x9f, 0x3e, 0x7c, 0xf9, 0xf3, 0xe7, 0xcf, 0x9f,
0x3e, 0x1c, 0xca, 0x7c, 0x7f, 0x2e, 0xc3, 0x7c,
0xf9, 0xf4, 0x37, 0xcf, 0x9f, 0x3e, 0x7c, 0xfa,
0xbb, 0xe7, 0xcf, 0x9f, 0x3e, 0x7c, 0xfa, 0x15,
0x77, 0xcf, 0x9f, 0x3e, 0x7c, 0xf9, 0xf3, 0xe7,
0xcf, 0x9f, 0x3e, 0x7c, 0xfd, 0x4d, 0x77, 0xcf,
0x9f, 0x3e, 0x7c, 0xf9, 0xf3, 0xe7, 0xcf, 0x9f,
0x3e, 0x7c, 0xf9, 0xf3, 0xe7, 0xcf, 0x87, 0x32,
0x9f, 0x1f, 0xcb, 0xb0, 0xdf, 0x3e, 0x7d, 0x0d,
0xf3, 0xe7, 0xcf, 0x9f, 0x3e, 0xae, 0xf9, 0xf3,
0xe7, 0xcf, 0x9f, 0x3e, 0x85, 0x5d, 0xf3, 0xe7,
0xcf, 0x9f, 0x3e, 0x7c, 0xf9, 0xf3, 0xe7, 0xcf,
0x9f, 0x3f, 0x53, 0x5d, 0xf3, 0xe7, 0xcf, 0x9f,
0x3e, 0x7c, 0xf9, 0xf3, 0xe7, 0xcf, 0x9f, 0x3e,
0x7c, 0xf9, 0xf3, 0xe1, 0xcc, 0xa7, 0xc7, 0xf2,
0xec, 0x37, 0xcf, 0x9f, 0x43, 0x7c, 0xf9, 0xf3,
0xe7, 0xcf, 0xab, 0xbe, 0x7c, 0xf9, 0xf3, 0xe7,
0xcf, 0xa1, 0x57, 0x7c, 0xf9, 0xf3, 0xe7, 0xcf,
0x9f, 0x3e, 0x7c, 0xf9, 0xf3, 0xe7, 0xcf, 0xd4,
0xd7, 0x7c, 0xf9, 0xf3, 0xe7, 0xcf, 0x9f, 0x3e,
0x7c, 0xf9, 0xf3, 0xe7, 0xcf, 0x9f, 0x3e, 0x7c,
0xf8, 0x73, 0x29, 0xf1, 0xfc, 0xbb, 0x0d, 0xf3,
0xe7, 0xd0, 0xdf, 0x3e, 0x7c, 0xf9, 0xf3, 0xea,
0xef, 0x9f, 0x3e, 0x7c, 0xf9, 0xf3, 0xe8, 0x55,
0xdf, 0x3e, 0x7c, 0xf9, 0xf3, 0xe7, 0xcf, 0x9f,
0x3e, 0x7c, 0xf9, 0xf3, 0xf5, 0x35, 0xdf, 0x3e,
0x7c, 0xf9, 0xf3, 0xe7, 0xcf, 0x9f, 0x3e, 0x7c,
0xf9, 0xf3, 0xe7, 0xcf, 0x9f, 0x3e, 0x00, 0x23,
0x28, 0x26, 0x20, 0x4a, 0x5a, 0xc2, 0x2b, 0x5a,
0xea, 0x05, 0x57, 0x88, 0x27, 0x47, 0x80, 0x11,
0x94, 0x13, 0x10, 0x25, 0x2d, 0x61, 0x15, 0xad,
0x75, 0x02, 0xab, 0xc4, 0x13, 0xa0, 0x8c, 0xa0,
0x98, 0x81, 0x29, 0x6b, 0x08, 0xad, 0x6b, 0xa8,
0x15, 0x5e, 0x20, 0x9d, 0x1e, 0x08, 0xca, 0x09,
0x88, 0x12, 0x96, 0xb0, 0x8a, 0xd6, 0xba, 0x81,
0x55, 0xe2, 0x09, 0xd0, 0x02, 0x32, 0x82, 0x62,
0x04, 0xa5, 0xac, 0x22, 0xb5, 0xae, 0xa0, 0x55,
0x78, 0x82, 0x74, 0x6e, 0x04, 0x85, 0x08, 0x81,
0x29, 0x6b, 0x08, 0xad, 0x6b, 0xa8, 0x15, 0x03,
0xe0, 0x00, 0x00, 0x09, 0xcb, 0x70, 0x19, 0xf4,
0xb7, 0x94, 0x97, 0x60, 0x84, 0xbf, 0x04, 0x1e,
0x59, 0x02, 0xbc, 0x6c, 0xe5, 0xb8, 0x0c, 0xfa,
0x5b, 0xca, 0x4b, 0xb0, 0x42, 0x5f, 0x82, 0x0f,
0x2c, 0x81, 0x67, 0x2d, 0xc0, 0x67, 0xd2, 0xde,
0x52, 0x5d, 0x82, 0x12, 0xfc, 0x10, 0x79, 0x64,
0x0a, 0xf2,
},
},
{
Header: rtp.Header{
Version: 2,
Marker: true,
PayloadType: 96,
SequenceNumber: 17646,
SSRC: 0x9dbb7812,
},
Payload: []byte{
0x03, 0x02, 0x72, 0xdc, 0x06, 0x7d, 0x2d, 0xe5,
0x25, 0xd8, 0x21, 0x2f, 0xc1, 0x07, 0x96, 0x40,
0xac, 0x9c, 0xb7, 0x01, 0x9f, 0x4b, 0x79, 0x49,
0x76, 0x08, 0x4b, 0xf0, 0x41, 0xe5, 0x90, 0x2b,
0x7f, 0x3b, 0xee, 0x27, 0xd2, 0xde, 0x52, 0x5d,
0x82, 0x12, 0xfc, 0x10, 0x1f, 0x01, 0x80, 0x0a,
0xae, 0xf9, 0xf0, 0x18, 0x0d, 0x8c, 0x57, 0x91,
0xdb, 0x1d, 0x98, 0x52, 0x45, 0x03, 0xd8, 0x84,
0x9b, 0x0c, 0xf1, 0xac, 0x06, 0xc6, 0x2b, 0xc8,
0xed, 0x8e, 0xcc, 0x29, 0x22, 0x81, 0xec, 0x42,
0x4d, 0x86, 0x60, 0x36, 0x31, 0x5e, 0x47, 0x6c,
0x76, 0x61, 0x49, 0x14, 0x0f, 0x62, 0x12, 0x6c,
0x33, 0xc6, 0x03, 0x63, 0x15, 0xe4, 0x76, 0xc7,
0x66, 0x14, 0x91, 0x40, 0xf6, 0x21, 0x26, 0xc3,
0x31, 0x80, 0xd8, 0xc5, 0x79, 0x1d, 0xb1, 0xd9,
0x85, 0x24, 0x50, 0x3d, 0x88, 0x49, 0xb0, 0xcd,
0xc3, 0x07, 0xb2, 0x5e, 0x47, 0x6c, 0x76, 0x61,
0x49, 0x14, 0x0f, 0x60, 0x7c, 0x04, 0x00, 0x29,
0xf3, 0xe7, 0xcf, 0x9f, 0x3e, 0x07, 0xae, 0xa1,
0x8f, 0xa9, 0x09, 0x79, 0xfa, 0x0f, 0x6a, 0xcf,
0xf1, 0xdd, 0xff, 0xad, 0x1e, 0x03, 0xd7, 0x50,
0xc7, 0xd4, 0x84, 0xbc, 0xfd, 0x07, 0xb5, 0x67,
0xf8, 0xee, 0xff, 0xd6, 0x9e, 0xba, 0x86, 0x3e,
0xa4, 0x25, 0xe7, 0xe8, 0x3d, 0xab, 0x3f, 0xc7,
0x77, 0xfe, 0xb4, 0x79, 0xeb, 0xa8, 0x63, 0xea,
0x42, 0x5e, 0x7e, 0x83, 0xda, 0xb3, 0xfc, 0x77,
0x7f, 0xeb, 0x40, 0x7a, 0xea, 0x18, 0xfa, 0x90,
0x97, 0x9f, 0xa0, 0xf6, 0xac, 0xff, 0x1d, 0xdf,
0xfa, 0xd1, 0xbf, 0xf6, 0x14, 0x5e, 0xa4, 0x25,
0xe7, 0xe8, 0x3d, 0xab, 0x3f, 0xc6, 0x0f, 0x80,
0x00, 0x00, 0x2a, 0xec, 0xb0, 0xeb, 0x89, 0xce,
0x62, 0x9e, 0x03, 0x0d, 0xfc, 0xac, 0xb2, 0xe8,
0x90, 0xf1, 0xb5, 0x76, 0x58, 0x75, 0xc4, 0xe7,
0x31, 0x4f, 0x01, 0x86, 0xfe, 0x56, 0x59, 0x74,
0x48, 0xab, 0xb2, 0xc3, 0xae, 0x27, 0x39, 0x8a,
0x78, 0x0c, 0x37, 0xf2, 0xb2, 0xcb, 0xa2, 0x43,
0xca, 0xbb, 0x2c, 0x3a, 0xe2, 0x73, 0x98, 0xa7,
0x80, 0xc3, 0x7f, 0x2b, 0x2c, 0xba, 0x24, 0x32,
0xae, 0xcb, 0x0e, 0xb8, 0x9c, 0xe6, 0x29, 0xe0,
0x30, 0xdf, 0xca, 0xcb, 0x2e, 0x89, 0x0d, 0xfd,
0x67, 0x96, 0xae, 0x27, 0x39, 0x8a, 0x78, 0x0c,
0x37, 0xf2, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00,
0xe4, 0xa2,
},
},
},
},
}
func TestEncode(t *testing.T) {
for _, ca := range cases {
t.Run(ca.name, func(t *testing.T) {
e := &Encoder{
PayloadType: 96,
SSRC: uint32Ptr(0x9dbb7812),
InitialSequenceNumber: uint16Ptr(0x44ed),
}
err := e.Init()
require.NoError(t, err)
pkts, err := e.Encode(ca.frames)
require.NoError(t, err)
require.Equal(t, ca.pkts, pkts)
})
}
}
func TestEncodeRandomInitialState(t *testing.T) {
e := &Encoder{
PayloadType: 96,
}
err := e.Init()
require.NoError(t, err)
require.NotEqual(t, nil, e.SSRC)
require.NotEqual(t, nil, e.InitialSequenceNumber)
}

View File

@@ -0,0 +1,2 @@
// Package rtpac3 contains a RTP/AC-3 decoder and encoder.
package rtpac3

View File

@@ -0,0 +1,5 @@
go test fuzz v1
[]byte("0")
bool(false)
[]byte("\x000\vw00A")
bool(false)

View File

@@ -0,0 +1,5 @@
go test fuzz v1
[]byte("\x010\vw00A")
bool(false)
[]byte("\x030")
bool(true)

View File

@@ -0,0 +1,5 @@
go test fuzz v1
[]byte("\x030")
bool(true)
[]byte("")
bool(false)

View File

@@ -0,0 +1,5 @@
go test fuzz v1
[]byte("\x000")
bool(false)
[]byte("\x030")
bool(false)

View File

@@ -0,0 +1,5 @@
go test fuzz v1
[]byte("0")
bool(true)
[]byte("\x010")
bool(false)

View File

@@ -0,0 +1,5 @@
go test fuzz v1
[]byte("")
bool(true)
[]byte("")
bool(false)

View File

@@ -0,0 +1,5 @@
go test fuzz v1
[]byte("\x010\vw00A0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")
bool(false)
[]byte("\x030")
bool(false)

View File

@@ -0,0 +1,5 @@
go test fuzz v1
[]byte("")
bool(true)
[]byte("00")
bool(false)

View File

@@ -24,19 +24,19 @@ func randUint32() (uint32, error) {
}
func lenAggregated(nalus [][]byte, addNALU []byte) int {
ret := 1 // header
n := 1 // header
for _, nalu := range nalus {
ret += 2 // size
ret += len(nalu) // nalu
n += 2 // size
n += len(nalu) // nalu
}
if addNALU != nil {
ret += 2 // size
ret += len(addNALU) // nalu
n += 2 // size
n += len(addNALU) // nalu
}
return ret
return n
}
func packetCount(avail, le int) int {
@@ -99,13 +99,13 @@ func (e *Encoder) Init() error {
return nil
}
// Encode encodes NALUs into RTP/H264 packets.
func (e *Encoder) Encode(nalus [][]byte) ([]*rtp.Packet, error) {
// Encode encodes an access unit into RTP/H264 packets.
func (e *Encoder) Encode(au [][]byte) ([]*rtp.Packet, error) {
var rets []*rtp.Packet
var batch [][]byte
// split NALUs into batches
for _, nalu := range nalus {
for _, nalu := range au {
if lenAggregated(batch, nalu) <= e.PayloadMaxSize {
// add to existing batch
batch = append(batch, nalu)

View File

@@ -82,13 +82,13 @@ func (e *Encoder) Init() error {
return nil
}
// Encode encodes NALUs into RTP/H265 packets.
func (e *Encoder) Encode(nalus [][]byte) ([]*rtp.Packet, error) {
// Encode encodes an access unit into RTP/H265 packets.
func (e *Encoder) Encode(au [][]byte) ([]*rtp.Packet, error) {
var rets []*rtp.Packet
var batch [][]byte
// split NALUs into batches
for _, nalu := range nalus {
for _, nalu := range au {
if e.lenAggregationUnit(batch, nalu) <= e.PayloadMaxSize {
// add to existing batch
batch = append(batch, nalu)

View File

@@ -22,11 +22,11 @@ func randUint32() (uint32, error) {
}
func lenAggregated(frames [][]byte, frame []byte) int {
l := 4 + len(frame)
n := 4 + len(frame)
for _, fr := range frames {
l += len(fr)
n += len(fr)
}
return l
return n
}
func packetCount(avail, le int) int {

View File

@@ -22,11 +22,11 @@ func randUint32() (uint32, error) {
}
func lenAggregated(slices [][]byte, slice []byte) int {
l := 4 + len(slice)
n := 4 + len(slice)
for _, fr := range slices {
l += len(fr)
n += len(fr)
}
return l
return n
}
func packetCount(avail, le int) int {

View File

@@ -184,7 +184,7 @@ func (e *Encoder) writeFragmented(au []byte, timestamp uint32) ([]*rtp.Packet, e
}
func (e *Encoder) lenAggregated(aus [][]byte, addAU []byte) int {
ret := 2 // AU-headers-length
n := 2 // AU-headers-length
// AU-headers
auHeadersLen := 0
@@ -204,18 +204,18 @@ func (e *Encoder) lenAggregated(aus [][]byte, addAU []byte) int {
auHeadersLen += e.SizeLength + e.IndexDeltaLength
}
}
ret += auHeadersLen / 8
n += auHeadersLen / 8
if (auHeadersLen % 8) != 0 {
ret++
n++
}
// AU
for _, au := range aus {
ret += len(au)
n += len(au)
}
ret += len(addAU)
n += len(addAU)
return ret
return n
}
func (e *Encoder) writeAggregated(aus [][]byte, timestamp uint32) ([]*rtp.Packet, error) {