Remove MimdRateControl and factories for RemoteBitrateEstimor.
BUG= R=stefan@webrtc.org Review URL: https://codereview.webrtc.org/1208083002. Cr-Commit-Position: refs/heads/master@{#9541}
This commit is contained in:
parent
d92f2674d7
commit
468e62a974
@ -29,16 +29,12 @@ source_set("rbe_components") {
|
||||
"aimd_rate_control.h",
|
||||
"inter_arrival.cc",
|
||||
"inter_arrival.h",
|
||||
"mimd_rate_control.cc",
|
||||
"mimd_rate_control.h",
|
||||
"overuse_detector.cc",
|
||||
"overuse_detector.h",
|
||||
"overuse_estimator.cc",
|
||||
"overuse_estimator.h",
|
||||
"remote_bitrate_estimator_abs_send_time.cc",
|
||||
"remote_bitrate_estimator_single_stream.cc",
|
||||
"remote_rate_control.cc",
|
||||
"remote_rate_control.h",
|
||||
]
|
||||
|
||||
configs += [ "../..:common_config" ]
|
||||
|
@ -21,6 +21,7 @@ namespace webrtc {
|
||||
static const int64_t kDefaultRttMs = 200;
|
||||
static const int64_t kLogIntervalMs = 1000;
|
||||
static const double kWithinIncomingBitrateHysteresis = 1.05;
|
||||
static const int64_t kMaxFeedbackIntervalMs = 1000;
|
||||
|
||||
AimdRateControl::AimdRateControl(uint32_t min_bitrate_bps)
|
||||
: min_configured_bitrate_bps_(min_bitrate_bps),
|
||||
@ -41,10 +42,6 @@ AimdRateControl::AimdRateControl(uint32_t min_bitrate_bps)
|
||||
rtt_(kDefaultRttMs),
|
||||
time_of_last_log_(-1) {}
|
||||
|
||||
RateControlType AimdRateControl::GetControlType() const {
|
||||
return kAimdControl;
|
||||
}
|
||||
|
||||
uint32_t AimdRateControl::GetMinBitrate() const {
|
||||
return min_configured_bitrate_bps_;
|
||||
}
|
||||
|
@ -11,38 +11,37 @@
|
||||
#ifndef WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_AIMD_RATE_CONTROL_H_
|
||||
#define WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_AIMD_RATE_CONTROL_H_
|
||||
|
||||
#include "webrtc/base/constructormagic.h"
|
||||
#include "webrtc/modules/remote_bitrate_estimator/include/bwe_defines.h"
|
||||
#include "webrtc/modules/remote_bitrate_estimator/remote_rate_control.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// A RemoteRateControl implementation based on additive increases of
|
||||
// A rate control implementation based on additive increases of
|
||||
// bitrate when no over-use is detected and multiplicative decreases when
|
||||
// over-uses are detected. When we think the available bandwidth has changes or
|
||||
// is unknown, we will switch to a "slow-start mode" where we increase
|
||||
// multiplicatively.
|
||||
class AimdRateControl : public RemoteRateControl {
|
||||
class AimdRateControl {
|
||||
public:
|
||||
explicit AimdRateControl(uint32_t min_bitrate_bps);
|
||||
virtual ~AimdRateControl() {}
|
||||
|
||||
// Implements RemoteRateControl.
|
||||
bool ValidEstimate() const override;
|
||||
RateControlType GetControlType() const override;
|
||||
uint32_t GetMinBitrate() const override;
|
||||
int64_t GetFeedbackInterval() const override;
|
||||
// Returns true if there is a valid estimate of the incoming bitrate, false
|
||||
// otherwise.
|
||||
bool ValidEstimate() const;
|
||||
uint32_t GetMinBitrate() const;
|
||||
int64_t GetFeedbackInterval() const;
|
||||
// Returns true if the bitrate estimate hasn't been changed for more than
|
||||
// an RTT, or if the incoming_bitrate is more than 5% above the current
|
||||
// estimate. Should be used to decide if we should reduce the rate further
|
||||
// when over-using.
|
||||
bool TimeToReduceFurther(int64_t time_now,
|
||||
uint32_t incoming_bitrate_bps) const override;
|
||||
uint32_t LatestEstimate() const override;
|
||||
uint32_t UpdateBandwidthEstimate(int64_t now_ms) override;
|
||||
void SetRtt(int64_t rtt) override;
|
||||
RateControlRegion Update(const RateControlInput* input,
|
||||
int64_t now_ms) override;
|
||||
void SetEstimate(int bitrate_bps, int64_t now_ms) override;
|
||||
uint32_t incoming_bitrate_bps) const;
|
||||
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 SetEstimate(int bitrate_bps, int64_t now_ms);
|
||||
|
||||
private:
|
||||
// Update the target bitrate according based on, among other things,
|
||||
|
@ -25,11 +25,6 @@ namespace webrtc {
|
||||
|
||||
class Clock;
|
||||
|
||||
enum RateControlType {
|
||||
kMimdControl,
|
||||
kAimdControl
|
||||
};
|
||||
|
||||
// RemoteBitrateObserver is used to signal changes in bitrate estimates for
|
||||
// the incoming streams.
|
||||
class RemoteBitrateObserver {
|
||||
@ -125,28 +120,6 @@ class RemoteBitrateEstimator : public CallStatsObserver, public Module {
|
||||
static const int64_t kStreamTimeOutMs = 2000;
|
||||
};
|
||||
|
||||
struct RemoteBitrateEstimatorFactory {
|
||||
RemoteBitrateEstimatorFactory() {}
|
||||
virtual ~RemoteBitrateEstimatorFactory() {}
|
||||
|
||||
virtual RemoteBitrateEstimator* Create(
|
||||
RemoteBitrateObserver* observer,
|
||||
Clock* clock,
|
||||
RateControlType control_type,
|
||||
uint32_t min_bitrate_bps) const;
|
||||
};
|
||||
|
||||
struct AbsoluteSendTimeRemoteBitrateEstimatorFactory
|
||||
: public RemoteBitrateEstimatorFactory {
|
||||
AbsoluteSendTimeRemoteBitrateEstimatorFactory() {}
|
||||
virtual ~AbsoluteSendTimeRemoteBitrateEstimatorFactory() {}
|
||||
|
||||
virtual RemoteBitrateEstimator* Create(
|
||||
RemoteBitrateObserver* observer,
|
||||
Clock* clock,
|
||||
RateControlType control_type,
|
||||
uint32_t min_bitrate_bps) const;
|
||||
};
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_INCLUDE_REMOTE_BITRATE_ESTIMATOR_H_
|
||||
|
@ -1,328 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014 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/mimd_rate_control.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
const int64_t kDefaultRttMs = 200;
|
||||
const int64_t kLogIntervalMs = 1000;
|
||||
|
||||
MimdRateControl::MimdRateControl(uint32_t min_bitrate_bps)
|
||||
: min_configured_bit_rate_(min_bitrate_bps),
|
||||
max_configured_bit_rate_(30000000),
|
||||
current_bit_rate_(max_configured_bit_rate_),
|
||||
max_hold_rate_(0),
|
||||
avg_max_bit_rate_(-1.0f),
|
||||
var_max_bit_rate_(0.4f),
|
||||
rate_control_state_(kRcHold),
|
||||
came_from_state_(kRcDecrease),
|
||||
rate_control_region_(kRcMaxUnknown),
|
||||
last_bit_rate_change_(-1),
|
||||
current_input_(kBwNormal, 0, 1.0),
|
||||
updated_(false),
|
||||
time_first_incoming_estimate_(-1),
|
||||
initialized_bit_rate_(false),
|
||||
avg_change_period_(1000.0f),
|
||||
last_change_ms_(-1),
|
||||
beta_(0.9f),
|
||||
rtt_(kDefaultRttMs),
|
||||
time_of_last_log_(-1)
|
||||
{
|
||||
}
|
||||
|
||||
RateControlType MimdRateControl::GetControlType() const {
|
||||
return kMimdControl;
|
||||
}
|
||||
|
||||
uint32_t MimdRateControl::GetMinBitrate() const {
|
||||
return min_configured_bit_rate_;
|
||||
}
|
||||
|
||||
bool MimdRateControl::ValidEstimate() const {
|
||||
return initialized_bit_rate_;
|
||||
}
|
||||
|
||||
int64_t MimdRateControl::GetFeedbackInterval() const {
|
||||
return kMaxFeedbackIntervalMs;
|
||||
}
|
||||
|
||||
bool MimdRateControl::TimeToReduceFurther(int64_t time_now,
|
||||
uint32_t incoming_bitrate_bps) const {
|
||||
const int64_t bitrate_reduction_interval =
|
||||
std::max<int64_t>(std::min<int64_t>(rtt_, 200), 10);
|
||||
if (time_now - last_bit_rate_change_ >= bitrate_reduction_interval) {
|
||||
return true;
|
||||
}
|
||||
if (ValidEstimate()) {
|
||||
const int threshold = static_cast<int>(1.05 * incoming_bitrate_bps);
|
||||
const int bitrate_difference = LatestEstimate() - incoming_bitrate_bps;
|
||||
return bitrate_difference > threshold;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t MimdRateControl::LatestEstimate() const {
|
||||
return current_bit_rate_;
|
||||
}
|
||||
|
||||
uint32_t MimdRateControl::UpdateBandwidthEstimate(int64_t now_ms) {
|
||||
current_bit_rate_ = ChangeBitRate(current_bit_rate_,
|
||||
current_input_._incomingBitRate,
|
||||
current_input_._noiseVar,
|
||||
now_ms);
|
||||
if (now_ms - time_of_last_log_ > kLogIntervalMs) {
|
||||
time_of_last_log_ = now_ms;
|
||||
}
|
||||
return current_bit_rate_;
|
||||
}
|
||||
|
||||
void MimdRateControl::SetRtt(int64_t rtt) {
|
||||
rtt_ = rtt;
|
||||
}
|
||||
|
||||
RateControlRegion MimdRateControl::Update(const RateControlInput* input,
|
||||
int64_t now_ms) {
|
||||
assert(input);
|
||||
|
||||
// Set the initial bit rate value to what we're receiving the first half
|
||||
// second.
|
||||
if (!initialized_bit_rate_) {
|
||||
if (time_first_incoming_estimate_ < 0) {
|
||||
if (input->_incomingBitRate > 0) {
|
||||
time_first_incoming_estimate_ = now_ms;
|
||||
}
|
||||
} else if (now_ms - time_first_incoming_estimate_ > 500 &&
|
||||
input->_incomingBitRate > 0) {
|
||||
current_bit_rate_ = input->_incomingBitRate;
|
||||
initialized_bit_rate_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (updated_ && current_input_._bwState == kBwOverusing) {
|
||||
// Only update delay factor and incoming bit rate. We always want to react
|
||||
// on an over-use.
|
||||
current_input_._noiseVar = input->_noiseVar;
|
||||
current_input_._incomingBitRate = input->_incomingBitRate;
|
||||
return rate_control_region_;
|
||||
}
|
||||
updated_ = true;
|
||||
current_input_ = *input;
|
||||
return rate_control_region_;
|
||||
}
|
||||
|
||||
void MimdRateControl::SetEstimate(int bitrate_bps, int64_t now_ms) {
|
||||
}
|
||||
|
||||
uint32_t MimdRateControl::ChangeBitRate(uint32_t current_bit_rate,
|
||||
uint32_t incoming_bit_rate,
|
||||
double noise_var,
|
||||
int64_t now_ms) {
|
||||
if (!updated_) {
|
||||
return current_bit_rate_;
|
||||
}
|
||||
updated_ = false;
|
||||
UpdateChangePeriod(now_ms);
|
||||
ChangeState(current_input_, now_ms);
|
||||
// calculated here because it's used in multiple places
|
||||
const float incoming_bit_rate_kbps = incoming_bit_rate / 1000.0f;
|
||||
// Calculate the max bit rate std dev given the normalized
|
||||
// variance and the current incoming bit rate.
|
||||
const float std_max_bit_rate = sqrt(var_max_bit_rate_ * avg_max_bit_rate_);
|
||||
bool recovery = false;
|
||||
switch (rate_control_state_) {
|
||||
case kRcHold: {
|
||||
max_hold_rate_ = std::max(max_hold_rate_, incoming_bit_rate);
|
||||
break;
|
||||
}
|
||||
case kRcIncrease: {
|
||||
if (avg_max_bit_rate_ >= 0) {
|
||||
if (incoming_bit_rate_kbps > avg_max_bit_rate_ + 3 * std_max_bit_rate) {
|
||||
ChangeRegion(kRcMaxUnknown);
|
||||
avg_max_bit_rate_ = -1.0;
|
||||
} else if (incoming_bit_rate_kbps > avg_max_bit_rate_ + 2.5 *
|
||||
std_max_bit_rate) {
|
||||
ChangeRegion(kRcAboveMax);
|
||||
}
|
||||
}
|
||||
const int64_t response_time =
|
||||
static_cast<int64_t>(avg_change_period_ + 0.5f) + rtt_ + 300;
|
||||
double alpha = RateIncreaseFactor(now_ms, last_bit_rate_change_,
|
||||
response_time, noise_var);
|
||||
|
||||
current_bit_rate = static_cast<uint32_t>(current_bit_rate * alpha) + 1000;
|
||||
if (max_hold_rate_ > 0 && beta_ * max_hold_rate_ > current_bit_rate) {
|
||||
current_bit_rate = static_cast<uint32_t>(beta_ * max_hold_rate_);
|
||||
avg_max_bit_rate_ = beta_ * max_hold_rate_ / 1000.0f;
|
||||
ChangeRegion(kRcNearMax);
|
||||
recovery = true;
|
||||
}
|
||||
max_hold_rate_ = 0;
|
||||
last_bit_rate_change_ = now_ms;
|
||||
break;
|
||||
}
|
||||
case kRcDecrease: {
|
||||
if (incoming_bit_rate < min_configured_bit_rate_) {
|
||||
current_bit_rate = min_configured_bit_rate_;
|
||||
} else {
|
||||
// Set bit rate to something slightly lower than max
|
||||
// to get rid of any self-induced delay.
|
||||
current_bit_rate = static_cast<uint32_t>(beta_ * incoming_bit_rate +
|
||||
0.5);
|
||||
if (current_bit_rate > current_bit_rate_) {
|
||||
// Avoid increasing the rate when over-using.
|
||||
if (rate_control_region_ != kRcMaxUnknown) {
|
||||
current_bit_rate = static_cast<uint32_t>(beta_ * avg_max_bit_rate_ *
|
||||
1000 + 0.5f);
|
||||
}
|
||||
current_bit_rate = std::min(current_bit_rate, current_bit_rate_);
|
||||
}
|
||||
ChangeRegion(kRcNearMax);
|
||||
|
||||
if (incoming_bit_rate_kbps < avg_max_bit_rate_ - 3 * std_max_bit_rate) {
|
||||
avg_max_bit_rate_ = -1.0f;
|
||||
}
|
||||
|
||||
UpdateMaxBitRateEstimate(incoming_bit_rate_kbps);
|
||||
}
|
||||
// Stay on hold until the pipes are cleared.
|
||||
ChangeState(kRcHold);
|
||||
last_bit_rate_change_ = now_ms;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
if (!recovery && (incoming_bit_rate > 100000 || current_bit_rate > 150000) &&
|
||||
current_bit_rate > 1.5 * incoming_bit_rate) {
|
||||
// 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
|
||||
current_bit_rate = current_bit_rate_;
|
||||
last_bit_rate_change_ = now_ms;
|
||||
}
|
||||
return current_bit_rate;
|
||||
}
|
||||
|
||||
double MimdRateControl::RateIncreaseFactor(int64_t now_ms,
|
||||
int64_t last_ms,
|
||||
int64_t reaction_time_ms,
|
||||
double noise_var) const {
|
||||
// alpha = 1.02 + B ./ (1 + exp(b*(tr - (c1*s2 + c2))))
|
||||
// Parameters
|
||||
const double B = 0.0407;
|
||||
const double b = 0.0025;
|
||||
const double c1 = -6700.0 / (33 * 33);
|
||||
const double c2 = 800.0;
|
||||
const double d = 0.85;
|
||||
|
||||
double alpha = 1.005 + B / (1 + exp( b * (d * reaction_time_ms -
|
||||
(c1 * noise_var + c2))));
|
||||
|
||||
if (alpha < 1.005) {
|
||||
alpha = 1.005;
|
||||
} else if (alpha > 1.3) {
|
||||
alpha = 1.3;
|
||||
}
|
||||
|
||||
if (last_ms > -1) {
|
||||
alpha = pow(alpha, (now_ms - last_ms) / 1000.0);
|
||||
}
|
||||
|
||||
if (rate_control_region_ == kRcNearMax) {
|
||||
// We're close to our previous maximum. Try to stabilize the
|
||||
// bit rate in this region, by increasing in smaller steps.
|
||||
alpha = alpha - (alpha - 1.0) / 2.0;
|
||||
} else if (rate_control_region_ == kRcMaxUnknown) {
|
||||
alpha = alpha + (alpha - 1.0) * 2.0;
|
||||
}
|
||||
|
||||
return alpha;
|
||||
}
|
||||
|
||||
void MimdRateControl::UpdateChangePeriod(int64_t now_ms) {
|
||||
int64_t change_period = 0;
|
||||
if (last_change_ms_ > -1) {
|
||||
change_period = now_ms - last_change_ms_;
|
||||
}
|
||||
last_change_ms_ = now_ms;
|
||||
avg_change_period_ = 0.9f * avg_change_period_ + 0.1f * change_period;
|
||||
}
|
||||
|
||||
void MimdRateControl::UpdateMaxBitRateEstimate(float incoming_bit_rate_kbps) {
|
||||
const float alpha = 0.05f;
|
||||
if (avg_max_bit_rate_ == -1.0f) {
|
||||
avg_max_bit_rate_ = incoming_bit_rate_kbps;
|
||||
} else {
|
||||
avg_max_bit_rate_ = (1 - alpha) * avg_max_bit_rate_ +
|
||||
alpha * incoming_bit_rate_kbps;
|
||||
}
|
||||
// Estimate the max bit rate variance and normalize the variance
|
||||
// with the average max bit rate.
|
||||
const float norm = std::max(avg_max_bit_rate_, 1.0f);
|
||||
var_max_bit_rate_ = (1 - alpha) * var_max_bit_rate_ +
|
||||
alpha * (avg_max_bit_rate_ - incoming_bit_rate_kbps) *
|
||||
(avg_max_bit_rate_ - incoming_bit_rate_kbps) / norm;
|
||||
// 0.4 ~= 14 kbit/s at 500 kbit/s
|
||||
if (var_max_bit_rate_ < 0.4f) {
|
||||
var_max_bit_rate_ = 0.4f;
|
||||
}
|
||||
// 2.5f ~= 35 kbit/s at 500 kbit/s
|
||||
if (var_max_bit_rate_ > 2.5f) {
|
||||
var_max_bit_rate_ = 2.5f;
|
||||
}
|
||||
}
|
||||
|
||||
void MimdRateControl::ChangeState(const RateControlInput& input,
|
||||
int64_t now_ms) {
|
||||
switch (current_input_._bwState) {
|
||||
case kBwNormal:
|
||||
if (rate_control_state_ == kRcHold) {
|
||||
last_bit_rate_change_ = now_ms;
|
||||
ChangeState(kRcIncrease);
|
||||
}
|
||||
break;
|
||||
case kBwOverusing:
|
||||
if (rate_control_state_ != kRcDecrease) {
|
||||
ChangeState(kRcDecrease);
|
||||
}
|
||||
break;
|
||||
case kBwUnderusing:
|
||||
ChangeState(kRcHold);
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
void MimdRateControl::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 MimdRateControl::ChangeState(RateControlState new_state) {
|
||||
came_from_state_ = rate_control_state_;
|
||||
rate_control_state_ = new_state;
|
||||
}
|
||||
} // namespace webrtc
|
@ -1,80 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014 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_MIMD_RATE_CONTROL_H_
|
||||
#define WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_MIMD_RATE_CONTROL_H_
|
||||
|
||||
#include "webrtc/modules/remote_bitrate_estimator/include/bwe_defines.h"
|
||||
#include "webrtc/modules/remote_bitrate_estimator/remote_rate_control.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// A RemoteRateControl implementation based on multiplicative increases of
|
||||
// bitrate when no over-use is detected and multiplicative decreases when
|
||||
// over-uses are detected.
|
||||
class MimdRateControl : public RemoteRateControl {
|
||||
public:
|
||||
explicit MimdRateControl(uint32_t min_bitrate_bps);
|
||||
virtual ~MimdRateControl() {}
|
||||
|
||||
// Implements RemoteRateControl.
|
||||
RateControlType GetControlType() const override;
|
||||
uint32_t GetMinBitrate() const override;
|
||||
bool ValidEstimate() const override;
|
||||
int64_t GetFeedbackInterval() const override;
|
||||
bool TimeToReduceFurther(int64_t time_now,
|
||||
uint32_t incoming_bitrate_bps) const override;
|
||||
uint32_t LatestEstimate() const override;
|
||||
uint32_t UpdateBandwidthEstimate(int64_t now_ms) override;
|
||||
void SetRtt(int64_t rtt) override;
|
||||
RateControlRegion Update(const RateControlInput* input,
|
||||
int64_t now_ms) override;
|
||||
void SetEstimate(int bitrate_bps, int64_t now_ms) override;
|
||||
|
||||
private:
|
||||
uint32_t ChangeBitRate(uint32_t current_bit_rate,
|
||||
uint32_t incoming_bit_rate,
|
||||
double delay_factor,
|
||||
int64_t now_ms);
|
||||
double RateIncreaseFactor(int64_t now_ms,
|
||||
int64_t last_ms,
|
||||
int64_t reaction_time_ms,
|
||||
double noise_var) const;
|
||||
void UpdateChangePeriod(int64_t now_ms);
|
||||
void UpdateMaxBitRateEstimate(float incoming_bit_rate_kbps);
|
||||
void ChangeState(const RateControlInput& input, int64_t now_ms);
|
||||
void ChangeState(RateControlState new_state);
|
||||
void ChangeRegion(RateControlRegion region);
|
||||
|
||||
uint32_t min_configured_bit_rate_;
|
||||
uint32_t max_configured_bit_rate_;
|
||||
uint32_t current_bit_rate_;
|
||||
uint32_t max_hold_rate_;
|
||||
float avg_max_bit_rate_;
|
||||
float var_max_bit_rate_;
|
||||
RateControlState rate_control_state_;
|
||||
RateControlState came_from_state_;
|
||||
RateControlRegion rate_control_region_;
|
||||
int64_t last_bit_rate_change_;
|
||||
RateControlInput current_input_;
|
||||
bool updated_;
|
||||
int64_t time_first_incoming_estimate_;
|
||||
bool initialized_bit_rate_;
|
||||
float avg_change_period_;
|
||||
int64_t last_change_ms_;
|
||||
float beta_;
|
||||
int64_t rtt_;
|
||||
int64_t time_of_last_log_;
|
||||
|
||||
DISALLOW_IMPLICIT_CONSTRUCTORS(MimdRateControl);
|
||||
};
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_MIMD_RATE_CONTROL_H_
|
@ -25,8 +25,6 @@
|
||||
'aimd_rate_control.h',
|
||||
'inter_arrival.cc',
|
||||
'inter_arrival.h',
|
||||
'mimd_rate_control.cc',
|
||||
'mimd_rate_control.h',
|
||||
'overuse_detector.cc',
|
||||
'overuse_detector.h',
|
||||
'overuse_estimator.cc',
|
||||
@ -34,9 +32,9 @@
|
||||
'rate_statistics.cc',
|
||||
'rate_statistics.h',
|
||||
'remote_bitrate_estimator_abs_send_time.cc',
|
||||
'remote_bitrate_estimator_abs_send_time.h',
|
||||
'remote_bitrate_estimator_single_stream.cc',
|
||||
'remote_rate_control.cc',
|
||||
'remote_rate_control.h',
|
||||
'remote_bitrate_estimator_single_stream.h',
|
||||
'test/bwe_test_logging.cc',
|
||||
'test/bwe_test_logging.h',
|
||||
], # source
|
||||
|
@ -8,18 +8,14 @@
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <map>
|
||||
|
||||
#include "webrtc/base/constructormagic.h"
|
||||
#include "webrtc/base/scoped_ptr.h"
|
||||
#include "webrtc/base/thread_annotations.h"
|
||||
#include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
|
||||
#include "webrtc/modules/remote_bitrate_estimator/inter_arrival.h"
|
||||
#include "webrtc/modules/remote_bitrate_estimator/overuse_detector.h"
|
||||
#include "webrtc/modules/remote_bitrate_estimator/overuse_estimator.h"
|
||||
#include "webrtc/modules/remote_bitrate_estimator/remote_rate_control.h"
|
||||
#include "webrtc/modules/remote_bitrate_estimator/rate_statistics.h"
|
||||
#include "webrtc/system_wrappers/interface/clock.h"
|
||||
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
|
||||
#include "webrtc/system_wrappers/interface/logging.h"
|
||||
@ -67,74 +63,9 @@ std::vector<K> Keys(const std::map<K, V>& map) {
|
||||
return keys;
|
||||
}
|
||||
|
||||
struct Probe {
|
||||
Probe(int64_t send_time_ms, int64_t recv_time_ms, size_t payload_size)
|
||||
: send_time_ms(send_time_ms),
|
||||
recv_time_ms(recv_time_ms),
|
||||
payload_size(payload_size) {}
|
||||
int64_t send_time_ms;
|
||||
int64_t recv_time_ms;
|
||||
size_t payload_size;
|
||||
};
|
||||
|
||||
struct Cluster {
|
||||
Cluster()
|
||||
: send_mean_ms(0.0f),
|
||||
recv_mean_ms(0.0f),
|
||||
mean_size(0),
|
||||
count(0),
|
||||
num_above_min_delta(0) {}
|
||||
|
||||
int GetSendBitrateBps() const {
|
||||
assert(send_mean_ms > 0);
|
||||
return mean_size * 8 * 1000 / send_mean_ms;
|
||||
}
|
||||
|
||||
int GetRecvBitrateBps() const {
|
||||
assert(recv_mean_ms > 0);
|
||||
return mean_size * 8 * 1000 / recv_mean_ms;
|
||||
}
|
||||
|
||||
float send_mean_ms;
|
||||
float recv_mean_ms;
|
||||
// TODO(holmer): Add some variance metric as well?
|
||||
size_t mean_size;
|
||||
int count;
|
||||
int num_above_min_delta;
|
||||
};
|
||||
|
||||
class RemoteBitrateEstimatorAbsSendTimeImpl : public RemoteBitrateEstimator {
|
||||
public:
|
||||
RemoteBitrateEstimatorAbsSendTimeImpl(RemoteBitrateObserver* observer,
|
||||
Clock* clock,
|
||||
RateControlType control_type,
|
||||
uint32_t min_bitrate_bps);
|
||||
virtual ~RemoteBitrateEstimatorAbsSendTimeImpl() {}
|
||||
|
||||
void IncomingPacketFeedbackVector(
|
||||
const std::vector<PacketInfo>& packet_feedback_vector) override;
|
||||
|
||||
void IncomingPacket(int64_t arrival_time_ms,
|
||||
size_t payload_size,
|
||||
const RTPHeader& header,
|
||||
bool was_paced) override;
|
||||
// This class relies on Process() being called periodically (at least once
|
||||
// every other second) for streams to be timed out properly. Therefore it
|
||||
// shouldn't be detached from the ProcessThread except if it's about to be
|
||||
// deleted.
|
||||
int32_t Process() override;
|
||||
int64_t TimeUntilNextProcess() override;
|
||||
void OnRttUpdate(int64_t rtt) override;
|
||||
void RemoveStream(unsigned int ssrc) override;
|
||||
bool LatestEstimate(std::vector<unsigned int>* ssrcs,
|
||||
unsigned int* bitrate_bps) const override;
|
||||
bool GetStats(ReceiveBandwidthEstimatorStats* output) const override;
|
||||
|
||||
private:
|
||||
typedef std::map<unsigned int, int64_t> Ssrcs;
|
||||
|
||||
static bool IsWithinClusterBounds(int send_delta_ms,
|
||||
const Cluster& cluster_aggregate) {
|
||||
bool RemoteBitrateEstimatorAbsSendTime::IsWithinClusterBounds(
|
||||
int send_delta_ms,
|
||||
const Cluster& cluster_aggregate) {
|
||||
if (cluster_aggregate.count == 0)
|
||||
return true;
|
||||
float cluster_mean = cluster_aggregate.send_mean_ms /
|
||||
@ -142,91 +73,43 @@ class RemoteBitrateEstimatorAbsSendTimeImpl : public RemoteBitrateEstimator {
|
||||
return fabs(static_cast<float>(send_delta_ms) - cluster_mean) < 2.5f;
|
||||
}
|
||||
|
||||
static void AddCluster(std::list<Cluster>* clusters, Cluster* cluster) {
|
||||
void RemoteBitrateEstimatorAbsSendTime::AddCluster(
|
||||
std::list<Cluster>* clusters,
|
||||
Cluster* cluster) {
|
||||
cluster->send_mean_ms /= static_cast<float>(cluster->count);
|
||||
cluster->recv_mean_ms /= static_cast<float>(cluster->count);
|
||||
cluster->mean_size /= cluster->count;
|
||||
clusters->push_back(*cluster);
|
||||
}
|
||||
|
||||
int Id() const {
|
||||
int RemoteBitrateEstimatorAbsSendTime::Id() const {
|
||||
return static_cast<int>(reinterpret_cast<uint64_t>(this));
|
||||
}
|
||||
|
||||
void IncomingPacketInfo(int64_t arrival_time_ms,
|
||||
uint32_t send_time_24bits,
|
||||
size_t payload_size,
|
||||
uint32_t ssrc,
|
||||
bool was_paced);
|
||||
|
||||
bool IsProbe(int64_t send_time_ms, int payload_size) const
|
||||
EXCLUSIVE_LOCKS_REQUIRED(crit_sect_.get());
|
||||
|
||||
// Triggers a new estimate calculation.
|
||||
void UpdateEstimate(int64_t now_ms)
|
||||
EXCLUSIVE_LOCKS_REQUIRED(crit_sect_.get());
|
||||
|
||||
void UpdateStats(int propagation_delta_ms, int64_t now_ms)
|
||||
EXCLUSIVE_LOCKS_REQUIRED(crit_sect_.get());
|
||||
|
||||
void ComputeClusters(std::list<Cluster>* clusters) const;
|
||||
|
||||
std::list<Cluster>::const_iterator FindBestProbe(
|
||||
const std::list<Cluster>& clusters) const
|
||||
EXCLUSIVE_LOCKS_REQUIRED(crit_sect_.get());
|
||||
|
||||
void ProcessClusters(int64_t now_ms)
|
||||
EXCLUSIVE_LOCKS_REQUIRED(crit_sect_.get());
|
||||
|
||||
bool IsBitrateImproving(int probe_bitrate_bps) const
|
||||
EXCLUSIVE_LOCKS_REQUIRED(crit_sect_.get());
|
||||
|
||||
rtc::scoped_ptr<CriticalSectionWrapper> crit_sect_;
|
||||
RemoteBitrateObserver* observer_ GUARDED_BY(crit_sect_.get());
|
||||
Clock* clock_;
|
||||
Ssrcs ssrcs_ GUARDED_BY(crit_sect_.get());
|
||||
rtc::scoped_ptr<InterArrival> inter_arrival_ GUARDED_BY(crit_sect_.get());
|
||||
OveruseEstimator estimator_ GUARDED_BY(crit_sect_.get());
|
||||
OveruseDetector detector_ GUARDED_BY(crit_sect_.get());
|
||||
RateStatistics incoming_bitrate_ GUARDED_BY(crit_sect_.get());
|
||||
rtc::scoped_ptr<RemoteRateControl> remote_rate_ GUARDED_BY(crit_sect_.get());
|
||||
int64_t last_process_time_;
|
||||
std::vector<int> recent_propagation_delta_ms_ GUARDED_BY(crit_sect_.get());
|
||||
std::vector<int64_t> recent_update_time_ms_ GUARDED_BY(crit_sect_.get());
|
||||
int64_t process_interval_ms_ GUARDED_BY(crit_sect_.get());
|
||||
int total_propagation_delta_ms_ GUARDED_BY(crit_sect_.get());
|
||||
|
||||
std::list<Probe> probes_;
|
||||
size_t total_probes_received_;
|
||||
int64_t first_packet_time_ms_;
|
||||
|
||||
DISALLOW_IMPLICIT_CONSTRUCTORS(RemoteBitrateEstimatorAbsSendTimeImpl);
|
||||
};
|
||||
|
||||
RemoteBitrateEstimatorAbsSendTimeImpl::RemoteBitrateEstimatorAbsSendTimeImpl(
|
||||
RemoteBitrateObserver* observer,
|
||||
Clock* clock,
|
||||
RateControlType control_type,
|
||||
uint32_t min_bitrate_bps)
|
||||
: crit_sect_(CriticalSectionWrapper::CreateCriticalSection()),
|
||||
observer_(observer),
|
||||
clock_(clock),
|
||||
ssrcs_(),
|
||||
inter_arrival_(),
|
||||
estimator_(OverUseDetectorOptions()),
|
||||
detector_(OverUseDetectorOptions()),
|
||||
incoming_bitrate_(1000, 8000),
|
||||
remote_rate_(RemoteRateControl::Create(control_type, min_bitrate_bps)),
|
||||
last_process_time_(-1),
|
||||
process_interval_ms_(kProcessIntervalMs),
|
||||
total_propagation_delta_ms_(0),
|
||||
total_probes_received_(0),
|
||||
first_packet_time_ms_(-1) {
|
||||
RemoteBitrateEstimatorAbsSendTime::RemoteBitrateEstimatorAbsSendTime(
|
||||
RemoteBitrateObserver* observer,
|
||||
Clock* clock,
|
||||
uint32_t min_bitrate_bps)
|
||||
: crit_sect_(CriticalSectionWrapper::CreateCriticalSection()),
|
||||
observer_(observer),
|
||||
clock_(clock),
|
||||
ssrcs_(),
|
||||
inter_arrival_(),
|
||||
estimator_(OverUseDetectorOptions()),
|
||||
detector_(OverUseDetectorOptions()),
|
||||
incoming_bitrate_(1000, 8000),
|
||||
remote_rate_(min_bitrate_bps),
|
||||
last_process_time_(-1),
|
||||
process_interval_ms_(kProcessIntervalMs),
|
||||
total_propagation_delta_ms_(0),
|
||||
total_probes_received_(0),
|
||||
first_packet_time_ms_(-1) {
|
||||
assert(observer_);
|
||||
assert(clock_);
|
||||
LOG(LS_INFO) << "RemoteBitrateEstimatorAbsSendTime: Instantiating.";
|
||||
}
|
||||
|
||||
void RemoteBitrateEstimatorAbsSendTimeImpl::ComputeClusters(
|
||||
void RemoteBitrateEstimatorAbsSendTime::ComputeClusters(
|
||||
std::list<Cluster>* clusters) const {
|
||||
Cluster current;
|
||||
int64_t prev_send_time = -1;
|
||||
@ -258,7 +141,7 @@ void RemoteBitrateEstimatorAbsSendTimeImpl::ComputeClusters(
|
||||
}
|
||||
|
||||
std::list<Cluster>::const_iterator
|
||||
RemoteBitrateEstimatorAbsSendTimeImpl::FindBestProbe(
|
||||
RemoteBitrateEstimatorAbsSendTime::FindBestProbe(
|
||||
const std::list<Cluster>& clusters) const {
|
||||
int highest_probe_bitrate_bps = 0;
|
||||
std::list<Cluster>::const_iterator best_it = clusters.end();
|
||||
@ -290,7 +173,7 @@ RemoteBitrateEstimatorAbsSendTimeImpl::FindBestProbe(
|
||||
return best_it;
|
||||
}
|
||||
|
||||
void RemoteBitrateEstimatorAbsSendTimeImpl::ProcessClusters(int64_t now_ms) {
|
||||
void RemoteBitrateEstimatorAbsSendTime::ProcessClusters(int64_t now_ms) {
|
||||
std::list<Cluster> clusters;
|
||||
ComputeClusters(&clusters);
|
||||
if (clusters.empty()) {
|
||||
@ -312,7 +195,7 @@ void RemoteBitrateEstimatorAbsSendTimeImpl::ProcessClusters(int64_t now_ms) {
|
||||
<< " bps. Mean send delta: " << best_it->send_mean_ms
|
||||
<< " ms, mean recv delta: " << best_it->recv_mean_ms
|
||||
<< " ms, num probes: " << best_it->count;
|
||||
remote_rate_->SetEstimate(probe_bitrate_bps, now_ms);
|
||||
remote_rate_.SetEstimate(probe_bitrate_bps, now_ms);
|
||||
}
|
||||
}
|
||||
|
||||
@ -322,16 +205,16 @@ void RemoteBitrateEstimatorAbsSendTimeImpl::ProcessClusters(int64_t now_ms) {
|
||||
probes_.clear();
|
||||
}
|
||||
|
||||
bool RemoteBitrateEstimatorAbsSendTimeImpl::IsBitrateImproving(
|
||||
bool RemoteBitrateEstimatorAbsSendTime::IsBitrateImproving(
|
||||
int new_bitrate_bps) const {
|
||||
bool initial_probe = !remote_rate_->ValidEstimate() && new_bitrate_bps > 0;
|
||||
bool initial_probe = !remote_rate_.ValidEstimate() && new_bitrate_bps > 0;
|
||||
bool bitrate_above_estimate =
|
||||
remote_rate_->ValidEstimate() &&
|
||||
new_bitrate_bps > static_cast<int>(remote_rate_->LatestEstimate());
|
||||
remote_rate_.ValidEstimate() &&
|
||||
new_bitrate_bps > static_cast<int>(remote_rate_.LatestEstimate());
|
||||
return initial_probe || bitrate_above_estimate;
|
||||
}
|
||||
|
||||
void RemoteBitrateEstimatorAbsSendTimeImpl::IncomingPacketFeedbackVector(
|
||||
void RemoteBitrateEstimatorAbsSendTime::IncomingPacketFeedbackVector(
|
||||
const std::vector<PacketInfo>& packet_feedback_vector) {
|
||||
for (const auto& packet_info : packet_feedback_vector) {
|
||||
// TODO(holmer): We should get rid of this conversion if possible as we may
|
||||
@ -344,11 +227,10 @@ void RemoteBitrateEstimatorAbsSendTimeImpl::IncomingPacketFeedbackVector(
|
||||
}
|
||||
}
|
||||
|
||||
void RemoteBitrateEstimatorAbsSendTimeImpl::IncomingPacket(
|
||||
int64_t arrival_time_ms,
|
||||
size_t payload_size,
|
||||
const RTPHeader& header,
|
||||
bool was_paced) {
|
||||
void RemoteBitrateEstimatorAbsSendTime::IncomingPacket(int64_t arrival_time_ms,
|
||||
size_t payload_size,
|
||||
const RTPHeader& header,
|
||||
bool was_paced) {
|
||||
if (!header.extension.hasAbsoluteSendTime) {
|
||||
LOG(LS_WARNING) << "RemoteBitrateEstimatorAbsSendTimeImpl: Incoming packet "
|
||||
"is missing absolute send time extension!";
|
||||
@ -357,7 +239,7 @@ void RemoteBitrateEstimatorAbsSendTimeImpl::IncomingPacket(
|
||||
payload_size, header.ssrc, was_paced);
|
||||
}
|
||||
|
||||
void RemoteBitrateEstimatorAbsSendTimeImpl::IncomingPacketInfo(
|
||||
void RemoteBitrateEstimatorAbsSendTime::IncomingPacketInfo(
|
||||
int64_t arrival_time_ms,
|
||||
uint32_t send_time_24bits,
|
||||
size_t payload_size,
|
||||
@ -385,7 +267,7 @@ void RemoteBitrateEstimatorAbsSendTimeImpl::IncomingPacketInfo(
|
||||
int size_delta = 0;
|
||||
// For now only try to detect probes while we don't have a valid estimate.
|
||||
if (was_paced &&
|
||||
(!remote_rate_->ValidEstimate() ||
|
||||
(!remote_rate_.ValidEstimate() ||
|
||||
now_ms - first_packet_time_ms_ < kInitialProbingIntervalMs)) {
|
||||
// TODO(holmer): Use a map instead to get correct order?
|
||||
if (total_probes_received_ < kMaxProbePackets) {
|
||||
@ -405,9 +287,9 @@ void RemoteBitrateEstimatorAbsSendTimeImpl::IncomingPacketInfo(
|
||||
ProcessClusters(now_ms);
|
||||
}
|
||||
if (!inter_arrival_.get()) {
|
||||
inter_arrival_.reset(new InterArrival(
|
||||
(kTimestampGroupLengthMs << kInterArrivalShift) / 1000, kTimestampToMs,
|
||||
remote_rate_->GetControlType() == kAimdControl));
|
||||
inter_arrival_.reset(
|
||||
new InterArrival((kTimestampGroupLengthMs << kInterArrivalShift) / 1000,
|
||||
kTimestampToMs, true));
|
||||
}
|
||||
if (inter_arrival_->ComputeDeltas(timestamp, arrival_time_ms, payload_size,
|
||||
&ts_delta, &t_delta, &size_delta)) {
|
||||
@ -420,7 +302,7 @@ void RemoteBitrateEstimatorAbsSendTimeImpl::IncomingPacketInfo(
|
||||
if (detector_.State() == kBwOverusing) {
|
||||
unsigned int incoming_bitrate = incoming_bitrate_.Rate(now_ms);
|
||||
if (prior_state != kBwOverusing ||
|
||||
remote_rate_->TimeToReduceFurther(now_ms, incoming_bitrate)) {
|
||||
remote_rate_.TimeToReduceFurther(now_ms, incoming_bitrate)) {
|
||||
// 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.
|
||||
@ -429,7 +311,7 @@ void RemoteBitrateEstimatorAbsSendTimeImpl::IncomingPacketInfo(
|
||||
}
|
||||
}
|
||||
|
||||
int32_t RemoteBitrateEstimatorAbsSendTimeImpl::Process() {
|
||||
int32_t RemoteBitrateEstimatorAbsSendTime::Process() {
|
||||
if (TimeUntilNextProcess() > 0) {
|
||||
return 0;
|
||||
}
|
||||
@ -441,7 +323,7 @@ int32_t RemoteBitrateEstimatorAbsSendTimeImpl::Process() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int64_t RemoteBitrateEstimatorAbsSendTimeImpl::TimeUntilNextProcess() {
|
||||
int64_t RemoteBitrateEstimatorAbsSendTime::TimeUntilNextProcess() {
|
||||
if (last_process_time_ < 0) {
|
||||
return 0;
|
||||
}
|
||||
@ -452,7 +334,7 @@ int64_t RemoteBitrateEstimatorAbsSendTimeImpl::TimeUntilNextProcess() {
|
||||
}
|
||||
}
|
||||
|
||||
void RemoteBitrateEstimatorAbsSendTimeImpl::UpdateEstimate(int64_t now_ms) {
|
||||
void RemoteBitrateEstimatorAbsSendTime::UpdateEstimate(int64_t now_ms) {
|
||||
if (!inter_arrival_.get()) {
|
||||
// No packets have been received on the active streams.
|
||||
return;
|
||||
@ -475,44 +357,44 @@ void RemoteBitrateEstimatorAbsSendTimeImpl::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);
|
||||
unsigned int target_bitrate = remote_rate_->UpdateBandwidthEstimate(now_ms);
|
||||
if (remote_rate_->ValidEstimate()) {
|
||||
process_interval_ms_ = remote_rate_->GetFeedbackInterval();
|
||||
const RateControlRegion region = 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 RemoteBitrateEstimatorAbsSendTimeImpl::OnRttUpdate(int64_t rtt) {
|
||||
void RemoteBitrateEstimatorAbsSendTime::OnRttUpdate(int64_t rtt) {
|
||||
CriticalSectionScoped cs(crit_sect_.get());
|
||||
remote_rate_->SetRtt(rtt);
|
||||
remote_rate_.SetRtt(rtt);
|
||||
}
|
||||
|
||||
void RemoteBitrateEstimatorAbsSendTimeImpl::RemoveStream(unsigned int ssrc) {
|
||||
void RemoteBitrateEstimatorAbsSendTime::RemoveStream(unsigned int ssrc) {
|
||||
CriticalSectionScoped cs(crit_sect_.get());
|
||||
ssrcs_.erase(ssrc);
|
||||
}
|
||||
|
||||
bool RemoteBitrateEstimatorAbsSendTimeImpl::LatestEstimate(
|
||||
bool RemoteBitrateEstimatorAbsSendTime::LatestEstimate(
|
||||
std::vector<unsigned int>* ssrcs,
|
||||
unsigned int* bitrate_bps) const {
|
||||
CriticalSectionScoped cs(crit_sect_.get());
|
||||
assert(ssrcs);
|
||||
assert(bitrate_bps);
|
||||
if (!remote_rate_->ValidEstimate()) {
|
||||
if (!remote_rate_.ValidEstimate()) {
|
||||
return false;
|
||||
}
|
||||
*ssrcs = Keys(ssrcs_);
|
||||
if (ssrcs_.empty()) {
|
||||
*bitrate_bps = 0;
|
||||
} else {
|
||||
*bitrate_bps = remote_rate_->LatestEstimate();
|
||||
*bitrate_bps = remote_rate_.LatestEstimate();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RemoteBitrateEstimatorAbsSendTimeImpl::GetStats(
|
||||
bool RemoteBitrateEstimatorAbsSendTime::GetStats(
|
||||
ReceiveBandwidthEstimatorStats* output) const {
|
||||
{
|
||||
CriticalSectionScoped cs(crit_sect_.get());
|
||||
@ -527,8 +409,8 @@ bool RemoteBitrateEstimatorAbsSendTimeImpl::GetStats(
|
||||
return true;
|
||||
}
|
||||
|
||||
void RemoteBitrateEstimatorAbsSendTimeImpl::UpdateStats(
|
||||
int propagation_delta_ms, int64_t now_ms) {
|
||||
void RemoteBitrateEstimatorAbsSendTime::UpdateStats(int propagation_delta_ms,
|
||||
int64_t now_ms) {
|
||||
// The caller must enter crit_sect_ before the call.
|
||||
|
||||
// Remove the oldest entry if the size limit is reached.
|
||||
@ -548,17 +430,4 @@ void RemoteBitrateEstimatorAbsSendTimeImpl::UpdateStats(
|
||||
total_propagation_delta_ms_ =
|
||||
std::max(total_propagation_delta_ms_ + propagation_delta_ms, 0);
|
||||
}
|
||||
|
||||
RemoteBitrateEstimator* AbsoluteSendTimeRemoteBitrateEstimatorFactory::Create(
|
||||
RemoteBitrateObserver* observer,
|
||||
Clock* clock,
|
||||
RateControlType control_type,
|
||||
uint32_t min_bitrate_bps) const {
|
||||
LOG(LS_INFO) << "AbsoluteSendTimeRemoteBitrateEstimatorFactory: "
|
||||
"Instantiating.";
|
||||
return new RemoteBitrateEstimatorAbsSendTimeImpl(observer,
|
||||
clock,
|
||||
control_type,
|
||||
min_bitrate_bps);
|
||||
}
|
||||
} // namespace webrtc
|
||||
|
@ -0,0 +1,154 @@
|
||||
/*
|
||||
* 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_REMOTE_BITRATE_ESTIMATOR_ABS_SEND_TIME_H_
|
||||
#define WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_REMOTE_BITRATE_ESTIMATOR_ABS_SEND_TIME_H_
|
||||
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include "webrtc/base/checks.h"
|
||||
#include "webrtc/base/scoped_ptr.h"
|
||||
#include "webrtc/modules/remote_bitrate_estimator/aimd_rate_control.h"
|
||||
#include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
|
||||
#include "webrtc/modules/remote_bitrate_estimator/inter_arrival.h"
|
||||
#include "webrtc/modules/remote_bitrate_estimator/overuse_detector.h"
|
||||
#include "webrtc/modules/remote_bitrate_estimator/overuse_estimator.h"
|
||||
#include "webrtc/modules/remote_bitrate_estimator/rate_statistics.h"
|
||||
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
struct Probe {
|
||||
Probe(int64_t send_time_ms, int64_t recv_time_ms, size_t payload_size)
|
||||
: send_time_ms(send_time_ms),
|
||||
recv_time_ms(recv_time_ms),
|
||||
payload_size(payload_size) {}
|
||||
int64_t send_time_ms;
|
||||
int64_t recv_time_ms;
|
||||
size_t payload_size;
|
||||
};
|
||||
|
||||
struct Cluster {
|
||||
Cluster()
|
||||
: send_mean_ms(0.0f),
|
||||
recv_mean_ms(0.0f),
|
||||
mean_size(0),
|
||||
count(0),
|
||||
num_above_min_delta(0) {}
|
||||
|
||||
int GetSendBitrateBps() const {
|
||||
CHECK_GT(send_mean_ms, 0.0f);
|
||||
return mean_size * 8 * 1000 / send_mean_ms;
|
||||
}
|
||||
|
||||
int GetRecvBitrateBps() const {
|
||||
CHECK_GT(recv_mean_ms, 0.0f);
|
||||
return mean_size * 8 * 1000 / recv_mean_ms;
|
||||
}
|
||||
|
||||
float send_mean_ms;
|
||||
float recv_mean_ms;
|
||||
// TODO(holmer): Add some variance metric as well?
|
||||
size_t mean_size;
|
||||
int count;
|
||||
int num_above_min_delta;
|
||||
};
|
||||
|
||||
class RemoteBitrateEstimatorAbsSendTime : public RemoteBitrateEstimator {
|
||||
public:
|
||||
RemoteBitrateEstimatorAbsSendTime(RemoteBitrateObserver* observer,
|
||||
Clock* clock,
|
||||
uint32_t min_bitrate_bps);
|
||||
virtual ~RemoteBitrateEstimatorAbsSendTime() {}
|
||||
|
||||
void IncomingPacketFeedbackVector(
|
||||
const std::vector<PacketInfo>& packet_feedback_vector) override;
|
||||
|
||||
void IncomingPacket(int64_t arrival_time_ms,
|
||||
size_t payload_size,
|
||||
const RTPHeader& header,
|
||||
bool was_paced) override;
|
||||
// This class relies on Process() being called periodically (at least once
|
||||
// every other second) for streams to be timed out properly. Therefore it
|
||||
// shouldn't be detached from the ProcessThread except if it's about to be
|
||||
// deleted.
|
||||
int32_t Process() override;
|
||||
int64_t TimeUntilNextProcess() override;
|
||||
void OnRttUpdate(int64_t rtt) override;
|
||||
void RemoveStream(unsigned int ssrc) override;
|
||||
bool LatestEstimate(std::vector<unsigned int>* ssrcs,
|
||||
unsigned int* bitrate_bps) const override;
|
||||
bool GetStats(ReceiveBandwidthEstimatorStats* output) const override;
|
||||
|
||||
private:
|
||||
typedef std::map<unsigned int, int64_t> Ssrcs;
|
||||
|
||||
static bool IsWithinClusterBounds(int send_delta_ms,
|
||||
const Cluster& cluster_aggregate);
|
||||
|
||||
static void AddCluster(std::list<Cluster>* clusters, Cluster* cluster);
|
||||
|
||||
int Id() const;
|
||||
|
||||
void IncomingPacketInfo(int64_t arrival_time_ms,
|
||||
uint32_t send_time_24bits,
|
||||
size_t payload_size,
|
||||
uint32_t ssrc,
|
||||
bool was_paced);
|
||||
|
||||
bool IsProbe(int64_t send_time_ms, int payload_size) const
|
||||
EXCLUSIVE_LOCKS_REQUIRED(crit_sect_.get());
|
||||
|
||||
// Triggers a new estimate calculation.
|
||||
void UpdateEstimate(int64_t now_ms)
|
||||
EXCLUSIVE_LOCKS_REQUIRED(crit_sect_.get());
|
||||
|
||||
void UpdateStats(int propagation_delta_ms, int64_t now_ms)
|
||||
EXCLUSIVE_LOCKS_REQUIRED(crit_sect_.get());
|
||||
|
||||
void ComputeClusters(std::list<Cluster>* clusters) const;
|
||||
|
||||
std::list<Cluster>::const_iterator FindBestProbe(
|
||||
const std::list<Cluster>& clusters) const
|
||||
EXCLUSIVE_LOCKS_REQUIRED(crit_sect_.get());
|
||||
|
||||
void ProcessClusters(int64_t now_ms)
|
||||
EXCLUSIVE_LOCKS_REQUIRED(crit_sect_.get());
|
||||
|
||||
bool IsBitrateImproving(int probe_bitrate_bps) const
|
||||
EXCLUSIVE_LOCKS_REQUIRED(crit_sect_.get());
|
||||
|
||||
rtc::scoped_ptr<CriticalSectionWrapper> crit_sect_;
|
||||
RemoteBitrateObserver* observer_ GUARDED_BY(crit_sect_.get());
|
||||
Clock* clock_;
|
||||
Ssrcs ssrcs_ GUARDED_BY(crit_sect_.get());
|
||||
rtc::scoped_ptr<InterArrival> inter_arrival_ GUARDED_BY(crit_sect_.get());
|
||||
OveruseEstimator estimator_ GUARDED_BY(crit_sect_.get());
|
||||
OveruseDetector detector_ GUARDED_BY(crit_sect_.get());
|
||||
RateStatistics incoming_bitrate_ GUARDED_BY(crit_sect_.get());
|
||||
AimdRateControl remote_rate_ GUARDED_BY(crit_sect_.get());
|
||||
int64_t last_process_time_;
|
||||
std::vector<int> recent_propagation_delta_ms_ GUARDED_BY(crit_sect_.get());
|
||||
std::vector<int64_t> recent_update_time_ms_ GUARDED_BY(crit_sect_.get());
|
||||
int64_t process_interval_ms_ GUARDED_BY(crit_sect_.get());
|
||||
int total_propagation_delta_ms_ GUARDED_BY(crit_sect_.get());
|
||||
|
||||
std::list<Probe> probes_;
|
||||
size_t total_probes_received_;
|
||||
int64_t first_packet_time_ms_;
|
||||
|
||||
DISALLOW_IMPLICIT_CONSTRUCTORS(RemoteBitrateEstimatorAbsSendTime);
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_REMOTE_BITRATE_ESTIMATOR_ABS_SEND_TIME_H_
|
@ -9,6 +9,7 @@
|
||||
*/
|
||||
|
||||
#include "webrtc/base/constructormagic.h"
|
||||
#include "webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time.h"
|
||||
#include "webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_unittest_helper.h"
|
||||
|
||||
namespace webrtc {
|
||||
@ -20,12 +21,9 @@ class RemoteBitrateEstimatorAbsSendTimeTest :
|
||||
|
||||
RemoteBitrateEstimatorAbsSendTimeTest() {}
|
||||
virtual void SetUp() {
|
||||
bitrate_estimator_.reset(
|
||||
AbsoluteSendTimeRemoteBitrateEstimatorFactory().Create(
|
||||
bitrate_observer_.get(),
|
||||
&clock_,
|
||||
kAimdControl,
|
||||
kRemoteBitrateEstimatorMinBitrateBps));
|
||||
bitrate_estimator_.reset(new RemoteBitrateEstimatorAbsSendTime(
|
||||
bitrate_observer_.get(), &clock_,
|
||||
kRemoteBitrateEstimatorMinBitrateBps));
|
||||
}
|
||||
protected:
|
||||
DISALLOW_COPY_AND_ASSIGN(RemoteBitrateEstimatorAbsSendTimeTest);
|
||||
|
@ -7,17 +7,16 @@
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#include <map>
|
||||
|
||||
#include "webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.h"
|
||||
|
||||
#include "webrtc/base/constructormagic.h"
|
||||
#include "webrtc/base/scoped_ptr.h"
|
||||
#include "webrtc/base/thread_annotations.h"
|
||||
#include "webrtc/modules/remote_bitrate_estimator/rate_statistics.h"
|
||||
#include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
|
||||
#include "webrtc/modules/remote_bitrate_estimator/inter_arrival.h"
|
||||
#include "webrtc/modules/remote_bitrate_estimator/overuse_detector.h"
|
||||
#include "webrtc/modules/remote_bitrate_estimator/overuse_estimator.h"
|
||||
#include "webrtc/modules/remote_bitrate_estimator/remote_rate_control.h"
|
||||
#include "webrtc/modules/remote_bitrate_estimator/aimd_rate_control.h"
|
||||
#include "webrtc/system_wrappers/interface/clock.h"
|
||||
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
|
||||
#include "webrtc/system_wrappers/interface/logging.h"
|
||||
@ -28,28 +27,7 @@ namespace webrtc {
|
||||
enum { kTimestampGroupLengthMs = 5 };
|
||||
static const double kTimestampToMs = 1.0 / 90.0;
|
||||
|
||||
class RemoteBitrateEstimatorImpl : public RemoteBitrateEstimator {
|
||||
public:
|
||||
RemoteBitrateEstimatorImpl(RemoteBitrateObserver* observer,
|
||||
Clock* clock,
|
||||
RateControlType control_type,
|
||||
uint32_t min_bitrate_bps);
|
||||
virtual ~RemoteBitrateEstimatorImpl();
|
||||
|
||||
void IncomingPacket(int64_t arrival_time_ms,
|
||||
size_t payload_size,
|
||||
const RTPHeader& header,
|
||||
bool was_paced) override;
|
||||
int32_t Process() override;
|
||||
int64_t TimeUntilNextProcess() override;
|
||||
void OnRttUpdate(int64_t rtt) override;
|
||||
void RemoveStream(unsigned int ssrc) override;
|
||||
bool LatestEstimate(std::vector<unsigned int>* ssrcs,
|
||||
unsigned int* bitrate_bps) const override;
|
||||
bool GetStats(ReceiveBandwidthEstimatorStats* output) const override;
|
||||
|
||||
private:
|
||||
struct Detector {
|
||||
struct RemoteBitrateEstimatorSingleStream::Detector {
|
||||
explicit Detector(int64_t last_packet_time_ms,
|
||||
const OverUseDetectorOptions& options,
|
||||
bool enable_burst_grouping)
|
||||
@ -64,43 +42,22 @@ class RemoteBitrateEstimatorImpl : public RemoteBitrateEstimator {
|
||||
OveruseDetector detector;
|
||||
};
|
||||
|
||||
typedef std::map<unsigned int, Detector*> SsrcOveruseEstimatorMap;
|
||||
|
||||
// Triggers a new estimate calculation.
|
||||
void UpdateEstimate(int64_t time_now)
|
||||
EXCLUSIVE_LOCKS_REQUIRED(crit_sect_.get());
|
||||
|
||||
void GetSsrcs(std::vector<unsigned int>* ssrcs) const
|
||||
SHARED_LOCKS_REQUIRED(crit_sect_.get());
|
||||
|
||||
Clock* clock_;
|
||||
SsrcOveruseEstimatorMap overuse_detectors_ GUARDED_BY(crit_sect_.get());
|
||||
RateStatistics incoming_bitrate_ GUARDED_BY(crit_sect_.get());
|
||||
rtc::scoped_ptr<RemoteRateControl> remote_rate_ GUARDED_BY(crit_sect_.get());
|
||||
RemoteBitrateObserver* observer_ GUARDED_BY(crit_sect_.get());
|
||||
rtc::scoped_ptr<CriticalSectionWrapper> crit_sect_;
|
||||
int64_t last_process_time_;
|
||||
int64_t process_interval_ms_ GUARDED_BY(crit_sect_.get());
|
||||
|
||||
DISALLOW_IMPLICIT_CONSTRUCTORS(RemoteBitrateEstimatorImpl);
|
||||
};
|
||||
|
||||
RemoteBitrateEstimatorImpl::RemoteBitrateEstimatorImpl(
|
||||
RemoteBitrateObserver* observer,
|
||||
Clock* clock,
|
||||
RateControlType control_type,
|
||||
uint32_t min_bitrate_bps)
|
||||
: clock_(clock),
|
||||
incoming_bitrate_(1000, 8000),
|
||||
remote_rate_(RemoteRateControl::Create(control_type, min_bitrate_bps)),
|
||||
observer_(observer),
|
||||
crit_sect_(CriticalSectionWrapper::CreateCriticalSection()),
|
||||
last_process_time_(-1),
|
||||
process_interval_ms_(kProcessIntervalMs) {
|
||||
RemoteBitrateEstimatorSingleStream::RemoteBitrateEstimatorSingleStream(
|
||||
RemoteBitrateObserver* observer,
|
||||
Clock* clock,
|
||||
uint32_t min_bitrate_bps)
|
||||
: clock_(clock),
|
||||
incoming_bitrate_(1000, 8000),
|
||||
remote_rate_(new AimdRateControl(min_bitrate_bps)),
|
||||
observer_(observer),
|
||||
crit_sect_(CriticalSectionWrapper::CreateCriticalSection()),
|
||||
last_process_time_(-1),
|
||||
process_interval_ms_(kProcessIntervalMs) {
|
||||
assert(observer_);
|
||||
LOG(LS_INFO) << "RemoteBitrateEstimatorSingleStream: Instantiating.";
|
||||
}
|
||||
|
||||
RemoteBitrateEstimatorImpl::~RemoteBitrateEstimatorImpl() {
|
||||
RemoteBitrateEstimatorSingleStream::~RemoteBitrateEstimatorSingleStream() {
|
||||
while (!overuse_detectors_.empty()) {
|
||||
SsrcOveruseEstimatorMap::iterator it = overuse_detectors_.begin();
|
||||
delete it->second;
|
||||
@ -108,10 +65,10 @@ RemoteBitrateEstimatorImpl::~RemoteBitrateEstimatorImpl() {
|
||||
}
|
||||
}
|
||||
|
||||
void RemoteBitrateEstimatorImpl::IncomingPacket(int64_t arrival_time_ms,
|
||||
size_t payload_size,
|
||||
const RTPHeader& header,
|
||||
bool was_paced) {
|
||||
void RemoteBitrateEstimatorSingleStream::IncomingPacket(int64_t arrival_time_ms,
|
||||
size_t payload_size,
|
||||
const RTPHeader& header,
|
||||
bool was_paced) {
|
||||
uint32_t ssrc = header.ssrc;
|
||||
uint32_t rtp_timestamp = header.timestamp +
|
||||
header.extension.transmissionTimeOffset;
|
||||
@ -126,10 +83,8 @@ void RemoteBitrateEstimatorImpl::IncomingPacket(int64_t arrival_time_ms,
|
||||
// automatically cleaned up when we have one RemoteBitrateEstimator per REMB
|
||||
// group.
|
||||
std::pair<SsrcOveruseEstimatorMap::iterator, bool> insert_result =
|
||||
overuse_detectors_.insert(std::make_pair(ssrc, new Detector(
|
||||
now_ms,
|
||||
OverUseDetectorOptions(),
|
||||
remote_rate_->GetControlType() == kAimdControl)));
|
||||
overuse_detectors_.insert(std::make_pair(
|
||||
ssrc, new Detector(now_ms, OverUseDetectorOptions(), true)));
|
||||
it = insert_result.first;
|
||||
}
|
||||
Detector* estimator = it->second;
|
||||
@ -161,7 +116,7 @@ void RemoteBitrateEstimatorImpl::IncomingPacket(int64_t arrival_time_ms,
|
||||
}
|
||||
}
|
||||
|
||||
int32_t RemoteBitrateEstimatorImpl::Process() {
|
||||
int32_t RemoteBitrateEstimatorSingleStream::Process() {
|
||||
if (TimeUntilNextProcess() > 0) {
|
||||
return 0;
|
||||
}
|
||||
@ -173,7 +128,7 @@ int32_t RemoteBitrateEstimatorImpl::Process() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int64_t RemoteBitrateEstimatorImpl::TimeUntilNextProcess() {
|
||||
int64_t RemoteBitrateEstimatorSingleStream::TimeUntilNextProcess() {
|
||||
if (last_process_time_ < 0) {
|
||||
return 0;
|
||||
}
|
||||
@ -184,7 +139,7 @@ int64_t RemoteBitrateEstimatorImpl::TimeUntilNextProcess() {
|
||||
}
|
||||
}
|
||||
|
||||
void RemoteBitrateEstimatorImpl::UpdateEstimate(int64_t now_ms) {
|
||||
void RemoteBitrateEstimatorSingleStream::UpdateEstimate(int64_t now_ms) {
|
||||
BandwidthUsage bw_state = kBwNormal;
|
||||
double sum_var_noise = 0.0;
|
||||
SsrcOveruseEstimatorMap::iterator it = overuse_detectors_.begin();
|
||||
@ -209,8 +164,7 @@ void RemoteBitrateEstimatorImpl::UpdateEstimate(int64_t now_ms) {
|
||||
}
|
||||
// We can't update the estimate if we don't have any active streams.
|
||||
if (overuse_detectors_.empty()) {
|
||||
remote_rate_.reset(RemoteRateControl::Create(
|
||||
remote_rate_->GetControlType(), remote_rate_->GetMinBitrate()));
|
||||
remote_rate_.reset(new AimdRateControl(remote_rate_->GetMinBitrate()));
|
||||
return;
|
||||
}
|
||||
double mean_noise_var = sum_var_noise /
|
||||
@ -231,12 +185,12 @@ void RemoteBitrateEstimatorImpl::UpdateEstimate(int64_t now_ms) {
|
||||
}
|
||||
}
|
||||
|
||||
void RemoteBitrateEstimatorImpl::OnRttUpdate(int64_t rtt) {
|
||||
void RemoteBitrateEstimatorSingleStream::OnRttUpdate(int64_t rtt) {
|
||||
CriticalSectionScoped cs(crit_sect_.get());
|
||||
remote_rate_->SetRtt(rtt);
|
||||
}
|
||||
|
||||
void RemoteBitrateEstimatorImpl::RemoveStream(unsigned int ssrc) {
|
||||
void RemoteBitrateEstimatorSingleStream::RemoveStream(unsigned int ssrc) {
|
||||
CriticalSectionScoped cs(crit_sect_.get());
|
||||
SsrcOveruseEstimatorMap::iterator it = overuse_detectors_.find(ssrc);
|
||||
if (it != overuse_detectors_.end()) {
|
||||
@ -245,7 +199,7 @@ void RemoteBitrateEstimatorImpl::RemoveStream(unsigned int ssrc) {
|
||||
}
|
||||
}
|
||||
|
||||
bool RemoteBitrateEstimatorImpl::LatestEstimate(
|
||||
bool RemoteBitrateEstimatorSingleStream::LatestEstimate(
|
||||
std::vector<unsigned int>* ssrcs,
|
||||
unsigned int* bitrate_bps) const {
|
||||
CriticalSectionScoped cs(crit_sect_.get());
|
||||
@ -261,13 +215,13 @@ bool RemoteBitrateEstimatorImpl::LatestEstimate(
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RemoteBitrateEstimatorImpl::GetStats(
|
||||
bool RemoteBitrateEstimatorSingleStream::GetStats(
|
||||
ReceiveBandwidthEstimatorStats* output) const {
|
||||
// Not implemented.
|
||||
return false;
|
||||
}
|
||||
|
||||
void RemoteBitrateEstimatorImpl::GetSsrcs(
|
||||
void RemoteBitrateEstimatorSingleStream::GetSsrcs(
|
||||
std::vector<unsigned int>* ssrcs) const {
|
||||
assert(ssrcs);
|
||||
ssrcs->resize(overuse_detectors_.size());
|
||||
@ -278,13 +232,4 @@ void RemoteBitrateEstimatorImpl::GetSsrcs(
|
||||
}
|
||||
}
|
||||
|
||||
RemoteBitrateEstimator* RemoteBitrateEstimatorFactory::Create(
|
||||
webrtc::RemoteBitrateObserver* observer,
|
||||
webrtc::Clock* clock,
|
||||
RateControlType control_type,
|
||||
uint32_t min_bitrate_bps) const {
|
||||
LOG(LS_INFO) << "RemoteBitrateEstimatorFactory: Instantiating.";
|
||||
return new RemoteBitrateEstimatorImpl(observer, clock, control_type,
|
||||
min_bitrate_bps);
|
||||
}
|
||||
} // namespace webrtc
|
||||
|
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* 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_REMOTE_BITRATE_ESTIMATOR_SINGLE_STREAM_H_
|
||||
#define WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_REMOTE_BITRATE_ESTIMATOR_SINGLE_STREAM_H_
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include "webrtc/modules/remote_bitrate_estimator/aimd_rate_control.h"
|
||||
#include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
|
||||
#include "webrtc/modules/remote_bitrate_estimator/rate_statistics.h"
|
||||
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
class RemoteBitrateEstimatorSingleStream : public RemoteBitrateEstimator {
|
||||
public:
|
||||
RemoteBitrateEstimatorSingleStream(RemoteBitrateObserver* observer,
|
||||
Clock* clock,
|
||||
uint32_t min_bitrate_bps);
|
||||
virtual ~RemoteBitrateEstimatorSingleStream();
|
||||
|
||||
void IncomingPacket(int64_t arrival_time_ms,
|
||||
size_t payload_size,
|
||||
const RTPHeader& header,
|
||||
bool was_paced) override;
|
||||
int32_t Process() override;
|
||||
int64_t TimeUntilNextProcess() override;
|
||||
void OnRttUpdate(int64_t rtt) override;
|
||||
void RemoveStream(unsigned int ssrc) override;
|
||||
bool LatestEstimate(std::vector<unsigned int>* ssrcs,
|
||||
unsigned int* bitrate_bps) const override;
|
||||
bool GetStats(ReceiveBandwidthEstimatorStats* output) const override;
|
||||
|
||||
private:
|
||||
struct Detector;
|
||||
|
||||
typedef std::map<unsigned int, Detector*> SsrcOveruseEstimatorMap;
|
||||
|
||||
// Triggers a new estimate calculation.
|
||||
void UpdateEstimate(int64_t time_now)
|
||||
EXCLUSIVE_LOCKS_REQUIRED(crit_sect_.get());
|
||||
|
||||
void GetSsrcs(std::vector<unsigned int>* ssrcs) const
|
||||
SHARED_LOCKS_REQUIRED(crit_sect_.get());
|
||||
|
||||
Clock* clock_;
|
||||
SsrcOveruseEstimatorMap overuse_detectors_ GUARDED_BY(crit_sect_.get());
|
||||
RateStatistics incoming_bitrate_ GUARDED_BY(crit_sect_.get());
|
||||
rtc::scoped_ptr<AimdRateControl> remote_rate_ GUARDED_BY(crit_sect_.get());
|
||||
RemoteBitrateObserver* observer_ GUARDED_BY(crit_sect_.get());
|
||||
rtc::scoped_ptr<CriticalSectionWrapper> crit_sect_;
|
||||
int64_t last_process_time_;
|
||||
int64_t process_interval_ms_ GUARDED_BY(crit_sect_.get());
|
||||
|
||||
DISALLOW_IMPLICIT_CONSTRUCTORS(RemoteBitrateEstimatorSingleStream);
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_REMOTE_BITRATE_ESTIMATOR_SINGLE_STREAM_H_
|
@ -9,6 +9,7 @@
|
||||
*/
|
||||
|
||||
#include "webrtc/base/constructormagic.h"
|
||||
#include "webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.h"
|
||||
#include "webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_unittest_helper.h"
|
||||
|
||||
namespace webrtc {
|
||||
@ -20,10 +21,8 @@ class RemoteBitrateEstimatorSingleTest :
|
||||
|
||||
RemoteBitrateEstimatorSingleTest() {}
|
||||
virtual void SetUp() {
|
||||
bitrate_estimator_.reset(RemoteBitrateEstimatorFactory().Create(
|
||||
bitrate_observer_.get(),
|
||||
&clock_,
|
||||
kMimdControl,
|
||||
bitrate_estimator_.reset(new RemoteBitrateEstimatorSingleStream(
|
||||
bitrate_observer_.get(), &clock_,
|
||||
kRemoteBitrateEstimatorMinBitrateBps));
|
||||
}
|
||||
protected:
|
||||
@ -39,35 +38,35 @@ TEST_F(RemoteBitrateEstimatorSingleTest, RateIncreaseReordering) {
|
||||
}
|
||||
|
||||
TEST_F(RemoteBitrateEstimatorSingleTest, RateIncreaseRtpTimestamps) {
|
||||
RateIncreaseRtpTimestampsTestHelper(1621);
|
||||
RateIncreaseRtpTimestampsTestHelper(1089);
|
||||
}
|
||||
|
||||
TEST_F(RemoteBitrateEstimatorSingleTest, CapacityDropOneStream) {
|
||||
CapacityDropTestHelper(1, false, 733);
|
||||
CapacityDropTestHelper(1, false, 700);
|
||||
}
|
||||
|
||||
TEST_F(RemoteBitrateEstimatorSingleTest, CapacityDropOneStreamWrap) {
|
||||
CapacityDropTestHelper(1, true, 733);
|
||||
CapacityDropTestHelper(1, true, 700);
|
||||
}
|
||||
|
||||
TEST_F(RemoteBitrateEstimatorSingleTest, CapacityDropTwoStreamsWrap) {
|
||||
CapacityDropTestHelper(2, true, 700);
|
||||
CapacityDropTestHelper(2, true, 666);
|
||||
}
|
||||
|
||||
TEST_F(RemoteBitrateEstimatorSingleTest, CapacityDropThreeStreamsWrap) {
|
||||
CapacityDropTestHelper(3, true, 733);
|
||||
CapacityDropTestHelper(3, true, 700);
|
||||
}
|
||||
|
||||
TEST_F(RemoteBitrateEstimatorSingleTest, CapacityDropThirteenStreamsWrap) {
|
||||
CapacityDropTestHelper(13, true, 733);
|
||||
CapacityDropTestHelper(13, true, 700);
|
||||
}
|
||||
|
||||
TEST_F(RemoteBitrateEstimatorSingleTest, CapacityDropNineteenStreamsWrap) {
|
||||
CapacityDropTestHelper(19, true, 733);
|
||||
CapacityDropTestHelper(19, true, 700);
|
||||
}
|
||||
|
||||
TEST_F(RemoteBitrateEstimatorSingleTest, CapacityDropThirtyStreamsWrap) {
|
||||
CapacityDropTestHelper(30, true, 733);
|
||||
CapacityDropTestHelper(30, true, 700);
|
||||
}
|
||||
|
||||
TEST_F(RemoteBitrateEstimatorSingleTest, TestTimestampGrouping) {
|
||||
|
@ -533,7 +533,7 @@ void RemoteBitrateEstimatorTest::TestTimestampGroupingTestHelper() {
|
||||
kFrameIntervalAbsSendTime);
|
||||
}
|
||||
EXPECT_TRUE(bitrate_observer_->updated());
|
||||
EXPECT_NEAR(450000u, bitrate_observer_->latest_bitrate(), 20000u);
|
||||
EXPECT_NEAR(470000u, bitrate_observer_->latest_bitrate(), 10000u);
|
||||
|
||||
// Insert batches of frames which were sent very close in time. Also simulate
|
||||
// capacity over-use to see that we back off correctly.
|
||||
|
@ -1,30 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "webrtc/modules/remote_bitrate_estimator/remote_rate_control.h"
|
||||
|
||||
#include "webrtc/modules/remote_bitrate_estimator/aimd_rate_control.h"
|
||||
#include "webrtc/modules/remote_bitrate_estimator/mimd_rate_control.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// static
|
||||
const int64_t RemoteRateControl::kMaxFeedbackIntervalMs = 1000;
|
||||
|
||||
RemoteRateControl* RemoteRateControl::Create(RateControlType control_type,
|
||||
uint32_t min_bitrate_bps) {
|
||||
if (control_type == kAimdControl) {
|
||||
return new AimdRateControl(min_bitrate_bps);
|
||||
} else {
|
||||
return new MimdRateControl(min_bitrate_bps);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
@ -1,51 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_REMOTE_RATE_CONTROL_H_
|
||||
#define WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_REMOTE_RATE_CONTROL_H_
|
||||
|
||||
#include "webrtc/modules/remote_bitrate_estimator/include/bwe_defines.h"
|
||||
#include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
class RemoteRateControl {
|
||||
public:
|
||||
static RemoteRateControl* Create(RateControlType control_type,
|
||||
uint32_t min_bitrate_bps);
|
||||
|
||||
virtual ~RemoteRateControl() {}
|
||||
|
||||
// Returns true if there is a valid estimate of the incoming bitrate, false
|
||||
// otherwise.
|
||||
virtual bool ValidEstimate() const = 0;
|
||||
virtual RateControlType GetControlType() const = 0;
|
||||
virtual uint32_t GetMinBitrate() const = 0;
|
||||
virtual int64_t GetFeedbackInterval() const = 0;
|
||||
|
||||
// Returns true if the bitrate estimate hasn't been changed for more than
|
||||
// an RTT, or if the incoming_bitrate is more than 5% above the current
|
||||
// estimate. Should be used to decide if we should reduce the rate further
|
||||
// when over-using.
|
||||
virtual bool TimeToReduceFurther(int64_t time_now,
|
||||
uint32_t incoming_bitrate_bps) const = 0;
|
||||
virtual uint32_t LatestEstimate() const = 0;
|
||||
virtual uint32_t UpdateBandwidthEstimate(int64_t now_ms) = 0;
|
||||
virtual void SetRtt(int64_t rtt) = 0;
|
||||
virtual RateControlRegion Update(const RateControlInput* input,
|
||||
int64_t now_ms) = 0;
|
||||
virtual void SetEstimate(int bitrate_bps, int64_t time_now_ms) = 0;
|
||||
|
||||
protected:
|
||||
static const int64_t kMaxFeedbackIntervalMs;
|
||||
};
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_REMOTE_RATE_CONTROL_H_
|
@ -15,6 +15,7 @@
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
#include "webrtc/base/common.h"
|
||||
#include "webrtc/modules/bitrate_controller/include/bitrate_controller.h"
|
||||
#include "webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time.h"
|
||||
#include "webrtc/modules/remote_bitrate_estimator/test/bwe_test_logging.h"
|
||||
#include "webrtc/modules/rtp_rtcp/interface/receive_statistics.h"
|
||||
|
||||
@ -67,10 +68,10 @@ RembReceiver::RembReceiver(int flow_id, bool plot)
|
||||
clock_(0),
|
||||
recv_stats_(ReceiveStatistics::Create(&clock_)),
|
||||
latest_estimate_bps_(-1),
|
||||
estimator_(AbsoluteSendTimeRemoteBitrateEstimatorFactory().Create(
|
||||
last_feedback_ms_(-1),
|
||||
estimator_(new RemoteBitrateEstimatorAbsSendTime(
|
||||
this,
|
||||
&clock_,
|
||||
kAimdControl,
|
||||
kRemoteBitrateEstimatorMinBitrateBps)) {
|
||||
std::stringstream ss;
|
||||
ss << "Estimate_" << flow_id_ << "#1";
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "webrtc/modules/remote_bitrate_estimator/test/estimators/send_side.h"
|
||||
|
||||
#include "webrtc/base/logging.h"
|
||||
#include "webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time.h"
|
||||
#include "webrtc/modules/remote_bitrate_estimator/test/bwe_test_logging.h"
|
||||
|
||||
namespace webrtc {
|
||||
@ -22,8 +23,9 @@ const int kFeedbackIntervalMs = 50;
|
||||
FullBweSender::FullBweSender(int kbps, BitrateObserver* observer, Clock* clock)
|
||||
: bitrate_controller_(
|
||||
BitrateController::CreateBitrateController(clock, observer)),
|
||||
rbe_(AbsoluteSendTimeRemoteBitrateEstimatorFactory()
|
||||
.Create(this, clock, kAimdControl, 1000 * kMinBitrateKbps)),
|
||||
rbe_(new RemoteBitrateEstimatorAbsSendTime(this,
|
||||
clock,
|
||||
1000 * kMinBitrateKbps)),
|
||||
feedback_observer_(bitrate_controller_->CreateRtcpBandwidthObserver()),
|
||||
clock_(clock),
|
||||
send_time_history_(10000),
|
||||
|
@ -13,7 +13,8 @@
|
||||
#include <stdio.h>
|
||||
#include <string>
|
||||
|
||||
#include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
|
||||
#include "webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time.h"
|
||||
#include "webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.h"
|
||||
#include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h"
|
||||
#include "webrtc/modules/rtp_rtcp/interface/rtp_payload_registry.h"
|
||||
#include "webrtc/test/rtp_file_reader.h"
|
||||
@ -51,16 +52,14 @@ bool ParseArgsAndSetupEstimator(int argc,
|
||||
if (estimator) {
|
||||
switch (extension) {
|
||||
case webrtc::kRtpExtensionAbsoluteSendTime: {
|
||||
webrtc::AbsoluteSendTimeRemoteBitrateEstimatorFactory factory;
|
||||
*estimator = factory.Create(observer, clock, webrtc::kAimdControl,
|
||||
kMinBitrateBps);
|
||||
*estimator = new webrtc::RemoteBitrateEstimatorAbsSendTime(
|
||||
observer, clock, kMinBitrateBps);
|
||||
*estimator_used = "AbsoluteSendTimeRemoteBitrateEstimator";
|
||||
break;
|
||||
}
|
||||
case webrtc::kRtpExtensionTransmissionTimeOffset: {
|
||||
webrtc::RemoteBitrateEstimatorFactory factory;
|
||||
*estimator = factory.Create(observer, clock, webrtc::kAimdControl,
|
||||
kMinBitrateBps);
|
||||
*estimator = new webrtc::RemoteBitrateEstimatorSingleStream(
|
||||
observer, clock, kMinBitrateBps);
|
||||
*estimator_used = "RemoteBitrateEstimator";
|
||||
break;
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "webrtc/common_types.h"
|
||||
#include "webrtc/modules/remote_bitrate_estimator/include/bwe_defines.h"
|
||||
#include "webrtc/modules/remote_bitrate_estimator/include/mock/mock_remote_bitrate_observer.h"
|
||||
#include "webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.h"
|
||||
#include "webrtc/modules/rtp_rtcp/source/rtcp_receiver.h"
|
||||
#include "webrtc/modules/rtp_rtcp/source/rtcp_sender.h"
|
||||
#include "webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h"
|
||||
@ -67,12 +68,10 @@ class RtcpFormatRembTest : public ::testing::Test {
|
||||
system_clock_(Clock::GetRealTimeClock()),
|
||||
receive_statistics_(ReceiveStatistics::Create(system_clock_)),
|
||||
remote_bitrate_observer_(),
|
||||
remote_bitrate_estimator_(
|
||||
RemoteBitrateEstimatorFactory().Create(
|
||||
&remote_bitrate_observer_,
|
||||
system_clock_,
|
||||
kMimdControl,
|
||||
kRemoteBitrateEstimatorMinBitrateBps)) {}
|
||||
remote_bitrate_estimator_(new RemoteBitrateEstimatorSingleStream(
|
||||
&remote_bitrate_observer_,
|
||||
system_clock_,
|
||||
kRemoteBitrateEstimatorMinBitrateBps)) {}
|
||||
void SetUp() override;
|
||||
void TearDown() override;
|
||||
|
||||
|
@ -18,7 +18,7 @@
|
||||
// Note: This file has no directory. Lint warning must be ignored.
|
||||
#include "webrtc/common_types.h"
|
||||
#include "webrtc/modules/remote_bitrate_estimator/include/mock/mock_remote_bitrate_observer.h"
|
||||
#include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
|
||||
#include "webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.h"
|
||||
#include "webrtc/modules/rtp_rtcp/source/rtcp_packet.h"
|
||||
#include "webrtc/modules/rtp_rtcp/source/rtcp_receiver.h"
|
||||
#include "webrtc/modules/rtp_rtcp/source/rtcp_sender.h"
|
||||
@ -69,12 +69,10 @@ class RtcpReceiverTest : public ::testing::Test {
|
||||
: over_use_detector_options_(),
|
||||
system_clock_(1335900000),
|
||||
remote_bitrate_observer_(),
|
||||
remote_bitrate_estimator_(
|
||||
RemoteBitrateEstimatorFactory().Create(
|
||||
&remote_bitrate_observer_,
|
||||
&system_clock_,
|
||||
kMimdControl,
|
||||
kRemoteBitrateEstimatorMinBitrateBps)) {
|
||||
remote_bitrate_estimator_(new RemoteBitrateEstimatorSingleStream(
|
||||
&remote_bitrate_observer_,
|
||||
&system_clock_,
|
||||
kRemoteBitrateEstimatorMinBitrateBps)) {
|
||||
test_transport_ = new TestTransport();
|
||||
|
||||
RtpRtcp::Configuration configuration;
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
#include "webrtc/common_types.h"
|
||||
#include "webrtc/modules/remote_bitrate_estimator/include/mock/mock_remote_bitrate_observer.h"
|
||||
#include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
|
||||
#include "webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.h"
|
||||
#include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h"
|
||||
#include "webrtc/modules/rtp_rtcp/interface/rtp_payload_registry.h"
|
||||
#include "webrtc/modules/rtp_rtcp/interface/rtp_receiver.h"
|
||||
@ -279,15 +279,13 @@ class RtcpSenderTest : public ::testing::Test {
|
||||
RtcpSenderTest()
|
||||
: over_use_detector_options_(),
|
||||
clock_(1335900000),
|
||||
rtp_payload_registry_(new RTPPayloadRegistry(
|
||||
RTPPayloadStrategy::CreateStrategy(false))),
|
||||
rtp_payload_registry_(
|
||||
new RTPPayloadRegistry(RTPPayloadStrategy::CreateStrategy(false))),
|
||||
remote_bitrate_observer_(),
|
||||
remote_bitrate_estimator_(
|
||||
RemoteBitrateEstimatorFactory().Create(
|
||||
&remote_bitrate_observer_,
|
||||
&clock_,
|
||||
kMimdControl,
|
||||
kRemoteBitrateEstimatorMinBitrateBps)),
|
||||
remote_bitrate_estimator_(new RemoteBitrateEstimatorSingleStream(
|
||||
&remote_bitrate_observer_,
|
||||
&clock_,
|
||||
kRemoteBitrateEstimatorMinBitrateBps)),
|
||||
receive_statistics_(ReceiveStatistics::Create(&clock_)) {
|
||||
test_transport_ = new TestTransport();
|
||||
|
||||
|
@ -272,13 +272,16 @@ class BitrateEstimatorTest : public test::CallTest {
|
||||
std::vector<Stream*> streams_;
|
||||
};
|
||||
|
||||
static const char* kAbsSendTimeLog =
|
||||
"RemoteBitrateEstimatorAbsSendTime: Instantiating.";
|
||||
static const char* kSingleStreamLog =
|
||||
"RemoteBitrateEstimatorSingleStream: Instantiating.";
|
||||
|
||||
TEST_F(BitrateEstimatorTest, InstantiatesTOFPerDefaultForVideo) {
|
||||
send_config_.rtp.extensions.push_back(
|
||||
RtpExtension(RtpExtension::kTOffset, kTOFExtensionId));
|
||||
receiver_trace_.PushExpectedLogLine(
|
||||
"RemoteBitrateEstimatorFactory: Instantiating.");
|
||||
receiver_trace_.PushExpectedLogLine(
|
||||
"RemoteBitrateEstimatorFactory: Instantiating.");
|
||||
receiver_trace_.PushExpectedLogLine(kSingleStreamLog);
|
||||
receiver_trace_.PushExpectedLogLine(kSingleStreamLog);
|
||||
streams_.push_back(new Stream(this, false));
|
||||
EXPECT_EQ(kEventSignaled, receiver_trace_.Wait());
|
||||
}
|
||||
@ -286,13 +289,10 @@ TEST_F(BitrateEstimatorTest, InstantiatesTOFPerDefaultForVideo) {
|
||||
TEST_F(BitrateEstimatorTest, ImmediatelySwitchToASTForAudio) {
|
||||
send_config_.rtp.extensions.push_back(
|
||||
RtpExtension(RtpExtension::kAbsSendTime, kASTExtensionId));
|
||||
receiver_trace_.PushExpectedLogLine(
|
||||
"RemoteBitrateEstimatorFactory: Instantiating.");
|
||||
receiver_trace_.PushExpectedLogLine(
|
||||
"RemoteBitrateEstimatorFactory: Instantiating.");
|
||||
receiver_trace_.PushExpectedLogLine(kSingleStreamLog);
|
||||
receiver_trace_.PushExpectedLogLine(kSingleStreamLog);
|
||||
receiver_trace_.PushExpectedLogLine("Switching to absolute send time RBE.");
|
||||
receiver_trace_.PushExpectedLogLine(
|
||||
"AbsoluteSendTimeRemoteBitrateEstimatorFactory: Instantiating.");
|
||||
receiver_trace_.PushExpectedLogLine(kAbsSendTimeLog);
|
||||
streams_.push_back(new Stream(this, true));
|
||||
EXPECT_EQ(kEventSignaled, receiver_trace_.Wait());
|
||||
}
|
||||
@ -300,30 +300,24 @@ TEST_F(BitrateEstimatorTest, ImmediatelySwitchToASTForAudio) {
|
||||
TEST_F(BitrateEstimatorTest, ImmediatelySwitchToASTForVideo) {
|
||||
send_config_.rtp.extensions.push_back(
|
||||
RtpExtension(RtpExtension::kAbsSendTime, kASTExtensionId));
|
||||
receiver_trace_.PushExpectedLogLine(
|
||||
"RemoteBitrateEstimatorFactory: Instantiating.");
|
||||
receiver_trace_.PushExpectedLogLine(
|
||||
"RemoteBitrateEstimatorFactory: Instantiating.");
|
||||
receiver_trace_.PushExpectedLogLine(kSingleStreamLog);
|
||||
receiver_trace_.PushExpectedLogLine(kSingleStreamLog);
|
||||
receiver_trace_.PushExpectedLogLine("Switching to absolute send time RBE.");
|
||||
receiver_trace_.PushExpectedLogLine(
|
||||
"AbsoluteSendTimeRemoteBitrateEstimatorFactory: Instantiating.");
|
||||
receiver_trace_.PushExpectedLogLine(kAbsSendTimeLog);
|
||||
streams_.push_back(new Stream(this, false));
|
||||
EXPECT_EQ(kEventSignaled, receiver_trace_.Wait());
|
||||
}
|
||||
|
||||
TEST_F(BitrateEstimatorTest, SwitchesToASTForAudio) {
|
||||
receiver_trace_.PushExpectedLogLine(
|
||||
"RemoteBitrateEstimatorFactory: Instantiating.");
|
||||
receiver_trace_.PushExpectedLogLine(
|
||||
"RemoteBitrateEstimatorFactory: Instantiating.");
|
||||
receiver_trace_.PushExpectedLogLine(kSingleStreamLog);
|
||||
receiver_trace_.PushExpectedLogLine(kSingleStreamLog);
|
||||
streams_.push_back(new Stream(this, true));
|
||||
EXPECT_EQ(kEventSignaled, receiver_trace_.Wait());
|
||||
|
||||
send_config_.rtp.extensions.push_back(
|
||||
RtpExtension(RtpExtension::kAbsSendTime, kASTExtensionId));
|
||||
receiver_trace_.PushExpectedLogLine("Switching to absolute send time RBE.");
|
||||
receiver_trace_.PushExpectedLogLine(
|
||||
"AbsoluteSendTimeRemoteBitrateEstimatorFactory: Instantiating.");
|
||||
receiver_trace_.PushExpectedLogLine(kAbsSendTimeLog);
|
||||
streams_.push_back(new Stream(this, true));
|
||||
EXPECT_EQ(kEventSignaled, receiver_trace_.Wait());
|
||||
}
|
||||
@ -331,18 +325,15 @@ TEST_F(BitrateEstimatorTest, SwitchesToASTForAudio) {
|
||||
TEST_F(BitrateEstimatorTest, SwitchesToASTForVideo) {
|
||||
send_config_.rtp.extensions.push_back(
|
||||
RtpExtension(RtpExtension::kTOffset, kTOFExtensionId));
|
||||
receiver_trace_.PushExpectedLogLine(
|
||||
"RemoteBitrateEstimatorFactory: Instantiating.");
|
||||
receiver_trace_.PushExpectedLogLine(
|
||||
"RemoteBitrateEstimatorFactory: Instantiating.");
|
||||
receiver_trace_.PushExpectedLogLine(kSingleStreamLog);
|
||||
receiver_trace_.PushExpectedLogLine(kSingleStreamLog);
|
||||
streams_.push_back(new Stream(this, false));
|
||||
EXPECT_EQ(kEventSignaled, receiver_trace_.Wait());
|
||||
|
||||
send_config_.rtp.extensions[0] =
|
||||
RtpExtension(RtpExtension::kAbsSendTime, kASTExtensionId);
|
||||
receiver_trace_.PushExpectedLogLine("Switching to absolute send time RBE.");
|
||||
receiver_trace_.PushExpectedLogLine(
|
||||
"AbsoluteSendTimeRemoteBitrateEstimatorFactory: Instantiating.");
|
||||
receiver_trace_.PushExpectedLogLine(kAbsSendTimeLog);
|
||||
streams_.push_back(new Stream(this, false));
|
||||
EXPECT_EQ(kEventSignaled, receiver_trace_.Wait());
|
||||
}
|
||||
@ -350,18 +341,15 @@ TEST_F(BitrateEstimatorTest, SwitchesToASTForVideo) {
|
||||
TEST_F(BitrateEstimatorTest, SwitchesToASTThenBackToTOFForVideo) {
|
||||
send_config_.rtp.extensions.push_back(
|
||||
RtpExtension(RtpExtension::kTOffset, kTOFExtensionId));
|
||||
receiver_trace_.PushExpectedLogLine(
|
||||
"RemoteBitrateEstimatorFactory: Instantiating.");
|
||||
receiver_trace_.PushExpectedLogLine(
|
||||
"RemoteBitrateEstimatorFactory: Instantiating.");
|
||||
receiver_trace_.PushExpectedLogLine(kSingleStreamLog);
|
||||
receiver_trace_.PushExpectedLogLine(kSingleStreamLog);
|
||||
streams_.push_back(new Stream(this, false));
|
||||
EXPECT_EQ(kEventSignaled, receiver_trace_.Wait());
|
||||
|
||||
send_config_.rtp.extensions[0] =
|
||||
RtpExtension(RtpExtension::kAbsSendTime, kASTExtensionId);
|
||||
receiver_trace_.PushExpectedLogLine("Switching to absolute send time RBE.");
|
||||
receiver_trace_.PushExpectedLogLine(
|
||||
"AbsoluteSendTimeRemoteBitrateEstimatorFactory: Instantiating.");
|
||||
receiver_trace_.PushExpectedLogLine(kAbsSendTimeLog);
|
||||
streams_.push_back(new Stream(this, false));
|
||||
EXPECT_EQ(kEventSignaled, receiver_trace_.Wait());
|
||||
|
||||
@ -369,8 +357,7 @@ TEST_F(BitrateEstimatorTest, SwitchesToASTThenBackToTOFForVideo) {
|
||||
RtpExtension(RtpExtension::kTOffset, kTOFExtensionId);
|
||||
receiver_trace_.PushExpectedLogLine(
|
||||
"WrappingBitrateEstimator: Switching to transmission time offset RBE.");
|
||||
receiver_trace_.PushExpectedLogLine(
|
||||
"RemoteBitrateEstimatorFactory: Instantiating.");
|
||||
receiver_trace_.PushExpectedLogLine(kSingleStreamLog);
|
||||
streams_.push_back(new Stream(this, false));
|
||||
streams_[0]->StopSending();
|
||||
streams_[1]->StopSending();
|
||||
|
@ -11,6 +11,8 @@
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
#include "webrtc/base/checks.h"
|
||||
#include "webrtc/base/common.h"
|
||||
#include "webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time.h"
|
||||
#include "webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.h"
|
||||
#include "webrtc/modules/rtp_rtcp/interface/receive_statistics.h"
|
||||
#include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h"
|
||||
#include "webrtc/modules/rtp_rtcp/interface/rtp_payload_registry.h"
|
||||
@ -24,6 +26,7 @@ namespace webrtc {
|
||||
namespace {
|
||||
|
||||
static const int kMaxPacketSize = 1500;
|
||||
const uint32_t kRemoteBitrateEstimatorMinBitrateBps = 30000;
|
||||
|
||||
std::vector<uint32_t> GenerateSsrcs(size_t num_streams,
|
||||
uint32_t ssrc_offset) {
|
||||
@ -36,9 +39,7 @@ std::vector<uint32_t> GenerateSsrcs(size_t num_streams,
|
||||
|
||||
StreamObserver::StreamObserver(const SsrcMap& rtx_media_ssrcs,
|
||||
newapi::Transport* feedback_transport,
|
||||
Clock* clock,
|
||||
RemoteBitrateEstimatorFactory* rbe_factory,
|
||||
RateControlType control_type)
|
||||
Clock* clock)
|
||||
: clock_(clock),
|
||||
test_done_(EventWrapper::Create()),
|
||||
rtp_parser_(RtpHeaderParser::Create()),
|
||||
@ -46,6 +47,7 @@ StreamObserver::StreamObserver(const SsrcMap& rtx_media_ssrcs,
|
||||
receive_stats_(ReceiveStatistics::Create(clock)),
|
||||
payload_registry_(
|
||||
new RTPPayloadRegistry(RTPPayloadStrategy::CreateStrategy(false))),
|
||||
remote_bitrate_estimator_(nullptr),
|
||||
expected_bitrate_bps_(0),
|
||||
start_bitrate_bps_(0),
|
||||
rtx_media_ssrcs_(rtx_media_ssrcs),
|
||||
@ -72,10 +74,6 @@ StreamObserver::StreamObserver(const SsrcMap& rtx_media_ssrcs,
|
||||
kAbsSendTimeExtensionId);
|
||||
rtp_parser_->RegisterRtpHeaderExtension(kRtpExtensionTransmissionTimeOffset,
|
||||
kTransmissionTimeOffsetExtensionId);
|
||||
const uint32_t kRemoteBitrateEstimatorMinBitrateBps = 30000;
|
||||
remote_bitrate_estimator_.reset(
|
||||
rbe_factory->Create(this, clock, control_type,
|
||||
kRemoteBitrateEstimatorMinBitrateBps));
|
||||
payload_registry_->SetRtxPayloadType(RampUpTest::kSendRtxPayloadType,
|
||||
RampUpTest::kFakeSendPayloadType);
|
||||
}
|
||||
@ -121,6 +119,7 @@ bool StreamObserver::SendRtp(const uint8_t* packet, size_t length) {
|
||||
EXPECT_TRUE(rtp_parser_->Parse(packet, length, &header));
|
||||
receive_stats_->IncomingPacket(header, length, false);
|
||||
payload_registry_->SetIncomingPayloadType(header);
|
||||
DCHECK(remote_bitrate_estimator_ != nullptr);
|
||||
remote_bitrate_estimator_->IncomingPacket(clock_->TimeInMilliseconds(),
|
||||
length - 12, header, true);
|
||||
if (remote_bitrate_estimator_->TimeUntilNextProcess() <= 0) {
|
||||
@ -159,6 +158,10 @@ EventTypeWrapper StreamObserver::Wait() {
|
||||
return test_done_->Wait(test::CallTest::kLongTimeoutMs);
|
||||
}
|
||||
|
||||
void StreamObserver::SetRemoteBitrateEstimator(RemoteBitrateEstimator* rbe) {
|
||||
remote_bitrate_estimator_.reset(rbe);
|
||||
}
|
||||
|
||||
void StreamObserver::ReportResult(const std::string& measurement,
|
||||
size_t value,
|
||||
const std::string& units) {
|
||||
@ -214,11 +217,9 @@ LowRateStreamObserver::LowRateStreamObserver(
|
||||
rtp_rtcp_->SetRTCPStatus(kRtcpNonCompound);
|
||||
rtp_parser_->RegisterRtpHeaderExtension(kRtpExtensionAbsoluteSendTime,
|
||||
kAbsSendTimeExtensionId);
|
||||
AbsoluteSendTimeRemoteBitrateEstimatorFactory rbe_factory;
|
||||
const uint32_t kRemoteBitrateEstimatorMinBitrateBps = 10000;
|
||||
remote_bitrate_estimator_.reset(
|
||||
rbe_factory.Create(this, clock, kAimdControl,
|
||||
kRemoteBitrateEstimatorMinBitrateBps));
|
||||
remote_bitrate_estimator_.reset(new RemoteBitrateEstimatorAbsSendTime(
|
||||
this, clock, kRemoteBitrateEstimatorMinBitrateBps));
|
||||
forward_transport_config_.link_capacity_kbps =
|
||||
kHighBandwidthLimitBps / 1000;
|
||||
forward_transport_config_.queue_length_packets = 100; // Something large.
|
||||
@ -382,27 +383,26 @@ void RampUpTest::RunRampUpTest(size_t num_streams,
|
||||
CreateSendConfig(num_streams);
|
||||
send_config_.rtp.extensions.clear();
|
||||
|
||||
rtc::scoped_ptr<RemoteBitrateEstimatorFactory> rbe_factory;
|
||||
RateControlType control_type;
|
||||
test::DirectTransport receiver_transport;
|
||||
StreamObserver stream_observer(rtx_ssrc_map, &receiver_transport,
|
||||
Clock::GetRealTimeClock());
|
||||
|
||||
if (extension_type == RtpExtension::kAbsSendTime) {
|
||||
control_type = kAimdControl;
|
||||
rbe_factory.reset(new AbsoluteSendTimeRemoteBitrateEstimatorFactory);
|
||||
stream_observer.SetRemoteBitrateEstimator(
|
||||
new RemoteBitrateEstimatorAbsSendTime(
|
||||
&stream_observer, Clock::GetRealTimeClock(),
|
||||
kRemoteBitrateEstimatorMinBitrateBps));
|
||||
send_config_.rtp.extensions.push_back(RtpExtension(
|
||||
extension_type.c_str(), kAbsSendTimeExtensionId));
|
||||
} else {
|
||||
control_type = kMimdControl;
|
||||
rbe_factory.reset(new RemoteBitrateEstimatorFactory);
|
||||
stream_observer.SetRemoteBitrateEstimator(
|
||||
new RemoteBitrateEstimatorSingleStream(
|
||||
&stream_observer, Clock::GetRealTimeClock(),
|
||||
kRemoteBitrateEstimatorMinBitrateBps));
|
||||
send_config_.rtp.extensions.push_back(RtpExtension(
|
||||
extension_type.c_str(), kTransmissionTimeOffsetExtensionId));
|
||||
}
|
||||
|
||||
test::DirectTransport receiver_transport;
|
||||
StreamObserver stream_observer(rtx_ssrc_map,
|
||||
&receiver_transport,
|
||||
Clock::GetRealTimeClock(),
|
||||
rbe_factory.get(),
|
||||
control_type);
|
||||
|
||||
Call::Config call_config(&stream_observer);
|
||||
if (start_bitrate_bps != 0) {
|
||||
call_config.bitrate_config.start_bitrate_bps = start_bitrate_bps;
|
||||
|
@ -40,9 +40,7 @@ class StreamObserver : public newapi::Transport, public RemoteBitrateObserver {
|
||||
typedef std::map<uint32_t, uint32_t> SsrcMap;
|
||||
StreamObserver(const SsrcMap& rtx_media_ssrcs,
|
||||
newapi::Transport* feedback_transport,
|
||||
Clock* clock,
|
||||
RemoteBitrateEstimatorFactory* rbe_factory,
|
||||
RateControlType control_type);
|
||||
Clock* clock);
|
||||
|
||||
void set_expected_bitrate_bps(unsigned int expected_bitrate_bps);
|
||||
|
||||
@ -57,6 +55,8 @@ class StreamObserver : public newapi::Transport, public RemoteBitrateObserver {
|
||||
|
||||
EventTypeWrapper Wait();
|
||||
|
||||
void SetRemoteBitrateEstimator(RemoteBitrateEstimator* rbe);
|
||||
|
||||
private:
|
||||
void ReportResult(const std::string& measurement,
|
||||
size_t value,
|
||||
|
@ -16,7 +16,8 @@
|
||||
#include "webrtc/experiments.h"
|
||||
#include "webrtc/modules/pacing/include/paced_sender.h"
|
||||
#include "webrtc/modules/pacing/include/packet_router.h"
|
||||
#include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
|
||||
#include "webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time.h"
|
||||
#include "webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.h"
|
||||
#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h"
|
||||
#include "webrtc/modules/utility/interface/process_thread.h"
|
||||
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
|
||||
@ -43,13 +44,11 @@ class WrappingBitrateEstimator : public RemoteBitrateEstimator {
|
||||
clock_(clock),
|
||||
crit_sect_(CriticalSectionWrapper::CreateCriticalSection()),
|
||||
min_bitrate_bps_(config.Get<RemoteBitrateEstimatorMinRate>().min_rate),
|
||||
rbe_(RemoteBitrateEstimatorFactory().Create(observer_,
|
||||
rbe_(new RemoteBitrateEstimatorSingleStream(observer_,
|
||||
clock_,
|
||||
kAimdControl,
|
||||
min_bitrate_bps_)),
|
||||
using_absolute_send_time_(false),
|
||||
packets_since_absolute_send_time_(0) {
|
||||
}
|
||||
packets_since_absolute_send_time_(0) {}
|
||||
|
||||
virtual ~WrappingBitrateEstimator() {}
|
||||
|
||||
@ -122,11 +121,11 @@ class WrappingBitrateEstimator : public RemoteBitrateEstimator {
|
||||
// Instantiate RBE for Time Offset or Absolute Send Time extensions.
|
||||
void PickEstimator() EXCLUSIVE_LOCKS_REQUIRED(crit_sect_.get()) {
|
||||
if (using_absolute_send_time_) {
|
||||
rbe_.reset(AbsoluteSendTimeRemoteBitrateEstimatorFactory().Create(
|
||||
observer_, clock_, kAimdControl, min_bitrate_bps_));
|
||||
rbe_.reset(new RemoteBitrateEstimatorAbsSendTime(observer_, clock_,
|
||||
min_bitrate_bps_));
|
||||
} else {
|
||||
rbe_.reset(RemoteBitrateEstimatorFactory().Create(
|
||||
observer_, clock_, kAimdControl, min_bitrate_bps_));
|
||||
rbe_.reset(new RemoteBitrateEstimatorSingleStream(observer_, clock_,
|
||||
min_bitrate_bps_));
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user