Index: webrtc/modules/remote_bitrate_estimator/overuse_detector_unittest.cc |
diff --git a/webrtc/modules/remote_bitrate_estimator/overuse_detector_unittest.cc b/webrtc/modules/remote_bitrate_estimator/overuse_detector_unittest.cc |
index 7c975cbe5f7f530700e9eef925a12f76ca60e586..4d77d4b4183c772231eba078126dd7949c47070a 100644 |
--- a/webrtc/modules/remote_bitrate_estimator/overuse_detector_unittest.cc |
+++ b/webrtc/modules/remote_bitrate_estimator/overuse_detector_unittest.cc |
@@ -19,6 +19,7 @@ |
#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/testsupport/gtest_disable.h" |
namespace webrtc { |
@@ -36,6 +37,7 @@ class OveruseDetectorTest : public ::testing::Test { |
overuse_detector_.reset(new OveruseDetector(options_)); |
overuse_estimator_.reset(new OveruseEstimator(options_)); |
inter_arrival_.reset(new InterArrival(5 * 90, kRtpTimestampToMs, true)); |
+ incoming_bitrate_.reset(new RateStatistics(1000, 8000)); |
} |
// Normal Distribution. |
#define PI 3.14159265 |
@@ -93,6 +95,7 @@ class OveruseDetectorTest : public ::testing::Test { |
uint32_t timestamp_delta; |
int64_t time_delta; |
int size_delta; |
+ incoming_bitrate_->Update(packet_size, receive_time_ms); |
if (inter_arrival_->ComputeDeltas(rtp_timestamp, |
receive_time_ms, |
packet_size, |
@@ -102,9 +105,10 @@ class OveruseDetectorTest : public ::testing::Test { |
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(), 0); |
+ overuse_detector_->Detect( |
+ overuse_estimator_->offset(), timestamp_delta_ms, |
+ overuse_estimator_->num_of_deltas(), receive_time_ms, |
+ incoming_bitrate_->Rate(receive_time_ms)); |
} |
} |
@@ -115,6 +119,7 @@ class OveruseDetectorTest : public ::testing::Test { |
rtc::scoped_ptr<OveruseDetector> overuse_detector_; |
rtc::scoped_ptr<OveruseEstimator> overuse_estimator_; |
rtc::scoped_ptr<InterArrival> inter_arrival_; |
+ rtc::scoped_ptr<RateStatistics> incoming_bitrate_; |
}; |
TEST_F(OveruseDetectorTest, GaussianRandom) { |
@@ -192,7 +197,7 @@ TEST_F(OveruseDetectorTest, SimpleOveruse2000Kbit30fps) { |
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); |
+ EXPECT_EQ(11, frames_until_overuse); |
} |
TEST_F(OveruseDetectorTest, SimpleOveruse100kbit10fps) { |
@@ -207,7 +212,7 @@ TEST_F(OveruseDetectorTest, SimpleOveruse100kbit10fps) { |
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(4, frames_until_overuse); |
+ EXPECT_EQ(11, frames_until_overuse); |
} |
TEST_F(OveruseDetectorTest, DISABLED_OveruseWithHighVariance100Kbit10fps) { |
@@ -299,7 +304,7 @@ TEST_F(OveruseDetectorTest, OveruseWithLowVariance2000Kbit30fps) { |
} |
// Simulate a higher send pace, that is too high. |
// Total build up of 30 ms. |
- for (int j = 0; j < 5; ++j) { |
+ for (int j = 0; j < 4; ++j) { |
UpdateDetector(rtp_timestamp, now_ms_, packet_size); |
UpdateDetector(rtp_timestamp, now_ms_, packet_size); |
UpdateDetector(rtp_timestamp, now_ms_, packet_size); |
@@ -326,7 +331,7 @@ TEST_F(OveruseDetectorTest, |
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_NEAR(29, frames_until_overuse, 5); |
+ EXPECT_NEAR(36, frames_until_overuse, 5); |
} |
TEST_F(OveruseDetectorTest, LowGaussianVarianceFastDrift30Kbit3fps) { |
@@ -383,7 +388,7 @@ TEST_F(OveruseDetectorTest, |
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_NEAR(29, frames_until_overuse, 5); |
+ EXPECT_NEAR(36, frames_until_overuse, 5); |
} |
TEST_F(OveruseDetectorTest, |
@@ -398,7 +403,7 @@ TEST_F(OveruseDetectorTest, |
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_NEAR(79, frames_until_overuse, 15); |
+ EXPECT_NEAR(109, frames_until_overuse, 15); |
} |
TEST_F(OveruseDetectorTest, |
@@ -413,7 +418,7 @@ TEST_F(OveruseDetectorTest, |
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_NEAR(29, frames_until_overuse, 5); |
+ EXPECT_NEAR(36, frames_until_overuse, 5); |
} |
TEST_F(OveruseDetectorTest, |
@@ -428,7 +433,7 @@ TEST_F(OveruseDetectorTest, |
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_NEAR(79, frames_until_overuse, 15); |
+ EXPECT_NEAR(109, frames_until_overuse, 15); |
} |
TEST_F(OveruseDetectorTest, |
@@ -601,5 +606,143 @@ TEST_F(OveruseDetectorTest, HighGaussianVarianceFastDrift2000Kbit30fps) { |
frame_duration_ms, sigma_ms, drift_per_frame_ms); |
EXPECT_NEAR(12, frames_until_overuse, 2); |
} |
+ |
+class AdaptiveThresholdDetector : public OveruseDetector { |
+ public: |
+ explicit AdaptiveThresholdDetector(const OverUseDetectorOptions& options) |
+ : OveruseDetector(options) {} |
+ |
+ virtual ~AdaptiveThresholdDetector() {} |
+ |
+ bool AdaptiveThresholdExperimentIsEnabled() const override { return true; } |
+ bool ExperimentVariationIsEnabled(const char* variation) const override { |
+ return true; |
+ } |
+}; |
+ |
+TEST_F(OveruseDetectorTest, ThresholdAdapts) { |
+ overuse_detector_.reset(new AdaptiveThresholdDetector(options_)); |
+ const double kOffset = 0.21; |
+ double kTsDelta = 3000.0; |
+ const int kIncomingBitrateBps = 1500000; |
+ 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, kIncomingBitrateBps); |
+ 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, kIncomingBitrateBps); |
+ 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, kIncomingBitrateBps); |
+ 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 < 10 * kBatchLength; ++i) { |
+ BandwidthUsage overuse_state = overuse_detector_->Detect( |
+ 0.7 * kOffset, kTsDelta, num_deltas, now_ms, kIncomingBitrateBps); |
+ 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, kIncomingBitrateBps); |
+ if (overuse_state == kBwOverusing) { |
+ overuse_detected = true; |
+ } |
+ ++num_deltas; |
+ now_ms += 5; |
+ } |
+ EXPECT_TRUE(overuse_detected); |
+} |
+ |
+TEST_F(OveruseDetectorTest, DoesntAdaptToSpikes) { |
+ overuse_detector_.reset(new AdaptiveThresholdDetector(options_)); |
+ const double kOffset = 1.0; |
+ const double kLargeOffset = 20.0; |
+ double kTsDelta = 3000.0; |
+ const int kIncomingBitrateBps = 1500000; |
+ 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, kIncomingBitrateBps); |
+ 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, kIncomingBitrateBps); |
+ 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, kIncomingBitrateBps); |
+ if (overuse_state == kBwOverusing) { |
+ overuse_detected = true; |
+ } |
+ ++num_deltas; |
+ now_ms += 5; |
+ } |
+ EXPECT_TRUE(overuse_detected); |
+} |
} // namespace testing |
} // namespace webrtc |