From a9fe9f331c0d2cb4749d7c426a77a60d68d38493 Mon Sep 17 00:00:00 2001 From: Raja Subramanian Date: Wed, 19 Apr 2023 13:05:43 +0530 Subject: [PATCH] Run quality scorer when there are no streams. (#1633) * Run quality scorer when there are no streams. In the down stream direction, receiver report is used for scoring. If there are no receiver reports, it should go to `dry` state and report poor quality. Update scorer on dry condition only when update score has not happened for longer than some multiple of update interval. Cannot update on every interval when there are no streams as receiver report might be just missed. Waiting for longer to ensure that report is definitely not received. * update last stats time --- pkg/sfu/connectionquality/connectionstats.go | 20 ++++++++++++++++++-- pkg/sfu/connectionquality/scorer.go | 4 ++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/pkg/sfu/connectionquality/connectionstats.go b/pkg/sfu/connectionquality/connectionstats.go index 185acc6e6..fb6caa91f 100644 --- a/pkg/sfu/connectionquality/connectionstats.go +++ b/pkg/sfu/connectionquality/connectionstats.go @@ -15,8 +15,9 @@ import ( ) const ( - UpdateInterval = 5 * time.Second - processThreshold = 0.95 + UpdateInterval = 5 * time.Second + processThreshold = 0.95 + noStatsTooLongMultiplier = 2 ) type ConnectionStatsParams struct { @@ -158,6 +159,17 @@ func (cs *ConnectionStats) updateLastStatsAt(at time.Time) { cs.lastStatsAt = at } +func (cs *ConnectionStats) isTooLongSinceLastStats() bool { + cs.lock.Lock() + defer cs.lock.Unlock() + + interval := cs.params.UpdateInterval + if interval == 0 { + interval = UpdateInterval + } + return !cs.lastStatsAt.IsZero() && time.Since(cs.lastStatsAt) > interval*noStatsTooLongMultiplier +} + func (cs *ConnectionStats) clearInProcess() { cs.lock.Lock() defer cs.lock.Unlock() @@ -177,6 +189,10 @@ func (cs *ConnectionStats) getStat(at time.Time) { streams := cs.params.GetDeltaStats() if len(streams) == 0 { + if cs.isTooLongSinceLastStats() { + cs.updateLastStatsAt(at) + cs.updateScore(streams, at) + } cs.clearInProcess() return } diff --git a/pkg/sfu/connectionquality/scorer.go b/pkg/sfu/connectionquality/scorer.go index af7861d15..e13575a32 100644 --- a/pkg/sfu/connectionquality/scorer.go +++ b/pkg/sfu/connectionquality/scorer.go @@ -363,6 +363,10 @@ func (q *qualityScorer) getPacketLossWeight(stat *windowStat) float64 { q.maxPPS = pps } + if q.maxPPS == 0 { + return q.params.PacketLossWeight + } + return math.Sqrt(pps/q.maxPPS) * q.params.PacketLossWeight }