blob: d474a4d3409b1c75a236d5a46879a5adb61b5f76 [file] [log] [blame]
/*
* 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()),
inter_arrival_(new InterArrival(5 * 90, kRtpTimestampToMs, true)),
random_(1234) {}
protected:
void SetUp() override { overuse_detector_.reset(new OveruseDetector()); }
int Run100000Samples(int packets_per_frame,
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_);
}
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,
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_);
}
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) {
uint32_t timestamp_delta;
int64_t time_delta;
if (inter_arrival_->ComputeDeltas(rtp_timestamp, receive_time_ms,
&timestamp_delta, &time_delta)) {
double timestamp_delta_ms = timestamp_delta / 90.0;
overuse_estimator_->Update(time_delta, timestamp_delta_ms,
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_;
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) {
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_);
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;
for (int i = 0; i < 1000; ++i) {
UpdateDetector(rtp_timestamp, now_ms_);
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;
for (int i = 0; i < 1000; ++i) {
UpdateDetector(rtp_timestamp, now_ms_);
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) {
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, frame_duration_ms, sigma_ms);
EXPECT_EQ(0, unique_overuse);
int frames_until_overuse = RunUntilOveruse(
packets_per_frame, frame_duration_ms, sigma_ms, drift_per_frame_ms);
EXPECT_EQ(8, frames_until_overuse);
}
TEST_F(OveruseDetectorTest, SimpleOveruse100kbit10fps) {
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, frame_duration_ms, sigma_ms);
EXPECT_EQ(0, unique_overuse);
int frames_until_overuse = RunUntilOveruse(
packets_per_frame, 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;
int offset = 10;
// Run 1000 samples to reach steady state.
for (int i = 0; i < 1000; ++i) {
UpdateDetector(rtp_timestamp, now_ms_);
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_);
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_);
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;
int offset = 10;
// Run 1000 samples to reach steady state.
for (int i = 0; i < 1000; ++i) {
UpdateDetector(rtp_timestamp, now_ms_);
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_);
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_);
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;
int offset = 0;
// Run 1000 samples to reach steady state.
for (int i = 0; i < 1000; ++i) {
UpdateDetector(rtp_timestamp, now_ms_);
UpdateDetector(rtp_timestamp, now_ms_);
UpdateDetector(rtp_timestamp, now_ms_);
UpdateDetector(rtp_timestamp, now_ms_);
UpdateDetector(rtp_timestamp, now_ms_);
UpdateDetector(rtp_timestamp, now_ms_);
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_);
UpdateDetector(rtp_timestamp, now_ms_);
UpdateDetector(rtp_timestamp, now_ms_);
UpdateDetector(rtp_timestamp, now_ms_);
UpdateDetector(rtp_timestamp, now_ms_);
UpdateDetector(rtp_timestamp, now_ms_);
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_);
EXPECT_EQ(kBwOverusing, overuse_detector_->State());
}
TEST_F(OveruseDetectorTest,
DISABLED_ON_ANDROID(LowGaussianVariance30Kbit3fps)) {
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, frame_duration_ms, sigma_ms);
EXPECT_EQ(13, unique_overuse);
int frames_until_overuse = RunUntilOveruse(
packets_per_frame, frame_duration_ms, sigma_ms, drift_per_frame_ms);
EXPECT_EQ(14, frames_until_overuse);
}
TEST_F(OveruseDetectorTest, LowGaussianVarianceFastDrift30Kbit3fps) {
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, frame_duration_ms, sigma_ms);
EXPECT_EQ(13, unique_overuse);
int frames_until_overuse = RunUntilOveruse(
packets_per_frame, frame_duration_ms, sigma_ms, drift_per_frame_ms);
EXPECT_EQ(4, frames_until_overuse);
}
TEST_F(OveruseDetectorTest, HighGaussianVariance30Kbit3fps) {
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, frame_duration_ms, sigma_ms);
EXPECT_EQ(50, unique_overuse);
int frames_until_overuse = RunUntilOveruse(
packets_per_frame, frame_duration_ms, sigma_ms, drift_per_frame_ms);
EXPECT_EQ(42, frames_until_overuse);
}
TEST_F(OveruseDetectorTest, HighGaussianVarianceFastDrift30Kbit3fps) {
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, frame_duration_ms, sigma_ms);
EXPECT_EQ(50, unique_overuse);
int frames_until_overuse = RunUntilOveruse(
packets_per_frame, frame_duration_ms, sigma_ms, drift_per_frame_ms);
EXPECT_EQ(4, frames_until_overuse);
}
TEST_F(OveruseDetectorTest,
DISABLED_ON_ANDROID(LowGaussianVariance100Kbit5fps)) {
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, frame_duration_ms, sigma_ms);
EXPECT_EQ(12, unique_overuse);
int frames_until_overuse = RunUntilOveruse(
packets_per_frame, frame_duration_ms, sigma_ms, drift_per_frame_ms);
EXPECT_EQ(12, frames_until_overuse);
}
TEST_F(OveruseDetectorTest,
DISABLED_ON_ANDROID(HighGaussianVariance100Kbit5fps)) {
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, frame_duration_ms, sigma_ms);
EXPECT_EQ(16, unique_overuse);
int frames_until_overuse = RunUntilOveruse(
packets_per_frame, frame_duration_ms, sigma_ms, drift_per_frame_ms);
EXPECT_EQ(37, frames_until_overuse);
}
TEST_F(OveruseDetectorTest,
DISABLED_ON_ANDROID(LowGaussianVariance100Kbit10fps)) {
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, frame_duration_ms, sigma_ms);
EXPECT_EQ(12, unique_overuse);
int frames_until_overuse = RunUntilOveruse(
packets_per_frame, frame_duration_ms, sigma_ms, drift_per_frame_ms);
EXPECT_EQ(12, frames_until_overuse);
}
TEST_F(OveruseDetectorTest,
DISABLED_ON_ANDROID(HighGaussianVariance100Kbit10fps)) {
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, frame_duration_ms, sigma_ms);
EXPECT_EQ(12, unique_overuse);
int frames_until_overuse = RunUntilOveruse(
packets_per_frame, frame_duration_ms, sigma_ms, drift_per_frame_ms);
EXPECT_EQ(37, frames_until_overuse);
}
TEST_F(OveruseDetectorTest,
DISABLED_ON_ANDROID(LowGaussianVariance300Kbit30fps)) {
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, frame_duration_ms, sigma_ms);
EXPECT_EQ(0, unique_overuse);
int frames_until_overuse = RunUntilOveruse(
packets_per_frame, frame_duration_ms, sigma_ms, drift_per_frame_ms);
EXPECT_EQ(14, frames_until_overuse);
}
TEST_F(OveruseDetectorTest, LowGaussianVarianceFastDrift300Kbit30fps) {
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, frame_duration_ms, sigma_ms);
EXPECT_EQ(0, unique_overuse);
int frames_until_overuse = RunUntilOveruse(
packets_per_frame, frame_duration_ms, sigma_ms, drift_per_frame_ms);
EXPECT_EQ(6, frames_until_overuse);
}
TEST_F(OveruseDetectorTest, HighGaussianVariance300Kbit30fps) {
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, frame_duration_ms, sigma_ms);
EXPECT_EQ(0, unique_overuse);
int frames_until_overuse = RunUntilOveruse(
packets_per_frame, frame_duration_ms, sigma_ms, drift_per_frame_ms);
EXPECT_EQ(49, frames_until_overuse);
}
TEST_F(OveruseDetectorTest, HighGaussianVarianceFastDrift300Kbit30fps) {
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, frame_duration_ms, sigma_ms);
EXPECT_EQ(0, unique_overuse);
int frames_until_overuse = RunUntilOveruse(
packets_per_frame, frame_duration_ms, sigma_ms, drift_per_frame_ms);
EXPECT_EQ(8, frames_until_overuse);
}
TEST_F(OveruseDetectorTest,
DISABLED_ON_ANDROID(LowGaussianVariance1000Kbit30fps)) {
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, frame_duration_ms, sigma_ms);
EXPECT_EQ(0, unique_overuse);
int frames_until_overuse = RunUntilOveruse(
packets_per_frame, frame_duration_ms, sigma_ms, drift_per_frame_ms);
EXPECT_EQ(14, frames_until_overuse);
}
TEST_F(OveruseDetectorTest, LowGaussianVarianceFastDrift1000Kbit30fps) {
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, frame_duration_ms, sigma_ms);
EXPECT_EQ(0, unique_overuse);
int frames_until_overuse = RunUntilOveruse(
packets_per_frame, frame_duration_ms, sigma_ms, drift_per_frame_ms);
EXPECT_EQ(6, frames_until_overuse);
}
TEST_F(OveruseDetectorTest, HighGaussianVariance1000Kbit30fps) {
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, frame_duration_ms, sigma_ms);
EXPECT_EQ(0, unique_overuse);
int frames_until_overuse = RunUntilOveruse(
packets_per_frame, frame_duration_ms, sigma_ms, drift_per_frame_ms);
EXPECT_EQ(49, frames_until_overuse);
}
TEST_F(OveruseDetectorTest, HighGaussianVarianceFastDrift1000Kbit30fps) {
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, frame_duration_ms, sigma_ms);
EXPECT_EQ(0, unique_overuse);
int frames_until_overuse = RunUntilOveruse(
packets_per_frame, frame_duration_ms, sigma_ms, drift_per_frame_ms);
EXPECT_EQ(8, frames_until_overuse);
}
TEST_F(OveruseDetectorTest,
DISABLED_ON_ANDROID(LowGaussianVariance2000Kbit30fps)) {
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, frame_duration_ms, sigma_ms);
EXPECT_EQ(0, unique_overuse);
int frames_until_overuse = RunUntilOveruse(
packets_per_frame, frame_duration_ms, sigma_ms, drift_per_frame_ms);
EXPECT_EQ(14, frames_until_overuse);
}
TEST_F(OveruseDetectorTest, LowGaussianVarianceFastDrift2000Kbit30fps) {
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, frame_duration_ms, sigma_ms);
EXPECT_EQ(0, unique_overuse);
int frames_until_overuse = RunUntilOveruse(
packets_per_frame, frame_duration_ms, sigma_ms, drift_per_frame_ms);
EXPECT_EQ(6, frames_until_overuse);
}
TEST_F(OveruseDetectorTest, HighGaussianVariance2000Kbit30fps) {
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, frame_duration_ms, sigma_ms);
EXPECT_EQ(0, unique_overuse);
int frames_until_overuse = RunUntilOveruse(
packets_per_frame, frame_duration_ms, sigma_ms, drift_per_frame_ms);
EXPECT_EQ(49, frames_until_overuse);
}
TEST_F(OveruseDetectorTest, HighGaussianVarianceFastDrift2000Kbit30fps) {
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, frame_duration_ms, sigma_ms);
EXPECT_EQ(0, unique_overuse);
int frames_until_overuse = RunUntilOveruse(
packets_per_frame, 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()); }
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