diff options
Diffstat (limited to 'webrtc/modules/video_coding/jitter_estimator_tests.cc')
-rw-r--r-- | webrtc/modules/video_coding/jitter_estimator_tests.cc | 160 |
1 files changed, 160 insertions, 0 deletions
diff --git a/webrtc/modules/video_coding/jitter_estimator_tests.cc b/webrtc/modules/video_coding/jitter_estimator_tests.cc new file mode 100644 index 0000000000..3d46ce2bcd --- /dev/null +++ b/webrtc/modules/video_coding/jitter_estimator_tests.cc @@ -0,0 +1,160 @@ +/* Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "webrtc/modules/video_coding/jitter_estimator.h" + +#include "testing/gtest/include/gtest/gtest.h" +#include "webrtc/system_wrappers/include/clock.h" + +namespace webrtc { + +class TestEstimator : public VCMJitterEstimator { + public: + explicit TestEstimator(bool exp_enabled) + : VCMJitterEstimator(&fake_clock_, 0, 0), + fake_clock_(0), + exp_enabled_(exp_enabled) {} + + virtual bool LowRateExperimentEnabled() { return exp_enabled_; } + + void AdvanceClock(int64_t microseconds) { + fake_clock_.AdvanceTimeMicroseconds(microseconds); + } + + private: + SimulatedClock fake_clock_; + const bool exp_enabled_; +}; + +class TestVCMJitterEstimator : public ::testing::Test { + protected: + TestVCMJitterEstimator() + : regular_estimator_(false), low_rate_estimator_(true) {} + + virtual void SetUp() { regular_estimator_.Reset(); } + + TestEstimator regular_estimator_; + TestEstimator low_rate_estimator_; +}; + +// Generates some simple test data in the form of a sawtooth wave. +class ValueGenerator { + public: + ValueGenerator(int32_t amplitude) : amplitude_(amplitude), counter_(0) {} + virtual ~ValueGenerator() {} + + int64_t Delay() { return ((counter_ % 11) - 5) * amplitude_; } + + uint32_t FrameSize() { return 1000 + Delay(); } + + void Advance() { ++counter_; } + + private: + const int32_t amplitude_; + int64_t counter_; +}; + +// 5 fps, disable jitter delay altogether. +TEST_F(TestVCMJitterEstimator, TestLowRate) { + ValueGenerator gen(10); + uint64_t time_delta = 1000000 / 5; + for (int i = 0; i < 60; ++i) { + regular_estimator_.UpdateEstimate(gen.Delay(), gen.FrameSize()); + regular_estimator_.AdvanceClock(time_delta); + low_rate_estimator_.UpdateEstimate(gen.Delay(), gen.FrameSize()); + low_rate_estimator_.AdvanceClock(time_delta); + EXPECT_GT(regular_estimator_.GetJitterEstimate(0), 0); + if (i > 2) + EXPECT_EQ(low_rate_estimator_.GetJitterEstimate(0), 0); + gen.Advance(); + } +} + +// 8 fps, steady state estimate should be in interpolated interval between 0 +// and value of previous method. +TEST_F(TestVCMJitterEstimator, TestMidRate) { + ValueGenerator gen(10); + uint64_t time_delta = 1000000 / 8; + for (int i = 0; i < 60; ++i) { + regular_estimator_.UpdateEstimate(gen.Delay(), gen.FrameSize()); + regular_estimator_.AdvanceClock(time_delta); + low_rate_estimator_.UpdateEstimate(gen.Delay(), gen.FrameSize()); + low_rate_estimator_.AdvanceClock(time_delta); + EXPECT_GT(regular_estimator_.GetJitterEstimate(0), 0); + EXPECT_GT(low_rate_estimator_.GetJitterEstimate(0), 0); + EXPECT_GE(regular_estimator_.GetJitterEstimate(0), + low_rate_estimator_.GetJitterEstimate(0)); + gen.Advance(); + } +} + +// 30 fps, steady state estimate should be same as previous method. +TEST_F(TestVCMJitterEstimator, TestHighRate) { + ValueGenerator gen(10); + uint64_t time_delta = 1000000 / 30; + for (int i = 0; i < 60; ++i) { + regular_estimator_.UpdateEstimate(gen.Delay(), gen.FrameSize()); + regular_estimator_.AdvanceClock(time_delta); + low_rate_estimator_.UpdateEstimate(gen.Delay(), gen.FrameSize()); + low_rate_estimator_.AdvanceClock(time_delta); + EXPECT_EQ(regular_estimator_.GetJitterEstimate(0), + low_rate_estimator_.GetJitterEstimate(0)); + gen.Advance(); + } +} + +// 10 fps, high jitter then low jitter. Low rate estimator should converge +// faster to low noise estimate. +TEST_F(TestVCMJitterEstimator, TestConvergence) { + // Reach a steady state with high noise. + ValueGenerator gen(50); + uint64_t time_delta = 1000000 / 10; + for (int i = 0; i < 100; ++i) { + regular_estimator_.UpdateEstimate(gen.Delay(), gen.FrameSize()); + regular_estimator_.AdvanceClock(time_delta * 2); + low_rate_estimator_.UpdateEstimate(gen.Delay(), gen.FrameSize()); + low_rate_estimator_.AdvanceClock(time_delta * 2); + gen.Advance(); + } + + int threshold = regular_estimator_.GetJitterEstimate(0) / 2; + + // New generator with zero noise. + ValueGenerator low_gen(0); + int regular_iterations = 0; + int low_rate_iterations = 0; + for (int i = 0; i < 500; ++i) { + if (regular_iterations == 0) { + regular_estimator_.UpdateEstimate(low_gen.Delay(), low_gen.FrameSize()); + regular_estimator_.AdvanceClock(time_delta); + if (regular_estimator_.GetJitterEstimate(0) < threshold) { + regular_iterations = i; + } + } + + if (low_rate_iterations == 0) { + low_rate_estimator_.UpdateEstimate(low_gen.Delay(), low_gen.FrameSize()); + low_rate_estimator_.AdvanceClock(time_delta); + if (low_rate_estimator_.GetJitterEstimate(0) < threshold) { + low_rate_iterations = i; + } + } + + if (regular_iterations != 0 && low_rate_iterations != 0) { + break; + } + + gen.Advance(); + } + + EXPECT_NE(regular_iterations, 0); + EXPECT_NE(low_rate_iterations, 0); + EXPECT_LE(low_rate_iterations, regular_iterations); +} +} |