add option to set max size of outgoing UDP packets (#1588) (#1601)
Some checks failed
apidocs
code
mod-tidy
test32
test64
test_highlevel

This commit is contained in:
Alessandro Ros
2023-03-31 11:53:49 +02:00
committed by GitHub
parent ebc723d9d4
commit 5b61983fa6
21 changed files with 144 additions and 82 deletions

View File

@@ -33,6 +33,8 @@ components:
type: string type: string
readBufferCount: readBufferCount:
type: integer type: integer
udpMaxPayloadSize:
type: integer
externalAuthenticationURL: externalAuthenticationURL:
type: string type: string
api: api:

View File

@@ -175,6 +175,7 @@ type Conf struct {
ReadTimeout StringDuration `json:"readTimeout"` ReadTimeout StringDuration `json:"readTimeout"`
WriteTimeout StringDuration `json:"writeTimeout"` WriteTimeout StringDuration `json:"writeTimeout"`
ReadBufferCount int `json:"readBufferCount"` ReadBufferCount int `json:"readBufferCount"`
UDPMaxPayloadSize int `json:"udpMaxPayloadSize"`
ExternalAuthenticationURL string `json:"externalAuthenticationURL"` ExternalAuthenticationURL string `json:"externalAuthenticationURL"`
API bool `json:"api"` API bool `json:"api"`
APIAddress string `json:"apiAddress"` APIAddress string `json:"apiAddress"`
@@ -285,7 +286,13 @@ func (conf *Conf) CheckAndFillMissing() error {
conf.ReadBufferCount = 512 conf.ReadBufferCount = 512
} }
if (conf.ReadBufferCount & (conf.ReadBufferCount - 1)) != 0 { if (conf.ReadBufferCount & (conf.ReadBufferCount - 1)) != 0 {
return fmt.Errorf("'ReadBufferCount' must be a power of two") return fmt.Errorf("'readBufferCount' must be a power of two")
}
if conf.UDPMaxPayloadSize == 0 {
conf.UDPMaxPayloadSize = 1500
}
if conf.UDPMaxPayloadSize > 1500 {
return fmt.Errorf("'udpMaxPayloadSize' must be less than 1500")
} }
if conf.ExternalAuthenticationURL != "" { if conf.ExternalAuthenticationURL != "" {
if !strings.HasPrefix(conf.ExternalAuthenticationURL, "http://") && if !strings.HasPrefix(conf.ExternalAuthenticationURL, "http://") &&

View File

@@ -244,6 +244,7 @@ func (p *Core) createResources(initial bool) error {
p.conf.ReadTimeout, p.conf.ReadTimeout,
p.conf.WriteTimeout, p.conf.WriteTimeout,
p.conf.ReadBufferCount, p.conf.ReadBufferCount,
p.conf.UDPMaxPayloadSize,
p.conf.Paths, p.conf.Paths,
p.externalCmdPool, p.externalCmdPool,
p.metrics, p.metrics,
@@ -486,6 +487,7 @@ func (p *Core) closeResources(newConf *conf.Conf, calledByAPI bool) {
newConf.ReadTimeout != p.conf.ReadTimeout || newConf.ReadTimeout != p.conf.ReadTimeout ||
newConf.WriteTimeout != p.conf.WriteTimeout || newConf.WriteTimeout != p.conf.WriteTimeout ||
newConf.ReadBufferCount != p.conf.ReadBufferCount || newConf.ReadBufferCount != p.conf.ReadBufferCount ||
newConf.UDPMaxPayloadSize != p.conf.UDPMaxPayloadSize ||
closeMetrics closeMetrics
if !closePathManager && !reflect.DeepEqual(newConf.Paths, p.conf.Paths) { if !closePathManager && !reflect.DeepEqual(newConf.Paths, p.conf.Paths) {
p.pathManager.confReload(newConf.Paths) p.pathManager.confReload(newConf.Paths)

View File

@@ -187,17 +187,18 @@ type pathAPIPathsListSubReq struct {
} }
type path struct { type path struct {
rtspAddress string rtspAddress string
readTimeout conf.StringDuration readTimeout conf.StringDuration
writeTimeout conf.StringDuration writeTimeout conf.StringDuration
readBufferCount int readBufferCount int
confName string udpMaxPayloadSize int
conf *conf.PathConf confName string
name string conf *conf.PathConf
matches []string name string
wg *sync.WaitGroup matches []string
externalCmdPool *externalcmd.Pool wg *sync.WaitGroup
parent pathParent externalCmdPool *externalcmd.Pool
parent pathParent
ctx context.Context ctx context.Context
ctxCancel func() ctxCancel func()
@@ -240,6 +241,7 @@ func newPath(
readTimeout conf.StringDuration, readTimeout conf.StringDuration,
writeTimeout conf.StringDuration, writeTimeout conf.StringDuration,
readBufferCount int, readBufferCount int,
udpMaxPayloadSize int,
confName string, confName string,
cnf *conf.PathConf, cnf *conf.PathConf,
name string, name string,
@@ -255,6 +257,7 @@ func newPath(
readTimeout: readTimeout, readTimeout: readTimeout,
writeTimeout: writeTimeout, writeTimeout: writeTimeout,
readBufferCount: readBufferCount, readBufferCount: readBufferCount,
udpMaxPayloadSize: udpMaxPayloadSize,
confName: confName, confName: confName,
conf: cnf, conf: cnf,
name: name, name: name,
@@ -632,7 +635,12 @@ func (pa *path) onDemandPublisherStop() {
} }
func (pa *path) sourceSetReady(medias media.Medias, allocateEncoder bool) error { func (pa *path) sourceSetReady(medias media.Medias, allocateEncoder bool) error {
stream, err := newStream(medias, allocateEncoder, pa.bytesReceived) stream, err := newStream(
pa.udpMaxPayloadSize,
medias,
allocateEncoder,
pa.bytesReceived,
)
if err != nil { if err != nil {
return err return err
} }

View File

@@ -40,14 +40,15 @@ type pathManagerParent interface {
} }
type pathManager struct { type pathManager struct {
rtspAddress string rtspAddress string
readTimeout conf.StringDuration readTimeout conf.StringDuration
writeTimeout conf.StringDuration writeTimeout conf.StringDuration
readBufferCount int readBufferCount int
pathConfs map[string]*conf.PathConf udpMaxPayloadSize int
externalCmdPool *externalcmd.Pool pathConfs map[string]*conf.PathConf
metrics *metrics externalCmdPool *externalcmd.Pool
parent pathManagerParent metrics *metrics
parent pathManagerParent
ctx context.Context ctx context.Context
ctxCancel func() ctxCancel func()
@@ -74,6 +75,7 @@ func newPathManager(
readTimeout conf.StringDuration, readTimeout conf.StringDuration,
writeTimeout conf.StringDuration, writeTimeout conf.StringDuration,
readBufferCount int, readBufferCount int,
udpMaxPayloadSize int,
pathConfs map[string]*conf.PathConf, pathConfs map[string]*conf.PathConf,
externalCmdPool *externalcmd.Pool, externalCmdPool *externalcmd.Pool,
metrics *metrics, metrics *metrics,
@@ -86,6 +88,7 @@ func newPathManager(
readTimeout: readTimeout, readTimeout: readTimeout,
writeTimeout: writeTimeout, writeTimeout: writeTimeout,
readBufferCount: readBufferCount, readBufferCount: readBufferCount,
udpMaxPayloadSize: udpMaxPayloadSize,
pathConfs: pathConfs, pathConfs: pathConfs,
externalCmdPool: externalCmdPool, externalCmdPool: externalCmdPool,
metrics: metrics, metrics: metrics,
@@ -303,6 +306,7 @@ func (pm *pathManager) createPath(
pm.readTimeout, pm.readTimeout,
pm.writeTimeout, pm.writeTimeout,
pm.readBufferCount, pm.readBufferCount,
pm.udpMaxPayloadSize,
pathConfName, pathConfName,
pathConf, pathConf,
name, name,

View File

@@ -15,6 +15,7 @@ type stream struct {
} }
func newStream( func newStream(
udpMaxPayloadSize int,
medias media.Medias, medias media.Medias,
generateRTPPackets bool, generateRTPPackets bool,
bytesReceived *uint64, bytesReceived *uint64,
@@ -28,7 +29,7 @@ func newStream(
for _, media := range s.rtspStream.Medias() { for _, media := range s.rtspStream.Medias() {
var err error var err error
s.smedias[media], err = newStreamMedia(media, generateRTPPackets) s.smedias[media], err = newStreamMedia(udpMaxPayloadSize, media, generateRTPPackets)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@@ -16,8 +16,12 @@ type streamFormat struct {
nonRTSPReaders map[reader]func(formatprocessor.Unit) nonRTSPReaders map[reader]func(formatprocessor.Unit)
} }
func newStreamFormat(forma format.Format, generateRTPPackets bool) (*streamFormat, error) { func newStreamFormat(
proc, err := formatprocessor.New(forma, generateRTPPackets) udpMaxPayloadSize int,
forma format.Format,
generateRTPPackets bool,
) (*streamFormat, error) {
proc, err := formatprocessor.New(udpMaxPayloadSize, forma, generateRTPPackets)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@@ -9,14 +9,17 @@ type streamMedia struct {
formats map[format.Format]*streamFormat formats map[format.Format]*streamFormat
} }
func newStreamMedia(medi *media.Media, generateRTPPackets bool) (*streamMedia, error) { func newStreamMedia(udpMaxPayloadSize int,
medi *media.Media,
generateRTPPackets bool,
) (*streamMedia, error) {
sm := &streamMedia{ sm := &streamMedia{
formats: make(map[format.Format]*streamFormat), formats: make(map[format.Format]*streamFormat),
} }
for _, forma := range medi.Formats { for _, forma := range medi.Formats {
var err error var err error
sm.formats[forma], err = newStreamFormat(forma, generateRTPPackets) sm.formats[forma], err = newStreamFormat(udpMaxPayloadSize, forma, generateRTPPackets)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@@ -21,6 +21,7 @@ import (
const ( const (
multicastTTL = 16 multicastTTL = 16
udpMTU = 1472
) )
var opusDurations = [32]int{ var opusDurations = [32]int{
@@ -127,7 +128,7 @@ func (s *udpSource) run(ctx context.Context, cnf *conf.PathConf, reloadConf chan
} }
} }
midbuffer := make([]byte, 0, 1472) // UDP MTU midbuffer := make([]byte, 0, udpMTU)
midbufferPos := 0 midbufferPos := 0
readPacket := func(buf []byte) (int, error) { readPacket := func(buf []byte) (int, error) {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -12,27 +12,31 @@ type Processor interface {
} }
// New allocates a Processor. // 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) { switch forma := forma.(type) {
case *format.H264: case *format.H264:
return newH264(forma, generateRTPPackets) return newH264(udpMaxPayloadSize, forma, generateRTPPackets)
case *format.H265: case *format.H265:
return newH265(forma, generateRTPPackets) return newH265(udpMaxPayloadSize, forma, generateRTPPackets)
case *format.VP8: case *format.VP8:
return newVP8(forma, generateRTPPackets) return newVP8(udpMaxPayloadSize, forma, generateRTPPackets)
case *format.VP9: case *format.VP9:
return newVP9(forma, generateRTPPackets) return newVP9(udpMaxPayloadSize, forma, generateRTPPackets)
case *format.MPEG4Audio: case *format.MPEG4Audio:
return newMPEG4Audio(forma, generateRTPPackets) return newMPEG4Audio(udpMaxPayloadSize, forma, generateRTPPackets)
case *format.Opus: case *format.Opus:
return newOpus(forma, generateRTPPackets) return newOpus(udpMaxPayloadSize, forma, generateRTPPackets)
default: 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 { type formatProcessorVP8 struct {
format *format.VP8 udpMaxPayloadSize int
encoder *rtpvp8.Encoder format *format.VP8
decoder *rtpvp8.Decoder encoder *rtpvp8.Encoder
decoder *rtpvp8.Decoder
} }
func newVP8( func newVP8(
udpMaxPayloadSize int,
forma *format.VP8, forma *format.VP8,
allocateEncoder bool, allocateEncoder bool,
) (*formatProcessorVP8, error) { ) (*formatProcessorVP8, error) {
t := &formatProcessorVP8{ t := &formatProcessorVP8{
format: forma, udpMaxPayloadSize: udpMaxPayloadSize,
format: forma,
} }
if allocateEncoder { if allocateEncoder {
@@ -58,9 +61,9 @@ func (t *formatProcessorVP8) Process(unit Unit, hasNonRTSPReaders bool) error {
pkt.Header.Padding = false pkt.Header.Padding = false
pkt.PaddingSize = 0 pkt.PaddingSize = 0
if pkt.MarshalSize() > maxPacketSize { if pkt.MarshalSize() > t.udpMaxPayloadSize {
return fmt.Errorf("payload size (%d) is greater than maximum allowed (%d)", return fmt.Errorf("payload size (%d) is greater than maximum allowed (%d)",
pkt.MarshalSize(), maxPacketSize) pkt.MarshalSize(), t.udpMaxPayloadSize)
} }
// decode from RTP // decode from RTP

View File

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

View File

@@ -16,6 +16,9 @@ writeTimeout: 10s
# Number of read buffers. # Number of read buffers.
# A higher value allows a wider throughput, a lower value allows to save RAM. # A higher value allows a wider throughput, a lower value allows to save RAM.
readBufferCount: 512 readBufferCount: 512
# Maximum size of payload of outgoing UDP packets.
# This can be decreased to avoid fragmentation on networks with a low UDP MTU.
udpMaxPayloadSize: 1472
# HTTP URL to perform external authentication. # HTTP URL to perform external authentication.
# Every time a user wants to authenticate, the server calls this URL # Every time a user wants to authenticate, the server calls this URL