/* * 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 #include #include #include #include "testing/gtest/include/gtest/gtest.h" #include "webrtc/base/random.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" 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_(123456789) {} 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_ + static_cast( random_.Gaussian(0, standard_deviation_ms) + 0.5)); 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_ + static_cast( random_.Gaussian(0, standard_deviation_ms) + 0.5)); 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 overuse_detector_; rtc::scoped_ptr overuse_estimator_; rtc::scoped_ptr inter_arrival_; 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 = random_.Rand(0, 49); 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 = random_.Rand(0, 1); 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 = random_.Rand(0, 1); 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()); } #if defined(WEBRTC_ANDROID) #define MAYBE_LowGaussianVariance30Kbit3fps \ DISABLED_LowGaussianVariance30Kbit3fps #else #define MAYBE_LowGaussianVariance30Kbit3fps LowGaussianVariance30Kbit3fps #endif TEST_F(OveruseDetectorTest, MAYBE_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(1, unique_overuse); int frames_until_overuse = RunUntilOveruse(packets_per_frame, packet_size, frame_duration_ms, sigma_ms, drift_per_frame_ms); EXPECT_EQ(13, 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(1, 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(1, unique_overuse); int frames_until_overuse = RunUntilOveruse(packets_per_frame, packet_size, frame_duration_ms, sigma_ms, drift_per_frame_ms); EXPECT_EQ(32, 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(1, 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); } #if defined(WEBRTC_ANDROID) #define MAYBE_LowGaussianVariance100Kbit5fps \ DISABLED_LowGaussianVariance100Kbit5fps #else #define MAYBE_LowGaussianVariance100Kbit5fps LowGaussianVariance100Kbit5fps #endif TEST_F(OveruseDetectorTest, MAYBE_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(0, unique_overuse); int frames_until_overuse = RunUntilOveruse(packets_per_frame, packet_size, frame_duration_ms, sigma_ms, drift_per_frame_ms); EXPECT_EQ(13, frames_until_overuse); } #if defined(WEBRTC_ANDROID) #define MAYBE_HighGaussianVariance100Kbit5fps \ DISABLED_HighGaussianVariance100Kbit5fps #else #define MAYBE_HighGaussianVariance100Kbit5fps HighGaussianVariance100Kbit5fps #endif TEST_F(OveruseDetectorTest, MAYBE_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(1, unique_overuse); int frames_until_overuse = RunUntilOveruse(packets_per_frame, packet_size, frame_duration_ms, sigma_ms, drift_per_frame_ms); EXPECT_EQ(32, frames_until_overuse); } #if defined(WEBRTC_ANDROID) #define MAYBE_LowGaussianVariance100Kbit10fps \ DISABLED_LowGaussianVariance100Kbit10fps #else #define MAYBE_LowGaussianVariance100Kbit10fps LowGaussianVariance100Kbit10fps #endif TEST_F(OveruseDetectorTest, MAYBE_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(1, unique_overuse); int frames_until_overuse = RunUntilOveruse(packets_per_frame, packet_size, frame_duration_ms, sigma_ms, drift_per_frame_ms); EXPECT_EQ(13, frames_until_overuse); } #if defined(WEBRTC_ANDROID) #define MAYBE_HighGaussianVariance100Kbit10fps \ DISABLED_HighGaussianVariance100Kbit10fps #else #define MAYBE_HighGaussianVariance100Kbit10fps HighGaussianVariance100Kbit10fps #endif TEST_F(OveruseDetectorTest, MAYBE_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(0, unique_overuse); int frames_until_overuse = RunUntilOveruse(packets_per_frame, packet_size, frame_duration_ms, sigma_ms, drift_per_frame_ms); EXPECT_EQ(32, frames_until_overuse); } #if defined(WEBRTC_ANDROID) #define MAYBE_LowGaussianVariance300Kbit30fps \ DISABLED_LowGaussianVariance300Kbit30fps #else #define MAYBE_LowGaussianVariance300Kbit30fps LowGaussianVariance300Kbit30fps #endif TEST_F(OveruseDetectorTest, MAYBE_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(15, 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(41, 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(10, frames_until_overuse); } #if defined(WEBRTC_ANDROID) #define MAYBE_LowGaussianVariance1000Kbit30fps \ DISABLED_LowGaussianVariance1000Kbit30fps #else #define MAYBE_LowGaussianVariance1000Kbit30fps LowGaussianVariance1000Kbit30fps #endif TEST_F(OveruseDetectorTest, MAYBE_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(15, 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(41, 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(10, frames_until_overuse); } #if defined(WEBRTC_ANDROID) #define MAYBE_LowGaussianVariance2000Kbit30fps \ DISABLED_LowGaussianVariance2000Kbit30fps #else #define MAYBE_LowGaussianVariance2000Kbit30fps LowGaussianVariance2000Kbit30fps #endif TEST_F(OveruseDetectorTest, MAYBE_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(15, 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(41, 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(10, 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