JitterEstimator: add field trial for not estimating noise for congested frames

The reason for rejecting the congested frames in the first place, is
that they do not obey a Gaussian distribution around the line from the
Kalman filter. It therefore also does not make sense to include them
in the noise (*) estimation.

(*) noise = variation around the line from the Kalman filter.

Bug: webrtc:14151
Change-Id: Id8a44ba5f13bf9787ab54848109430ef7657f67a
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/275762
Commit-Queue: Rasmus Brandt <brandtr@webrtc.org>
Reviewed-by: Philip Eliasson <philipel@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#38100}
This commit is contained in:
Rasmus Brandt
2022-09-16 13:27:47 +02:00
committed by WebRTC LUCI CQ
parent f6332f29c0
commit e4bc975a8a
3 changed files with 64 additions and 9 deletions

View File

@ -161,6 +161,24 @@ TEST_F(JitterEstimatorTest, Single2xFrameSizeImpactsJitterEstimate) {
EXPECT_GT(outlier_jitter.ms(), steady_state_jitter.ms());
}
// Under the default config, congested frames are used when calculating the
// noise variance, meaning that they will impact the final jitter estimate.
TEST_F(JitterEstimatorTest, CongestedFrameImpactsJitterEstimate) {
ValueGenerator gen(10);
// Steady state.
Run(/*duration_s=*/10, /*framerate_fps=*/30, gen);
TimeDelta steady_state_jitter =
estimator_.GetJitterEstimate(0, absl::nullopt);
// Congested frame...
estimator_.UpdateEstimate(-10 * gen.Delay(), 0.1 * gen.FrameSize());
TimeDelta outlier_jitter = estimator_.GetJitterEstimate(0, absl::nullopt);
// ...impacts the estimate.
EXPECT_GT(outlier_jitter.ms(), steady_state_jitter.ms());
}
TEST_F(JitterEstimatorTest, EmptyFieldTrialsParsesToUnsetConfig) {
JitterEstimator::Config config = estimator_.GetConfigForTest();
EXPECT_FALSE(config.avg_frame_size_median);
@ -170,6 +188,7 @@ TEST_F(JitterEstimatorTest, EmptyFieldTrialsParsesToUnsetConfig) {
EXPECT_FALSE(config.num_stddev_delay_outlier.has_value());
EXPECT_FALSE(config.num_stddev_size_outlier.has_value());
EXPECT_FALSE(config.congestion_rejection_factor.has_value());
EXPECT_TRUE(config.estimate_noise_when_congested);
}
class FieldTrialsOverriddenJitterEstimatorTest : public JitterEstimatorTest {
@ -183,7 +202,8 @@ class FieldTrialsOverriddenJitterEstimatorTest : public JitterEstimatorTest {
"num_stddev_delay_clamp:1.1,"
"num_stddev_delay_outlier:2,"
"num_stddev_size_outlier:3.1,"
"congestion_rejection_factor:-1.55/") {}
"congestion_rejection_factor:-1.55,"
"estimate_noise_when_congested:false/") {}
~FieldTrialsOverriddenJitterEstimatorTest() {}
};
@ -196,6 +216,7 @@ TEST_F(FieldTrialsOverriddenJitterEstimatorTest, FieldTrialsParsesCorrectly) {
EXPECT_EQ(*config.num_stddev_delay_outlier, 2.0);
EXPECT_EQ(*config.num_stddev_size_outlier, 3.1);
EXPECT_EQ(*config.congestion_rejection_factor, -1.55);
EXPECT_FALSE(config.estimate_noise_when_congested);
}
TEST_F(FieldTrialsOverriddenJitterEstimatorTest,
@ -239,6 +260,25 @@ TEST_F(FieldTrialsOverriddenJitterEstimatorTest,
EXPECT_GT(outlier_jitter_4x.ms(), outlier_jitter_3x.ms());
}
// When so configured, congested frames are NOT used when calculating the
// noise variance, meaning that they will NOT impact the final jitter estimate.
TEST_F(FieldTrialsOverriddenJitterEstimatorTest,
CongestedFrameDoesNotImpactJitterEstimate) {
ValueGenerator gen(10);
// Steady state.
Run(/*duration_s=*/10, /*framerate_fps=*/30, gen);
TimeDelta steady_state_jitter =
estimator_.GetJitterEstimate(0, absl::nullopt);
// Congested frame...
estimator_.UpdateEstimate(-10 * gen.Delay(), 0.1 * gen.FrameSize());
TimeDelta outlier_jitter = estimator_.GetJitterEstimate(0, absl::nullopt);
// ...does not impact the estimate.
EXPECT_EQ(outlier_jitter.ms(), steady_state_jitter.ms());
}
class MisconfiguredFieldTrialsJitterEstimatorTest : public JitterEstimatorTest {
protected:
MisconfiguredFieldTrialsJitterEstimatorTest()