mirror of
https://github.com/livekit/livekit.git
synced 2026-08-02 09:09:57 +00:00
Refactor receiver and buffer into Base and higher layer. (#4185)
* Refactor receiver and buffer into Base and higher layer. To be able to share code/functionality with relay. * WIP * WIP * WIP * WIP * WIP * WIP * WIP * WIP * clean up * deps * fix test * fix test
This commit is contained in:
@@ -23,7 +23,7 @@ require (
|
||||
github.com/jxskiss/base62 v1.1.0
|
||||
github.com/livekit/mageutil v0.0.0-20250511045019-0f1ff63f7731
|
||||
github.com/livekit/mediatransportutil v0.0.0-20251213100503-cc390ae365e9
|
||||
github.com/livekit/protocol v1.43.5-0.20251222031942-17875e94bb49
|
||||
github.com/livekit/protocol v1.43.5-0.20251222225221-fa169ac100d9
|
||||
github.com/livekit/psrpc v0.7.1
|
||||
github.com/mackerelio/go-osstat v0.2.6
|
||||
github.com/magefile/mage v1.15.0
|
||||
@@ -36,9 +36,9 @@ require (
|
||||
github.com/pion/ice/v4 v4.1.0
|
||||
github.com/pion/interceptor v0.1.42
|
||||
github.com/pion/rtcp v1.2.16
|
||||
github.com/pion/rtp v1.8.26
|
||||
github.com/pion/rtp v1.8.27
|
||||
github.com/pion/sctp v1.8.41
|
||||
github.com/pion/sdp/v3 v3.0.16
|
||||
github.com/pion/sdp/v3 v3.0.17
|
||||
github.com/pion/transport/v3 v3.1.1
|
||||
github.com/pion/turn/v4 v4.1.3
|
||||
github.com/pion/webrtc/v4 v4.1.8
|
||||
@@ -55,7 +55,7 @@ require (
|
||||
go.uber.org/atomic v1.11.0
|
||||
go.uber.org/multierr v1.11.0
|
||||
go.uber.org/zap v1.27.1
|
||||
golang.org/x/exp v0.0.0-20251209150349-8475f28825e9
|
||||
golang.org/x/exp v0.0.0-20251219203646-944ab1f22d93
|
||||
golang.org/x/mod v0.31.0
|
||||
golang.org/x/sync v0.19.0
|
||||
google.golang.org/protobuf v1.36.11
|
||||
@@ -145,8 +145,8 @@ require (
|
||||
golang.org/x/sys v0.39.0 // indirect
|
||||
golang.org/x/text v0.32.0 // indirect
|
||||
golang.org/x/tools v0.40.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20251213004720-97cd9d5aeac2 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2 // indirect
|
||||
google.golang.org/grpc v1.77.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20251222181119-0a764e51fe1b // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b // indirect
|
||||
google.golang.org/grpc v1.78.0 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
)
|
||||
|
||||
@@ -173,10 +173,8 @@ github.com/livekit/mageutil v0.0.0-20250511045019-0f1ff63f7731 h1:9x+U2HGLrSw5AT
|
||||
github.com/livekit/mageutil v0.0.0-20250511045019-0f1ff63f7731/go.mod h1:Rs3MhFwutWhGwmY1VQsygw28z5bWcnEYmS1OG9OxjOQ=
|
||||
github.com/livekit/mediatransportutil v0.0.0-20251213100503-cc390ae365e9 h1:ciqzzn+oEex3mCa1n1GmlQrv+ZkGpgUbQPSG3PD0htM=
|
||||
github.com/livekit/mediatransportutil v0.0.0-20251213100503-cc390ae365e9/go.mod h1:mSNtYzSf6iY9xM3UX42VEI+STHvMgHmrYzEHPcdhB8A=
|
||||
github.com/livekit/protocol v1.43.5-0.20251217174542-5c369b107325 h1:oaqg6YhJDFh1JShsEUK7iXlkLFcm6GEiaVhm0JP+Rsg=
|
||||
github.com/livekit/protocol v1.43.5-0.20251217174542-5c369b107325/go.mod h1:n00Ul4P6o2YILGhxw+O57B0h/bF3Je9PzRN36fElCmw=
|
||||
github.com/livekit/protocol v1.43.5-0.20251222031942-17875e94bb49 h1:c2mvLX0IQE7cC/LYYtBeKUrGdHVuXAJMtj4fcjN9vTk=
|
||||
github.com/livekit/protocol v1.43.5-0.20251222031942-17875e94bb49/go.mod h1:n00Ul4P6o2YILGhxw+O57B0h/bF3Je9PzRN36fElCmw=
|
||||
github.com/livekit/protocol v1.43.5-0.20251222225221-fa169ac100d9 h1:SHaCOwMj3MPOeouW+hSIN/UkL6LAqwQOt6WD53NKuEQ=
|
||||
github.com/livekit/protocol v1.43.5-0.20251222225221-fa169ac100d9/go.mod h1:n00Ul4P6o2YILGhxw+O57B0h/bF3Je9PzRN36fElCmw=
|
||||
github.com/livekit/psrpc v0.7.1 h1:ms37az0QTD3UXIWuUC5D/SkmKOlRMVRsI261eBWu/Vw=
|
||||
github.com/livekit/psrpc v0.7.1/go.mod h1:bZ4iHFQptTkbPnB0LasvRNu/OBYXEu1NA6O5BMFo9kk=
|
||||
github.com/mackerelio/go-osstat v0.2.6 h1:gs4U8BZeS1tjrL08tt5VUliVvSWP26Ai2Ob8Lr7f2i0=
|
||||
@@ -256,12 +254,12 @@ github.com/pion/randutil v0.1.0 h1:CFG1UdESneORglEsnimhUjf33Rwjubwj6xfiOXBa3mA=
|
||||
github.com/pion/randutil v0.1.0/go.mod h1:XcJrSMMbbMRhASFVOlj/5hQial/Y8oH/HVo7TBZq+j8=
|
||||
github.com/pion/rtcp v1.2.16 h1:fk1B1dNW4hsI78XUCljZJlC4kZOPk67mNRuQ0fcEkSo=
|
||||
github.com/pion/rtcp v1.2.16/go.mod h1:/as7VKfYbs5NIb4h6muQ35kQF/J0ZVNz2Z3xKoCBYOo=
|
||||
github.com/pion/rtp v1.8.26 h1:VB+ESQFQhBXFytD+Gk8cxB6dXeVf2WQzg4aORvAvAAc=
|
||||
github.com/pion/rtp v1.8.26/go.mod h1:rF5nS1GqbR7H/TCpKwylzeq6yDM+MM6k+On5EgeThEM=
|
||||
github.com/pion/rtp v1.8.27 h1:kbWTdZr62RDlYjatVAW4qFwrAu9XcGnwMsofCfAHlOU=
|
||||
github.com/pion/rtp v1.8.27/go.mod h1:rF5nS1GqbR7H/TCpKwylzeq6yDM+MM6k+On5EgeThEM=
|
||||
github.com/pion/sctp v1.8.41 h1:20R4OHAno4Vky3/iE4xccInAScAa83X6nWUfyc65MIs=
|
||||
github.com/pion/sctp v1.8.41/go.mod h1:2wO6HBycUH7iCssuGyc2e9+0giXVW0pyCv3ZuL8LiyY=
|
||||
github.com/pion/sdp/v3 v3.0.16 h1:0dKzYO6gTAvuLaAKQkC02eCPjMIi4NuAr/ibAwrGDCo=
|
||||
github.com/pion/sdp/v3 v3.0.16/go.mod h1:9tyKzznud3qiweZcD86kS0ff1pGYB3VX+Bcsmkx6IXo=
|
||||
github.com/pion/sdp/v3 v3.0.17 h1:9SfLAW/fF1XC8yRqQ3iWGzxkySxup4k4V7yN8Fs8nuo=
|
||||
github.com/pion/sdp/v3 v3.0.17/go.mod h1:9tyKzznud3qiweZcD86kS0ff1pGYB3VX+Bcsmkx6IXo=
|
||||
github.com/pion/srtp/v3 v3.0.9 h1:lRGF4G61xxj+m/YluB3ZnBpiALSri2lTzba0kGZMrQY=
|
||||
github.com/pion/srtp/v3 v3.0.9/go.mod h1:E+AuWd7Ug2Fp5u38MKnhduvpVkveXJX6J4Lq4rxUYt8=
|
||||
github.com/pion/stun/v3 v3.0.2 h1:BJuGEN2oLrJisiNEJtUTJC4BGbzbfp37LizfqswblFU=
|
||||
@@ -375,8 +373,8 @@ golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1m
|
||||
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||
golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU=
|
||||
golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0=
|
||||
golang.org/x/exp v0.0.0-20251209150349-8475f28825e9 h1:MDfG8Cvcqlt9XXrmEiD4epKn7VJHZO84hejP9Jmp0MM=
|
||||
golang.org/x/exp v0.0.0-20251209150349-8475f28825e9/go.mod h1:EPRbTFwzwjXj9NpYyyrvenVh9Y+GFeEvMNh7Xuz7xgU=
|
||||
golang.org/x/exp v0.0.0-20251219203646-944ab1f22d93 h1:fQsdNF2N+/YewlRZiricy4P1iimyPKZ/xwniHj8Q2a0=
|
||||
golang.org/x/exp v0.0.0-20251219203646-944ab1f22d93/go.mod h1:EPRbTFwzwjXj9NpYyyrvenVh9Y+GFeEvMNh7Xuz7xgU=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
@@ -487,12 +485,12 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
|
||||
gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20251213004720-97cd9d5aeac2 h1:7LRqPCEdE4TP4/9psdaB7F2nhZFfBiGJomA5sojLWdU=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20251213004720-97cd9d5aeac2/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2 h1:2I6GHUeJ/4shcDpoUlLs/2WPnhg7yJwvXtqcMJt9liA=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk=
|
||||
google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM=
|
||||
google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20251222181119-0a764e51fe1b h1:uA40e2M6fYRBf0+8uN5mLlqUtV192iiksiICIBkYJ1E=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20251222181119-0a764e51fe1b/go.mod h1:Xa7le7qx2vmqB/SzWUBa7KdMjpdpAHlh5QCSnjessQk=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b h1:Mv8VFug0MP9e5vUxfBcE3vUkV6CImK3cMNMIDFjmzxU=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ=
|
||||
google.golang.org/grpc v1.78.0 h1:K1XZG/yGDJnzMdd/uZHAkVqJE+xIDOcmdSFZkBUicNc=
|
||||
google.golang.org/grpc v1.78.0/go.mod h1:I47qjTo4OKbMkjA/aOOwxDIiPSBofUtQUI5EfpWvW7U=
|
||||
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
|
||||
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
|
||||
@@ -306,7 +306,12 @@ func (t *MediaTrack) AddReceiver(receiver *webrtc.RTPReceiver, track sfu.TrackRe
|
||||
case *rtcp.SourceDescription:
|
||||
case *rtcp.SenderReport:
|
||||
if pkt.SSRC == uint32(track.SSRC()) {
|
||||
buff.SetSenderReportData(pkt.RTPTime, pkt.NTPTime, pkt.PacketCount, pkt.OctetCount)
|
||||
buff.SetSenderReportData(&livekit.RTCPSenderReportState{
|
||||
RtpTimestamp: pkt.RTPTime,
|
||||
NtpTimestamp: pkt.NTPTime,
|
||||
Packets: pkt.PacketCount,
|
||||
Octets: uint64(pkt.OctetCount),
|
||||
})
|
||||
}
|
||||
case *rtcp.ExtendedReport:
|
||||
rttFromXR:
|
||||
@@ -527,12 +532,12 @@ func (t *MediaTrack) AddReceiver(receiver *webrtc.RTPReceiver, track sfu.TrackRe
|
||||
return newCodec, false
|
||||
}
|
||||
|
||||
var bitrates int
|
||||
var expectedBitrate int
|
||||
layers := buffer.GetVideoLayersForMimeType(mimeType, ti)
|
||||
if layer >= 0 && len(layers) > int(layer) {
|
||||
bitrates = int(layers[layer].GetBitrate())
|
||||
expectedBitrate = int(layers[layer].GetBitrate())
|
||||
}
|
||||
if err := buff.Bind(receiver.GetParameters(), track.Codec().RTPCodecCapability, bitrates); err != nil {
|
||||
if err := buff.Bind(receiver.GetParameters(), track.Codec().RTPCodecCapability, expectedBitrate); err != nil {
|
||||
t.params.Logger.Warnw(
|
||||
"binding buffer failed", err,
|
||||
"rid", track.RID(),
|
||||
|
||||
@@ -396,7 +396,7 @@ func (d *DummyReceiver) GetDownTracks() []sfu.TrackSender {
|
||||
return maps.Values(d.downTracks)
|
||||
}
|
||||
|
||||
func (d *DummyReceiver) DebugInfo() map[string]interface{} {
|
||||
func (d *DummyReceiver) DebugInfo() map[string]any {
|
||||
if receiver := d.getReceiver(); receiver != nil {
|
||||
return receiver.DebugInfo()
|
||||
}
|
||||
|
||||
+97
-1173
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+65
-782
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+59
-29
@@ -42,18 +42,20 @@ func (dt *dummyDowntrack) WriteRTP(p *buffer.ExtPacket, _ int32) int32 {
|
||||
return 1
|
||||
}
|
||||
|
||||
func (dt *dummyDowntrack) TrackInfoAvailable() {}
|
||||
|
||||
func TestRedReceiver(t *testing.T) {
|
||||
dt := &dummyDowntrack{TrackSender: &DownTrack{}}
|
||||
|
||||
t.Run("normal", func(t *testing.T) {
|
||||
w := &WebRTCReceiver{
|
||||
isRED: true,
|
||||
kind: webrtc.RTPCodecTypeAudio,
|
||||
logger: logger.GetLogger(),
|
||||
ReceiverBase: &ReceiverBase{
|
||||
params: ReceiverBaseParams{
|
||||
Kind: webrtc.RTPCodecTypeAudio,
|
||||
Logger: logger.GetLogger(),
|
||||
},
|
||||
isRED: true,
|
||||
},
|
||||
}
|
||||
require.Equal(t, w.GetRedReceiver(), w)
|
||||
require.Equal(t, w.GetRedReceiver(), w.ReceiverBase)
|
||||
w.isRED = false
|
||||
red := w.GetRedReceiver().(*RedReceiver)
|
||||
require.NotNil(t, red)
|
||||
@@ -75,8 +77,12 @@ func TestRedReceiver(t *testing.T) {
|
||||
|
||||
t.Run("packet lost and jump", func(t *testing.T) {
|
||||
w := &WebRTCReceiver{
|
||||
kind: webrtc.RTPCodecTypeAudio,
|
||||
logger: logger.GetLogger(),
|
||||
ReceiverBase: &ReceiverBase{
|
||||
params: ReceiverBaseParams{
|
||||
Kind: webrtc.RTPCodecTypeAudio,
|
||||
Logger: logger.GetLogger(),
|
||||
},
|
||||
},
|
||||
}
|
||||
red := w.GetRedReceiver().(*RedReceiver)
|
||||
require.NoError(t, red.AddDownTrack(dt))
|
||||
@@ -126,8 +132,12 @@ func TestRedReceiver(t *testing.T) {
|
||||
|
||||
t.Run("unorder and repeat", func(t *testing.T) {
|
||||
w := &WebRTCReceiver{
|
||||
kind: webrtc.RTPCodecTypeAudio,
|
||||
logger: logger.GetLogger(),
|
||||
ReceiverBase: &ReceiverBase{
|
||||
params: ReceiverBaseParams{
|
||||
Kind: webrtc.RTPCodecTypeAudio,
|
||||
Logger: logger.GetLogger(),
|
||||
},
|
||||
},
|
||||
}
|
||||
red := w.GetRedReceiver().(*RedReceiver)
|
||||
require.NoError(t, red.AddDownTrack(dt))
|
||||
@@ -158,11 +168,15 @@ func TestRedReceiver(t *testing.T) {
|
||||
|
||||
t.Run("encoding exceed space", func(t *testing.T) {
|
||||
w := &WebRTCReceiver{
|
||||
isRED: true,
|
||||
kind: webrtc.RTPCodecTypeAudio,
|
||||
logger: logger.GetLogger(),
|
||||
ReceiverBase: &ReceiverBase{
|
||||
params: ReceiverBaseParams{
|
||||
Kind: webrtc.RTPCodecTypeAudio,
|
||||
Logger: logger.GetLogger(),
|
||||
},
|
||||
isRED: true,
|
||||
},
|
||||
}
|
||||
require.Equal(t, w.GetRedReceiver(), w)
|
||||
require.Equal(t, w.GetRedReceiver(), w.ReceiverBase)
|
||||
w.isRED = false
|
||||
red := w.GetRedReceiver().(*RedReceiver)
|
||||
require.NotNil(t, red)
|
||||
@@ -183,11 +197,15 @@ func TestRedReceiver(t *testing.T) {
|
||||
|
||||
t.Run("large timestamp gap", func(t *testing.T) {
|
||||
w := &WebRTCReceiver{
|
||||
isRED: true,
|
||||
kind: webrtc.RTPCodecTypeAudio,
|
||||
logger: logger.GetLogger(),
|
||||
ReceiverBase: &ReceiverBase{
|
||||
params: ReceiverBaseParams{
|
||||
Kind: webrtc.RTPCodecTypeAudio,
|
||||
Logger: logger.GetLogger(),
|
||||
},
|
||||
isRED: true,
|
||||
},
|
||||
}
|
||||
require.Equal(t, w.GetRedReceiver(), w)
|
||||
require.Equal(t, w.GetRedReceiver(), w.ReceiverBase)
|
||||
w.isRED = false
|
||||
red := w.GetRedReceiver().(*RedReceiver)
|
||||
require.NotNil(t, red)
|
||||
@@ -283,11 +301,15 @@ func generateRedPkts(t *testing.T, pkts []*rtp.Packet, redCount int) []*rtp.Pack
|
||||
func testRedRedPrimaryReceiver(t *testing.T, maxPktCount, redCount int, sendPktIdx, expectPktIdx []int) {
|
||||
dt := &dummyDowntrack{TrackSender: &DownTrack{}}
|
||||
w := &WebRTCReceiver{
|
||||
kind: webrtc.RTPCodecTypeAudio,
|
||||
logger: logger.GetLogger(),
|
||||
codec: webrtc.RTPCodecParameters{PayloadType: opusREDPT, RTPCodecCapability: webrtc.RTPCodecCapability{MimeType: "audio/red"}},
|
||||
ReceiverBase: &ReceiverBase{
|
||||
params: ReceiverBaseParams{
|
||||
Kind: webrtc.RTPCodecTypeAudio,
|
||||
Logger: logger.GetLogger(),
|
||||
Codec: webrtc.RTPCodecParameters{PayloadType: opusREDPT, RTPCodecCapability: webrtc.RTPCodecCapability{MimeType: "audio/red"}},
|
||||
},
|
||||
},
|
||||
}
|
||||
require.Equal(t, w.GetPrimaryReceiverForRed(), w)
|
||||
require.Equal(t, w.GetPrimaryReceiverForRed(), w.ReceiverBase)
|
||||
w.isRED = true
|
||||
red := w.GetPrimaryReceiverForRed().(*RedPrimaryReceiver)
|
||||
require.NotNil(t, red)
|
||||
@@ -313,10 +335,14 @@ func testRedRedPrimaryReceiver(t *testing.T, maxPktCount, redCount int, sendPktI
|
||||
|
||||
func TestRedPrimaryReceiver(t *testing.T) {
|
||||
w := &WebRTCReceiver{
|
||||
kind: webrtc.RTPCodecTypeAudio,
|
||||
logger: logger.GetLogger(),
|
||||
ReceiverBase: &ReceiverBase{
|
||||
params: ReceiverBaseParams{
|
||||
Kind: webrtc.RTPCodecTypeAudio,
|
||||
Logger: logger.GetLogger(),
|
||||
},
|
||||
},
|
||||
}
|
||||
require.Equal(t, w.GetPrimaryReceiverForRed(), w)
|
||||
require.Equal(t, w.GetPrimaryReceiverForRed(), w.ReceiverBase)
|
||||
w.isRED = true
|
||||
red := w.GetPrimaryReceiverForRed().(*RedPrimaryReceiver)
|
||||
require.NotNil(t, red)
|
||||
@@ -383,11 +409,15 @@ func TestRedPrimaryReceiver(t *testing.T) {
|
||||
t.Run("mixed primary codec", func(t *testing.T) {
|
||||
dt := &dummyDowntrack{TrackSender: &DownTrack{}}
|
||||
w := &WebRTCReceiver{
|
||||
kind: webrtc.RTPCodecTypeAudio,
|
||||
logger: logger.GetLogger(),
|
||||
codec: webrtc.RTPCodecParameters{PayloadType: opusREDPT, RTPCodecCapability: webrtc.RTPCodecCapability{MimeType: "audio/red"}},
|
||||
ReceiverBase: &ReceiverBase{
|
||||
params: ReceiverBaseParams{
|
||||
Kind: webrtc.RTPCodecTypeAudio,
|
||||
Logger: logger.GetLogger(),
|
||||
Codec: webrtc.RTPCodecParameters{PayloadType: opusREDPT, RTPCodecCapability: webrtc.RTPCodecCapability{MimeType: "audio/red"}},
|
||||
},
|
||||
},
|
||||
}
|
||||
require.Equal(t, w.GetPrimaryReceiverForRed(), w)
|
||||
require.Equal(t, w.GetPrimaryReceiverForRed(), w.ReceiverBase)
|
||||
w.isRED = true
|
||||
red := w.GetPrimaryReceiverForRed().(*RedPrimaryReceiver)
|
||||
require.NotNil(t, red)
|
||||
|
||||
@@ -680,7 +680,7 @@ func (r *rtpStatsBase) updateJitter(ets uint64, packetTime int64) float64 {
|
||||
}
|
||||
|
||||
func (r *rtpStatsBase) getAndResetSnapshot(snapshotID uint32, extStartSN uint64, extHighestSN uint64) (*snapshot, *snapshot) {
|
||||
if !r.initialized {
|
||||
if !r.initialized || snapshotID < cFirstSnapshotID {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -751,6 +751,10 @@ func (r *RTPStatsReceiver) MarshalLogObject(e zapcore.ObjectEncoder) error {
|
||||
}
|
||||
|
||||
func (r *RTPStatsReceiver) ToProto() *livekit.RTPStats {
|
||||
if r == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
r.lock.RLock()
|
||||
defer r.lock.RUnlock()
|
||||
|
||||
|
||||
@@ -1125,7 +1125,7 @@ func (r *RTPStatsSender) ToProto() *livekit.RTPStats {
|
||||
}
|
||||
|
||||
func (r *RTPStatsSender) getAndResetSenderSnapshotWindow(senderSnapshotID uint32) (*senderSnapshotWindow, *senderSnapshotWindow) {
|
||||
if !r.initialized {
|
||||
if !r.initialized || senderSnapshotID < cFirstSnapshotID {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
@@ -1166,7 +1166,7 @@ func (r *RTPStatsSender) getSenderSnapshotWindow(startTime int64) senderSnapshot
|
||||
}
|
||||
|
||||
func (r *RTPStatsSender) getAndResetSenderSnapshotReceiverView(senderSnapshotID uint32) (*senderSnapshotReceiverView, *senderSnapshotReceiverView) {
|
||||
if !r.initialized || r.lastRRTime == 0 {
|
||||
if !r.initialized || r.lastRRTime == 0 || senderSnapshotID < cFirstSnapshotID {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,17 @@
|
||||
// Copyright 2023 LiveKit, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package sfu
|
||||
|
||||
import "github.com/pion/webrtc/v4"
|
||||
|
||||
Reference in New Issue
Block a user