diff options
Diffstat (limited to 'dom/media/driftcontrol/DriftController.cpp')
-rw-r--r-- | dom/media/driftcontrol/DriftController.cpp | 32 |
1 files changed, 17 insertions, 15 deletions
diff --git a/dom/media/driftcontrol/DriftController.cpp b/dom/media/driftcontrol/DriftController.cpp index b5603f72bb..791bfe9614 100644 --- a/dom/media/driftcontrol/DriftController.cpp +++ b/dom/media/driftcontrol/DriftController.cpp @@ -50,7 +50,7 @@ DriftController::DriftController(uint32_t aSourceRate, uint32_t aTargetRate, mSourceRate(aSourceRate), mTargetRate(aTargetRate), mDesiredBuffering(aDesiredBuffering), - mCorrectedTargetRate(static_cast<float>(aTargetRate)), + mCorrectedSourceRate(static_cast<float>(aSourceRate)), mMeasuredSourceLatency(5), mMeasuredTargetLatency(5) { LOG_CONTROLLER( @@ -76,8 +76,8 @@ void DriftController::ResetAfterUnderrun() { mTargetClock = mAdjustmentInterval; } -uint32_t DriftController::GetCorrectedTargetRate() const { - return std::lround(mCorrectedTargetRate); +uint32_t DriftController::GetCorrectedSourceRate() const { + return std::lround(mCorrectedSourceRate); } void DriftController::UpdateClock(media::TimeUnit aSourceDuration, @@ -112,14 +112,16 @@ void DriftController::CalculateCorrection(uint32_t aBufferedFrames, static constexpr float kDerivativeGain = 0.12; // Maximum 0.1% change per update. - const float cap = static_cast<float>(mTargetRate) / 1000.0f; + const float cap = static_cast<float>(mSourceRate) / 1000.0f; // The integral term can make us grow far outside the cap. Impose a cap on // it individually that is roughly equivalent to the final cap. const float integralCap = cap / kIntegralGain; - int32_t error = CheckedInt32(mDesiredBuffering.ToTicksAtRate(mSourceRate) - - aBufferedFrames) + // Use nominal (not corrected) source rate when interpreting desired + // buffering so that the set point is independent of the control value. + int32_t error = CheckedInt32(aBufferedFrames - + mDesiredBuffering.ToTicksAtRate(mSourceRate)) .value(); int32_t proportional = error; // targetClockSec is the number of target clock seconds since last @@ -135,12 +137,12 @@ void DriftController::CalculateCorrection(uint32_t aBufferedFrames, kIntegralGain * mIntegral + kDerivativeGain * derivative; float correctedRate = - std::clamp(static_cast<float>(mTargetRate) + controlSignal, - mCorrectedTargetRate - cap, mCorrectedTargetRate + cap); + std::clamp(static_cast<float>(mSourceRate) + controlSignal, + mCorrectedSourceRate - cap, mCorrectedSourceRate + cap); // mDesiredBuffering is divided by this to calculate the amount of // hysteresis to apply. With a denominator of 5, an error within +/- 20% of - // the desired buffering will not make corrections to the target sample + // the desired buffering will not make corrections to the source sample // rate. static constexpr uint32_t kHysteresisDenominator = 5; // +/- 20% @@ -183,7 +185,7 @@ void DriftController::CalculateCorrection(uint32_t aBufferedFrames, return correctedRate; } - return mCorrectedTargetRate; + return mCorrectedSourceRate; }(); if (mDurationWithinHysteresis > mIntegralCapTimeLimit) { @@ -201,10 +203,10 @@ void DriftController::CalculateCorrection(uint32_t aBufferedFrames, LOG_CONTROLLER( LogLevel::Verbose, this, "Recalculating Correction: Nominal: %uHz->%uHz, Corrected: " - "%uHz->%.2fHz (diff %.2fHz), error: %.2fms (hysteresisThreshold: " + "%.2fHz->%uHz (diff %.2fHz), error: %.2fms (hysteresisThreshold: " "%.2fms), buffering: %.2fms, desired buffering: %.2fms", - mSourceRate, mTargetRate, mSourceRate, hysteresisCorrectedRate, - hysteresisCorrectedRate - mCorrectedTargetRate, + mSourceRate, mTargetRate, hysteresisCorrectedRate, mTargetRate, + hysteresisCorrectedRate - mCorrectedSourceRate, media::TimeUnit(error, mSourceRate).ToSeconds() * 1000.0, media::TimeUnit(hysteresisThreshold, mSourceRate).ToSeconds() * 1000.0, media::TimeUnit(aBufferedFrames, mSourceRate).ToSeconds() * 1000.0, @@ -219,13 +221,13 @@ void DriftController::CalculateCorrection(uint32_t aBufferedFrames, kProportionalGain * proportional, kIntegralGain * mIntegral, kDerivativeGain * derivative, controlSignal); - if (std::lround(mCorrectedTargetRate) != + if (std::lround(mCorrectedSourceRate) != std::lround(hysteresisCorrectedRate)) { ++mNumCorrectionChanges; } mPreviousError = error; - mCorrectedTargetRate = hysteresisCorrectedRate; + mCorrectedSourceRate = std::max(1.f, hysteresisCorrectedRate); // Reset the counters to prepare for the next period. mTargetClock = media::TimeUnit::Zero(); |