diff options
author | Chih-hung Hsieh <chh@google.com> | 2015-12-01 17:00:05 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2015-12-01 17:00:05 +0000 |
commit | fe8b4a657979b49e1701bd92f6d5814a99e0b2be (patch) | |
tree | 672a185b294789cf991f385c3e395dd63bea9063 /webrtc/modules/remote_bitrate_estimator/overuse_detector_unittest.cc | |
parent | 4ee733eff36690bdf8c8e8042762574a01c711e6 (diff) | |
parent | 675d4373f87b2468a334f2ed48bfa4e6946d80f1 (diff) | |
download | webrtc-fe8b4a657979b49e1701bd92f6d5814a99e0b2be.tar.gz |
Merge changes I7bbf776e,I1b827825
* changes:
WIP: Changes after merge commit 'cb3f9bd'
WIP: Merge commit 'cb3f9bd' into chh.merge.cb3f9bd
Diffstat (limited to 'webrtc/modules/remote_bitrate_estimator/overuse_detector_unittest.cc')
-rw-r--r-- | webrtc/modules/remote_bitrate_estimator/overuse_detector_unittest.cc | 740 |
1 files changed, 740 insertions, 0 deletions
diff --git a/webrtc/modules/remote_bitrate_estimator/overuse_detector_unittest.cc b/webrtc/modules/remote_bitrate_estimator/overuse_detector_unittest.cc new file mode 100644 index 0000000000..dcad04b5f6 --- /dev/null +++ b/webrtc/modules/remote_bitrate_estimator/overuse_detector_unittest.cc @@ -0,0 +1,740 @@ +/* + * Copyright (c) 2012 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 <math.h> +#include <cmath> +#include <cstdlib> + +#include "testing/gtest/include/gtest/gtest.h" + +#include "webrtc/base/scoped_ptr.h" +#include "webrtc/common_types.h" +#include "webrtc/modules/remote_bitrate_estimator/inter_arrival.h" +#include "webrtc/modules/remote_bitrate_estimator/overuse_detector.h" +#include "webrtc/modules/remote_bitrate_estimator/overuse_estimator.h" +#include "webrtc/modules/remote_bitrate_estimator/rate_statistics.h" +#include "webrtc/test/field_trial.h" +#include "webrtc/test/random.h" +#include "webrtc/test/testsupport/gtest_disable.h" + +namespace webrtc { +namespace testing { + +const double kRtpTimestampToMs = 1.0 / 90.0; + +class OveruseDetectorTest : public ::testing::Test { + public: + OveruseDetectorTest() + : now_ms_(0), + receive_time_ms_(0), + rtp_timestamp_(10 * 90), + overuse_detector_(), + overuse_estimator_(new OveruseEstimator(options_)), + inter_arrival_(new InterArrival(5 * 90, kRtpTimestampToMs, true)), + random_(1234) {} + + protected: + void SetUp() override { + overuse_detector_.reset(new OveruseDetector(options_)); + } + + int Run100000Samples(int packets_per_frame, size_t packet_size, int mean_ms, + int standard_deviation_ms) { + int unique_overuse = 0; + int last_overuse = -1; + for (int i = 0; i < 100000; ++i) { + for (int j = 0; j < packets_per_frame; ++j) { + UpdateDetector(rtp_timestamp_, receive_time_ms_, packet_size); + } + rtp_timestamp_ += mean_ms * 90; + now_ms_ += mean_ms; + receive_time_ms_ = + std::max(receive_time_ms_, + now_ms_ + random_.Gaussian(0, standard_deviation_ms)); + if (kBwOverusing == overuse_detector_->State()) { + if (last_overuse + 1 != i) { + unique_overuse++; + } + last_overuse = i; + } + } + return unique_overuse; + } + + int RunUntilOveruse(int packets_per_frame, size_t packet_size, int mean_ms, + int standard_deviation_ms, int drift_per_frame_ms) { + // Simulate a higher send pace, that is too high. + for (int i = 0; i < 1000; ++i) { + for (int j = 0; j < packets_per_frame; ++j) { + UpdateDetector(rtp_timestamp_, receive_time_ms_, packet_size); + } + rtp_timestamp_ += mean_ms * 90; + now_ms_ += mean_ms + drift_per_frame_ms; + receive_time_ms_ = + std::max(receive_time_ms_, + now_ms_ + random_.Gaussian(0, standard_deviation_ms)); + if (kBwOverusing == overuse_detector_->State()) { + return i + 1; + } + } + return -1; + } + + void UpdateDetector(uint32_t rtp_timestamp, int64_t receive_time_ms, + size_t packet_size) { + uint32_t timestamp_delta; + int64_t time_delta; + int size_delta; + if (inter_arrival_->ComputeDeltas(rtp_timestamp, + receive_time_ms, + packet_size, + ×tamp_delta, + &time_delta, + &size_delta)) { + double timestamp_delta_ms = timestamp_delta / 90.0; + overuse_estimator_->Update(time_delta, timestamp_delta_ms, size_delta, + overuse_detector_->State()); + overuse_detector_->Detect( + overuse_estimator_->offset(), timestamp_delta_ms, + overuse_estimator_->num_of_deltas(), receive_time_ms); + } + } + + int64_t now_ms_; + int64_t receive_time_ms_; + uint32_t rtp_timestamp_; + OverUseDetectorOptions options_; + rtc::scoped_ptr<OveruseDetector> overuse_detector_; + rtc::scoped_ptr<OveruseEstimator> overuse_estimator_; + rtc::scoped_ptr<InterArrival> inter_arrival_; + test::Random random_; +}; + +TEST_F(OveruseDetectorTest, GaussianRandom) { + int buckets[100]; + memset(buckets, 0, sizeof(buckets)); + for (int i = 0; i < 100000; ++i) { + int index = random_.Gaussian(49, 10); + if (index >= 0 && index < 100) + buckets[index]++; + } + for (int n = 0; n < 100; ++n) { + printf("Bucket n:%d, %d\n", n, buckets[n]); + } +} + +TEST_F(OveruseDetectorTest, SimpleNonOveruse30fps) { + size_t packet_size = 1200; + uint32_t frame_duration_ms = 33; + uint32_t rtp_timestamp = 10 * 90; + + // No variance. + for (int i = 0; i < 1000; ++i) { + UpdateDetector(rtp_timestamp, now_ms_, packet_size); + now_ms_ += frame_duration_ms; + rtp_timestamp += frame_duration_ms * 90; + EXPECT_EQ(kBwNormal, overuse_detector_->State()); + } +} + +// Roughly 1 Mbit/s +TEST_F(OveruseDetectorTest, SimpleNonOveruseWithReceiveVariance) { + uint32_t frame_duration_ms = 10; + uint32_t rtp_timestamp = 10 * 90; + size_t packet_size = 1200; + + for (int i = 0; i < 1000; ++i) { + UpdateDetector(rtp_timestamp, now_ms_, packet_size); + rtp_timestamp += frame_duration_ms * 90; + if (i % 2) { + now_ms_ += frame_duration_ms - 5; + } else { + now_ms_ += frame_duration_ms + 5; + } + EXPECT_EQ(kBwNormal, overuse_detector_->State()); + } +} + +TEST_F(OveruseDetectorTest, SimpleNonOveruseWithRtpTimestampVariance) { + // Roughly 1 Mbit/s. + uint32_t frame_duration_ms = 10; + uint32_t rtp_timestamp = 10 * 90; + size_t packet_size = 1200; + + for (int i = 0; i < 1000; ++i) { + UpdateDetector(rtp_timestamp, now_ms_, packet_size); + now_ms_ += frame_duration_ms; + if (i % 2) { + rtp_timestamp += (frame_duration_ms - 5) * 90; + } else { + rtp_timestamp += (frame_duration_ms + 5) * 90; + } + EXPECT_EQ(kBwNormal, overuse_detector_->State()); + } +} + +TEST_F(OveruseDetectorTest, SimpleOveruse2000Kbit30fps) { + size_t packet_size = 1200; + int packets_per_frame = 6; + int frame_duration_ms = 33; + int drift_per_frame_ms = 1; + int sigma_ms = 0; // No variance. + int unique_overuse = Run100000Samples(packets_per_frame, packet_size, + frame_duration_ms, sigma_ms); + + EXPECT_EQ(0, unique_overuse); + int frames_until_overuse = RunUntilOveruse(packets_per_frame, packet_size, + frame_duration_ms, sigma_ms, drift_per_frame_ms); + EXPECT_EQ(8, frames_until_overuse); +} + +TEST_F(OveruseDetectorTest, SimpleOveruse100kbit10fps) { + size_t packet_size = 1200; + int packets_per_frame = 1; + int frame_duration_ms = 100; + int drift_per_frame_ms = 1; + int sigma_ms = 0; // No variance. + int unique_overuse = Run100000Samples(packets_per_frame, packet_size, + frame_duration_ms, sigma_ms); + + EXPECT_EQ(0, unique_overuse); + int frames_until_overuse = RunUntilOveruse(packets_per_frame, packet_size, + frame_duration_ms, sigma_ms, drift_per_frame_ms); + EXPECT_EQ(6, frames_until_overuse); +} + +TEST_F(OveruseDetectorTest, DISABLED_OveruseWithHighVariance100Kbit10fps) { + uint32_t frame_duration_ms = 100; + uint32_t drift_per_frame_ms = 10; + uint32_t rtp_timestamp = frame_duration_ms * 90; + size_t packet_size = 1200; + int offset = 10; + + // Run 1000 samples to reach steady state. + for (int i = 0; i < 1000; ++i) { + UpdateDetector(rtp_timestamp, now_ms_, packet_size); + rtp_timestamp += frame_duration_ms * 90; + if (i % 2) { + offset = rand() % 50; + now_ms_ += frame_duration_ms - offset; + } else { + now_ms_ += frame_duration_ms + offset; + } + EXPECT_EQ(kBwNormal, overuse_detector_->State()); + } + // Simulate a higher send pace, that is too high. + // Above noise generate a standard deviation of approximately 28 ms. + // Total build up of 150 ms. + for (int j = 0; j < 15; ++j) { + UpdateDetector(rtp_timestamp, now_ms_, packet_size); + now_ms_ += frame_duration_ms + drift_per_frame_ms; + rtp_timestamp += frame_duration_ms * 90; + EXPECT_EQ(kBwNormal, overuse_detector_->State()); + } + UpdateDetector(rtp_timestamp, now_ms_, packet_size); + EXPECT_EQ(kBwOverusing, overuse_detector_->State()); +} + +TEST_F(OveruseDetectorTest, DISABLED_OveruseWithLowVariance100Kbit10fps) { + uint32_t frame_duration_ms = 100; + uint32_t drift_per_frame_ms = 1; + uint32_t rtp_timestamp = frame_duration_ms * 90; + size_t packet_size = 1200; + int offset = 10; + + // Run 1000 samples to reach steady state. + for (int i = 0; i < 1000; ++i) { + UpdateDetector(rtp_timestamp, now_ms_, packet_size); + rtp_timestamp += frame_duration_ms * 90; + if (i % 2) { + offset = rand() % 2; + now_ms_ += frame_duration_ms - offset; + } else { + now_ms_ += frame_duration_ms + offset; + } + EXPECT_EQ(kBwNormal, overuse_detector_->State()); + } + // Simulate a higher send pace, that is too high. + // Total build up of 6 ms. + for (int j = 0; j < 6; ++j) { + UpdateDetector(rtp_timestamp, now_ms_, packet_size); + now_ms_ += frame_duration_ms + drift_per_frame_ms; + rtp_timestamp += frame_duration_ms * 90; + EXPECT_EQ(kBwNormal, overuse_detector_->State()); + } + UpdateDetector(rtp_timestamp, now_ms_, packet_size); + EXPECT_EQ(kBwOverusing, overuse_detector_->State()); +} + +TEST_F(OveruseDetectorTest, OveruseWithLowVariance2000Kbit30fps) { + uint32_t frame_duration_ms = 33; + uint32_t drift_per_frame_ms = 1; + uint32_t rtp_timestamp = frame_duration_ms * 90; + size_t packet_size = 1200; + int offset = 0; + + // Run 1000 samples to reach steady state. + for (int i = 0; i < 1000; ++i) { + UpdateDetector(rtp_timestamp, now_ms_, packet_size); + UpdateDetector(rtp_timestamp, now_ms_, packet_size); + UpdateDetector(rtp_timestamp, now_ms_, packet_size); + UpdateDetector(rtp_timestamp, now_ms_, packet_size); + UpdateDetector(rtp_timestamp, now_ms_, packet_size); + UpdateDetector(rtp_timestamp, now_ms_, packet_size); + rtp_timestamp += frame_duration_ms * 90; + if (i % 2) { + offset = rand() % 2; + now_ms_ += frame_duration_ms - offset; + } else { + now_ms_ += frame_duration_ms + offset; + } + EXPECT_EQ(kBwNormal, overuse_detector_->State()); + } + // Simulate a higher send pace, that is too high. + // Total build up of 30 ms. + for (int j = 0; j < 5; ++j) { + UpdateDetector(rtp_timestamp, now_ms_, packet_size); + UpdateDetector(rtp_timestamp, now_ms_, packet_size); + UpdateDetector(rtp_timestamp, now_ms_, packet_size); + UpdateDetector(rtp_timestamp, now_ms_, packet_size); + UpdateDetector(rtp_timestamp, now_ms_, packet_size); + UpdateDetector(rtp_timestamp, now_ms_, packet_size); + now_ms_ += frame_duration_ms + drift_per_frame_ms * 6; + rtp_timestamp += frame_duration_ms * 90; + EXPECT_EQ(kBwNormal, overuse_detector_->State()); + } + UpdateDetector(rtp_timestamp, now_ms_, packet_size); + EXPECT_EQ(kBwOverusing, overuse_detector_->State()); +} + +TEST_F(OveruseDetectorTest, + DISABLED_ON_ANDROID(LowGaussianVariance30Kbit3fps)) { + size_t packet_size = 1200; + int packets_per_frame = 1; + int frame_duration_ms = 333; + int drift_per_frame_ms = 1; + int sigma_ms = 3; + int unique_overuse = Run100000Samples(packets_per_frame, packet_size, + frame_duration_ms, sigma_ms); + EXPECT_EQ(13, unique_overuse); + int frames_until_overuse = RunUntilOveruse(packets_per_frame, packet_size, + frame_duration_ms, sigma_ms, drift_per_frame_ms); + EXPECT_EQ(14, frames_until_overuse); +} + +TEST_F(OveruseDetectorTest, LowGaussianVarianceFastDrift30Kbit3fps) { + size_t packet_size = 1200; + int packets_per_frame = 1; + int frame_duration_ms = 333; + int drift_per_frame_ms = 100; + int sigma_ms = 3; + int unique_overuse = Run100000Samples(packets_per_frame, packet_size, + frame_duration_ms, sigma_ms); + EXPECT_EQ(13, unique_overuse); + int frames_until_overuse = RunUntilOveruse(packets_per_frame, packet_size, + frame_duration_ms, sigma_ms, drift_per_frame_ms); + EXPECT_EQ(4, frames_until_overuse); +} + +TEST_F(OveruseDetectorTest, HighGaussianVariance30Kbit3fps) { + size_t packet_size = 1200; + int packets_per_frame = 1; + int frame_duration_ms = 333; + int drift_per_frame_ms = 1; + int sigma_ms = 10; + int unique_overuse = Run100000Samples(packets_per_frame, packet_size, + frame_duration_ms, sigma_ms); + EXPECT_EQ(46, unique_overuse); + int frames_until_overuse = RunUntilOveruse(packets_per_frame, packet_size, + frame_duration_ms, sigma_ms, drift_per_frame_ms); + EXPECT_EQ(42, frames_until_overuse); +} + +TEST_F(OveruseDetectorTest, HighGaussianVarianceFastDrift30Kbit3fps) { + size_t packet_size = 1200; + int packets_per_frame = 1; + int frame_duration_ms = 333; + int drift_per_frame_ms = 100; + int sigma_ms = 10; + int unique_overuse = Run100000Samples(packets_per_frame, packet_size, + frame_duration_ms, sigma_ms); + EXPECT_EQ(46, unique_overuse); + int frames_until_overuse = RunUntilOveruse(packets_per_frame, packet_size, + frame_duration_ms, sigma_ms, drift_per_frame_ms); + EXPECT_EQ(4, frames_until_overuse); +} + +TEST_F(OveruseDetectorTest, + DISABLED_ON_ANDROID(LowGaussianVariance100Kbit5fps)) { + size_t packet_size = 1200; + int packets_per_frame = 2; + int frame_duration_ms = 200; + int drift_per_frame_ms = 1; + int sigma_ms = 3; + int unique_overuse = Run100000Samples(packets_per_frame, packet_size, + frame_duration_ms, sigma_ms); + EXPECT_EQ(12, unique_overuse); + int frames_until_overuse = RunUntilOveruse(packets_per_frame, packet_size, + frame_duration_ms, sigma_ms, drift_per_frame_ms); + EXPECT_EQ(12, frames_until_overuse); +} + +TEST_F(OveruseDetectorTest, + DISABLED_ON_ANDROID(HighGaussianVariance100Kbit5fps)) { + size_t packet_size = 1200; + int packets_per_frame = 2; + int frame_duration_ms = 200; + int drift_per_frame_ms = 1; + int sigma_ms = 10; + int unique_overuse = Run100000Samples(packets_per_frame, packet_size, + frame_duration_ms, sigma_ms); + EXPECT_EQ(16, unique_overuse); + int frames_until_overuse = RunUntilOveruse(packets_per_frame, packet_size, + frame_duration_ms, sigma_ms, drift_per_frame_ms); + EXPECT_EQ(37, frames_until_overuse); +} + +TEST_F(OveruseDetectorTest, + DISABLED_ON_ANDROID(LowGaussianVariance100Kbit10fps)) { + size_t packet_size = 1200; + int packets_per_frame = 1; + int frame_duration_ms = 100; + int drift_per_frame_ms = 1; + int sigma_ms = 3; + int unique_overuse = Run100000Samples(packets_per_frame, packet_size, + frame_duration_ms, sigma_ms); + EXPECT_EQ(12, unique_overuse); + int frames_until_overuse = RunUntilOveruse(packets_per_frame, packet_size, + frame_duration_ms, sigma_ms, drift_per_frame_ms); + EXPECT_EQ(12, frames_until_overuse); +} + +TEST_F(OveruseDetectorTest, + DISABLED_ON_ANDROID(HighGaussianVariance100Kbit10fps)) { + size_t packet_size = 1200; + int packets_per_frame = 1; + int frame_duration_ms = 100; + int drift_per_frame_ms = 1; + int sigma_ms = 10; + int unique_overuse = Run100000Samples(packets_per_frame, packet_size, + frame_duration_ms, sigma_ms); + EXPECT_EQ(12, unique_overuse); + int frames_until_overuse = RunUntilOveruse(packets_per_frame, packet_size, + frame_duration_ms, sigma_ms, drift_per_frame_ms); + EXPECT_EQ(37, frames_until_overuse); +} + +TEST_F(OveruseDetectorTest, + DISABLED_ON_ANDROID(LowGaussianVariance300Kbit30fps)) { + size_t packet_size = 1200; + int packets_per_frame = 1; + int frame_duration_ms = 33; + int drift_per_frame_ms = 1; + int sigma_ms = 3; + int unique_overuse = Run100000Samples(packets_per_frame, packet_size, + frame_duration_ms, sigma_ms); + EXPECT_EQ(0, unique_overuse); + int frames_until_overuse = RunUntilOveruse(packets_per_frame, packet_size, + frame_duration_ms, sigma_ms, drift_per_frame_ms); + EXPECT_EQ(14, frames_until_overuse); +} + +TEST_F(OveruseDetectorTest, LowGaussianVarianceFastDrift300Kbit30fps) { + size_t packet_size = 1200; + int packets_per_frame = 1; + int frame_duration_ms = 33; + int drift_per_frame_ms = 10; + int sigma_ms = 3; + int unique_overuse = Run100000Samples(packets_per_frame, packet_size, + frame_duration_ms, sigma_ms); + EXPECT_EQ(0, unique_overuse); + int frames_until_overuse = RunUntilOveruse(packets_per_frame, packet_size, + frame_duration_ms, sigma_ms, drift_per_frame_ms); + EXPECT_EQ(6, frames_until_overuse); +} + +TEST_F(OveruseDetectorTest, HighGaussianVariance300Kbit30fps) { + size_t packet_size = 1200; + int packets_per_frame = 1; + int frame_duration_ms = 33; + int drift_per_frame_ms = 1; + int sigma_ms = 10; + int unique_overuse = Run100000Samples(packets_per_frame, packet_size, + frame_duration_ms, sigma_ms); + EXPECT_EQ(0, unique_overuse); + int frames_until_overuse = RunUntilOveruse(packets_per_frame, packet_size, + frame_duration_ms, sigma_ms, drift_per_frame_ms); + EXPECT_EQ(49, frames_until_overuse); +} + +TEST_F(OveruseDetectorTest, HighGaussianVarianceFastDrift300Kbit30fps) { + size_t packet_size = 1200; + int packets_per_frame = 1; + int frame_duration_ms = 33; + int drift_per_frame_ms = 10; + int sigma_ms = 10; + int unique_overuse = Run100000Samples(packets_per_frame, packet_size, + frame_duration_ms, sigma_ms); + EXPECT_EQ(0, unique_overuse); + int frames_until_overuse = RunUntilOveruse(packets_per_frame, packet_size, + frame_duration_ms, sigma_ms, drift_per_frame_ms); + EXPECT_EQ(8, frames_until_overuse); +} + +TEST_F(OveruseDetectorTest, + DISABLED_ON_ANDROID(LowGaussianVariance1000Kbit30fps)) { + size_t packet_size = 1200; + int packets_per_frame = 3; + int frame_duration_ms = 33; + int drift_per_frame_ms = 1; + int sigma_ms = 3; + int unique_overuse = Run100000Samples(packets_per_frame, packet_size, + frame_duration_ms, sigma_ms); + EXPECT_EQ(0, unique_overuse); + int frames_until_overuse = RunUntilOveruse(packets_per_frame, packet_size, + frame_duration_ms, sigma_ms, drift_per_frame_ms); + EXPECT_EQ(14, frames_until_overuse); +} + +TEST_F(OveruseDetectorTest, LowGaussianVarianceFastDrift1000Kbit30fps) { + size_t packet_size = 1200; + int packets_per_frame = 3; + int frame_duration_ms = 33; + int drift_per_frame_ms = 10; + int sigma_ms = 3; + int unique_overuse = Run100000Samples(packets_per_frame, packet_size, + frame_duration_ms, sigma_ms); + EXPECT_EQ(0, unique_overuse); + int frames_until_overuse = RunUntilOveruse(packets_per_frame, packet_size, + frame_duration_ms, sigma_ms, drift_per_frame_ms); + EXPECT_EQ(6, frames_until_overuse); +} + +TEST_F(OveruseDetectorTest, HighGaussianVariance1000Kbit30fps) { + size_t packet_size = 1200; + int packets_per_frame = 3; + int frame_duration_ms = 33; + int drift_per_frame_ms = 1; + int sigma_ms = 10; + int unique_overuse = Run100000Samples(packets_per_frame, packet_size, + frame_duration_ms, sigma_ms); + EXPECT_EQ(0, unique_overuse); + int frames_until_overuse = RunUntilOveruse(packets_per_frame, packet_size, + frame_duration_ms, sigma_ms, drift_per_frame_ms); + EXPECT_EQ(49, frames_until_overuse); +} + +TEST_F(OveruseDetectorTest, HighGaussianVarianceFastDrift1000Kbit30fps) { + size_t packet_size = 1200; + int packets_per_frame = 3; + int frame_duration_ms = 33; + int drift_per_frame_ms = 10; + int sigma_ms = 10; + int unique_overuse = Run100000Samples(packets_per_frame, packet_size, + frame_duration_ms, sigma_ms); + EXPECT_EQ(0, unique_overuse); + int frames_until_overuse = RunUntilOveruse(packets_per_frame, packet_size, + frame_duration_ms, sigma_ms, drift_per_frame_ms); + EXPECT_EQ(8, frames_until_overuse); +} + +TEST_F(OveruseDetectorTest, + DISABLED_ON_ANDROID(LowGaussianVariance2000Kbit30fps)) { + size_t packet_size = 1200; + int packets_per_frame = 6; + int frame_duration_ms = 33; + int drift_per_frame_ms = 1; + int sigma_ms = 3; + int unique_overuse = Run100000Samples(packets_per_frame, packet_size, + frame_duration_ms, sigma_ms); + EXPECT_EQ(0, unique_overuse); + int frames_until_overuse = RunUntilOveruse(packets_per_frame, packet_size, + frame_duration_ms, sigma_ms, drift_per_frame_ms); + EXPECT_EQ(14, frames_until_overuse); +} + +TEST_F(OveruseDetectorTest, LowGaussianVarianceFastDrift2000Kbit30fps) { + size_t packet_size = 1200; + int packets_per_frame = 6; + int frame_duration_ms = 33; + int drift_per_frame_ms = 10; + int sigma_ms = 3; + int unique_overuse = Run100000Samples(packets_per_frame, packet_size, + frame_duration_ms, sigma_ms); + EXPECT_EQ(0, unique_overuse); + int frames_until_overuse = RunUntilOveruse(packets_per_frame, packet_size, + frame_duration_ms, sigma_ms, drift_per_frame_ms); + EXPECT_EQ(6, frames_until_overuse); +} + +TEST_F(OveruseDetectorTest, HighGaussianVariance2000Kbit30fps) { + size_t packet_size = 1200; + int packets_per_frame = 6; + int frame_duration_ms = 33; + int drift_per_frame_ms = 1; + int sigma_ms = 10; + int unique_overuse = Run100000Samples(packets_per_frame, packet_size, + frame_duration_ms, sigma_ms); + EXPECT_EQ(0, unique_overuse); + int frames_until_overuse = RunUntilOveruse(packets_per_frame, packet_size, + frame_duration_ms, sigma_ms, drift_per_frame_ms); + EXPECT_EQ(49, frames_until_overuse); +} + +TEST_F(OveruseDetectorTest, HighGaussianVarianceFastDrift2000Kbit30fps) { + size_t packet_size = 1200; + int packets_per_frame = 6; + int frame_duration_ms = 33; + int drift_per_frame_ms = 10; + int sigma_ms = 10; + int unique_overuse = Run100000Samples(packets_per_frame, packet_size, + frame_duration_ms, sigma_ms); + EXPECT_EQ(0, unique_overuse); + int frames_until_overuse = RunUntilOveruse(packets_per_frame, packet_size, + frame_duration_ms, sigma_ms, drift_per_frame_ms); + EXPECT_EQ(8, frames_until_overuse); +} + +class OveruseDetectorExperimentTest : public OveruseDetectorTest { + public: + OveruseDetectorExperimentTest() + : override_field_trials_( + "WebRTC-AdaptiveBweThreshold/Enabled-0.01,0.00018/") {} + + protected: + void SetUp() override { + overuse_detector_.reset(new OveruseDetector(options_)); + } + + test::ScopedFieldTrials override_field_trials_; +}; + +TEST_F(OveruseDetectorExperimentTest, ThresholdAdapts) { + const double kOffset = 0.21; + double kTsDelta = 3000.0; + int64_t now_ms = 0; + int num_deltas = 60; + const int kBatchLength = 10; + + // Pass in a positive offset and verify it triggers overuse. + bool overuse_detected = false; + for (int i = 0; i < kBatchLength; ++i) { + BandwidthUsage overuse_state = + overuse_detector_->Detect(kOffset, kTsDelta, num_deltas, now_ms); + if (overuse_state == kBwOverusing) { + overuse_detected = true; + } + ++num_deltas; + now_ms += 5; + } + EXPECT_TRUE(overuse_detected); + + // Force the threshold to increase by passing in a higher offset. + overuse_detected = false; + for (int i = 0; i < kBatchLength; ++i) { + BandwidthUsage overuse_state = + overuse_detector_->Detect(1.1 * kOffset, kTsDelta, num_deltas, now_ms); + if (overuse_state == kBwOverusing) { + overuse_detected = true; + } + ++num_deltas; + now_ms += 5; + } + EXPECT_TRUE(overuse_detected); + + // Verify that the same offset as before no longer triggers overuse. + overuse_detected = false; + for (int i = 0; i < kBatchLength; ++i) { + BandwidthUsage overuse_state = + overuse_detector_->Detect(kOffset, kTsDelta, num_deltas, now_ms); + if (overuse_state == kBwOverusing) { + overuse_detected = true; + } + ++num_deltas; + now_ms += 5; + } + EXPECT_FALSE(overuse_detected); + + // Pass in a low offset to make the threshold adapt down. + for (int i = 0; i < 15 * kBatchLength; ++i) { + BandwidthUsage overuse_state = + overuse_detector_->Detect(0.7 * kOffset, kTsDelta, num_deltas, now_ms); + if (overuse_state == kBwOverusing) { + overuse_detected = true; + } + ++num_deltas; + now_ms += 5; + } + EXPECT_FALSE(overuse_detected); + + // Make sure the original offset now again triggers overuse. + for (int i = 0; i < kBatchLength; ++i) { + BandwidthUsage overuse_state = + overuse_detector_->Detect(kOffset, kTsDelta, num_deltas, now_ms); + if (overuse_state == kBwOverusing) { + overuse_detected = true; + } + ++num_deltas; + now_ms += 5; + } + EXPECT_TRUE(overuse_detected); +} + +TEST_F(OveruseDetectorExperimentTest, DoesntAdaptToSpikes) { + const double kOffset = 1.0; + const double kLargeOffset = 20.0; + double kTsDelta = 3000.0; + int64_t now_ms = 0; + int num_deltas = 60; + const int kBatchLength = 10; + const int kShortBatchLength = 3; + + // Pass in a positive offset and verify it triggers overuse. + bool overuse_detected = false; + for (int i = 0; i < kBatchLength; ++i) { + BandwidthUsage overuse_state = + overuse_detector_->Detect(kOffset, kTsDelta, num_deltas, now_ms); + if (overuse_state == kBwOverusing) { + overuse_detected = true; + } + ++num_deltas; + now_ms += 5; + } + + // Pass in a large offset. This shouldn't have a too big impact on the + // threshold, but still trigger an overuse. + now_ms += 100; + overuse_detected = false; + for (int i = 0; i < kShortBatchLength; ++i) { + BandwidthUsage overuse_state = + overuse_detector_->Detect(kLargeOffset, kTsDelta, num_deltas, now_ms); + if (overuse_state == kBwOverusing) { + overuse_detected = true; + } + ++num_deltas; + now_ms += 5; + } + EXPECT_TRUE(overuse_detected); + + // Pass in a positive normal offset and verify it still triggers. + overuse_detected = false; + for (int i = 0; i < kBatchLength; ++i) { + BandwidthUsage overuse_state = + overuse_detector_->Detect(kOffset, kTsDelta, num_deltas, now_ms); + if (overuse_state == kBwOverusing) { + overuse_detected = true; + } + ++num_deltas; + now_ms += 5; + } + EXPECT_TRUE(overuse_detected); +} +} // namespace testing +} // namespace webrtc |