install go2rtc on bob
This commit is contained in:
@@ -0,0 +1,109 @@
|
||||
package pcm
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/AlexxIT/go2rtc/pkg/core"
|
||||
"github.com/pion/rtp"
|
||||
)
|
||||
|
||||
// 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)
|
||||
}
|
||||
}
|
||||
|
||||
// LittleToBig - convert PCM little endian to PCM big endian
|
||||
func LittleToBig(handler core.HandlerFunc) core.HandlerFunc {
|
||||
return func(packet *rtp.Packet) {
|
||||
clone := *packet
|
||||
clone.Payload = FlipEndian(packet.Payload)
|
||||
handler(&clone)
|
||||
}
|
||||
}
|
||||
|
||||
func TranscodeHandler(dst, src *core.Codec, handler core.HandlerFunc) core.HandlerFunc {
|
||||
var ts uint32
|
||||
k := float32(BytesPerFrame(dst)) / float32(BytesPerFrame(src))
|
||||
f := Transcode(dst, src)
|
||||
|
||||
return func(packet *rtp.Packet) {
|
||||
ts += uint32(k * float32(len(packet.Payload)))
|
||||
|
||||
clone := *packet
|
||||
clone.Payload = f(packet.Payload)
|
||||
clone.Timestamp = ts
|
||||
handler(&clone)
|
||||
}
|
||||
}
|
||||
|
||||
func BytesPerSample(codec *core.Codec) int {
|
||||
switch codec.Name {
|
||||
case core.CodecPCML, core.CodecPCM:
|
||||
return 2
|
||||
case core.CodecPCMU, core.CodecPCMA:
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func BytesPerFrame(codec *core.Codec) int {
|
||||
if codec.Channels <= 1 {
|
||||
return BytesPerSample(codec)
|
||||
}
|
||||
return int(codec.Channels) * BytesPerSample(codec)
|
||||
}
|
||||
|
||||
func FramesPerDuration(codec *core.Codec, duration time.Duration) int {
|
||||
return int(time.Duration(codec.ClockRate) * duration / time.Second)
|
||||
}
|
||||
|
||||
func BytesPerDuration(codec *core.Codec, duration time.Duration) int {
|
||||
return BytesPerFrame(codec) * FramesPerDuration(codec, duration)
|
||||
}
|
||||
Reference in New Issue
Block a user