From c2a398211c054b6e9a296df4c580b8a40399886e Mon Sep 17 00:00:00 2001 From: Alexey Khit Date: Tue, 4 Jul 2023 12:06:11 +0300 Subject: [PATCH] Rewrite repack G711 func (for RTSP backchannel) --- pkg/pcm/helpers.go | 44 ------------------------------------- pkg/pcm/pcm.go | 52 ++++++++++++++++++++++++++++++++++++++++++++ pkg/rtsp/consumer.go | 4 ++-- 3 files changed, 54 insertions(+), 46 deletions(-) delete mode 100644 pkg/pcm/helpers.go diff --git a/pkg/pcm/helpers.go b/pkg/pcm/helpers.go deleted file mode 100644 index f2e723d5..00000000 --- a/pkg/pcm/helpers.go +++ /dev/null @@ -1,44 +0,0 @@ -package pcm - -import ( - "github.com/AlexxIT/go2rtc/pkg/core" - "github.com/pion/rtp" - "sync" -) - -func RepackBackchannel(handler core.HandlerFunc) core.HandlerFunc { - var buf []byte - var seq uint16 - - // fix https://github.com/AlexxIT/go2rtc/issues/432 - var mu sync.Mutex - - return func(packet *rtp.Packet) { - mu.Lock() - - buf = append(buf, packet.Payload...) - if len(buf) < 1024 { - mu.Unlock() - return - } - - pkt := &rtp.Packet{ - Header: rtp.Header{ - Version: 2, - Marker: true, // should be true - PayloadType: packet.PayloadType, // will be owerwriten - SequenceNumber: seq, - Timestamp: 0, // should be always zero - SSRC: packet.SSRC, - }, - Payload: buf[:1024], - } - - buf = buf[1024:] - seq++ - - mu.Unlock() - - handler(pkt) - } -} diff --git a/pkg/pcm/pcm.go b/pkg/pcm/pcm.go index 717a1450..d2c08717 100644 --- a/pkg/pcm/pcm.go +++ b/pkg/pcm/pcm.go @@ -3,6 +3,7 @@ package pcm import ( "github.com/AlexxIT/go2rtc/pkg/core" "github.com/pion/rtp" + "sync" ) func Resample(codec *core.Codec, sampleRate uint32, handler core.HandlerFunc) core.HandlerFunc { @@ -114,3 +115,54 @@ func DownsamplePCM(fromPCM func(int16) byte, n float32, handler core.HandlerFunc handler(&clone) } } + +// RepackG711 - Repack G.711 PCMA/PCMU into frames of size 1024 +// 1. Fixes WebRTC audio quality issue (monotonic timestamp) +// 2. Fixes Reolink Doorbell backchannel issue (zero timestamp) +// https://github.com/AlexxIT/go2rtc/issues/331 +func RepackG711(zeroTS bool, handler core.HandlerFunc) core.HandlerFunc { + const PacketSize = 1024 + + var buf []byte + var seq uint16 + var ts uint32 + + // fix https://github.com/AlexxIT/go2rtc/issues/432 + var mu sync.Mutex + + return func(packet *rtp.Packet) { + mu.Lock() + + buf = append(buf, packet.Payload...) + if len(buf) < PacketSize { + mu.Unlock() + return + } + + pkt := &rtp.Packet{ + Header: rtp.Header{ + Version: 2, + Marker: true, // should be true + PayloadType: packet.PayloadType, // will be owerwriten + SequenceNumber: seq, + SSRC: packet.SSRC, + }, + Payload: buf[:PacketSize], + } + + seq++ + + // don't know if zero TS important for Reolink Doorbell + // don't have this strange devices for tests + if !zeroTS { + pkt.Timestamp = ts + ts += PacketSize + } + + buf = buf[PacketSize:] + + mu.Unlock() + + handler(pkt) + } +} diff --git a/pkg/rtsp/consumer.go b/pkg/rtsp/consumer.go index 903967c1..a0cc9662 100644 --- a/pkg/rtsp/consumer.go +++ b/pkg/rtsp/consumer.go @@ -62,9 +62,9 @@ func (c *Conn) AddTrack(media *core.Media, codec *core.Codec, track *core.Receiv // important to send original codec for valid IsRTP check sender.Handler = c.packetWriter(track.Codec, channel, codec.PayloadType) - // https://github.com/AlexxIT/go2rtc/issues/331 if c.mode == core.ModeActiveProducer && track.Codec.Name == core.CodecPCMA { - sender.Handler = pcm.RepackBackchannel(sender.Handler) + // Fix Reolink Doorbell https://github.com/AlexxIT/go2rtc/issues/331 + sender.Handler = pcm.RepackG711(true, sender.Handler) } sender.HandleRTP(track)