|  | /* | 
|  | *  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 |