Rewrite repack G711 func (for RTSP backchannel)

This commit is contained in:
Alexey Khit
2023-07-04 12:06:11 +03:00
parent 6c2f883f9e
commit c2a398211c
3 changed files with 54 additions and 46 deletions
-44
View File
@@ -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)
}
}
+52
View File
@@ -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)
}
}
+2 -2
View File
@@ -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)