summaryrefslogtreecommitdiffstats
path: root/dom/media/driftcontrol/DriftController.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'dom/media/driftcontrol/DriftController.cpp')
-rw-r--r--dom/media/driftcontrol/DriftController.cpp32
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();