summaryrefslogtreecommitdiffstats
path: root/dom/media/driftcontrol/gtest
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-12 05:35:29 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-12 05:35:29 +0000
commit59203c63bb777a3bacec32fb8830fba33540e809 (patch)
tree58298e711c0ff0575818c30485b44a2f21bf28a0 /dom/media/driftcontrol/gtest
parentAdding upstream version 126.0.1. (diff)
downloadfirefox-59203c63bb777a3bacec32fb8830fba33540e809.tar.xz
firefox-59203c63bb777a3bacec32fb8830fba33540e809.zip
Adding upstream version 127.0.upstream/127.0
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'dom/media/driftcontrol/gtest')
-rw-r--r--dom/media/driftcontrol/gtest/TestAudioDriftCorrection.cpp60
-rw-r--r--dom/media/driftcontrol/gtest/TestAudioResampler.cpp50
-rw-r--r--dom/media/driftcontrol/gtest/TestDriftController.cpp97
-rw-r--r--dom/media/driftcontrol/gtest/TestDynamicResampler.cpp76
4 files changed, 162 insertions, 121 deletions
diff --git a/dom/media/driftcontrol/gtest/TestAudioDriftCorrection.cpp b/dom/media/driftcontrol/gtest/TestAudioDriftCorrection.cpp
index c13f443d37..9d3f0f091a 100644
--- a/dom/media/driftcontrol/gtest/TestAudioDriftCorrection.cpp
+++ b/dom/media/driftcontrol/gtest/TestAudioDriftCorrection.cpp
@@ -260,10 +260,10 @@ TEST(TestAudioDriftCorrection, LargerTransmitterBlockSizeThanDesiredBuffering)
// Input is stable so no corrections should occur.
EXPECT_EQ(ad.NumCorrectionChanges(), 0U);
- // The drift correction buffer size had to be larger than the desired (the
- // buffer size is twice the initial buffering level), to accomodate the large
- // input block size.
- EXPECT_EQ(ad.BufferSize(), 9600U);
+ // The desired buffering and pre-buffering level was
+ // transmitterBlockSize * 11 / 10 to accomodate the large input block size.
+ // The buffer size was twice the pre-buffering level.
+ EXPECT_EQ(ad.BufferSize(), transmitterBlockSize * 11 / 10 * 2);
}
TEST(TestAudioDriftCorrection, LargerReceiverBlockSizeThanDesiredBuffering)
@@ -275,9 +275,9 @@ TEST(TestAudioDriftCorrection, LargerReceiverBlockSizeThanDesiredBuffering)
MakePrincipalHandle(nsContentUtils::GetSystemPrincipal());
AudioDriftCorrection ad(sampleRate, sampleRate, testPrincipal);
+ AudioSegment inSegment;
for (uint32_t i = 0; i < (sampleRate / 1000) * 500;
i += transmitterBlockSize) {
- AudioSegment inSegment;
AudioChunk chunk =
CreateAudioChunk<float>(transmitterBlockSize, 1, AUDIO_FORMAT_FLOAT32);
inSegment.AppendAndConsumeChunk(std::move(chunk));
@@ -285,6 +285,7 @@ TEST(TestAudioDriftCorrection, LargerReceiverBlockSizeThanDesiredBuffering)
if (i % receiverBlockSize == 0) {
AudioSegment outSegment = ad.RequestFrames(inSegment, receiverBlockSize);
EXPECT_EQ(outSegment.GetDuration(), receiverBlockSize);
+ inSegment.Clear();
}
if (i >= receiverBlockSize) {
@@ -294,11 +295,12 @@ TEST(TestAudioDriftCorrection, LargerReceiverBlockSizeThanDesiredBuffering)
// Input is stable so no corrections should occur.
EXPECT_EQ(ad.NumCorrectionChanges(), 0U);
+ EXPECT_EQ(ad.NumUnderruns(), 0U);
// The drift correction buffer size had to be larger than the desired (the
// buffer size is twice the initial buffering level), to accomodate the large
// input block size that gets buffered in the resampler only when processing
// output.
- EXPECT_EQ(ad.BufferSize(), 19200U);
+ EXPECT_EQ(ad.BufferSize(), 9600U);
}
TEST(TestAudioDriftCorrection, DynamicInputBufferSizeChanges)
@@ -329,9 +331,9 @@ TEST(TestAudioDriftCorrection, DynamicInputBufferSizeChanges)
if (((receivedFramesStart - transmittedFramesStart + i) /
aTransmitterBlockSize) > numBlocksTransmitted) {
tone.Generate(inSegment, aTransmitterBlockSize);
- MOZ_ASSERT(!inSegment.IsNull());
+ MOZ_RELEASE_ASSERT(!inSegment.IsNull());
inToneVerifier.AppendData(inSegment);
- MOZ_ASSERT(!inSegment.IsNull());
+ MOZ_RELEASE_ASSERT(!inSegment.IsNull());
++numBlocksTransmitted;
totalFramesTransmitted += aTransmitterBlockSize;
}
@@ -459,29 +461,50 @@ TEST(TestAudioDriftCorrection, DriftStepResponseUnderrunHighLatencyInput)
constexpr uint32_t iterations = 200;
const PrincipalHandle testPrincipal =
MakePrincipalHandle(nsContentUtils::GetSystemPrincipal());
- uint32_t inputRate = nominalRate * 1005 / 1000; // 0.5% drift
- uint32_t inputInterval = inputRate;
+ uint32_t inputRate1 = nominalRate * 1005 / 1000; // 0.5% drift
+ uint32_t inputInterval1 = inputRate1;
AudioGenerator<AudioDataValue> tone(1, nominalRate, 440);
AudioDriftCorrection ad(nominalRate, nominalRate, testPrincipal);
for (uint32_t i = 0; i < interval * iterations; i += interval / 100) {
AudioSegment inSegment;
if (i > 0 && i % interval == 0) {
- tone.Generate(inSegment, inputInterval);
+ tone.Generate(inSegment, inputInterval1);
}
ad.RequestFrames(inSegment, interval / 100);
}
- inputRate = nominalRate * 995 / 1000; // -0.5% drift
- inputInterval = inputRate;
+ uint32_t inputRate2 = nominalRate * 995 / 1000; // -0.5% drift
+ uint32_t inputInterval2 = inputRate2;
for (uint32_t i = 0; i < interval * iterations; i += interval / 100) {
AudioSegment inSegment;
+ // The first segment is skipped to cause an underrun.
if (i > 0 && i % interval == 0) {
- tone.Generate(inSegment, inputInterval);
+ tone.Generate(inSegment, inputInterval2);
}
ad.RequestFrames(inSegment, interval / 100);
+ if (i >= interval / 10 && i < interval) {
+ // While the DynamicResampler has not set its pre-buffer after the
+ // underrun, InFramesBuffered() reports the pre-buffer size.
+ // The initial desired buffer and pre-buffer size was
+ // inputInterval1 * 11 / 10 to accomodate the large input block size.
+ // This was doubled when the underrun occurred.
+ EXPECT_EQ(ad.CurrentBuffering(), inputInterval1 * 11 / 10 * 2)
+ << "for i=" << i;
+ } else if (i == interval) {
+ // After the pre-buffer was set and used to generate the first output
+ // block, the actual number of frames buffered almost matches the
+ // pre-buffer size, with some rounding from output to input frame count
+ // conversion.
+ EXPECT_EQ(ad.CurrentBuffering(), inputInterval1 * 11 / 10 * 2 - 1)
+ << "after first input after underrun";
+ }
}
- EXPECT_EQ(ad.BufferSize(), 220800U);
+ // The initial desired buffering and pre-buffering level was
+ // inputInterval1 * 11 / 10 to accomodate the large input block size.
+ // The buffer size was initially twice the pre-buffering level, and then
+ // doubled when the underrun occurred.
+ EXPECT_EQ(ad.BufferSize(), inputInterval1 * 11 / 10 * 2 * 2);
EXPECT_EQ(ad.NumUnderruns(), 1u);
}
@@ -511,7 +534,7 @@ TEST(TestAudioDriftCorrection, DriftStepResponseOverrun)
ad.RequestFrames(inSegment, interval / 100);
}
- // Change input callbacks to 2000ms (+0.5% drift) = 48200 frames, which will
+ // Change input callbacks to 1000ms (+0.5% drift) = 48200 frames, which will
// overrun the ring buffer.
for (uint32_t i = 0; i < interval * iterations; i += interval / 100) {
AudioSegment inSegment;
@@ -524,6 +547,9 @@ TEST(TestAudioDriftCorrection, DriftStepResponseOverrun)
ad.RequestFrames(inSegment, interval / 100);
}
- EXPECT_EQ(ad.BufferSize(), 105600U);
+ // The desired buffering and pre-buffering levels were increased to
+ // inputInterval * 11 / 10 to accomodate the large input block size.
+ // The buffer size was increased to twice the pre-buffering level.
+ EXPECT_EQ(ad.BufferSize(), inputInterval * 11 / 10 * 2);
EXPECT_EQ(ad.NumUnderruns(), 1u);
}
diff --git a/dom/media/driftcontrol/gtest/TestAudioResampler.cpp b/dom/media/driftcontrol/gtest/TestAudioResampler.cpp
index f04bc87314..7122b60a1a 100644
--- a/dom/media/driftcontrol/gtest/TestAudioResampler.cpp
+++ b/dom/media/driftcontrol/gtest/TestAudioResampler.cpp
@@ -64,8 +64,7 @@ TEST(TestAudioResampler, OutAudioSegment_Float)
uint32_t pre_buffer = 21;
- AudioResampler dr(in_rate, out_rate, media::TimeUnit(pre_buffer, in_rate),
- testPrincipal);
+ AudioResampler dr(in_rate, out_rate, pre_buffer, testPrincipal);
AudioSegment inSegment =
CreateAudioSegment<float>(in_frames, channels, AUDIO_FORMAT_FLOAT32);
@@ -91,9 +90,9 @@ TEST(TestAudioResampler, OutAudioSegment_Float)
}
}
- // Update out rate
- out_rate = 44100;
- dr.UpdateOutRate(out_rate);
+ // Update in rate
+ in_rate = 26122;
+ dr.UpdateInRate(in_rate);
out_frames = in_frames * out_rate / in_rate;
EXPECT_EQ(out_frames, 18u);
// Even if we provide no input if we have enough buffered input, we can create
@@ -121,8 +120,7 @@ TEST(TestAudioResampler, OutAudioSegment_Short)
uint32_t pre_buffer = 21;
- AudioResampler dr(in_rate, out_rate, media::TimeUnit(pre_buffer, in_rate),
- testPrincipal);
+ AudioResampler dr(in_rate, out_rate, pre_buffer, testPrincipal);
AudioSegment inSegment =
CreateAudioSegment<short>(in_frames, channels, AUDIO_FORMAT_S16);
@@ -148,9 +146,9 @@ TEST(TestAudioResampler, OutAudioSegment_Short)
}
}
- // Update out rate
- out_rate = 44100;
- dr.UpdateOutRate(out_rate);
+ // Update in rate
+ in_rate = 26122;
+ dr.UpdateInRate(out_rate);
out_frames = in_frames * out_rate / in_rate;
EXPECT_EQ(out_frames, 18u);
// Even if we provide no input if we have enough buffered input, we can create
@@ -175,8 +173,7 @@ TEST(TestAudioResampler, OutAudioSegmentLargerThanResampledInput_Float)
uint32_t pre_buffer = 5;
- AudioResampler dr(in_rate, out_rate, media::TimeUnit(pre_buffer, in_rate),
- PRINCIPAL_HANDLE_NONE);
+ AudioResampler dr(in_rate, out_rate, pre_buffer, PRINCIPAL_HANDLE_NONE);
AudioSegment inSegment =
CreateAudioSegment<float>(in_frames, channels, AUDIO_FORMAT_FLOAT32);
@@ -209,8 +206,7 @@ TEST(TestAudioResampler, InAudioSegment_Float)
uint32_t out_rate = 48000;
uint32_t pre_buffer = 10;
- AudioResampler dr(in_rate, out_rate, media::TimeUnit(pre_buffer, in_rate),
- testPrincipal);
+ AudioResampler dr(in_rate, out_rate, pre_buffer, testPrincipal);
AudioSegment inSegment;
@@ -275,8 +271,7 @@ TEST(TestAudioResampler, InAudioSegment_Short)
uint32_t out_rate = 48000;
uint32_t pre_buffer = 10;
- AudioResampler dr(in_rate, out_rate, media::TimeUnit(pre_buffer, in_rate),
- testPrincipal);
+ AudioResampler dr(in_rate, out_rate, pre_buffer, testPrincipal);
AudioSegment inSegment;
@@ -342,8 +337,7 @@ TEST(TestAudioResampler, ChannelChange_MonoToStereo)
uint32_t pre_buffer = 0;
- AudioResampler dr(in_rate, out_rate, media::TimeUnit(pre_buffer, in_rate),
- testPrincipal);
+ AudioResampler dr(in_rate, out_rate, pre_buffer, testPrincipal);
AudioChunk monoChunk =
CreateAudioChunk<float>(in_frames, 1, AUDIO_FORMAT_FLOAT32);
@@ -378,8 +372,7 @@ TEST(TestAudioResampler, ChannelChange_StereoToMono)
uint32_t pre_buffer = 0;
- AudioResampler dr(in_rate, out_rate, media::TimeUnit(pre_buffer, in_rate),
- testPrincipal);
+ AudioResampler dr(in_rate, out_rate, pre_buffer, testPrincipal);
AudioChunk monoChunk =
CreateAudioChunk<float>(in_frames, 1, AUDIO_FORMAT_FLOAT32);
@@ -414,8 +407,7 @@ TEST(TestAudioResampler, ChannelChange_StereoToQuad)
uint32_t pre_buffer = 0;
- AudioResampler dr(in_rate, out_rate, media::TimeUnit(pre_buffer, in_rate),
- testPrincipal);
+ AudioResampler dr(in_rate, out_rate, pre_buffer, testPrincipal);
AudioChunk stereoChunk =
CreateAudioChunk<float>(in_frames, 2, AUDIO_FORMAT_FLOAT32);
@@ -452,7 +444,7 @@ TEST(TestAudioResampler, ChannelChange_QuadToStereo)
uint32_t in_rate = 24000;
uint32_t out_rate = 48000;
- AudioResampler dr(in_rate, out_rate, media::TimeUnit::Zero(), testPrincipal);
+ AudioResampler dr(in_rate, out_rate, 0, testPrincipal);
AudioChunk stereoChunk =
CreateAudioChunk<float>(in_frames, 2, AUDIO_FORMAT_FLOAT32);
@@ -497,7 +489,7 @@ TEST(TestAudioResampler, ChannelChange_Discontinuity)
uint32_t in_frames = in_rate / 100;
uint32_t out_frames = out_rate / 100;
- AudioResampler dr(in_rate, out_rate, media::TimeUnit::Zero(), testPrincipal);
+ AudioResampler dr(in_rate, out_rate, 0, testPrincipal);
AudioChunk monoChunk =
CreateAudioChunk<float>(in_frames, 1, AUDIO_FORMAT_FLOAT32);
@@ -560,8 +552,7 @@ TEST(TestAudioResampler, ChannelChange_Discontinuity2)
uint32_t in_frames = in_rate / 100;
uint32_t out_frames = out_rate / 100;
- AudioResampler dr(in_rate, out_rate, media::TimeUnit(10, in_rate),
- testPrincipal);
+ AudioResampler dr(in_rate, out_rate, 10, testPrincipal);
AudioChunk monoChunk =
CreateAudioChunk<float>(in_frames / 2, 1, AUDIO_FORMAT_FLOAT32);
@@ -630,8 +621,7 @@ TEST(TestAudioResampler, ChannelChange_Discontinuity3)
uint32_t in_frames = in_rate / 100;
uint32_t out_frames = out_rate / 100;
- AudioResampler dr(in_rate, out_rate, media::TimeUnit(10, in_rate),
- testPrincipal);
+ AudioResampler dr(in_rate, out_rate, 10, testPrincipal);
AudioChunk stereoChunk =
CreateAudioChunk<float>(in_frames, 2, AUDIO_FORMAT_FLOAT32);
@@ -660,9 +650,9 @@ TEST(TestAudioResampler, ChannelChange_Discontinuity3)
// The resampler here is updated due to the rate change. This is because the
// in and out rate was the same so a pass through logic was used. By updating
- // the out rate to something different than the in rate, the resampler will
+ // the in rate to something different than the out rate, the resampler will
// start being used and discontinuity will exist.
- dr.UpdateOutRate(out_rate + 400);
+ dr.UpdateInRate(in_rate - 400);
dr.AppendInput(inSegment);
AudioSegment s2 = dr.Resample(out_frames, &hasUnderrun);
EXPECT_FALSE(hasUnderrun);
diff --git a/dom/media/driftcontrol/gtest/TestDriftController.cpp b/dom/media/driftcontrol/gtest/TestDriftController.cpp
index 33486f945f..132577e44a 100644
--- a/dom/media/driftcontrol/gtest/TestDriftController.cpp
+++ b/dom/media/driftcontrol/gtest/TestDriftController.cpp
@@ -18,50 +18,50 @@ TEST(TestDriftController, Basic)
constexpr uint32_t bufferedHigh = 7 * 480;
DriftController c(48000, 48000, media::TimeUnit::FromSeconds(0.05));
- EXPECT_EQ(c.GetCorrectedTargetRate(), 48000U);
+ EXPECT_EQ(c.GetCorrectedSourceRate(), 48000U);
// The adjustment interval is 1s.
const auto oneSec = media::TimeUnit(48000, 48000);
c.UpdateClock(oneSec, oneSec, buffered, 0);
- EXPECT_EQ(c.GetCorrectedTargetRate(), 48000u);
+ EXPECT_EQ(c.GetCorrectedSourceRate(), 48000u);
c.UpdateClock(oneSec, oneSec, bufferedLow, 0);
- EXPECT_EQ(c.GetCorrectedTargetRate(), 48048u);
+ EXPECT_EQ(c.GetCorrectedSourceRate(), 47952u);
c.UpdateClock(oneSec, oneSec, bufferedHigh, 0);
- EXPECT_EQ(c.GetCorrectedTargetRate(), 48000u);
+ EXPECT_EQ(c.GetCorrectedSourceRate(), 48000u);
c.UpdateClock(oneSec, oneSec, bufferedHigh, 0);
- EXPECT_EQ(c.GetCorrectedTargetRate(), 47952u);
+ EXPECT_EQ(c.GetCorrectedSourceRate(), 48048u);
}
TEST(TestDriftController, BasicResampler)
{
// The buffer level is the only input to the controller logic.
- constexpr uint32_t buffered = 5 * 240;
- constexpr uint32_t bufferedLow = 3 * 240;
- constexpr uint32_t bufferedHigh = 7 * 240;
+ constexpr uint32_t buffered = 5 * 480;
+ constexpr uint32_t bufferedLow = 3 * 480;
+ constexpr uint32_t bufferedHigh = 7 * 480;
- DriftController c(24000, 48000, media::TimeUnit::FromSeconds(0.05));
+ DriftController c(48000, 24000, media::TimeUnit::FromSeconds(0.05));
// The adjustment interval is 1s.
const auto oneSec = media::TimeUnit(48000, 48000);
c.UpdateClock(oneSec, oneSec, buffered, 0);
- EXPECT_EQ(c.GetCorrectedTargetRate(), 48000u);
+ EXPECT_EQ(c.GetCorrectedSourceRate(), 48000u);
// low
c.UpdateClock(oneSec, oneSec, bufferedLow, 0);
- EXPECT_EQ(c.GetCorrectedTargetRate(), 48048u);
+ EXPECT_EQ(c.GetCorrectedSourceRate(), 47952u);
// high
c.UpdateClock(oneSec, oneSec, bufferedHigh, 0);
- EXPECT_EQ(c.GetCorrectedTargetRate(), 48000u);
+ EXPECT_EQ(c.GetCorrectedSourceRate(), 48000u);
// high
c.UpdateClock(oneSec, oneSec, bufferedHigh, 0);
- EXPECT_EQ(c.GetCorrectedTargetRate(), 47964u);
+ EXPECT_EQ(c.GetCorrectedSourceRate(), 48048u);
}
TEST(TestDriftController, BufferedInput)
@@ -72,56 +72,56 @@ TEST(TestDriftController, BufferedInput)
constexpr uint32_t bufferedHigh = 7 * 480;
DriftController c(48000, 48000, media::TimeUnit::FromSeconds(0.05));
- EXPECT_EQ(c.GetCorrectedTargetRate(), 48000u);
+ EXPECT_EQ(c.GetCorrectedSourceRate(), 48000u);
// The adjustment interval is 1s.
const auto oneSec = media::TimeUnit(48000, 48000);
c.UpdateClock(oneSec, oneSec, buffered, 0);
- EXPECT_EQ(c.GetCorrectedTargetRate(), 48000u);
+ EXPECT_EQ(c.GetCorrectedSourceRate(), 48000u);
// 0 buffered when updating correction
c.UpdateClock(oneSec, oneSec, 0, 0);
- EXPECT_EQ(c.GetCorrectedTargetRate(), 48048u);
+ EXPECT_EQ(c.GetCorrectedSourceRate(), 47952u);
c.UpdateClock(oneSec, oneSec, bufferedLow, 0);
- EXPECT_EQ(c.GetCorrectedTargetRate(), 48000u);
+ EXPECT_EQ(c.GetCorrectedSourceRate(), 48000u);
c.UpdateClock(oneSec, oneSec, buffered, 0);
- EXPECT_EQ(c.GetCorrectedTargetRate(), 48000u);
+ EXPECT_EQ(c.GetCorrectedSourceRate(), 48000u);
c.UpdateClock(oneSec, oneSec, bufferedHigh, 0);
- EXPECT_EQ(c.GetCorrectedTargetRate(), 47952u);
+ EXPECT_EQ(c.GetCorrectedSourceRate(), 48048u);
}
TEST(TestDriftController, BufferedInputWithResampling)
{
// The buffer level is the only input to the controller logic.
- constexpr uint32_t buffered = 5 * 240;
- constexpr uint32_t bufferedLow = 3 * 240;
- constexpr uint32_t bufferedHigh = 7 * 240;
+ constexpr uint32_t buffered = 5 * 480;
+ constexpr uint32_t bufferedLow = 3 * 480;
+ constexpr uint32_t bufferedHigh = 7 * 480;
- DriftController c(24000, 48000, media::TimeUnit::FromSeconds(0.05));
- EXPECT_EQ(c.GetCorrectedTargetRate(), 48000u);
+ DriftController c(48000, 24000, media::TimeUnit::FromSeconds(0.05));
+ EXPECT_EQ(c.GetCorrectedSourceRate(), 48000u);
// The adjustment interval is 1s.
const auto oneSec = media::TimeUnit(24000, 24000);
c.UpdateClock(oneSec, oneSec, buffered, 0);
- EXPECT_EQ(c.GetCorrectedTargetRate(), 48000u);
+ EXPECT_EQ(c.GetCorrectedSourceRate(), 48000u);
// 0 buffered when updating correction
c.UpdateClock(oneSec, oneSec, 0, 0);
- EXPECT_EQ(c.GetCorrectedTargetRate(), 48048u);
+ EXPECT_EQ(c.GetCorrectedSourceRate(), 47952u);
c.UpdateClock(oneSec, oneSec, bufferedLow, 0);
- EXPECT_EQ(c.GetCorrectedTargetRate(), 48000u);
+ EXPECT_EQ(c.GetCorrectedSourceRate(), 48000u);
c.UpdateClock(oneSec, oneSec, buffered, 0);
- EXPECT_EQ(c.GetCorrectedTargetRate(), 48000u);
+ EXPECT_EQ(c.GetCorrectedSourceRate(), 48000u);
c.UpdateClock(oneSec, oneSec, bufferedHigh, 0);
- EXPECT_EQ(c.GetCorrectedTargetRate(), 47952u);
+ EXPECT_EQ(c.GetCorrectedSourceRate(), 48048u);
}
TEST(TestDriftController, SmallError)
@@ -132,21 +132,21 @@ TEST(TestDriftController, SmallError)
constexpr uint32_t bufferedHigh = buffered + 48;
DriftController c(48000, 48000, media::TimeUnit::FromSeconds(0.05));
- EXPECT_EQ(c.GetCorrectedTargetRate(), 48000u);
+ EXPECT_EQ(c.GetCorrectedSourceRate(), 48000u);
// The adjustment interval is 1s.
const auto oneSec = media::TimeUnit(48000, 48000);
c.UpdateClock(oneSec, oneSec, buffered, 0);
- EXPECT_EQ(c.GetCorrectedTargetRate(), 48000u);
+ EXPECT_EQ(c.GetCorrectedSourceRate(), 48000u);
c.UpdateClock(oneSec, oneSec, bufferedLow, 0);
- EXPECT_EQ(c.GetCorrectedTargetRate(), 48000u);
+ EXPECT_EQ(c.GetCorrectedSourceRate(), 48000u);
c.UpdateClock(oneSec, oneSec, bufferedHigh, 0);
- EXPECT_EQ(c.GetCorrectedTargetRate(), 48000u);
+ EXPECT_EQ(c.GetCorrectedSourceRate(), 48000u);
c.UpdateClock(oneSec, oneSec, bufferedHigh, 0);
- EXPECT_EQ(c.GetCorrectedTargetRate(), 48000u);
+ EXPECT_EQ(c.GetCorrectedSourceRate(), 48000u);
}
TEST(TestDriftController, SmallBufferedFrames)
@@ -158,11 +158,34 @@ TEST(TestDriftController, SmallBufferedFrames)
media::TimeUnit oneSec = media::TimeUnit::FromSeconds(1);
media::TimeUnit hundredMillis = oneSec / 10;
- EXPECT_EQ(c.GetCorrectedTargetRate(), 48000U);
+ EXPECT_EQ(c.GetCorrectedSourceRate(), 48000U);
for (uint32_t i = 0; i < 9; ++i) {
c.UpdateClock(hundredMillis, hundredMillis, bufferedLow, 0);
}
- EXPECT_EQ(c.GetCorrectedTargetRate(), 48000U);
+ EXPECT_EQ(c.GetCorrectedSourceRate(), 48000U);
c.UpdateClock(hundredMillis, hundredMillis, bufferedLow, 0);
- EXPECT_EQ(c.GetCorrectedTargetRate(), 48048U);
+ EXPECT_EQ(c.GetCorrectedSourceRate(), 47952U);
+}
+
+TEST(TestDriftController, VerySmallBufferedFrames)
+{
+ // The buffer level is the only input to the controller logic.
+ uint32_t bufferedLow = 1;
+ uint32_t nominalRate = 48000;
+
+ DriftController c(nominalRate, nominalRate, media::TimeUnit::FromSeconds(1));
+ media::TimeUnit oneSec = media::TimeUnit::FromSeconds(1);
+ media::TimeUnit sourceDuration(1, nominalRate);
+
+ EXPECT_EQ(c.GetCorrectedSourceRate(), nominalRate);
+ uint32_t previousCorrected = nominalRate;
+ // Steps are limited to nominalRate/1000.
+ // Perform 1001 steps to check the corrected rate does not underflow zero.
+ for (uint32_t i = 0; i < 1001; ++i) {
+ c.UpdateClock(sourceDuration, oneSec, bufferedLow, 0);
+ uint32_t correctedRate = c.GetCorrectedSourceRate();
+ EXPECT_LE(correctedRate, previousCorrected) << "for i=" << i;
+ EXPECT_GT(correctedRate, 0u) << "for i=" << i;
+ previousCorrected = correctedRate;
+ }
}
diff --git a/dom/media/driftcontrol/gtest/TestDynamicResampler.cpp b/dom/media/driftcontrol/gtest/TestDynamicResampler.cpp
index fb8ac52ae4..539dfbfbea 100644
--- a/dom/media/driftcontrol/gtest/TestDynamicResampler.cpp
+++ b/dom/media/driftcontrol/gtest/TestDynamicResampler.cpp
@@ -19,7 +19,7 @@ TEST(TestDynamicResampler, SameRates_Float1)
DynamicResampler dr(in_rate, out_rate);
dr.SetSampleFormat(AUDIO_FORMAT_FLOAT32);
- EXPECT_EQ(dr.GetOutRate(), out_rate);
+ EXPECT_EQ(dr.GetInRate(), in_rate);
EXPECT_EQ(dr.GetChannels(), channels);
// float in_ch1[] = {.1, .2, .3, .4, .5, .6, .7, .8, .9, 1.0};
@@ -76,7 +76,7 @@ TEST(TestDynamicResampler, SameRates_Short1)
DynamicResampler dr(in_rate, out_rate);
dr.SetSampleFormat(AUDIO_FORMAT_S16);
- EXPECT_EQ(dr.GetOutRate(), out_rate);
+ EXPECT_EQ(dr.GetInRate(), in_rate);
EXPECT_EQ(dr.GetChannels(), channels);
short in_ch1[] = {1, 2, 3};
@@ -298,9 +298,9 @@ TEST(TestDynamicResampler, UpdateOutRate_Float)
uint32_t pre_buffer = 20;
- DynamicResampler dr(in_rate, out_rate, media::TimeUnit(pre_buffer, in_rate));
+ DynamicResampler dr(in_rate, out_rate);
dr.SetSampleFormat(AUDIO_FORMAT_FLOAT32);
- EXPECT_EQ(dr.GetOutRate(), out_rate);
+ EXPECT_EQ(dr.GetInRate(), in_rate);
EXPECT_EQ(dr.GetChannels(), channels);
float in_ch1[10] = {};
@@ -329,10 +329,10 @@ TEST(TestDynamicResampler, UpdateOutRate_Float)
EXPECT_FLOAT_EQ(out_ch2[i], 0.0);
}
- // Update out rate
- out_rate = 44100;
- dr.UpdateResampler(out_rate, channels);
- EXPECT_EQ(dr.GetOutRate(), out_rate);
+ // Update in rate
+ in_rate = 26122;
+ dr.UpdateResampler(in_rate, channels);
+ EXPECT_EQ(dr.GetInRate(), in_rate);
EXPECT_EQ(dr.GetChannels(), channels);
out_frames = in_frames * out_rate / in_rate;
EXPECT_EQ(out_frames, 18u);
@@ -354,9 +354,9 @@ TEST(TestDynamicResampler, UpdateOutRate_Short)
uint32_t pre_buffer = 20;
- DynamicResampler dr(in_rate, out_rate, media::TimeUnit(pre_buffer, in_rate));
+ DynamicResampler dr(in_rate, out_rate);
dr.SetSampleFormat(AUDIO_FORMAT_S16);
- EXPECT_EQ(dr.GetOutRate(), out_rate);
+ EXPECT_EQ(dr.GetInRate(), in_rate);
EXPECT_EQ(dr.GetChannels(), channels);
short in_ch1[10] = {};
@@ -385,10 +385,10 @@ TEST(TestDynamicResampler, UpdateOutRate_Short)
EXPECT_EQ(out_ch2[i], 0.0);
}
- // Update out rate
- out_rate = 44100;
- dr.UpdateResampler(out_rate, channels);
- EXPECT_EQ(dr.GetOutRate(), out_rate);
+ // Update in rate
+ in_rate = 26122;
+ dr.UpdateResampler(in_rate, channels);
+ EXPECT_EQ(dr.GetInRate(), in_rate);
EXPECT_EQ(dr.GetChannels(), channels);
out_frames = in_frames * out_rate / in_rate;
EXPECT_EQ(out_frames, 18u);
@@ -400,16 +400,15 @@ TEST(TestDynamicResampler, UpdateOutRate_Short)
EXPECT_FALSE(hasUnderrun);
}
-TEST(TestDynamicResampler, BigRangeOutRates_Float)
+TEST(TestDynamicResampler, BigRangeInRates_Float)
{
uint32_t in_frames = 10;
uint32_t out_frames = 10;
uint32_t channels = 2;
uint32_t in_rate = 44100;
uint32_t out_rate = 44100;
- uint32_t pre_buffer = 20;
- DynamicResampler dr(in_rate, out_rate, media::TimeUnit(pre_buffer, in_rate));
+ DynamicResampler dr(in_rate, out_rate);
dr.SetSampleFormat(AUDIO_FORMAT_FLOAT32);
const uint32_t in_capacity = 40;
@@ -427,10 +426,14 @@ TEST(TestDynamicResampler, BigRangeOutRates_Float)
float out_ch1[out_capacity] = {};
float out_ch2[out_capacity] = {};
- for (uint32_t rate = 10000; rate < 90000; ++rate) {
- out_rate = rate;
- dr.UpdateResampler(out_rate, channels);
- EXPECT_EQ(dr.GetOutRate(), out_rate);
+ // Downsampling at a high enough ratio happens to have enough excess
+ // in_frames from rounding in the out_frames calculation to cover the
+ // skipped input latency when switching from zero-latency 44100->44100 to a
+ // non-1:1 ratio.
+ for (uint32_t rate = 100000; rate >= 10000; rate -= 2) {
+ in_rate = rate;
+ dr.UpdateResampler(in_rate, channels);
+ EXPECT_EQ(dr.GetInRate(), in_rate);
EXPECT_EQ(dr.GetChannels(), channels);
in_frames = 20; // more than we need
out_frames = in_frames * out_rate / in_rate;
@@ -444,16 +447,15 @@ TEST(TestDynamicResampler, BigRangeOutRates_Float)
}
}
-TEST(TestDynamicResampler, BigRangeOutRates_Short)
+TEST(TestDynamicResampler, BigRangeInRates_Short)
{
uint32_t in_frames = 10;
uint32_t out_frames = 10;
uint32_t channels = 2;
uint32_t in_rate = 44100;
uint32_t out_rate = 44100;
- uint32_t pre_buffer = 20;
- DynamicResampler dr(in_rate, out_rate, media::TimeUnit(pre_buffer, in_rate));
+ DynamicResampler dr(in_rate, out_rate);
dr.SetSampleFormat(AUDIO_FORMAT_S16);
const uint32_t in_capacity = 40;
@@ -471,9 +473,9 @@ TEST(TestDynamicResampler, BigRangeOutRates_Short)
short out_ch1[out_capacity] = {};
short out_ch2[out_capacity] = {};
- for (uint32_t rate = 10000; rate < 90000; ++rate) {
- out_rate = rate;
- dr.UpdateResampler(out_rate, channels);
+ for (uint32_t rate = 100000; rate >= 10000; rate -= 2) {
+ in_rate = rate;
+ dr.UpdateResampler(in_rate, channels);
in_frames = 20; // more than we need
out_frames = in_frames * out_rate / in_rate;
for (uint32_t y = 0; y < 2; ++y) {
@@ -517,8 +519,8 @@ TEST(TestDynamicResampler, UpdateChannels_Float)
EXPECT_FALSE(hasUnderrun);
// Add 3rd channel
- dr.UpdateResampler(out_rate, 3);
- EXPECT_EQ(dr.GetOutRate(), out_rate);
+ dr.UpdateResampler(in_rate, 3);
+ EXPECT_EQ(dr.GetInRate(), in_rate);
EXPECT_EQ(dr.GetChannels(), 3u);
float in_ch3[10] = {};
@@ -546,8 +548,8 @@ TEST(TestDynamicResampler, UpdateChannels_Float)
in_buffer[3] = in_ch4;
float out_ch4[10] = {};
- dr.UpdateResampler(out_rate, 4);
- EXPECT_EQ(dr.GetOutRate(), out_rate);
+ dr.UpdateResampler(in_rate, 4);
+ EXPECT_EQ(dr.GetInRate(), in_rate);
EXPECT_EQ(dr.GetChannels(), 4u);
dr.AppendInput(in_buffer, in_frames);
@@ -592,8 +594,8 @@ TEST(TestDynamicResampler, UpdateChannels_Short)
EXPECT_FALSE(hasUnderrun);
// Add 3rd channel
- dr.UpdateResampler(out_rate, 3);
- EXPECT_EQ(dr.GetOutRate(), out_rate);
+ dr.UpdateResampler(in_rate, 3);
+ EXPECT_EQ(dr.GetInRate(), in_rate);
EXPECT_EQ(dr.GetChannels(), 3u);
short in_ch3[10] = {};
@@ -622,8 +624,8 @@ TEST(TestDynamicResampler, UpdateChannels_Short)
in_buffer[3] = in_ch4;
short out_ch4[10] = {};
- dr.UpdateResampler(out_rate, 4);
- EXPECT_EQ(dr.GetOutRate(), out_rate);
+ dr.UpdateResampler(in_rate, 4);
+ EXPECT_EQ(dr.GetInRate(), in_rate);
EXPECT_EQ(dr.GetChannels(), 4u);
dr.AppendInput(in_buffer, in_frames);
@@ -647,7 +649,7 @@ TEST(TestDynamicResampler, Underrun)
DynamicResampler dr(in_rate, out_rate);
dr.SetSampleFormat(AUDIO_FORMAT_FLOAT32);
- EXPECT_EQ(dr.GetOutRate(), out_rate);
+ EXPECT_EQ(dr.GetInRate(), in_rate);
EXPECT_EQ(dr.GetChannels(), channels);
float in_ch1[in_frames] = {};
@@ -689,7 +691,7 @@ TEST(TestDynamicResampler, Underrun)
}
// Now try with resampling.
- dr.UpdateResampler(out_rate / 2, channels);
+ dr.UpdateResampler(in_rate * 2, channels);
dr.AppendInput(in_buffer, in_frames);
hasUnderrun = dr.Resample(out_ch1, out_frames, 0);
EXPECT_TRUE(hasUnderrun);