Cleanup: Improving readability in AimdRateControl
Bug: webrtc:9883 Change-Id: I780772c939f7baf34e31da86c675fb3299505b22 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/169841 Commit-Queue: Sebastian Jansson <srte@webrtc.org> Reviewed-by: Ali Tofigh <alito@webrtc.org> Cr-Commit-Position: refs/heads/master@{#30711}
This commit is contained in:
parent
37e388ad2d
commit
4940e08f6b
@ -205,7 +205,7 @@ DataRate AimdRateControl::Update(const RateControlInput* input,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
current_bitrate_ = ChangeBitrate(current_bitrate_, *input, at_time);
|
ChangeBitrate(*input, at_time);
|
||||||
return current_bitrate_;
|
return current_bitrate_;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -216,7 +216,7 @@ void AimdRateControl::SetInApplicationLimitedRegion(bool in_alr) {
|
|||||||
void AimdRateControl::SetEstimate(DataRate bitrate, Timestamp at_time) {
|
void AimdRateControl::SetEstimate(DataRate bitrate, Timestamp at_time) {
|
||||||
bitrate_is_initialized_ = true;
|
bitrate_is_initialized_ = true;
|
||||||
DataRate prev_bitrate = current_bitrate_;
|
DataRate prev_bitrate = current_bitrate_;
|
||||||
current_bitrate_ = ClampBitrate(bitrate, bitrate);
|
current_bitrate_ = ClampBitrate(bitrate);
|
||||||
time_last_bitrate_change_ = at_time;
|
time_last_bitrate_change_ = at_time;
|
||||||
if (current_bitrate_ < prev_bitrate) {
|
if (current_bitrate_ < prev_bitrate) {
|
||||||
time_last_bitrate_decrease_ = at_time;
|
time_last_bitrate_decrease_ = at_time;
|
||||||
@ -261,9 +261,9 @@ TimeDelta AimdRateControl::GetExpectedBandwidthPeriod() const {
|
|||||||
return period.Clamped(kMinPeriod, kMaxPeriod);
|
return period.Clamped(kMinPeriod, kMaxPeriod);
|
||||||
}
|
}
|
||||||
|
|
||||||
DataRate AimdRateControl::ChangeBitrate(DataRate new_bitrate,
|
void AimdRateControl::ChangeBitrate(const RateControlInput& input,
|
||||||
const RateControlInput& input,
|
Timestamp at_time) {
|
||||||
Timestamp at_time) {
|
absl::optional<DataRate> new_bitrate;
|
||||||
DataRate estimated_throughput =
|
DataRate estimated_throughput =
|
||||||
input.estimated_throughput.value_or(latest_estimated_throughput_);
|
input.estimated_throughput.value_or(latest_estimated_throughput_);
|
||||||
if (input.estimated_throughput)
|
if (input.estimated_throughput)
|
||||||
@ -274,10 +274,16 @@ DataRate AimdRateControl::ChangeBitrate(DataRate new_bitrate,
|
|||||||
// we will end up with a valid estimate.
|
// we will end up with a valid estimate.
|
||||||
if (!bitrate_is_initialized_ &&
|
if (!bitrate_is_initialized_ &&
|
||||||
input.bw_state != BandwidthUsage::kBwOverusing)
|
input.bw_state != BandwidthUsage::kBwOverusing)
|
||||||
return current_bitrate_;
|
return;
|
||||||
|
|
||||||
ChangeState(input, at_time);
|
ChangeState(input, at_time);
|
||||||
|
|
||||||
|
// We limit the new bitrate based on the troughput to avoid unlimited bitrate
|
||||||
|
// increases. We allow a bit more lag at very low rates to not too easily get
|
||||||
|
// stuck if the encoder produces uneven outputs.
|
||||||
|
const DataRate troughput_based_limit =
|
||||||
|
1.5 * estimated_throughput + DataRate::KilobitsPerSec(10);
|
||||||
|
|
||||||
switch (rate_control_state_) {
|
switch (rate_control_state_) {
|
||||||
case kRcHold:
|
case kRcHold:
|
||||||
break;
|
break;
|
||||||
@ -289,7 +295,11 @@ DataRate AimdRateControl::ChangeBitrate(DataRate new_bitrate,
|
|||||||
// Do not increase the delay based estimate in alr since the estimator
|
// Do not increase the delay based estimate in alr since the estimator
|
||||||
// will not be able to get transport feedback necessary to detect if
|
// will not be able to get transport feedback necessary to detect if
|
||||||
// the new estimate is correct.
|
// the new estimate is correct.
|
||||||
if (!(send_side_ && in_alr_ && no_bitrate_increase_in_alr_)) {
|
// If we have previously increased above the limit (for instance due to
|
||||||
|
// probing), we don't allow further changes.
|
||||||
|
if (current_bitrate_ < troughput_based_limit &&
|
||||||
|
!(send_side_ && in_alr_ && no_bitrate_increase_in_alr_)) {
|
||||||
|
DataRate increased_bitrate = DataRate::MinusInfinity();
|
||||||
if (link_capacity_.has_estimate()) {
|
if (link_capacity_.has_estimate()) {
|
||||||
// The link_capacity estimate is reset if the measured throughput
|
// The link_capacity estimate is reset if the measured throughput
|
||||||
// is too far from the estimate. We can therefore assume that our
|
// is too far from the estimate. We can therefore assume that our
|
||||||
@ -297,56 +307,66 @@ DataRate AimdRateControl::ChangeBitrate(DataRate new_bitrate,
|
|||||||
// increase.
|
// increase.
|
||||||
DataRate additive_increase =
|
DataRate additive_increase =
|
||||||
AdditiveRateIncrease(at_time, time_last_bitrate_change_);
|
AdditiveRateIncrease(at_time, time_last_bitrate_change_);
|
||||||
new_bitrate += additive_increase;
|
increased_bitrate = current_bitrate_ + additive_increase;
|
||||||
} else {
|
} else {
|
||||||
// If we don't have an estimate of the link capacity, use faster ramp
|
// If we don't have an estimate of the link capacity, use faster ramp
|
||||||
// up to discover the capacity.
|
// up to discover the capacity.
|
||||||
DataRate multiplicative_increase = MultiplicativeRateIncrease(
|
DataRate multiplicative_increase = MultiplicativeRateIncrease(
|
||||||
at_time, time_last_bitrate_change_, new_bitrate);
|
at_time, time_last_bitrate_change_, current_bitrate_);
|
||||||
new_bitrate += multiplicative_increase;
|
increased_bitrate = current_bitrate_ + multiplicative_increase;
|
||||||
}
|
}
|
||||||
|
new_bitrate = std::min(increased_bitrate, troughput_based_limit);
|
||||||
}
|
}
|
||||||
|
|
||||||
time_last_bitrate_change_ = at_time;
|
time_last_bitrate_change_ = at_time;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case kRcDecrease:
|
case kRcDecrease: {
|
||||||
|
DataRate decreased_bitrate = DataRate::PlusInfinity();
|
||||||
if (estimated_throughput > low_throughput_threshold_) {
|
if (estimated_throughput > low_throughput_threshold_) {
|
||||||
// Set bit rate to something slightly lower than the measured throughput
|
// Set bit rate to something slightly lower than the measured throughput
|
||||||
// to get rid of any self-induced delay.
|
// to get rid of any self-induced delay.
|
||||||
new_bitrate = estimated_throughput * beta_;
|
decreased_bitrate = estimated_throughput * beta_;
|
||||||
if (new_bitrate > current_bitrate_ && !link_capacity_fix_) {
|
if (decreased_bitrate > current_bitrate_ && !link_capacity_fix_) {
|
||||||
// TODO(terelius): The link_capacity estimate may be based on old
|
// TODO(terelius): The link_capacity estimate may be based on old
|
||||||
// throughput measurements. Relying on them may lead to unnecessary
|
// throughput measurements. Relying on them may lead to unnecessary
|
||||||
// BWE drops.
|
// BWE drops.
|
||||||
if (link_capacity_.has_estimate()) {
|
if (link_capacity_.has_estimate()) {
|
||||||
new_bitrate = beta_ * link_capacity_.estimate();
|
decreased_bitrate = beta_ * link_capacity_.estimate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (estimate_bounded_backoff_ && network_estimate_) {
|
if (estimate_bounded_backoff_ && network_estimate_) {
|
||||||
new_bitrate = std::max(
|
decreased_bitrate =
|
||||||
new_bitrate, network_estimate_->link_capacity_lower * beta_);
|
std::max(decreased_bitrate,
|
||||||
|
network_estimate_->link_capacity_lower * beta_);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
new_bitrate = estimated_throughput;
|
decreased_bitrate = estimated_throughput;
|
||||||
if (link_capacity_.has_estimate()) {
|
if (link_capacity_.has_estimate()) {
|
||||||
new_bitrate = std::max(new_bitrate, link_capacity_.estimate());
|
decreased_bitrate =
|
||||||
|
std::max(decreased_bitrate, link_capacity_.estimate());
|
||||||
}
|
}
|
||||||
new_bitrate = std::min(new_bitrate, low_throughput_threshold_.Get());
|
decreased_bitrate =
|
||||||
|
std::min(decreased_bitrate, low_throughput_threshold_.Get());
|
||||||
}
|
}
|
||||||
// Avoid increasing the rate when over-using.
|
// Avoid increasing the rate when over-using.
|
||||||
new_bitrate = std::min(new_bitrate, current_bitrate_);
|
if (decreased_bitrate < current_bitrate_) {
|
||||||
|
new_bitrate = decreased_bitrate;
|
||||||
|
}
|
||||||
|
|
||||||
if (bitrate_is_initialized_ && estimated_throughput < current_bitrate_) {
|
if (bitrate_is_initialized_ && estimated_throughput < current_bitrate_) {
|
||||||
constexpr double kDegradationFactor = 0.9;
|
constexpr double kDegradationFactor = 0.9;
|
||||||
if (smoothing_experiment_ &&
|
if (!new_bitrate.has_value()) {
|
||||||
new_bitrate < kDegradationFactor * beta_ * current_bitrate_) {
|
last_decrease_ = DataRate::Zero();
|
||||||
|
} else if (smoothing_experiment_ &&
|
||||||
|
*new_bitrate <
|
||||||
|
kDegradationFactor * beta_ * current_bitrate_) {
|
||||||
// If bitrate decreases more than a normal back off after overuse, it
|
// If bitrate decreases more than a normal back off after overuse, it
|
||||||
// indicates a real network degradation. We do not let such a decrease
|
// indicates a real network degradation. We do not let such a decrease
|
||||||
// to determine the bandwidth estimation period.
|
// to determine the bandwidth estimation period.
|
||||||
last_decrease_ = absl::nullopt;
|
last_decrease_ = absl::nullopt;
|
||||||
} else {
|
} else {
|
||||||
last_decrease_ = current_bitrate_ - new_bitrate;
|
last_decrease_ = current_bitrate_ - *new_bitrate;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (estimated_throughput < link_capacity_.LowerBound()) {
|
if (estimated_throughput < link_capacity_.LowerBound()) {
|
||||||
@ -362,24 +382,15 @@ DataRate AimdRateControl::ChangeBitrate(DataRate new_bitrate,
|
|||||||
time_last_bitrate_change_ = at_time;
|
time_last_bitrate_change_ = at_time;
|
||||||
time_last_bitrate_decrease_ = at_time;
|
time_last_bitrate_decrease_ = at_time;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
assert(false);
|
assert(false);
|
||||||
}
|
}
|
||||||
return ClampBitrate(new_bitrate, estimated_throughput);
|
|
||||||
|
current_bitrate_ = ClampBitrate(new_bitrate.value_or(current_bitrate_));
|
||||||
}
|
}
|
||||||
|
|
||||||
DataRate AimdRateControl::ClampBitrate(DataRate new_bitrate,
|
DataRate AimdRateControl::ClampBitrate(DataRate new_bitrate) const {
|
||||||
DataRate estimated_throughput) const {
|
|
||||||
// Don't change the bit rate if the send side is too far off.
|
|
||||||
// We allow a bit more lag at very low rates to not too easily get stuck if
|
|
||||||
// the encoder produces uneven outputs.
|
|
||||||
const DataRate max_bitrate =
|
|
||||||
1.5 * estimated_throughput + DataRate::KilobitsPerSec(10);
|
|
||||||
if (new_bitrate > current_bitrate_ && new_bitrate > max_bitrate) {
|
|
||||||
new_bitrate = std::max(current_bitrate_, max_bitrate);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (estimate_bounded_increase_ && network_estimate_) {
|
if (estimate_bounded_increase_ && network_estimate_) {
|
||||||
DataRate upper_bound = network_estimate_->link_capacity_upper;
|
DataRate upper_bound = network_estimate_->link_capacity_upper;
|
||||||
new_bitrate = std::min(new_bitrate, upper_bound);
|
new_bitrate = std::min(new_bitrate, upper_bound);
|
||||||
|
|||||||
@ -73,14 +73,9 @@ class AimdRateControl {
|
|||||||
// in the "decrease" state the bitrate will be decreased to slightly below the
|
// in the "decrease" state the bitrate will be decreased to slightly below the
|
||||||
// current throughput. When in the "hold" state the bitrate will be kept
|
// current throughput. When in the "hold" state the bitrate will be kept
|
||||||
// constant to allow built up queues to drain.
|
// constant to allow built up queues to drain.
|
||||||
DataRate ChangeBitrate(DataRate current_bitrate,
|
void ChangeBitrate(const RateControlInput& input, Timestamp at_time);
|
||||||
const RateControlInput& input,
|
|
||||||
Timestamp at_time);
|
DataRate ClampBitrate(DataRate new_bitrate) const;
|
||||||
// Clamps new_bitrate to within the configured min bitrate and a linear
|
|
||||||
// function of the throughput, so that the new bitrate can't grow too
|
|
||||||
// large compared to the bitrate actually being received by the other end.
|
|
||||||
DataRate ClampBitrate(DataRate new_bitrate,
|
|
||||||
DataRate estimated_throughput) const;
|
|
||||||
DataRate MultiplicativeRateIncrease(Timestamp at_time,
|
DataRate MultiplicativeRateIncrease(Timestamp at_time,
|
||||||
Timestamp last_ms,
|
Timestamp last_ms,
|
||||||
DataRate current_bitrate) const;
|
DataRate current_bitrate) const;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user