mirror of
https://github.com/bluenviron/mediamtx.git
synced 2025-12-25 12:32:01 -08:00
parent
ebc723d9d4
commit
5b61983fa6
21 changed files with 144 additions and 82 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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{
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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{
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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{
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue