Skip to content
This repository was archived by the owner on Jul 9, 2025. It is now read-only.

Commit 84c3cc7

Browse files
committed
Backed out 47 changesets (bug 1656438) for bustages on DynamicResampler.cpp . CLOSED TREE
Backed out changeset dc497e6c016d (bug 1656438) Backed out changeset 780a6b48d876 (bug 1656438) Backed out changeset a9baeaefbb85 (bug 1656438) Backed out changeset 297b4dbd2380 (bug 1656438) Backed out changeset 8c3c64217bf6 (bug 1656438) Backed out changeset d51cd6827d3b (bug 1656438) Backed out changeset 1e48be97c8ad (bug 1656438) Backed out changeset 44d075680b27 (bug 1656438) Backed out changeset 64c35518d82f (bug 1656438) Backed out changeset 159e8137d4ad (bug 1656438) Backed out changeset 0546062cc053 (bug 1656438) Backed out changeset 18079c579276 (bug 1656438) Backed out changeset b6f3e65401b4 (bug 1656438) Backed out changeset cfbc65954235 (bug 1656438) Backed out changeset d35cf2a0b659 (bug 1656438) Backed out changeset 5da08b28c7b5 (bug 1656438) Backed out changeset 8071a5b82a62 (bug 1656438) Backed out changeset 4f2aeff6e0e4 (bug 1656438) Backed out changeset 4bb23c108319 (bug 1656438) Backed out changeset 90c2ec79a8fc (bug 1656438) Backed out changeset ffb479620b65 (bug 1656438) Backed out changeset 9e9f40be7bd7 (bug 1656438) Backed out changeset 664f66d512ff (bug 1656438) Backed out changeset ce3a1f7b1c79 (bug 1656438) Backed out changeset 8e59070e92ea (bug 1656438) Backed out changeset fd84761e9af8 (bug 1656438) Backed out changeset 50ec7aa8a44a (bug 1656438) Backed out changeset 338a090e2657 (bug 1656438) Backed out changeset 1f262745a844 (bug 1656438) Backed out changeset 3b904a06afd1 (bug 1656438) Backed out changeset d5c5afc9239f (bug 1656438) Backed out changeset 9351b87ca40b (bug 1656438) Backed out changeset 2baecf74521e (bug 1656438) Backed out changeset 8571622fc9a0 (bug 1656438) Backed out changeset c4ad7c72bc9c (bug 1656438) Backed out changeset e505d1d051c4 (bug 1656438) Backed out changeset a51bb724a78c (bug 1656438) Backed out changeset 8cacc0e96a3e (bug 1656438) Backed out changeset 58838694eb67 (bug 1656438) Backed out changeset 2baa906a480d (bug 1656438) Backed out changeset 52e1ae3a4fd7 (bug 1656438) Backed out changeset 1da839e0562d (bug 1656438) Backed out changeset 55c9c22b0a13 (bug 1656438) Backed out changeset d116b82ffad9 (bug 1656438) Backed out changeset b640887eca0e (bug 1656438) Backed out changeset 5be36600b092 (bug 1656438) Backed out changeset 7b07bbe610ae (bug 1656438)
1 parent d79006c commit 84c3cc7

27 files changed

Lines changed: 1251 additions & 1853 deletions

dom/media/AudioDriftCorrection.h

Lines changed: 69 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010

