rtsp: restore support for H264 packetization-mode 0 (#5846) (#5857)

H264 streams with packetization-mode=0 cannot be routed with UDP since
packets are too big. Inbound streams with packetization-mode=0 are
blocked by the server since v1.19.0 but this caused compatibility
issues with some cameras.

The server is now able to receive such streams with TCP, and
automatically remuxes them in streams with packetization-mode=1, which
can be routed freely.
This commit is contained in:
Alessandro Ros
2026-06-10 23:59:40 +02:00
committed by GitHub
parent 5e4fd927bb
commit 3940e68415
5 changed files with 40 additions and 4 deletions
+1 -1
View File
@@ -12,7 +12,7 @@ require (
github.com/asticode/go-astits v1.15.0
github.com/bluenviron/gohlslib/v2 v2.4.0
github.com/bluenviron/gortmplib v0.4.0
github.com/bluenviron/gortsplib/v5 v5.5.5-0.20260610213428-fb7a9dca6ded
github.com/bluenviron/gortsplib/v5 v5.5.5-0.20260610215215-4cff4156075d
github.com/bluenviron/mediacommon/v2 v2.9.0
github.com/datarhei/gosrt v0.11.0
github.com/fsnotify/fsnotify v1.10.1
+2 -2
View File
@@ -39,8 +39,8 @@ github.com/bluenviron/gohlslib/v2 v2.4.0 h1:O0bmUvyOMVPuRx3givLqfGWUzOKicKwkSCIn
github.com/bluenviron/gohlslib/v2 v2.4.0/go.mod h1:iqU6QJ5geVuCDpUeAbK/Si2RtDC3ocBTp8LnPHBkN6U=
github.com/bluenviron/gortmplib v0.4.0 h1:ydwTrOUxFOJkKagzXON2IetEP2yVQwRByzClpapSODc=
github.com/bluenviron/gortmplib v0.4.0/go.mod h1:6AAQoyC8vSHnw02fCW6Kjll93Hk1rEH4+S0uy5NFyDM=
github.com/bluenviron/gortsplib/v5 v5.5.5-0.20260610213428-fb7a9dca6ded h1:RH7gq7G2k4xHpZU9fgBigXvM78NEmE0iJdKDn4wzhCU=
github.com/bluenviron/gortsplib/v5 v5.5.5-0.20260610213428-fb7a9dca6ded/go.mod h1:sT0KqICjZKSpHmx7R3xFRY1tfgP2iMe2bF3i3MxX/jE=
github.com/bluenviron/gortsplib/v5 v5.5.5-0.20260610215215-4cff4156075d h1:fLpgWxE6YC95+7qvuhWYLmz4LjajNFUrhlwuIjEIVDk=
github.com/bluenviron/gortsplib/v5 v5.5.5-0.20260610215215-4cff4156075d/go.mod h1:sT0KqICjZKSpHmx7R3xFRY1tfgP2iMe2bF3i3MxX/jE=
github.com/bluenviron/mediacommon/v2 v2.9.0 h1:8gBeby10B/qD8ctnesKTHx3pgdsxiZcaQZe+RR6Djx4=
github.com/bluenviron/mediacommon/v2 v2.9.0/go.mod h1:syqw4j2RmBCKZgUtGFtB/7gcnh1aaX8I3vd24+bgXWc=
github.com/bytedance/gopkg v0.1.3 h1:TPBSwH8RsouGCBcMBktLt1AymVo2TVsBVCY4b6TnZ/M=
+8
View File
@@ -51,6 +51,7 @@ type streamFormat struct {
parent logger.Writer
outFormat format.Format
forceRemux bool
ptsOffset int64
formatUpdater formatUpdater
unitRemuxer unitRemuxer
@@ -62,6 +63,13 @@ type streamFormat struct {
func (sf *streamFormat) initialize() error {
sf.outFormat = cloneFormatShallow(sf.origFormat)
if forma, ok := sf.outFormat.(*format.H264); ok && forma.PacketizationMode == 0 {
sf.parent.Log(logger.Info, "remuxing in order to change H264 packetization-mode from 0 to 1")
forma.PacketizationMode = 1
sf.forceRemux = true
}
sf.formatUpdater = newFormatUpdater(sf.outFormat)
sf.unitRemuxer = newUnitRemuxer(sf.outFormat)
+26
View File
@@ -1307,3 +1307,29 @@ func TestStreamEncode(t *testing.T) {
})
}
}
func TestStreamUpgradeH264PacketizationMode(t *testing.T) {
forma := &format.H264{
PacketizationMode: 0,
SPS: []byte{0x67, 0x42, 0xc0, 0x28},
PPS: []byte{0x08, 0x06},
}
strm := &Stream{
OrigDesc: &description.Session{Medias: []*description.Media{{Formats: []format.Format{forma}}}},
WriteQueueSize: 512,
RTPMaxPayloadSize: 1450,
Parent: &nilLogger{},
}
err := strm.Initialize()
require.NoError(t, err)
defer strm.Close()
outDesc := strm.OutDescCopy()
require.Equal(t, &format.H264{
PacketizationMode: 1,
SPS: []byte{0x67, 0x42, 0xc0, 0x28},
PPS: []byte{0x08, 0x06},
}, outDesc.Medias[0].Formats[0])
}
+3 -1
View File
@@ -27,7 +27,9 @@ func (ssf *subStreamFormat) initialize() error {
}
}
if ssf.streamFormat.rtpEncoder == nil && (!ssf.useRTPPackets || ssf.streamFormat.alwaysAvailable) {
if ssf.streamFormat.rtpEncoder == nil && (!ssf.useRTPPackets ||
ssf.streamFormat.alwaysAvailable ||
ssf.streamFormat.forceRemux) {
var err error
ssf.streamFormat.rtpEncoder, err = newRTPEncoder(
ssf.streamFormat.outFormat,