From db2e9f1f8be2d95f6595b3a7c2b3d484745fcf08 Mon Sep 17 00:00:00 2001 From: Raja Subramanian Date: Thu, 23 Mar 2023 13:16:14 +0530 Subject: [PATCH] Use layer 2 for SVC always. (#1542) This fixes the case of screen share forwarding. We should probably also look at proper AddTrack. The problem was that - AddTrack used two layers for screen share from JS sample app - Track was published with rid = f. Given that and the track info, consistent layer mapping set the layer as 1. - `getBufferLocked` always uses the highest layer for SVC - Between the two, when down track was requesting PLI, there was no buffer at the requested layer and hence no PLI went out. A few other notes - Tried locking SVC to layer 0 (instead of layer 2), but that resulted in PLI layer lock spamming. It did not happen in v1.3.0 of the server though. Not sure what causes that. Need to investigate later. But, that does not happen when using layer 2 buffer as SVC buffer. - When using layer 2 for SVC, the PLI throttle config will be using that of layer 2. Is that okay? - `buffer` structure should maintain more stats about spatial layers for SVC case so that layer stats can be reported to analytics/scoring etc. - In general, `buffer` may need some more hooks to make it SVC aware so that it can handle various spetial layer aware/specific bits. --- pkg/sfu/connectionquality/scorer.go | 5 ++++- pkg/sfu/receiver.go | 7 ++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/pkg/sfu/connectionquality/scorer.go b/pkg/sfu/connectionquality/scorer.go index 7711e89ca..af7861d15 100644 --- a/pkg/sfu/connectionquality/scorer.go +++ b/pkg/sfu/connectionquality/scorer.go @@ -252,13 +252,14 @@ func (q *qualityScorer) Update(stat *windowStat, at time.Time) { return } + plw := q.getPacketLossWeight(stat) reason := "none" var score float64 if stat.packetsExpected == 0 { reason = "dry" score = poorScore } else { - packetScore := stat.calculatePacketScore(q.getPacketLossWeight(stat), q.params.IsDependentRTT, q.params.IsDependentJitter) + packetScore := stat.calculatePacketScore(plw, q.params.IsDependentRTT, q.params.IsDependentJitter) bitrateScore := stat.calculateBitrateScore(expectedBitrate) layerScore := math.Max(math.Min(maxScore, maxScore-(expectedDistance*distanceWeight)), 0.0) @@ -302,6 +303,8 @@ func (q *qualityScorer) Update(stat *windowStat, at time.Time) { "score", score, "quality", scoreToConnectionQuality(score), "stat", stat, + "packetLossWeight", plw, + "maxPPS", q.maxPPS, "expectedBitrate", expectedBitrate, "expectedDistance", expectedDistance, ) diff --git a/pkg/sfu/receiver.go b/pkg/sfu/receiver.go index 05d7303e2..67f00f22c 100644 --- a/pkg/sfu/receiver.go +++ b/pkg/sfu/receiver.go @@ -298,7 +298,12 @@ func (w *WebRTCReceiver) AddUpTrack(track *webrtc.TrackRemote, buff *buffer.Buff } layer := int32(0) - if w.Kind() == webrtc.RTPCodecTypeVideo { + // for svc codecs, use layer full quality instead. + // we only have buffer for full quality + if w.isSVC { + layer = int32(len(w.buffers)) - 1 + } + if w.Kind() == webrtc.RTPCodecTypeVideo && !w.isSVC { layer = buffer.RidToSpatialLayer(track.RID(), w.trackInfo) } buff.SetLogger(w.logger.WithValues("layer", layer))