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()) {