add option to set max size of outgoing UDP packets (#1588) (#1601)

This commit is contained in:
Alessandro Ros 2023-03-31 11:53:49 +02:00 committed by GitHub
parent ebc723d9d4
commit 5b61983fa6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
21 changed files with 144 additions and 82 deletions

View file

@ -8,11 +8,6 @@ import (
"github.com/pion/rtp"
)
const (
// 1500 (UDP MTU) - 20 (IP header) - 8 (UDP header)
maxPacketSize = 1472
)
// UnitGeneric is a generic data unit.
type UnitGeneric struct {
RTPPackets []*rtp.Packet
@ -29,14 +24,22 @@ func (d *UnitGeneric) GetNTP() time.Time {
return d.NTP
}
type formatProcessorGeneric struct{}
type formatProcessorGeneric struct {
udpMaxPayloadSize int
}
func newGeneric(forma format.Format, generateRTPPackets bool) (*formatProcessorGeneric, error) {
func newGeneric(
udpMaxPayloadSize int,
forma format.Format,
generateRTPPackets bool,
) (*formatProcessorGeneric, error) {
if generateRTPPackets {
return nil, fmt.Errorf("we don't know how to generate RTP packets of format %+v", forma)
}
return &formatProcessorGeneric{}, nil
return &formatProcessorGeneric{
udpMaxPayloadSize: udpMaxPayloadSize,
}, nil
}
func (t *formatProcessorGeneric) Process(unit Unit, hasNonRTSPReaders bool) error {
@ -48,9 +51,9 @@ func (t *formatProcessorGeneric) Process(unit Unit, hasNonRTSPReaders bool) erro
pkt.Header.Padding = false
pkt.PaddingSize = 0
if pkt.MarshalSize() > maxPacketSize {
if pkt.MarshalSize() > t.udpMaxPayloadSize {
return fmt.Errorf("payload size (%d) is greater than maximum allowed (%d)",
pkt.MarshalSize(), maxPacketSize)
pkt.MarshalSize(), t.udpMaxPayloadSize)
}
return nil

View file

@ -15,7 +15,7 @@ func TestGenericRemovePadding(t *testing.T) {
}
forma.Init()
p, err := New(forma, false)
p, err := New(1472, forma, false)
require.NoError(t, err)
pkt := &rtp.Packet{

View file

@ -86,18 +86,21 @@ func (d *UnitH264) GetNTP() time.Time {
}
type formatProcessorH264 struct {
format *format.H264
udpMaxPayloadSize int
format *format.H264
encoder *rtph264.Encoder
decoder *rtph264.Decoder
}
func newH264(
udpMaxPayloadSize int,
forma *format.H264,
allocateEncoder bool,
) (*formatProcessorH264, error) {
t := &formatProcessorH264{
format: forma,
udpMaxPayloadSize: udpMaxPayloadSize,
format: forma,
}
if allocateEncoder {
@ -211,11 +214,12 @@ func (t *formatProcessorH264) Process(unit Unit, hasNonRTSPReaders bool) error {
pkt.PaddingSize = 0
// RTP packets exceed maximum size: start re-encoding them
if pkt.MarshalSize() > maxPacketSize {
if pkt.MarshalSize() > t.udpMaxPayloadSize {
v1 := pkt.SSRC
v2 := pkt.SequenceNumber
v3 := pkt.Timestamp
t.encoder = &rtph264.Encoder{
PayloadMaxSize: t.udpMaxPayloadSize - 12,
PayloadType: pkt.PayloadType,
SSRC: &v1,
InitialSequenceNumber: &v2,

View file

@ -16,7 +16,7 @@ func TestH264DynamicParams(t *testing.T) {
PacketizationMode: 1,
}
p, err := New(forma, false)
p, err := New(1472, forma, false)
require.NoError(t, err)
enc := forma.CreateEncoder()
@ -61,7 +61,7 @@ func TestH264OversizedPackets(t *testing.T) {
PacketizationMode: 1,
}
p, err := New(forma, false)
p, err := New(1472, forma, false)
require.NoError(t, err)
var out []*rtp.Packet
@ -158,7 +158,7 @@ func TestH264EmptyPacket(t *testing.T) {
PacketizationMode: 1,
}
p, err := New(forma, true)
p, err := New(1472, forma, true)
require.NoError(t, err)
unit := &UnitH264{

View file

@ -93,18 +93,21 @@ func (d *UnitH265) GetNTP() time.Time {
}
type formatProcessorH265 struct {
format *format.H265
udpMaxPayloadSize int
format *format.H265
encoder *rtph265.Encoder
decoder *rtph265.Decoder
}
func newH265(
udpMaxPayloadSize int,
forma *format.H265,
allocateEncoder bool,
) (*formatProcessorH265, error) {
t := &formatProcessorH265{
format: forma,
udpMaxPayloadSize: udpMaxPayloadSize,
format: forma,
}
if allocateEncoder {
@ -232,11 +235,12 @@ func (t *formatProcessorH265) Process(unit Unit, hasNonRTSPReaders bool) error {
pkt.PaddingSize = 0
// RTP packets exceed maximum size: start re-encoding them
if pkt.MarshalSize() > maxPacketSize {
if pkt.MarshalSize() > t.udpMaxPayloadSize {
v1 := pkt.SSRC
v2 := pkt.SequenceNumber
v3 := pkt.Timestamp
t.encoder = &rtph265.Encoder{
PayloadMaxSize: t.udpMaxPayloadSize - 12,
PayloadType: pkt.PayloadType,
SSRC: &v1,
InitialSequenceNumber: &v2,

View file

@ -15,7 +15,7 @@ func TestH265DynamicParams(t *testing.T) {
PayloadTyp: 96,
}
p, err := New(forma, false)
p, err := New(1472, forma, false)
require.NoError(t, err)
enc := forma.CreateEncoder()
@ -66,7 +66,7 @@ func TestH265OversizedPackets(t *testing.T) {
PPS: []byte{byte(h265.NALUType_PPS_NUT) << 1, 16, 17, 18},
}
p, err := New(forma, false)
p, err := New(1472, forma, false)
require.NoError(t, err)
var out []*rtp.Packet
@ -150,7 +150,7 @@ func TestH265EmptyPacket(t *testing.T) {
PayloadTyp: 96,
}
p, err := New(forma, true)
p, err := New(1472, forma, true)
require.NoError(t, err)
unit := &UnitH265{

View file

@ -28,17 +28,20 @@ func (d *UnitMPEG4Audio) GetNTP() time.Time {
}
type formatProcessorMPEG4Audio struct {
format *format.MPEG4Audio
encoder *rtpmpeg4audio.Encoder
decoder *rtpmpeg4audio.Decoder
udpMaxPayloadSize int
format *format.MPEG4Audio
encoder *rtpmpeg4audio.Encoder
decoder *rtpmpeg4audio.Decoder
}
func newMPEG4Audio(
udpMaxPayloadSize int,
forma *format.MPEG4Audio,
allocateEncoder bool,
) (*formatProcessorMPEG4Audio, error) {
t := &formatProcessorMPEG4Audio{
format: forma,
udpMaxPayloadSize: udpMaxPayloadSize,
format: forma,
}
if allocateEncoder {
@ -58,9 +61,9 @@ func (t *formatProcessorMPEG4Audio) Process(unit Unit, hasNonRTSPReaders bool) e
pkt.Header.Padding = false
pkt.PaddingSize = 0
if pkt.MarshalSize() > maxPacketSize {
if pkt.MarshalSize() > t.udpMaxPayloadSize {
return fmt.Errorf("payload size (%d) is greater than maximum allowed (%d)",
pkt.MarshalSize(), maxPacketSize)
pkt.MarshalSize(), t.udpMaxPayloadSize)
}
// decode from RTP

View file

@ -28,17 +28,20 @@ func (d *UnitOpus) GetNTP() time.Time {
}
type formatProcessorOpus struct {
format *format.Opus
encoder *rtpsimpleaudio.Encoder
decoder *rtpsimpleaudio.Decoder
udpMaxPayloadSize int
format *format.Opus
encoder *rtpsimpleaudio.Encoder
decoder *rtpsimpleaudio.Decoder
}
func newOpus(
udpMaxPayloadSize int,
forma *format.Opus,
allocateEncoder bool,
) (*formatProcessorOpus, error) {
t := &formatProcessorOpus{
format: forma,
udpMaxPayloadSize: udpMaxPayloadSize,
format: forma,
}
if allocateEncoder {
@ -58,9 +61,9 @@ func (t *formatProcessorOpus) Process(unit Unit, hasNonRTSPReaders bool) error {
pkt.Header.Padding = false
pkt.PaddingSize = 0
if pkt.MarshalSize() > maxPacketSize {
if pkt.MarshalSize() > t.udpMaxPayloadSize {
return fmt.Errorf("payload size (%d) is greater than maximum allowed (%d)",
pkt.MarshalSize(), maxPacketSize)
pkt.MarshalSize(), t.udpMaxPayloadSize)
}
// decode from RTP

View file

@ -12,27 +12,31 @@ type Processor interface {
}
// New allocates a Processor.
func New(forma format.Format, generateRTPPackets bool) (Processor, error) {
func New(
udpMaxPayloadSize int,
forma format.Format,
generateRTPPackets bool,
) (Processor, error) {
switch forma := forma.(type) {
case *format.H264:
return newH264(forma, generateRTPPackets)
return newH264(udpMaxPayloadSize, forma, generateRTPPackets)
case *format.H265:
return newH265(forma, generateRTPPackets)
return newH265(udpMaxPayloadSize, forma, generateRTPPackets)
case *format.VP8:
return newVP8(forma, generateRTPPackets)
return newVP8(udpMaxPayloadSize, forma, generateRTPPackets)
case *format.VP9:
return newVP9(forma, generateRTPPackets)
return newVP9(udpMaxPayloadSize, forma, generateRTPPackets)
case *format.MPEG4Audio:
return newMPEG4Audio(forma, generateRTPPackets)
return newMPEG4Audio(udpMaxPayloadSize, forma, generateRTPPackets)
case *format.Opus:
return newOpus(forma, generateRTPPackets)
return newOpus(udpMaxPayloadSize, forma, generateRTPPackets)
default:
return newGeneric(forma, generateRTPPackets)
return newGeneric(udpMaxPayloadSize, forma, generateRTPPackets)
}
}

View file

@ -28,17 +28,20 @@ func (d *UnitVP8) GetNTP() time.Time {
}
type formatProcessorVP8 struct {
format *format.VP8
encoder *rtpvp8.Encoder
decoder *rtpvp8.Decoder
udpMaxPayloadSize int
format *format.VP8
encoder *rtpvp8.Encoder
decoder *rtpvp8.Decoder
}
func newVP8(
udpMaxPayloadSize int,
forma *format.VP8,
allocateEncoder bool,
) (*formatProcessorVP8, error) {
t := &formatProcessorVP8{
format: forma,
udpMaxPayloadSize: udpMaxPayloadSize,
format: forma,
}
if allocateEncoder {
@ -58,9 +61,9 @@ func (t *formatProcessorVP8) Process(unit Unit, hasNonRTSPReaders bool) error {
pkt.Header.Padding = false
pkt.PaddingSize = 0
if pkt.MarshalSize() > maxPacketSize {
if pkt.MarshalSize() > t.udpMaxPayloadSize {
return fmt.Errorf("payload size (%d) is greater than maximum allowed (%d)",
pkt.MarshalSize(), maxPacketSize)
pkt.MarshalSize(), t.udpMaxPayloadSize)
}
// decode from RTP

View file

@ -28,17 +28,20 @@ func (d *UnitVP9) GetNTP() time.Time {
}
type formatProcessorVP9 struct {
format *format.VP9
encoder *rtpvp9.Encoder
decoder *rtpvp9.Decoder
udpMaxPayloadSize int
format *format.VP9
encoder *rtpvp9.Encoder
decoder *rtpvp9.Decoder
}
func newVP9(
udpMaxPayloadSize int,
forma *format.VP9,
allocateEncoder bool,
) (*formatProcessorVP9, error) {
t := &formatProcessorVP9{
format: forma,
udpMaxPayloadSize: udpMaxPayloadSize,
format: forma,
}
if allocateEncoder {
@ -58,9 +61,9 @@ func (t *formatProcessorVP9) Process(unit Unit, hasNonRTSPReaders bool) error {
pkt.Header.Padding = false
pkt.PaddingSize = 0
if pkt.MarshalSize() > maxPacketSize {
if pkt.MarshalSize() > t.udpMaxPayloadSize {
return fmt.Errorf("payload size (%d) is greater than maximum allowed (%d)",
pkt.MarshalSize(), maxPacketSize)
pkt.MarshalSize(), t.udpMaxPayloadSize)
}
// decode from RTP