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}
This commit is contained in:
stefan
2015-07-07 04:20:34 -07:00
committed by Commit bot
parent 4e7aa43ea0
commit c62642c7a6
24 changed files with 448 additions and 221 deletions

View File

@@ -763,8 +763,8 @@ struct OverUseDetectorOptions {
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;

View File

@@ -175,6 +175,8 @@ class IntervalBudget {
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 @@ class IntervalBudget {
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 @@ class IntervalBudget {
int target_rate_kbps() const { return target_rate_kbps_; }
private:
static const int kWindowMs = 500;
int target_rate_kbps_;
int bytes_remaining_;
};

View File

@@ -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 @@ AimdRateControl::AimdRateControl(uint32_t min_bitrate_bps)
: 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 @@ void AimdRateControl::SetRtt(int64_t rtt) {
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 @@ RateControlRegion AimdRateControl::Update(const RateControlInput* input,
updated_ = true;
current_input_ = *input;
}
return rate_control_region_;
}
void AimdRateControl::SetEstimate(int bitrate_bps, int64_t now_ms) {
@@ -145,22 +144,16 @@ uint32_t AimdRateControl::ChangeBitrate(uint32_t current_bitrate_bps,
// 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 @@ uint32_t AimdRateControl::ChangeBitrate(uint32_t current_bitrate_bps,
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 @@ uint32_t AimdRateControl::ChangeBitrate(uint32_t current_bitrate_bps,
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 @@ uint32_t AimdRateControl::AdditiveRateIncrease(
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::ChangeState(const RateControlInput& input,
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

View File

@@ -40,7 +40,7 @@ class AimdRateControl {
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 @@ class AimdRateControl {
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 @@ class AimdRateControl {
float beta_;
int64_t rtt_;
int64_t time_of_last_log_;
bool in_experiment_;
DISALLOW_IMPLICIT_CONSTRUCTORS(AimdRateControl);
};

View File

@@ -116,7 +116,7 @@ TEST_P(BweSimulation, Choke1000kbps500kbps1000kbps) {
}
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, PacerChoke10000kbps) {
}
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, PacerGoogleWifiTrace3Mbps) {
}
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 @@ TEST_P(BweSimulation, SelfFairnessTest) {
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);

View File

@@ -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 @@ BandwidthUsage OveruseDetector::State() const {
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 @@ BandwidthUsage OveruseDetector::Detect(double offset,
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 @@ BandwidthUsage OveruseDetector::Detect(double offset,
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 @@ BandwidthUsage OveruseDetector::Detect(double offset,
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

View File

@@ -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 @@ class OveruseDetector {
// 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_;

View File

@@ -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 @@ namespace testing {
const double kRtpTimestampToMs = 1.0 / 90.0;
class OveruseDetectorTest : public ::testing::Test {
public:
OveruseDetectorTest()
: now_ms_(0),
receive_time_ms_(0),
rtp_timestamp_(10 * 90),
overuse_detector_(),
overuse_estimator_(new OveruseEstimator(options_)),
inter_arrival_(new InterArrival(5 * 90, kRtpTimestampToMs, true)),
random_(1234) {}
protected:
void SetUp() {
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 @@ class OveruseDetectorTest : public ::testing::Test {
}
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 @@ class OveruseDetectorTest : public ::testing::Test {
}
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 @@ class OveruseDetectorTest : public ::testing::Test {
double timestamp_delta_ms = timestamp_delta / 90.0;
overuse_estimator_->Update(time_delta, timestamp_delta_ms, size_delta,
overuse_detector_->State());
overuse_detector_->Detect(overuse_estimator_->offset(),
timestamp_delta_ms,
overuse_estimator_->num_of_deltas(), 0);
overuse_detector_->Detect(
overuse_estimator_->offset(), timestamp_delta_ms,
overuse_estimator_->num_of_deltas(), receive_time_ms);
}
}
@@ -115,13 +114,14 @@ class OveruseDetectorTest : public ::testing::Test {
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 @@ TEST_F(OveruseDetectorTest, SimpleOveruse2000Kbit30fps) {
EXPECT_EQ(0, unique_overuse);
int frames_until_overuse = RunUntilOveruse(packets_per_frame, packet_size,
frame_duration_ms, sigma_ms, drift_per_frame_ms);
EXPECT_EQ(6, frames_until_overuse);
EXPECT_EQ(13, frames_until_overuse);
}
TEST_F(OveruseDetectorTest, SimpleOveruse100kbit10fps) {
@@ -207,7 +207,7 @@ TEST_F(OveruseDetectorTest, SimpleOveruse100kbit10fps) {
EXPECT_EQ(0, unique_overuse);
int frames_until_overuse = RunUntilOveruse(packets_per_frame, packet_size,
frame_duration_ms, sigma_ms, drift_per_frame_ms);
EXPECT_EQ(4, frames_until_overuse);
EXPECT_EQ(11, frames_until_overuse);
}
TEST_F(OveruseDetectorTest, DISABLED_OveruseWithHighVariance100Kbit10fps) {
@@ -299,7 +299,7 @@ TEST_F(OveruseDetectorTest, OveruseWithLowVariance2000Kbit30fps) {
}
// Simulate a higher send pace, that is too high.
// Total build up of 30 ms.
for (int j = 0; j < 5; ++j) {
for (int j = 0; j < 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 @@ TEST_F(OveruseDetectorTest,
EXPECT_EQ(0, unique_overuse);
int frames_until_overuse = RunUntilOveruse(packets_per_frame, packet_size,
frame_duration_ms, sigma_ms, drift_per_frame_ms);
EXPECT_NEAR(29, frames_until_overuse, 5);
EXPECT_EQ(36, frames_until_overuse);
}
TEST_F(OveruseDetectorTest, LowGaussianVarianceFastDrift30Kbit3fps) {
@@ -340,7 +340,7 @@ TEST_F(OveruseDetectorTest, LowGaussianVarianceFastDrift30Kbit3fps) {
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 @@ TEST_F(OveruseDetectorTest, HighGaussianVariance30Kbit3fps) {
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 @@ TEST_F(OveruseDetectorTest, HighGaussianVarianceFastDrift30Kbit3fps) {
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 @@ TEST_F(OveruseDetectorTest,
EXPECT_EQ(0, unique_overuse);
int frames_until_overuse = RunUntilOveruse(packets_per_frame, packet_size,
frame_duration_ms, sigma_ms, drift_per_frame_ms);
EXPECT_NEAR(29, frames_until_overuse, 5);
EXPECT_EQ(35, frames_until_overuse);
}
TEST_F(OveruseDetectorTest,
@@ -398,7 +398,7 @@ TEST_F(OveruseDetectorTest,
EXPECT_EQ(0, unique_overuse);
int frames_until_overuse = RunUntilOveruse(packets_per_frame, packet_size,
frame_duration_ms, sigma_ms, drift_per_frame_ms);
EXPECT_NEAR(79, frames_until_overuse, 15);
EXPECT_EQ(115, frames_until_overuse);
}
TEST_F(OveruseDetectorTest,
@@ -413,7 +413,7 @@ TEST_F(OveruseDetectorTest,
EXPECT_EQ(0, unique_overuse);
int frames_until_overuse = RunUntilOveruse(packets_per_frame, packet_size,
frame_duration_ms, sigma_ms, drift_per_frame_ms);
EXPECT_NEAR(29, frames_until_overuse, 5);
EXPECT_EQ(30, frames_until_overuse);
}
TEST_F(OveruseDetectorTest,
@@ -428,7 +428,7 @@ TEST_F(OveruseDetectorTest,
EXPECT_EQ(0, unique_overuse);
int frames_until_overuse = RunUntilOveruse(packets_per_frame, packet_size,
frame_duration_ms, sigma_ms, drift_per_frame_ms);
EXPECT_NEAR(79, frames_until_overuse, 15);
EXPECT_EQ(98, frames_until_overuse);
}
TEST_F(OveruseDetectorTest,
@@ -443,7 +443,7 @@ TEST_F(OveruseDetectorTest,
EXPECT_EQ(0, unique_overuse);
int frames_until_overuse = RunUntilOveruse(packets_per_frame, packet_size,
frame_duration_ms, sigma_ms, drift_per_frame_ms);
EXPECT_NEAR(30, frames_until_overuse, 5);
EXPECT_EQ(36, frames_until_overuse);
}
TEST_F(OveruseDetectorTest, LowGaussianVarianceFastDrift300Kbit30fps) {
@@ -457,7 +457,7 @@ TEST_F(OveruseDetectorTest, LowGaussianVarianceFastDrift300Kbit30fps) {
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 @@ TEST_F(OveruseDetectorTest, HighGaussianVariance300Kbit30fps) {
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 @@ TEST_F(OveruseDetectorTest, HighGaussianVarianceFastDrift300Kbit30fps) {
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 @@ TEST_F(OveruseDetectorTest,
EXPECT_EQ(0, unique_overuse);
int frames_until_overuse = RunUntilOveruse(packets_per_frame, packet_size,
frame_duration_ms, sigma_ms, drift_per_frame_ms);
EXPECT_NEAR(30, frames_until_overuse, 5);
EXPECT_EQ(36, frames_until_overuse);
}
TEST_F(OveruseDetectorTest, LowGaussianVarianceFastDrift1000Kbit30fps) {
@@ -514,7 +514,7 @@ TEST_F(OveruseDetectorTest, LowGaussianVarianceFastDrift1000Kbit30fps) {
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 @@ TEST_F(OveruseDetectorTest, HighGaussianVariance1000Kbit30fps) {
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 @@ TEST_F(OveruseDetectorTest, HighGaussianVarianceFastDrift1000Kbit30fps) {
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 @@ TEST_F(OveruseDetectorTest,
EXPECT_EQ(0, unique_overuse);
int frames_until_overuse = RunUntilOveruse(packets_per_frame, packet_size,
frame_duration_ms, sigma_ms, drift_per_frame_ms);
EXPECT_NEAR(30, frames_until_overuse, 5);
EXPECT_EQ(36, frames_until_overuse);
}
TEST_F(OveruseDetectorTest, LowGaussianVarianceFastDrift2000Kbit30fps) {
@@ -571,7 +571,7 @@ TEST_F(OveruseDetectorTest, LowGaussianVarianceFastDrift2000Kbit30fps) {
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 @@ TEST_F(OveruseDetectorTest, HighGaussianVariance2000Kbit30fps) {
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 @@ TEST_F(OveruseDetectorTest, HighGaussianVarianceFastDrift2000Kbit30fps) {
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

View File

@@ -146,8 +146,8 @@ void OveruseEstimator::UpdateNoiseEstimate(double residual,
+ (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

View File

@@ -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',

View File

@@ -296,13 +296,13 @@ void RemoteBitrateEstimatorAbsSendTime::IncomingPacketInfo(
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 @@ void RemoteBitrateEstimatorAbsSendTime::UpdateEstimate(int64_t now_ms) {
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) {

View File

@@ -42,35 +42,35 @@ TEST_F(RemoteBitrateEstimatorAbsSendTimeTest, RateIncreaseRtpTimestamps) {
}
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) {

View File

@@ -105,9 +105,9 @@ void RemoteBitrateEstimatorSingleStream::IncomingPacket(int64_t arrival_time_ms,
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 @@ void RemoteBitrateEstimatorSingleStream::UpdateEstimate(int64_t now_ms) {
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 @@ void RemoteBitrateEstimatorSingleStream::UpdateEstimate(int64_t now_ms) {
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) {

View File

@@ -42,34 +42,34 @@ TEST_F(RemoteBitrateEstimatorSingleTest, RateIncreaseRtpTimestamps) {
}
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

View File

@@ -513,7 +513,8 @@ void RemoteBitrateEstimatorTest::CapacityDropTestHelper(
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 @@ void RemoteBitrateEstimatorTest::TestTimestampGroupingTestHelper() {
}
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() {

View File

@@ -190,8 +190,7 @@ class RemoteBitrateEstimatorTest : public ::testing::Test {
unsigned int max_bitrate,
unsigned int target_bitrate);
void TestTimestampGroupingTestHelper();
void TestTimestampGroupingTestHelper(uint32_t bitrate_bps);
void TestGetStatsHelper();

View File

@@ -264,6 +264,20 @@ INSTANTIATE_TEST_CASE_P(VideoSendersTest,
::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, PacedSelfFairness50msTest) {
}
TEST_P(BweFeedbackTest, PacedSelfFairness500msTest) {
RunFairnessTest(GetParam(), 4, 0, 300, 3000, 50);
RunFairnessTest(GetParam(), 4, 0, 300, 3000, 500);
}
TEST_P(BweFeedbackTest, PacedSelfFairness1000msTest) {

View File

@@ -80,7 +80,7 @@ class LinkedSet {
std::list<PacketIdentifierNode*> list_;
};
const int kMinBitrateKbps = 150;
const int kMinBitrateKbps = 20;
const int kMaxBitrateKbps = 3000;
class BweSender : public Module {

View File

@@ -254,7 +254,7 @@ void BweTest::RunFairnessTest(BandwidthEstimatorType bwe_type,
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.

View File

@@ -94,33 +94,6 @@ class RateCounter {
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) {
}

View File

@@ -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 @@ template<typename T> class Stats {
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;

View File

@@ -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

View File

@@ -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_

View File

@@ -45,11 +45,12 @@ namespace test {
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()) {