mirror of
https://github.com/livekit/livekit.git
synced 2026-07-21 11:11:17 +00:00
Tweak adaptation to increase in propagation delay. (#2598)
* Tweak adaptation to increase in propagation delay. A couple of issues - RTCP Sender Reports rate will vary based on underying track bitrate. (at least in theory, not all entities will do it though, for example SFU does standard rate of one per three seconds irrespective of track bit rate). So, adapt the long term estimate of propagation delay delta based on spacing of reports. - Re-init of propagation delay to adapt to path change was taking the last value before the switch. But, that one value could have been an outlier and accepting it is not great. So, adapt spike time propagation delay in a smoother fashion to ensure that all values during spike contribute to the final value. * clean up
This commit is contained in:
@@ -41,6 +41,8 @@ const (
|
||||
cPropagationDelayFallFactor = float64(0.95)
|
||||
cPropagationDelayRiseFactor = float64(0.05)
|
||||
|
||||
cPropagationDelaySpikeAdaptationFactor = float64(0.5)
|
||||
|
||||
// do not adapt to small OR large (outlier) changes
|
||||
cPropagationDelayDeltaThresholdMin = 5 * time.Millisecond
|
||||
cPropagationDelayDeltaThresholdMaxFactor = 2
|
||||
@@ -51,7 +53,7 @@ const (
|
||||
// A long term version of delta of propagation delay is maintained and delta propagation delay exceeding
|
||||
// a factor of the long term version is considered a sharp increase. That will trigger the start of the
|
||||
// path change condition and if it persists, propagation delay will be reset.
|
||||
cPropagationDelayDeltaAdaptationFactor = float64(0.05)
|
||||
cPropagationDelayDeltaMaxInterval = 10 * time.Second
|
||||
cPropagationDelayDeltaHighResetNumReports = 3
|
||||
cPropagationDelayDeltaHighResetWait = 10 * time.Second
|
||||
)
|
||||
@@ -83,6 +85,7 @@ type RTPStatsReceiver struct {
|
||||
longTermDeltaPropagationDelay time.Duration
|
||||
propagationDelayDeltaHighCount int
|
||||
propagationDelayDeltaHighStartTime time.Time
|
||||
propagationDelaySpike time.Duration
|
||||
|
||||
clockSkewCount int
|
||||
outOfOrderSsenderReportCount int
|
||||
@@ -370,11 +373,17 @@ func (r *RTPStatsReceiver) SetRtcpSenderReportData(srData *RTCPSenderReportData)
|
||||
"current", &srDataCopy,
|
||||
}
|
||||
}
|
||||
initPropagationDelay := func(pd time.Duration) {
|
||||
r.propagationDelay = pd
|
||||
r.longTermDeltaPropagationDelay = 0
|
||||
resetDelta := func() {
|
||||
r.propagationDelayDeltaHighCount = 0
|
||||
r.propagationDelayDeltaHighStartTime = time.Time{}
|
||||
r.propagationDelaySpike = 0
|
||||
}
|
||||
initPropagationDelay := func(pd time.Duration) {
|
||||
r.propagationDelay = pd
|
||||
|
||||
r.longTermDeltaPropagationDelay = 0
|
||||
|
||||
resetDelta()
|
||||
}
|
||||
|
||||
ntpTime := srDataCopy.NTPTimestamp.Time()
|
||||
@@ -392,14 +401,18 @@ func (r *RTPStatsReceiver) SetRtcpSenderReportData(srData *RTCPSenderReportData)
|
||||
if r.propagationDelayDeltaHighStartTime.IsZero() {
|
||||
r.propagationDelayDeltaHighStartTime = time.Now()
|
||||
}
|
||||
if r.propagationDelaySpike == 0 {
|
||||
r.propagationDelaySpike = propagationDelay
|
||||
} else {
|
||||
r.propagationDelaySpike += time.Duration(cPropagationDelaySpikeAdaptationFactor * float64(propagationDelay-r.propagationDelaySpike))
|
||||
}
|
||||
|
||||
if r.propagationDelayDeltaHighCount >= cPropagationDelayDeltaHighResetNumReports && time.Since(r.propagationDelayDeltaHighStartTime) >= cPropagationDelayDeltaHighResetWait {
|
||||
r.logger.Debugw("re-initializing propagation delay", append(getPropagationFields(), "newPropagationDelay", propagationDelay.String())...)
|
||||
initPropagationDelay(propagationDelay)
|
||||
initPropagationDelay(r.propagationDelaySpike)
|
||||
}
|
||||
} else {
|
||||
r.propagationDelayDeltaHighCount = 0
|
||||
r.propagationDelayDeltaHighStartTime = time.Time{}
|
||||
resetDelta()
|
||||
|
||||
if deltaPropagationDelay.Abs() > cPropagationDelayDeltaThresholdMin {
|
||||
factor := cPropagationDelayFallFactor
|
||||
@@ -421,7 +434,9 @@ func (r *RTPStatsReceiver) SetRtcpSenderReportData(srData *RTCPSenderReportData)
|
||||
if r.longTermDeltaPropagationDelay == 0 {
|
||||
r.longTermDeltaPropagationDelay = deltaPropagationDelay
|
||||
} else {
|
||||
r.longTermDeltaPropagationDelay += time.Duration(cPropagationDelayDeltaAdaptationFactor * float64(deltaPropagationDelay-r.longTermDeltaPropagationDelay))
|
||||
sinceLastReport := srDataCopy.NTPTimestamp.Time().Sub(r.srNewest.NTPTimestamp.Time())
|
||||
adaptationFactor := min(1.0, float64(sinceLastReport)/float64(cPropagationDelayDeltaMaxInterval))
|
||||
r.longTermDeltaPropagationDelay += time.Duration(adaptationFactor * float64(deltaPropagationDelay-r.longTermDeltaPropagationDelay))
|
||||
}
|
||||
}
|
||||
// adjust receive time to estimated propagation delay
|
||||
|
||||
Reference in New Issue
Block a user