1111
namespace mozilla {
1212

13-
extern LazyLogModule gMediaTrackGraphLog;
14-
1513
/**
1614
* ClockDrift calculates the diverge of the source clock from the nominal
1715
* (provided) rate compared to the target clock, which is considered the master
@@ -30,19 +28,23 @@ extern LazyLogModule gMediaTrackGraphLog;
3028
* performance impact.
3129
*
3230
* The pref `media.clock drift.buffering` can be used to configure the desired
33-
* internal buffering. Right now it is at 50ms. But it can be increased if there
31+
* internal buffering. Right now it is at 5ms. But it can be increased if there
3432
* are audio quality problems.
3533
*/
3634
class ClockDrift final {
3735
public:
3836
/**
3937
* Provide the nominal source and the target sample rate.
4038
*/
41-
ClockDrift(uint32_t aSourceRate, uint32_t aTargetRate,
42-
uint32_t aDesiredBuffering)
39+
ClockDrift(int32_t aSourceRate, int32_t aTargetRate)
4340
: mSourceRate(aSourceRate),
4441
mTargetRate(aTargetRate),
45-
mDesiredBuffering(aDesiredBuffering) {}
42+
mDesiredBuffering(5 * mSourceRate / 100) {
43+
if (Preferences::HasUserValue("media.clockdrift.buffering")) {
44+
int msecs = Preferences::GetInt("media.clockdrift.buffering");
45+
mDesiredBuffering = msecs * mSourceRate / 100;
46+
}
47+
}
4648

4749
/**
4850
* The correction in the form of a ratio. A correction of 0.98 means that the
@@ -53,80 +55,81 @@ class ClockDrift final {
5355

5456
/**
5557
* Update the available source frames, target frames, and the current
56-
* buffer, in every iteration. If the conditions are met a new correction is
58+
* buffering, in every iteration. If the condition are met a new correction is
5759
* calculated. A new correction is calculated in the following cases:
58-
* 1. Every mAdjustmentIntervalMs milliseconds (1000ms).
59-
* 2. Every time we run low on buffered frames (less than 20ms).
60+
* 1. Every 100 iterations which mean every 100 calls of this method.
61+
* 2. Every time we run out of buffered frames (less than 2ms).
6062
* In addition to that, the correction is clamped to 10% to avoid sound
6163
* distortion so the result will be in [0.9, 1.1].
6264
*/
63-
void UpdateClock(uint32_t aSourceFrames, uint32_t aTargetFrames,
64-
uint32_t aBufferedFrames, uint32_t aRemainingFrames) {
65-
if (mSourceClock >= mSourceRate / 10 || mTargetClock >= mTargetRate / 10) {
66-
// Only update the correction if 100ms has passed since last update.
67-
if (aBufferedFrames < mDesiredBuffering * 4 / 10 /*40%*/ ||
68-
aRemainingFrames < mDesiredBuffering * 4 / 10 /*40%*/) {
69-
// We are getting close to the lower or upper bound of the internal
70-
// buffer. Steer clear.
71-
CalculateCorrection(0.9, aBufferedFrames, aRemainingFrames);
72-
} else if ((mTargetClock * 1000 / mTargetRate) >= mAdjustmentIntervalMs ||
73-
(mSourceClock * 1000 / mSourceRate) >= mAdjustmentIntervalMs) {
74-
// The adjustment interval has passed on one side. Recalculate.
75-
CalculateCorrection(0.6, aBufferedFrames, aRemainingFrames);
76-
}
65+
void UpdateClock(int aSourceClock, int aTargetClock, int aBufferedFrames) {
66+
if (mIterations == mAdjustementWindow) {
67+
CalculateCorrection(aBufferedFrames);
68+
} else if (aBufferedFrames < 2 * mSourceRate / 100 /*20ms*/) {
69+
BufferedFramesCorrection(aBufferedFrames);
7770
}
78-
mTargetClock += aTargetFrames;
79-
mSourceClock += aSourceFrames;
71+
mTargetClock += aTargetClock;
72+
mSourceClock += aSourceClock;
73+
++mIterations;
8074
}
8175

8276
private:
83-
/**
84-
* aCalculationWeight is a percentage [0, 1] with which the calculated
85-
* correction will be weighted. The existing correction will be weighted with
86-
* 1 - aCalculationWeight. This gives some inertia to the speed at which the
87-
* correction changes, for smoother changes.
88-
*/
89-
void CalculateCorrection(float aCalculationWeight, uint32_t aBufferedFrames,
90-
uint32_t aRemainingFrames) {
91-
// We want to maintain the desired buffer
92-
uint32_t bufferedFramesDiff = aBufferedFrames - mDesiredBuffering;
93-
uint32_t resampledSourceClock =
94-
std::max(1u, mSourceClock + bufferedFramesDiff);
77+
void CalculateCorrection(int aBufferedFrames) {
78+
// We want to maintain 4 ms buffered
79+
int32_t bufferedFramesDiff = aBufferedFrames - mDesiredBuffering;
80+
int32_t resampledSourceClock = mSourceClock + bufferedFramesDiff;
9581
if (mTargetRate != mSourceRate) {
96-
resampledSourceClock *= static_cast<float>(mTargetRate) / mSourceRate;
82+
resampledSourceClock =
83+
resampledSourceClock *
84+
(static_cast<float>(mTargetRate) / static_cast<float>(mSourceRate));
9785
}
86+
mCorrection = (float)mTargetClock / resampledSourceClock;
9887

99-
MOZ_LOG(gMediaTrackGraphLog, LogLevel::Verbose,
100-
("ClockDrift %p Calculated correction %.3f (with weight: %.1f -> "
101-
"%.3f) (buffer: %u, desired: %u, remaining: %u)",
102-
this, static_cast<float>(mTargetClock) / resampledSourceClock,
103-
aCalculationWeight,
104-
(1 - aCalculationWeight) * mCorrection +
105-
aCalculationWeight * mTargetClock / resampledSourceClock,
106-
aBufferedFrames, mDesiredBuffering, aRemainingFrames));
107-
108-
mCorrection = (1 - aCalculationWeight) * mCorrection +
109-
aCalculationWeight * mTargetClock / resampledSourceClock;
110-
111-
// Clamp to range [0.9, 1.1] to avoid distortion
88+
// Clamp to ragnge [0.9, 1.1] to avoid distortion
11289
mCorrection = std::min(std::max(mCorrection, 0.9f), 1.1f);
11390

114-
// Reset the counters to prepare for the next period.
91+
// If previous correction slightly smaller (-1%) ignore it to avoid
92+
// recalculations. Don't do it when is greater (+1%) to avoid risking
93+
// running out of frames.
94+
if (mPreviousCorrection - mCorrection <= 0.01 &&
95+
mPreviousCorrection - mCorrection > 0) {
96+
mCorrection = mPreviousCorrection;
97+
}
98+
mPreviousCorrection = mCorrection;
99+
100+
// Reset the counters to preper for the new period.
101+
mIterations = 0;
115102
mTargetClock = 0;
116103
mSourceClock = 0;
117104
}
118105

119-
public:
120-
const uint32_t mSourceRate;
121-
const uint32_t mTargetRate;
122-
const uint32_t mAdjustmentIntervalMs = 1000;
123-
const uint32_t mDesiredBuffering;
106+
void BufferedFramesCorrection(int aBufferedFrames) {
107+
int32_t bufferedFramesDiff = aBufferedFrames - mDesiredBuffering;
108+
int32_t resampledSourceClock = mSourceRate + bufferedFramesDiff;
109+
if (mTargetRate != mSourceRate) {
110+
resampledSourceClock = resampledSourceClock *
111+
(static_cast<float>(mTargetRate) / mSourceRate);
112+
}
113+
MOZ_ASSERT(mTargetRate > resampledSourceClock);
114+
mPreviousCorrection = mCorrection;
115+
mCorrection +=
116+
static_cast<float>(mTargetRate) / resampledSourceClock - 1.0f;
117+
// Clamp to range [0.9, 1.1] to avoid distortion
118+
mCorrection = std::min(std::max(mCorrection, 0.9f), 1.1f);
119+
}
124120

125121
private:
122+
const int32_t mSourceRate;
123+
const int32_t mTargetRate;
124+
126125
float mCorrection = 1.0;
126+
float mPreviousCorrection = 1.0;
127+
const int32_t mAdjustementWindow = 100;
128+
int32_t mDesiredBuffering; // defult: 5ms
127129

128-
uint32_t mSourceClock = 0;
129-
uint32_t mTargetClock = 0;
130+
int32_t mSourceClock = 0;
131+
int32_t mTargetClock = 0;
132+
int32_t mIterations = 0;
130133
};
131134

132135
/**
@@ -150,13 +153,10 @@ class ClockDrift final {
150153
*/
151154
class AudioDriftCorrection final {
152155
public:
153-
AudioDriftCorrection(uint32_t aSourceRate, uint32_t aTargetRate)
154-
: mDesiredBuffering(
155-
std::max(5, Preferences::GetInt("media.clockdrift.buffering", 50)) *
156-
aSourceRate / 1000),
157-
mTargetRate(aTargetRate),
158-
mClockDrift(aSourceRate, aTargetRate, mDesiredBuffering),
159-
mResampler(aSourceRate, aTargetRate, mDesiredBuffering) {}
156+
AudioDriftCorrection(int32_t aSourceRate, int32_t aTargetRate)
157+
: mClockDrift(aSourceRate, aTargetRate),
158+
mResampler(aSourceRate, aTargetRate, aTargetRate / 20 /*50ms*/),
159+
mTargetRate(aTargetRate) {}
160160

161161
/**
162162
* The source audio frames and request the number of target audio frames must
@@ -168,37 +168,30 @@ class AudioDriftCorrection final {
168168
* AudioSegment will be returned. Not thread-safe.
169169
*/
170170
AudioSegment RequestFrames(const AudioSegment& aInput,
171-
uint32_t aOutputFrames) {
171+
int32_t aOutputFrames) {
172172
// Very important to go first since the Dynamic will get the sample format
173173
// from the chunk.
174174
if (aInput.GetDuration()) {
175175
// Always go through the resampler because the clock might shift later.
176176
mResampler.AppendInput(aInput);
177177
}
178178
mClockDrift.UpdateClock(aInput.GetDuration(), aOutputFrames,
179-
mResampler.InputDuration(),
180-
mResampler.InputRemainingDuration());
179+
mResampler.InputDuration());
181180
TrackRate receivingRate = mTargetRate * mClockDrift.GetCorrection();
182181
// Update resampler's rate if there is a new correction.
183182
mResampler.UpdateOutRate(receivingRate);
184183
// If it does not have enough frames the result will be an empty segment.
185184
AudioSegment output = mResampler.Resample(aOutputFrames);
186185
if (output.IsEmpty()) {
187-
NS_WARNING("Got nothing from the resampler");
188186
output.AppendNullData(aOutputFrames);
189187
}
190188
return output;
191189
}
192190

193-
// Only accessible from the same thread that is driving RequestFrames().
194-
uint32_t CurrentBuffering() const { return mResampler.InputDuration(); }
195-
196-
const uint32_t mDesiredBuffering;
197-
const uint32_t mTargetRate;
198-
199191
private:
200192
ClockDrift mClockDrift;
201193
AudioResampler mResampler;
194+
const int32_t mTargetRate;
202195
};
203196

204197
}; // namespace mozilla

0 commit comments

Comments
 (0)