Make the BWE threshold adaptive.
This improves self-fairness and competing for resources with TCP flows.
BUG=4711
Review URL: https://codereview.webrtc.org/1151603008
Cr-Commit-Position: refs/heads/master@{#9545}
diff --git a/webrtc/common_types.h b/webrtc/common_types.h
index d8317ef..1156bbc 100644
--- a/webrtc/common_types.h
+++ b/webrtc/common_types.h
@@ -763,8 +763,8 @@
initial_e[0][0] = 100;
initial_e[1][1] = 1e-1;
initial_e[0][1] = initial_e[1][0] = 0;
- initial_process_noise[0] = 1e-10;
- initial_process_noise[1] = 1e-2;
+ initial_process_noise[0] = 1e-13;
+ initial_process_noise[1] = 1e-3;
}
double initial_slope;
double initial_offset;
diff --git a/webrtc/modules/pacing/paced_sender.cc b/webrtc/modules/pacing/paced_sender.cc
index f251341..7c842bf 100644
--- a/webrtc/modules/pacing/paced_sender.cc
+++ b/webrtc/modules/pacing/paced_sender.cc
@@ -175,6 +175,8 @@
void set_target_rate_kbps(int target_rate_kbps) {
target_rate_kbps_ = target_rate_kbps;
+ bytes_remaining_ =
+ std::max(-kWindowMs * target_rate_kbps_ / 8, bytes_remaining_);
}
void IncreaseBudget(int64_t delta_time_ms) {
@@ -190,7 +192,7 @@
void UseBudget(size_t bytes) {
bytes_remaining_ = std::max(bytes_remaining_ - static_cast<int>(bytes),
- -500 * target_rate_kbps_ / 8);
+ -kWindowMs * target_rate_kbps_ / 8);
}
size_t bytes_remaining() const {
@@ -200,6 +202,8 @@
int target_rate_kbps() const { return target_rate_kbps_; }
private:
+ static const int kWindowMs = 500;
+
int target_rate_kbps_;
int bytes_remaining_;
};
diff --git a/webrtc/modules/remote_bitrate_estimator/aimd_rate_control.cc b/webrtc/modules/remote_bitrate_estimator/aimd_rate_control.cc
index 81ab973..bcb71d6 100644
--- a/webrtc/modules/remote_bitrate_estimator/aimd_rate_control.cc
+++ b/webrtc/modules/remote_bitrate_estimator/aimd_rate_control.cc
@@ -14,6 +14,7 @@
#include <cassert>
#include <cmath>
+#include "webrtc/modules/remote_bitrate_estimator/overuse_detector.h"
#include "webrtc/modules/remote_bitrate_estimator/test/bwe_test_logging.h"
namespace webrtc {
@@ -27,20 +28,20 @@
: min_configured_bitrate_bps_(min_bitrate_bps),
max_configured_bitrate_bps_(30000000),
current_bitrate_bps_(max_configured_bitrate_bps_),
- max_hold_rate_bps_(0),
avg_max_bitrate_kbps_(-1.0f),
var_max_bitrate_kbps_(0.4f),
rate_control_state_(kRcHold),
- came_from_state_(kRcDecrease),
rate_control_region_(kRcMaxUnknown),
time_last_bitrate_change_(-1),
current_input_(kBwNormal, 0, 1.0),
updated_(false),
time_first_incoming_estimate_(-1),
bitrate_is_initialized_(false),
- beta_(0.9f),
+ beta_(0.85f),
rtt_(kDefaultRttMs),
- time_of_last_log_(-1) {}
+ time_of_last_log_(-1),
+ in_experiment_(AdaptiveThresholdExperimentIsEnabled()) {
+}
uint32_t AimdRateControl::GetMinBitrate() const {
return min_configured_bitrate_bps_;
@@ -95,8 +96,7 @@
rtt_ = rtt;
}
-RateControlRegion AimdRateControl::Update(const RateControlInput* input,
- int64_t now_ms) {
+void AimdRateControl::Update(const RateControlInput* input, int64_t now_ms) {
assert(input);
// Set the initial bit rate value to what we're receiving the first half
@@ -122,7 +122,6 @@
updated_ = true;
current_input_ = *input;
}
- return rate_control_region_;
}
void AimdRateControl::SetEstimate(int bitrate_bps, int64_t now_ms) {
@@ -145,22 +144,16 @@
// variance and the current incoming bit rate.
const float std_max_bit_rate = sqrt(var_max_bitrate_kbps_ *
avg_max_bitrate_kbps_);
- bool fast_recovery_after_hold = false;
switch (rate_control_state_) {
- case kRcHold: {
- max_hold_rate_bps_ = std::max(max_hold_rate_bps_, incoming_bitrate_bps);
+ case kRcHold:
break;
- }
- case kRcIncrease: {
- if (avg_max_bitrate_kbps_ >= 0) {
- if (incoming_bitrate_kbps > avg_max_bitrate_kbps_ +
- 3 * std_max_bit_rate) {
- ChangeRegion(kRcMaxUnknown);
- avg_max_bitrate_kbps_ = -1.0;
- } else if (incoming_bitrate_kbps > avg_max_bitrate_kbps_ +
- 2.5 * std_max_bit_rate) {
- ChangeRegion(kRcAboveMax);
- }
+
+ case kRcIncrease:
+ if (avg_max_bitrate_kbps_ >= 0 &&
+ incoming_bitrate_kbps >
+ avg_max_bitrate_kbps_ + 3 * std_max_bit_rate) {
+ ChangeRegion(kRcMaxUnknown);
+ avg_max_bitrate_kbps_ = -1.0;
}
if (rate_control_region_ == kRcNearMax) {
// Approximate the over-use estimator delay to 100 ms.
@@ -175,18 +168,10 @@
current_bitrate_bps += multiplicative_increase_bps;
}
- if (max_hold_rate_bps_ > 0 &&
- beta_ * max_hold_rate_bps_ > current_bitrate_bps) {
- current_bitrate_bps = static_cast<uint32_t>(beta_ * max_hold_rate_bps_);
- avg_max_bitrate_kbps_ = beta_ * max_hold_rate_bps_ / 1000.0f;
- ChangeRegion(kRcNearMax);
- fast_recovery_after_hold = true;
- }
- max_hold_rate_bps_ = 0;
time_last_bitrate_change_ = now_ms;
break;
- }
- case kRcDecrease: {
+
+ case kRcDecrease:
if (incoming_bitrate_bps < min_configured_bitrate_bps_) {
current_bitrate_bps = min_configured_bitrate_bps_;
} else {
@@ -216,12 +201,11 @@
ChangeState(kRcHold);
time_last_bitrate_change_ = now_ms;
break;
- }
+
default:
assert(false);
}
- if (!fast_recovery_after_hold && (incoming_bitrate_bps > 100000 ||
- current_bitrate_bps > 150000) &&
+ if ((incoming_bitrate_bps > 100000 || current_bitrate_bps > 150000) &&
current_bitrate_bps > 1.5 * incoming_bitrate_bps) {
// Allow changing the bit rate if we are operating at very low rates
// Don't change the bit rate if the send side is too far off
@@ -249,8 +233,10 @@
assert(response_time_ms > 0);
double beta = 0.0;
if (last_ms > 0) {
- beta = std::min((now_ms - last_ms) /
- static_cast<double>(response_time_ms), 1.0);
+ beta = std::min((now_ms - last_ms) / static_cast<double>(response_time_ms),
+ 1.0);
+ if (in_experiment_)
+ beta /= 2.0;
}
double bits_per_frame = static_cast<double>(current_bitrate_bps_) / 30.0;
double packets_per_frame = std::ceil(bits_per_frame / (8.0 * 1200.0));
@@ -308,21 +294,9 @@
void AimdRateControl::ChangeRegion(RateControlRegion region) {
rate_control_region_ = region;
- switch (rate_control_region_) {
- case kRcAboveMax:
- case kRcMaxUnknown:
- beta_ = 0.9f;
- break;
- case kRcNearMax:
- beta_ = 0.95f;
- break;
- default:
- assert(false);
- }
}
void AimdRateControl::ChangeState(RateControlState new_state) {
- came_from_state_ = rate_control_state_;
rate_control_state_ = new_state;
}
} // namespace webrtc
diff --git a/webrtc/modules/remote_bitrate_estimator/aimd_rate_control.h b/webrtc/modules/remote_bitrate_estimator/aimd_rate_control.h
index 74cb11f..b8c47a4 100644
--- a/webrtc/modules/remote_bitrate_estimator/aimd_rate_control.h
+++ b/webrtc/modules/remote_bitrate_estimator/aimd_rate_control.h
@@ -40,7 +40,7 @@
uint32_t LatestEstimate() const;
uint32_t UpdateBandwidthEstimate(int64_t now_ms);
void SetRtt(int64_t rtt);
- RateControlRegion Update(const RateControlInput* input, int64_t now_ms);
+ void Update(const RateControlInput* input, int64_t now_ms);
void SetEstimate(int bitrate_bps, int64_t now_ms);
private:
@@ -71,7 +71,6 @@
float avg_max_bitrate_kbps_;
float var_max_bitrate_kbps_;
RateControlState rate_control_state_;
- RateControlState came_from_state_;
RateControlRegion rate_control_region_;
int64_t time_last_bitrate_change_;
RateControlInput current_input_;
@@ -81,6 +80,7 @@
float beta_;
int64_t rtt_;
int64_t time_of_last_log_;
+ bool in_experiment_;
DISALLOW_IMPLICIT_CONSTRUCTORS(AimdRateControl);
};
diff --git a/webrtc/modules/remote_bitrate_estimator/bwe_simulations.cc b/webrtc/modules/remote_bitrate_estimator/bwe_simulations.cc
index 09d23fa..af69924 100644
--- a/webrtc/modules/remote_bitrate_estimator/bwe_simulations.cc
+++ b/webrtc/modules/remote_bitrate_estimator/bwe_simulations.cc
@@ -116,7 +116,7 @@
}
TEST_P(BweSimulation, PacerChoke1000kbps500kbps1000kbps) {
- PeriodicKeyFrameSource source(0, 30, 300, 0, 0, 1000);
+ AdaptiveVideoSource source(0, 30, 300, 0, 0);
PacedVideoSender sender(&uplink_, &source, GetParam());
ChokeFilter filter(&uplink_, 0);
RateCounterFilter counter(&uplink_, 0, "receiver_input");
@@ -142,7 +142,7 @@
}
TEST_P(BweSimulation, PacerChoke200kbps30kbps200kbps) {
- PeriodicKeyFrameSource source(0, 30, 300, 0, 0, 1000);
+ AdaptiveVideoSource source(0, 30, 300, 0, 0);
PacedVideoSender sender(&uplink_, &source, GetParam());
ChokeFilter filter(&uplink_, 0);
RateCounterFilter counter(&uplink_, 0, "receiver_input");
@@ -234,15 +234,16 @@
}
TEST_P(BweSimulation, SelfFairnessTest) {
- const int kAllFlowIds[] = {0, 1, 2};
+ srand(Clock::GetRealTimeClock()->TimeInMicroseconds());
+ const int kAllFlowIds[] = {0, 1, 2, 3};
const size_t kNumFlows = sizeof(kAllFlowIds) / sizeof(kAllFlowIds[0]);
- rtc::scoped_ptr<AdaptiveVideoSource> sources[kNumFlows];
+ rtc::scoped_ptr<VideoSource> sources[kNumFlows];
rtc::scoped_ptr<VideoSender> senders[kNumFlows];
for (size_t i = 0; i < kNumFlows; ++i) {
// Streams started 20 seconds apart to give them different advantage when
// competing for the bandwidth.
- sources[i].reset(
- new AdaptiveVideoSource(kAllFlowIds[i], 30, 300, 0, i * 20000));
+ sources[i].reset(new AdaptiveVideoSource(kAllFlowIds[i], 30, 300, 0,
+ i * (rand() % 40000)));
senders[i].reset(new VideoSender(&uplink_, sources[i].get(), GetParam()));
}
@@ -267,11 +268,16 @@
RunFor(30 * 60 * 1000);
}
-TEST_P(BweSimulation, PacedSelfFairnessTest) {
+TEST_P(BweSimulation, PacedSelfFairness50msTest) {
srand(Clock::GetRealTimeClock()->TimeInMicroseconds());
RunFairnessTest(GetParam(), 4, 0, 1000, 3000, 50);
}
+TEST_P(BweSimulation, PacedSelfFairness500msTest) {
+ srand(Clock::GetRealTimeClock()->TimeInMicroseconds());
+ RunFairnessTest(GetParam(), 4, 0, 1000, 3000, 500);
+}
+
TEST_P(BweSimulation, PacedSelfFairness1000msTest) {
srand(Clock::GetRealTimeClock()->TimeInMicroseconds());
RunFairnessTest(GetParam(), 4, 0, 1000, 3000, 1000);
diff --git a/webrtc/modules/remote_bitrate_estimator/overuse_detector.cc b/webrtc/modules/remote_bitrate_estimator/overuse_detector.cc
index 33b234c..b21933a 100644
--- a/webrtc/modules/remote_bitrate_estimator/overuse_detector.cc
+++ b/webrtc/modules/remote_bitrate_estimator/overuse_detector.cc
@@ -11,25 +11,60 @@
#include "webrtc/modules/remote_bitrate_estimator/overuse_detector.h"
#include <algorithm>
+#include <sstream>
#include <math.h>
#include <stdlib.h>
+#include "webrtc/base/checks.h"
+#include "webrtc/base/common.h"
#include "webrtc/modules/remote_bitrate_estimator/include/bwe_defines.h"
#include "webrtc/modules/remote_bitrate_estimator/test/bwe_test_logging.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_utility.h"
+#include "webrtc/system_wrappers/interface/field_trial.h"
#include "webrtc/system_wrappers/interface/trace.h"
namespace webrtc {
-enum { kOverUsingTimeThreshold = 100 };
+const char kAdaptiveThresholdExperiment[] = "WebRTC-AdaptiveBweThreshold";
+const char kEnabledPrefix[] = "Enabled";
+const size_t kEnabledPrefixLength = sizeof(kEnabledPrefix) - 1;
+const size_t kMinExperimentLength = kEnabledPrefixLength + 3;
+
+const double kMaxAdaptOffsetMs = 15.0;
+const double kOverUsingTimeThreshold = 10;
+
+bool AdaptiveThresholdExperimentIsEnabled() {
+ std::string experiment_string =
+ webrtc::field_trial::FindFullName(kAdaptiveThresholdExperiment);
+ if (experiment_string.length() < kMinExperimentLength)
+ return false;
+ return experiment_string.substr(0, kEnabledPrefixLength) == kEnabledPrefix;
+}
+
+// Gets thresholds from the experiment name following the format
+// "WebRTC-AdaptiveBweThreshold/Enabled-0.5,0.002/".
+bool ReadExperimentConstants(double* k_up, double* k_down) {
+ std::string experiment_string =
+ webrtc::field_trial::FindFullName(kAdaptiveThresholdExperiment);
+ return sscanf(experiment_string.substr(kEnabledPrefixLength + 1).c_str(),
+ "%lf,%lf", k_up, k_down) == 2;
+}
OveruseDetector::OveruseDetector(const OverUseDetectorOptions& options)
- : options_(options),
- threshold_(options_.initial_threshold),
+ : in_experiment_(AdaptiveThresholdExperimentIsEnabled()),
+ k_up_(0.01),
+ k_down_(0.00018),
+ overusing_time_threshold_(100),
+ options_(options),
+ threshold_(12.5),
+ last_update_ms_(-1),
prev_offset_(0.0),
time_over_using_(-1),
overuse_counter_(0),
- hypothesis_(kBwNormal) {}
+ hypothesis_(kBwNormal) {
+ if (in_experiment_)
+ InitializeExperiment();
+}
OveruseDetector::~OveruseDetector() {}
@@ -37,21 +72,6 @@
return hypothesis_;
}
-
-void OveruseDetector::SetRateControlRegion(RateControlRegion region) {
- switch (region) {
- case kRcMaxUnknown: {
- threshold_ = options_.initial_threshold;
- break;
- }
- case kRcAboveMax:
- case kRcNearMax: {
- threshold_ = options_.initial_threshold / 2;
- break;
- }
- }
-}
-
BandwidthUsage OveruseDetector::Detect(double offset,
double ts_delta,
int num_of_deltas,
@@ -64,7 +84,6 @@
const double T = std::min(num_of_deltas, 60) * offset;
BWE_TEST_LOGGING_PLOT(1, "offset", now_ms, T);
BWE_TEST_LOGGING_PLOT(1, "threshold", now_ms, threshold_);
-
if (T > threshold_) {
if (time_over_using_ == -1) {
// Initialize the timer. Assume that we've been
@@ -76,8 +95,7 @@
time_over_using_ += ts_delta;
}
overuse_counter_++;
- if (time_over_using_ > kOverUsingTimeThreshold
- && overuse_counter_ > 1) {
+ if (time_over_using_ > overusing_time_threshold_ && overuse_counter_ > 1) {
if (offset >= prev_offset) {
time_over_using_ = 0;
overuse_counter_ = 0;
@@ -93,6 +111,45 @@
overuse_counter_ = 0;
hypothesis_ = kBwNormal;
}
+
+ UpdateThreshold(T, now_ms);
+
return hypothesis_;
}
+
+void OveruseDetector::UpdateThreshold(double modified_offset, int64_t now_ms) {
+ if (!in_experiment_)
+ return;
+
+ if (last_update_ms_ == -1)
+ last_update_ms_ = now_ms;
+
+ if (fabs(modified_offset) > threshold_ + kMaxAdaptOffsetMs) {
+ // Avoid adapting the threshold to big latency spikes, caused e.g.,
+ // by a sudden capacity drop.
+ last_update_ms_ = now_ms;
+ return;
+ }
+
+ const double k = fabs(modified_offset) < threshold_ ? k_down_ : k_up_;
+ threshold_ +=
+ k * (fabs(modified_offset) - threshold_) * (now_ms - last_update_ms_);
+
+ const double kMinThreshold = 6;
+ const double kMaxThreshold = 600;
+ threshold_ = std::min(std::max(threshold_, kMinThreshold), kMaxThreshold);
+
+ last_update_ms_ = now_ms;
+}
+
+void OveruseDetector::InitializeExperiment() {
+ DCHECK(in_experiment_);
+ double k_up = 0.0;
+ double k_down = 0.0;
+ overusing_time_threshold_ = kOverUsingTimeThreshold;
+ if (ReadExperimentConstants(&k_up, &k_down)) {
+ k_up_ = k_up;
+ k_down_ = k_down;
+ }
+}
} // namespace webrtc
diff --git a/webrtc/modules/remote_bitrate_estimator/overuse_detector.h b/webrtc/modules/remote_bitrate_estimator/overuse_detector.h
index 8269368..5a07b4e 100644
--- a/webrtc/modules/remote_bitrate_estimator/overuse_detector.h
+++ b/webrtc/modules/remote_bitrate_estimator/overuse_detector.h
@@ -20,10 +20,12 @@
namespace webrtc {
enum RateControlRegion;
+bool AdaptiveThresholdExperimentIsEnabled();
+
class OveruseDetector {
public:
explicit OveruseDetector(const OverUseDetectorOptions& options);
- ~OveruseDetector();
+ virtual ~OveruseDetector();
// Update the detection state based on the estimated inter-arrival time delta
// offset. |timestamp_delta| is the delta between the last timestamp which the
@@ -39,15 +41,19 @@
// Returns the current detector state.
BandwidthUsage State() const;
- // Sets the current rate-control region as decided by RemoteRateControl. This
- // affects the sensitivity of the detector.
- void SetRateControlRegion(webrtc::RateControlRegion region);
-
private:
+ void UpdateThreshold(double modified_offset, int64_t now_ms);
+ void InitializeExperiment();
+
+ const bool in_experiment_;
+ double k_up_;
+ double k_down_;
+ double overusing_time_threshold_;
// Must be first member variable. Cannot be const because we need to be
// copyable.
webrtc::OverUseDetectorOptions options_;
double threshold_;
+ int64_t last_update_ms_;
double prev_offset_;
double time_over_using_;
int overuse_counter_;
diff --git a/webrtc/modules/remote_bitrate_estimator/overuse_detector_unittest.cc b/webrtc/modules/remote_bitrate_estimator/overuse_detector_unittest.cc
index 7c975cb..320cb43 100644
--- a/webrtc/modules/remote_bitrate_estimator/overuse_detector_unittest.cc
+++ b/webrtc/modules/remote_bitrate_estimator/overuse_detector_unittest.cc
@@ -19,6 +19,9 @@
#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/modules/remote_bitrate_estimator/test/random.h"
+#include "webrtc/test/field_trial.h"
#include "webrtc/test/testsupport/gtest_disable.h"
namespace webrtc {
@@ -27,25 +30,19 @@
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() {
- srand(1234);
- now_ms_ = 0;
- receive_time_ms_ = 0;
- rtp_timestamp_ = 10 * 90;
+ void SetUp() override {
overuse_detector_.reset(new OveruseDetector(options_));
- overuse_estimator_.reset(new OveruseEstimator(options_));
- inter_arrival_.reset(new InterArrival(5 * 90, kRtpTimestampToMs, true));
- }
- // Normal Distribution.
- #define PI 3.14159265
- int GaussianRandom(int mean_ms, int standard_deviation_ms) {
- // Creating a Normal distribution variable from two independent uniform
- // variables based on the Box-Muller transform.
- double uniform1 = (std::rand() + 1.0) / (RAND_MAX + 1.0);
- double uniform2 = (std::rand() + 1.0) / (RAND_MAX + 1.0);
- return static_cast<int>(mean_ms + standard_deviation_ms *
- sqrt(-2 * log(uniform1)) * cos(2 * PI * uniform2));
}
int Run100000Samples(int packets_per_frame, size_t packet_size, int mean_ms,
@@ -58,8 +55,9 @@
}
rtp_timestamp_ += mean_ms * 90;
now_ms_ += mean_ms;
- receive_time_ms_ = std::max(receive_time_ms_,
- now_ms_ + GaussianRandom(0, standard_deviation_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++;
@@ -79,8 +77,9 @@
}
rtp_timestamp_ += mean_ms * 90;
now_ms_ += mean_ms + drift_per_frame_ms;
- receive_time_ms_ = std::max(receive_time_ms_,
- now_ms_ + GaussianRandom(0, standard_deviation_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;
}
@@ -102,9 +101,9 @@
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);
}
}
@@ -115,13 +114,14 @@
rtc::scoped_ptr<OveruseDetector> overuse_detector_;
rtc::scoped_ptr<OveruseEstimator> overuse_estimator_;
rtc::scoped_ptr<InterArrival> 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 = GaussianRandom(49, 10);
+ int index = random_.Gaussian(49, 10);
if (index >= 0 && index < 100)
buckets[index]++;
}
@@ -192,7 +192,7 @@
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(13, frames_until_overuse);
}
TEST_F(OveruseDetectorTest, SimpleOveruse100kbit10fps) {
@@ -207,7 +207,7 @@
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 +299,7 @@
}
// 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 < 6; ++j) {
UpdateDetector(rtp_timestamp, now_ms_, packet_size);
UpdateDetector(rtp_timestamp, now_ms_, packet_size);
UpdateDetector(rtp_timestamp, now_ms_, packet_size);
@@ -326,7 +326,7 @@
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_EQ(36, frames_until_overuse);
}
TEST_F(OveruseDetectorTest, LowGaussianVarianceFastDrift30Kbit3fps) {
@@ -340,7 +340,7 @@
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(4, frames_until_overuse, 1);
+ EXPECT_EQ(4, frames_until_overuse);
}
TEST_F(OveruseDetectorTest, HighGaussianVariance30Kbit3fps) {
@@ -354,7 +354,7 @@
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, 30);
+ EXPECT_EQ(119, frames_until_overuse);
}
TEST_F(OveruseDetectorTest, HighGaussianVarianceFastDrift30Kbit3fps) {
@@ -368,7 +368,7 @@
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(4, frames_until_overuse, 1);
+ EXPECT_EQ(5, frames_until_overuse);
}
TEST_F(OveruseDetectorTest,
@@ -383,7 +383,7 @@
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_EQ(35, frames_until_overuse);
}
TEST_F(OveruseDetectorTest,
@@ -398,7 +398,7 @@
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_EQ(115, frames_until_overuse);
}
TEST_F(OveruseDetectorTest,
@@ -413,7 +413,7 @@
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_EQ(30, frames_until_overuse);
}
TEST_F(OveruseDetectorTest,
@@ -428,7 +428,7 @@
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_EQ(98, frames_until_overuse);
}
TEST_F(OveruseDetectorTest,
@@ -443,7 +443,7 @@
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(30, frames_until_overuse, 5);
+ EXPECT_EQ(36, frames_until_overuse);
}
TEST_F(OveruseDetectorTest, LowGaussianVarianceFastDrift300Kbit30fps) {
@@ -457,7 +457,7 @@
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(7, frames_until_overuse, 1);
+ EXPECT_EQ(8, frames_until_overuse);
}
TEST_F(OveruseDetectorTest, HighGaussianVariance300Kbit30fps) {
@@ -471,7 +471,7 @@
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(98, frames_until_overuse, 22);
+ EXPECT_EQ(108, frames_until_overuse);
}
TEST_F(OveruseDetectorTest, HighGaussianVarianceFastDrift300Kbit30fps) {
@@ -485,7 +485,7 @@
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(12, frames_until_overuse, 2);
+ EXPECT_EQ(14, frames_until_overuse);
}
TEST_F(OveruseDetectorTest,
@@ -500,7 +500,7 @@
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(30, frames_until_overuse, 5);
+ EXPECT_EQ(36, frames_until_overuse);
}
TEST_F(OveruseDetectorTest, LowGaussianVarianceFastDrift1000Kbit30fps) {
@@ -514,7 +514,7 @@
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(7, frames_until_overuse, 1);
+ EXPECT_EQ(8, frames_until_overuse);
}
TEST_F(OveruseDetectorTest, HighGaussianVariance1000Kbit30fps) {
@@ -528,7 +528,7 @@
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(98, frames_until_overuse, 22);
+ EXPECT_EQ(108, frames_until_overuse);
}
TEST_F(OveruseDetectorTest, HighGaussianVarianceFastDrift1000Kbit30fps) {
@@ -542,7 +542,7 @@
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(12, frames_until_overuse, 2);
+ EXPECT_EQ(14, frames_until_overuse);
}
TEST_F(OveruseDetectorTest,
@@ -557,7 +557,7 @@
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(30, frames_until_overuse, 5);
+ EXPECT_EQ(36, frames_until_overuse);
}
TEST_F(OveruseDetectorTest, LowGaussianVarianceFastDrift2000Kbit30fps) {
@@ -571,7 +571,7 @@
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(7, frames_until_overuse, 1);
+ EXPECT_EQ(8, frames_until_overuse);
}
TEST_F(OveruseDetectorTest, HighGaussianVariance2000Kbit30fps) {
@@ -585,7 +585,7 @@
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(98, frames_until_overuse, 22);
+ EXPECT_EQ(108, frames_until_overuse);
}
TEST_F(OveruseDetectorTest, HighGaussianVarianceFastDrift2000Kbit30fps) {
@@ -599,7 +599,139 @@
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(12, frames_until_overuse, 2);
+ EXPECT_EQ(14, frames_until_overuse);
+}
+
+class OveruseDetectorExperimentTest : public OveruseDetectorTest {
+ protected:
+ void SetUp() override {
+ test::InitFieldTrialsFromString(
+ "WebRTC-AdaptiveBweThreshold/Enabled-0.01,0.00018/");
+ overuse_detector_.reset(new OveruseDetector(options_));
+ }
+
+ void TearDown() override { test::InitFieldTrialsFromString(""); }
+};
+
+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
diff --git a/webrtc/modules/remote_bitrate_estimator/overuse_estimator.cc b/webrtc/modules/remote_bitrate_estimator/overuse_estimator.cc
index 2f6e330..cf7df26 100644
--- a/webrtc/modules/remote_bitrate_estimator/overuse_estimator.cc
+++ b/webrtc/modules/remote_bitrate_estimator/overuse_estimator.cc
@@ -146,8 +146,8 @@
+ (1 - beta) * residual;
var_noise_ = beta * var_noise_
+ (1 - beta) * (avg_noise_ - residual) * (avg_noise_ - residual);
- if (var_noise_ < 1e-7) {
- var_noise_ = 1e-7;
+ if (var_noise_ < 1) {
+ var_noise_ = 1;
}
}
} // namespace webrtc
diff --git a/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator.gypi b/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator.gypi
index 84f581f..e4b21db 100644
--- a/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator.gypi
+++ b/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator.gypi
@@ -78,6 +78,8 @@
'test/packet_sender.cc',
'test/packet_sender.h',
'test/packet.h',
+ 'test/random.cc',
+ 'test/random.h',
'test/estimators/nada.cc',
'test/estimators/nada.h',
'test/estimators/nada_unittest.cc',
diff --git a/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time.cc b/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time.cc
index e0145a9..7033c66 100644
--- a/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time.cc
+++ b/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time.cc
@@ -296,13 +296,13 @@
double ts_delta_ms = (1000.0 * ts_delta) / (1 << kInterArrivalShift);
estimator_.Update(t_delta, ts_delta_ms, size_delta, detector_.State());
detector_.Detect(estimator_.offset(), ts_delta_ms,
- estimator_.num_of_deltas(), now_ms);
+ estimator_.num_of_deltas(), arrival_time_ms);
UpdateStats(static_cast<int>(t_delta - ts_delta_ms), now_ms);
}
if (detector_.State() == kBwOverusing) {
- unsigned int incoming_bitrate = incoming_bitrate_.Rate(now_ms);
+ uint32_t incoming_bitrate_bps = incoming_bitrate_.Rate(now_ms);
if (prior_state != kBwOverusing ||
- remote_rate_.TimeToReduceFurther(now_ms, incoming_bitrate)) {
+ remote_rate_.TimeToReduceFurther(now_ms, incoming_bitrate_bps)) {
// The first overuse should immediately trigger a new estimate.
// We also have to update the estimate immediately if we are overusing
// and the target bitrate is too high compared to what we are receiving.
@@ -357,13 +357,12 @@
const RateControlInput input(detector_.State(),
incoming_bitrate_.Rate(now_ms),
estimator_.var_noise());
- const RateControlRegion region = remote_rate_.Update(&input, now_ms);
+ remote_rate_.Update(&input, now_ms);
unsigned int target_bitrate = remote_rate_.UpdateBandwidthEstimate(now_ms);
if (remote_rate_.ValidEstimate()) {
process_interval_ms_ = remote_rate_.GetFeedbackInterval();
observer_->OnReceiveBitrateChanged(Keys(ssrcs_), target_bitrate);
}
- detector_.SetRateControlRegion(region);
}
void RemoteBitrateEstimatorAbsSendTime::OnRttUpdate(int64_t rtt) {
diff --git a/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time_unittest.cc b/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time_unittest.cc
index 2516b8c..91e8e1d 100644
--- a/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time_unittest.cc
+++ b/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time_unittest.cc
@@ -42,35 +42,35 @@
}
TEST_F(RemoteBitrateEstimatorAbsSendTimeTest, CapacityDropOneStream) {
- CapacityDropTestHelper(1, false, 700);
+ CapacityDropTestHelper(1, false, 567);
}
TEST_F(RemoteBitrateEstimatorAbsSendTimeTest, CapacityDropOneStreamWrap) {
- CapacityDropTestHelper(1, true, 700);
+ CapacityDropTestHelper(1, true, 567);
}
TEST_F(RemoteBitrateEstimatorAbsSendTimeTest, CapacityDropTwoStreamsWrap) {
- CapacityDropTestHelper(2, true, 700);
+ CapacityDropTestHelper(2, true, 667);
}
TEST_F(RemoteBitrateEstimatorAbsSendTimeTest, CapacityDropThreeStreamsWrap) {
- CapacityDropTestHelper(3, true, 700);
+ CapacityDropTestHelper(3, true, 633);
}
TEST_F(RemoteBitrateEstimatorAbsSendTimeTest, CapacityDropThirteenStreamsWrap) {
- CapacityDropTestHelper(13, true, 666);
+ CapacityDropTestHelper(13, true, 633);
}
TEST_F(RemoteBitrateEstimatorAbsSendTimeTest, CapacityDropNineteenStreamsWrap) {
- CapacityDropTestHelper(19, true, 666);
+ CapacityDropTestHelper(19, true, 633);
}
TEST_F(RemoteBitrateEstimatorAbsSendTimeTest, CapacityDropThirtyStreamsWrap) {
- CapacityDropTestHelper(30, true, 666);
+ CapacityDropTestHelper(30, true, 633);
}
TEST_F(RemoteBitrateEstimatorAbsSendTimeTest, TestTimestampGrouping) {
- TestTimestampGroupingTestHelper();
+ TestTimestampGroupingTestHelper(361080u);
}
TEST_F(RemoteBitrateEstimatorAbsSendTimeTest, TestGetStats) {
diff --git a/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.cc b/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.cc
index 032de13..bca8ba6 100644
--- a/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.cc
+++ b/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.cc
@@ -105,9 +105,9 @@
estimator->estimator.num_of_deltas(), now_ms);
}
if (estimator->detector.State() == kBwOverusing) {
- uint32_t incoming_bitrate = incoming_bitrate_.Rate(now_ms);
+ uint32_t incoming_bitrate_bps = incoming_bitrate_.Rate(now_ms);
if (prior_state != kBwOverusing ||
- remote_rate_->TimeToReduceFurther(now_ms, incoming_bitrate)) {
+ remote_rate_->TimeToReduceFurther(now_ms, incoming_bitrate_bps)) {
// The first overuse should immediately trigger a new estimate.
// We also have to update the estimate immediately if we are overusing
// and the target bitrate is too high compared to what we are receiving.
@@ -172,7 +172,7 @@
const RateControlInput input(bw_state,
incoming_bitrate_.Rate(now_ms),
mean_noise_var);
- const RateControlRegion region = remote_rate_->Update(&input, now_ms);
+ remote_rate_->Update(&input, now_ms);
unsigned int target_bitrate = remote_rate_->UpdateBandwidthEstimate(now_ms);
if (remote_rate_->ValidEstimate()) {
process_interval_ms_ = remote_rate_->GetFeedbackInterval();
@@ -180,9 +180,6 @@
GetSsrcs(&ssrcs);
observer_->OnReceiveBitrateChanged(ssrcs, target_bitrate);
}
- for (it = overuse_detectors_.begin(); it != overuse_detectors_.end(); ++it) {
- it->second->detector.SetRateControlRegion(region);
- }
}
void RemoteBitrateEstimatorSingleStream::OnRttUpdate(int64_t rtt) {
diff --git a/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream_unittest.cc b/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream_unittest.cc
index a7e1aa6..7cd7704 100644
--- a/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream_unittest.cc
+++ b/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream_unittest.cc
@@ -42,34 +42,34 @@
}
TEST_F(RemoteBitrateEstimatorSingleTest, CapacityDropOneStream) {
- CapacityDropTestHelper(1, false, 700);
+ CapacityDropTestHelper(1, false, 567);
}
TEST_F(RemoteBitrateEstimatorSingleTest, CapacityDropOneStreamWrap) {
- CapacityDropTestHelper(1, true, 700);
+ CapacityDropTestHelper(1, true, 567);
}
TEST_F(RemoteBitrateEstimatorSingleTest, CapacityDropTwoStreamsWrap) {
- CapacityDropTestHelper(2, true, 666);
+ CapacityDropTestHelper(2, true, 667);
}
TEST_F(RemoteBitrateEstimatorSingleTest, CapacityDropThreeStreamsWrap) {
- CapacityDropTestHelper(3, true, 700);
+ CapacityDropTestHelper(3, true, 633);
}
TEST_F(RemoteBitrateEstimatorSingleTest, CapacityDropThirteenStreamsWrap) {
- CapacityDropTestHelper(13, true, 700);
+ CapacityDropTestHelper(13, true, 633);
}
TEST_F(RemoteBitrateEstimatorSingleTest, CapacityDropNineteenStreamsWrap) {
- CapacityDropTestHelper(19, true, 700);
+ CapacityDropTestHelper(19, true, 633);
}
TEST_F(RemoteBitrateEstimatorSingleTest, CapacityDropThirtyStreamsWrap) {
- CapacityDropTestHelper(30, true, 700);
+ CapacityDropTestHelper(30, true, 600);
}
TEST_F(RemoteBitrateEstimatorSingleTest, TestTimestampGrouping) {
- TestTimestampGroupingTestHelper();
+ TestTimestampGroupingTestHelper(361080u);
}
} // namespace webrtc
diff --git a/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_unittest_helper.cc b/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_unittest_helper.cc
index 5ee994a..0d8bd19 100644
--- a/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_unittest_helper.cc
+++ b/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_unittest_helper.cc
@@ -513,7 +513,8 @@
EXPECT_EQ(0u, latest_bps);
}
-void RemoteBitrateEstimatorTest::TestTimestampGroupingTestHelper() {
+void RemoteBitrateEstimatorTest::TestTimestampGroupingTestHelper(
+ uint32_t bitrate_bps) {
const int kFramerate = 50; // 50 fps to avoid rounding errors.
const int kFrameIntervalMs = 1000 / kFramerate;
const uint32_t kFrameIntervalAbsSendTime = AbsSendTime(1, kFramerate);
@@ -561,7 +562,7 @@
}
EXPECT_TRUE(bitrate_observer_->updated());
// Should have reduced the estimate.
- EXPECT_EQ(378720u, bitrate_observer_->latest_bitrate());
+ EXPECT_EQ(bitrate_bps, bitrate_observer_->latest_bitrate());
}
void RemoteBitrateEstimatorTest::TestGetStatsHelper() {
diff --git a/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_unittest_helper.h b/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_unittest_helper.h
index 7df05f1..fa4cc54 100644
--- a/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_unittest_helper.h
+++ b/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_unittest_helper.h
@@ -190,8 +190,7 @@
unsigned int max_bitrate,
unsigned int target_bitrate);
-
- void TestTimestampGroupingTestHelper();
+ void TestTimestampGroupingTestHelper(uint32_t bitrate_bps);
void TestGetStatsHelper();
diff --git a/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimators_test.cc b/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimators_test.cc
index 3b8138c..62d8e12 100644
--- a/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimators_test.cc
+++ b/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimators_test.cc
@@ -264,6 +264,20 @@
::testing::Values(kRembEstimator,
kFullSendSideEstimator));
+TEST_P(BweFeedbackTest, ConstantCapacity) {
+ AdaptiveVideoSource source(0, 30, 300, 0, 0);
+ PacedVideoSender sender(&uplink_, &source, GetParam());
+ ChokeFilter filter(&uplink_, 0);
+ RateCounterFilter counter(&uplink_, 0, "receiver_input");
+ PacketReceiver receiver(&uplink_, 0, GetParam(), false, false);
+ const int kCapacityKbps = 1000;
+ filter.SetCapacity(kCapacityKbps);
+ filter.SetMaxDelay(500);
+ RunFor(180 * 1000);
+ PrintResults(kCapacityKbps, counter.GetBitrateStats(), 0,
+ receiver.GetDelayStats(), counter.GetBitrateStats());
+}
+
TEST_P(BweFeedbackTest, Choke1000kbps500kbps1000kbps) {
AdaptiveVideoSource source(0, 30, 300, 0, 0);
PacedVideoSender sender(&uplink_, &source, GetParam());
@@ -338,7 +352,7 @@
}
TEST_P(BweFeedbackTest, PacedSelfFairness500msTest) {
- RunFairnessTest(GetParam(), 4, 0, 300, 3000, 50);
+ RunFairnessTest(GetParam(), 4, 0, 300, 3000, 500);
}
TEST_P(BweFeedbackTest, PacedSelfFairness1000msTest) {
diff --git a/webrtc/modules/remote_bitrate_estimator/test/bwe.h b/webrtc/modules/remote_bitrate_estimator/test/bwe.h
index d059871..6aa79ca 100644
--- a/webrtc/modules/remote_bitrate_estimator/test/bwe.h
+++ b/webrtc/modules/remote_bitrate_estimator/test/bwe.h
@@ -80,7 +80,7 @@
std::list<PacketIdentifierNode*> list_;
};
-const int kMinBitrateKbps = 150;
+const int kMinBitrateKbps = 20;
const int kMaxBitrateKbps = 3000;
class BweSender : public Module {
diff --git a/webrtc/modules/remote_bitrate_estimator/test/bwe_test.cc b/webrtc/modules/remote_bitrate_estimator/test/bwe_test.cc
index 86e8cb0..a2ce340 100644
--- a/webrtc/modules/remote_bitrate_estimator/test/bwe_test.cc
+++ b/webrtc/modules/remote_bitrate_estimator/test/bwe_test.cc
@@ -254,7 +254,7 @@
std::vector<VideoSource*> sources;
std::vector<PacketSender*> senders;
- size_t i = 0;
+ size_t i = 1;
for (int media_flow : media_flow_ids) {
// Streams started 20 seconds apart to give them different advantage when
// competing for the bandwidth.
diff --git a/webrtc/modules/remote_bitrate_estimator/test/bwe_test_framework.cc b/webrtc/modules/remote_bitrate_estimator/test/bwe_test_framework.cc
index ad1f5fd..5e66697 100644
--- a/webrtc/modules/remote_bitrate_estimator/test/bwe_test_framework.cc
+++ b/webrtc/modules/remote_bitrate_estimator/test/bwe_test_framework.cc
@@ -94,33 +94,6 @@
std::list<TimeSizePair> window_;
};
-Random::Random(uint32_t seed)
- : a_(0x531FDB97 ^ seed),
- b_(0x6420ECA8 + seed) {
-}
-
-float Random::Rand() {
- const float kScale = 1.0f / 0xffffffff;
- float result = kScale * b_;
- a_ ^= b_;
- b_ += a_;
- return result;
-}
-
-int Random::Gaussian(int mean, int standard_deviation) {
- // Creating a Normal distribution variable from two independent uniform
- // variables based on the Box-Muller transform, which is defined on the
- // interval (0, 1], hence the mask+add below.
- const double kPi = 3.14159265358979323846;
- const double kScale = 1.0 / 0x80000000ul;
- double u1 = kScale * ((a_ & 0x7ffffffful) + 1);
- double u2 = kScale * ((b_ & 0x7ffffffful) + 1);
- a_ ^= b_;
- b_ += a_;
- return static_cast<int>(mean + standard_deviation *
- sqrt(-2 * log(u1)) * cos(2 * kPi * u2));
-}
-
Packet::Packet()
: flow_id_(0), creation_time_us_(-1), send_time_us_(-1), payload_size_(0) {
}
diff --git a/webrtc/modules/remote_bitrate_estimator/test/bwe_test_framework.h b/webrtc/modules/remote_bitrate_estimator/test/bwe_test_framework.h
index 9fb219d..cfbac9c 100644
--- a/webrtc/modules/remote_bitrate_estimator/test/bwe_test_framework.h
+++ b/webrtc/modules/remote_bitrate_estimator/test/bwe_test_framework.h
@@ -28,6 +28,7 @@
#include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
#include "webrtc/modules/remote_bitrate_estimator/test/bwe_test_logging.h"
#include "webrtc/modules/remote_bitrate_estimator/test/packet.h"
+#include "webrtc/modules/remote_bitrate_estimator/test/random.h"
#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
#include "webrtc/system_wrappers/interface/clock.h"
@@ -142,26 +143,6 @@
T max_;
};
-class Random {
- public:
- explicit Random(uint32_t seed);
-
- // Return pseudo random number in the interval [0.0, 1.0].
- float Rand();
-
- // Normal Distribution.
- int Gaussian(int mean, int standard_deviation);
-
- // TODO(solenberg): Random from histogram.
- // template<typename T> int Distribution(const std::vector<T> histogram) {
-
- private:
- uint32_t a_;
- uint32_t b_;
-
- DISALLOW_IMPLICIT_CONSTRUCTORS(Random);
-};
-
bool IsTimeSorted(const Packets& packets);
class PacketProcessor;
diff --git a/webrtc/modules/remote_bitrate_estimator/test/random.cc b/webrtc/modules/remote_bitrate_estimator/test/random.cc
new file mode 100644
index 0000000..d803be0
--- /dev/null
+++ b/webrtc/modules/remote_bitrate_estimator/test/random.cc
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2015 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 "webrtc/modules/remote_bitrate_estimator/test/random.h"
+
+#include <math.h>
+
+namespace webrtc {
+
+Random::Random(uint32_t seed) : a_(0x531FDB97 ^ seed), b_(0x6420ECA8 + seed) {
+}
+
+float Random::Rand() {
+ const float kScale = 1.0f / 0xffffffff;
+ float result = kScale * b_;
+ a_ ^= b_;
+ b_ += a_;
+ return result;
+}
+
+int Random::Gaussian(int mean, int standard_deviation) {
+ // Creating a Normal distribution variable from two independent uniform
+ // variables based on the Box-Muller transform, which is defined on the
+ // interval (0, 1], hence the mask+add below.
+ const double kPi = 3.14159265358979323846;
+ const double kScale = 1.0 / 0x80000000ul;
+ double u1 = kScale * ((a_ & 0x7ffffffful) + 1);
+ double u2 = kScale * ((b_ & 0x7ffffffful) + 1);
+ a_ ^= b_;
+ b_ += a_;
+ return static_cast<int>(
+ mean + standard_deviation * sqrt(-2 * log(u1)) * cos(2 * kPi * u2));
+}
+} // namespace webrtc
diff --git a/webrtc/modules/remote_bitrate_estimator/test/random.h b/webrtc/modules/remote_bitrate_estimator/test/random.h
new file mode 100644
index 0000000..9713e43
--- /dev/null
+++ b/webrtc/modules/remote_bitrate_estimator/test/random.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2015 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.
+ */
+
+#ifndef WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_RANDOM_H_
+#define WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_RANDOM_H_
+
+#include "webrtc/typedefs.h"
+#include "webrtc/base/constructormagic.h"
+
+namespace webrtc {
+
+class Random {
+ public:
+ explicit Random(uint32_t seed);
+
+ // Return pseudo-random number in the interval [0.0, 1.0].
+ float Rand();
+
+ // Normal Distribution.
+ int Gaussian(int mean, int standard_deviation);
+
+ // TODO(solenberg): Random from histogram.
+ // template<typename T> int Distribution(const std::vector<T> histogram) {
+
+ private:
+ uint32_t a_;
+ uint32_t b_;
+
+ DISALLOW_IMPLICIT_CONSTRUCTORS(Random);
+};
+} // namespace webrtc
+
+#endif // WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_RANDOM_H_
diff --git a/webrtc/test/field_trial.cc b/webrtc/test/field_trial.cc
index 6b3d83c..1f56ad3 100644
--- a/webrtc/test/field_trial.cc
+++ b/webrtc/test/field_trial.cc
@@ -45,11 +45,12 @@
void InitFieldTrialsFromString(const std::string& trials_string) {
static const char kPersistentStringSeparator = '/';
- // Catch an error if this is called more than once.
- assert(field_trials_initiated_ == false);
field_trials_initiated_ = true;
- if (trials_string.empty()) return;
+ if (trials_string.empty()) {
+ field_trials_.clear();
+ return;
+ }
size_t next_item = 0;
while (next_item < trials_string.length()) {