New loss-based bandwidth control mechanism.
Bug: none Change-Id: Ie60e9225e2a2260624342ffbadb08cb887b2b6f5 Reviewed-on: https://webrtc-review.googlesource.com/c/109923 Commit-Queue: Christoffer Rodbro <crodbro@webrtc.org> Reviewed-by: Sebastian Jansson <srte@webrtc.org> Cr-Commit-Position: refs/heads/master@{#25696}
This commit is contained in:
parent
26e88b0c1d
commit
3a83748422
@ -15,6 +15,8 @@ rtc_static_library("bitrate_controller") {
|
||||
"bitrate_controller_impl.cc",
|
||||
"bitrate_controller_impl.h",
|
||||
"include/bitrate_controller.h",
|
||||
"loss_based_bandwidth_estimation.cc",
|
||||
"loss_based_bandwidth_estimation.h",
|
||||
"send_side_bandwidth_estimation.cc",
|
||||
"send_side_bandwidth_estimation.h",
|
||||
]
|
||||
|
||||
215
modules/bitrate_controller/loss_based_bandwidth_estimation.cc
Normal file
215
modules/bitrate_controller/loss_based_bandwidth_estimation.cc
Normal file
@ -0,0 +1,215 @@
|
||||
/*
|
||||
* Copyright (c) 2018 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 "modules/bitrate_controller/loss_based_bandwidth_estimation.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "api/units/data_rate.h"
|
||||
#include "api/units/time_delta.h"
|
||||
#include "system_wrappers/include/field_trial.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace {
|
||||
const char kBweLossBasedControl[] = "WebRTC-Bwe-LossBasedControl";
|
||||
|
||||
// Increase slower when RTT is high.
|
||||
double GetIncreaseFactor(const LossBasedControlConfig& config, TimeDelta rtt) {
|
||||
// Clamp the RTT
|
||||
if (rtt < config.increase_low_rtt) {
|
||||
rtt = config.increase_low_rtt;
|
||||
} else if (rtt > config.increase_high_rtt) {
|
||||
rtt = config.increase_high_rtt;
|
||||
}
|
||||
auto rtt_range = config.increase_high_rtt.Get() - config.increase_low_rtt;
|
||||
if (rtt_range <= TimeDelta::Zero()) {
|
||||
RTC_DCHECK(false); // Only on misconfiguration.
|
||||
return config.min_increase_factor;
|
||||
}
|
||||
auto rtt_offset = rtt - config.increase_low_rtt;
|
||||
auto relative_offset = std::max(0.0, std::min(rtt_offset / rtt_range, 1.0));
|
||||
auto factor_range = config.max_increase_factor - config.min_increase_factor;
|
||||
return config.min_increase_factor + (1 - relative_offset) * factor_range;
|
||||
}
|
||||
|
||||
double LossFromBitrate(DataRate bitrate,
|
||||
DataRate loss_bandwidth_balance,
|
||||
double exponent) {
|
||||
if (loss_bandwidth_balance >= bitrate)
|
||||
return 1.0;
|
||||
return pow(loss_bandwidth_balance / bitrate, exponent);
|
||||
}
|
||||
|
||||
DataRate BitrateFromLoss(double loss,
|
||||
DataRate loss_bandwidth_balance,
|
||||
double exponent) {
|
||||
if (exponent <= 0) {
|
||||
RTC_DCHECK(false);
|
||||
return DataRate::Infinity();
|
||||
}
|
||||
if (loss < 1e-5)
|
||||
return DataRate::Infinity();
|
||||
return loss_bandwidth_balance * pow(loss, -1.0 / exponent);
|
||||
}
|
||||
|
||||
double ExponentialUpdate(TimeDelta window, TimeDelta interval) {
|
||||
// Use the convention that exponential window length (which is really
|
||||
// infinite) is the time it takes to dampen to 1/e.
|
||||
if (window <= TimeDelta::Zero()) {
|
||||
RTC_DCHECK(false);
|
||||
return 1.0f;
|
||||
}
|
||||
return 1.0f - exp(interval / window * -1.0);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
LossBasedControlConfig::LossBasedControlConfig()
|
||||
: enabled(field_trial::IsEnabled(kBweLossBasedControl)),
|
||||
min_increase_factor("min_incr", 1.02),
|
||||
max_increase_factor("max_incr", 1.08),
|
||||
increase_low_rtt("incr_low_rtt", TimeDelta::ms(200)),
|
||||
increase_high_rtt("incr_high_rtt", TimeDelta::ms(800)),
|
||||
decrease_factor("decr", 0.99),
|
||||
loss_window("loss_win", TimeDelta::ms(800)),
|
||||
loss_max_window("loss_max_win", TimeDelta::ms(800)),
|
||||
acknowledged_rate_max_window("ackrate_max_win", TimeDelta::ms(800)),
|
||||
increase_offset("incr_offset", DataRate::bps(1000)),
|
||||
loss_bandwidth_balance_increase("balance_incr", DataRate::kbps(0.5)),
|
||||
loss_bandwidth_balance_decrease("balance_decr", DataRate::kbps(4)),
|
||||
loss_bandwidth_balance_exponent("exponent", 0.5),
|
||||
allow_resets("resets", false),
|
||||
decrease_interval("decr_intvl", TimeDelta::ms(300)),
|
||||
loss_report_timeout("timeout", TimeDelta::ms(6000)) {
|
||||
std::string trial_string = field_trial::FindFullName(kBweLossBasedControl);
|
||||
ParseFieldTrial(
|
||||
{&min_increase_factor, &max_increase_factor, &increase_low_rtt,
|
||||
&increase_high_rtt, &decrease_factor, &loss_window, &loss_max_window,
|
||||
&acknowledged_rate_max_window, &increase_offset,
|
||||
&loss_bandwidth_balance_increase, &loss_bandwidth_balance_decrease,
|
||||
&loss_bandwidth_balance_exponent, &allow_resets, &decrease_interval,
|
||||
&loss_report_timeout},
|
||||
trial_string);
|
||||
}
|
||||
LossBasedControlConfig::LossBasedControlConfig(const LossBasedControlConfig&) =
|
||||
default;
|
||||
LossBasedControlConfig::~LossBasedControlConfig() = default;
|
||||
|
||||
LossBasedBandwidthEstimation::LossBasedBandwidthEstimation()
|
||||
: config_(LossBasedControlConfig()),
|
||||
average_loss_(0),
|
||||
average_loss_max_(0),
|
||||
loss_based_bitrate_(DataRate::Zero()),
|
||||
acknowledged_bitrate_max_(DataRate::Zero()),
|
||||
acknowledged_bitrate_last_update_(Timestamp::MinusInfinity()),
|
||||
time_last_decrease_(Timestamp::MinusInfinity()),
|
||||
has_decreased_since_last_loss_report_(false),
|
||||
last_loss_packet_report_(Timestamp::MinusInfinity()),
|
||||
last_loss_ratio_(0) {}
|
||||
|
||||
void LossBasedBandwidthEstimation::UpdateLossStatistics(
|
||||
const std::vector<PacketResult>& packet_results,
|
||||
Timestamp at_time) {
|
||||
if (packet_results.empty()) {
|
||||
RTC_DCHECK(false);
|
||||
return;
|
||||
}
|
||||
int loss_count = 0;
|
||||
for (auto pkt : packet_results) {
|
||||
loss_count += pkt.receive_time.IsInfinite() ? 1 : 0;
|
||||
}
|
||||
last_loss_ratio_ = static_cast<double>(loss_count) / packet_results.size();
|
||||
const TimeDelta time_passed = last_loss_packet_report_.IsFinite()
|
||||
? at_time - last_loss_packet_report_
|
||||
: TimeDelta::seconds(1);
|
||||
last_loss_packet_report_ = at_time;
|
||||
has_decreased_since_last_loss_report_ = false;
|
||||
|
||||
average_loss_ += ExponentialUpdate(config_.loss_window, time_passed) *
|
||||
(last_loss_ratio_ - average_loss_);
|
||||
if (average_loss_ > average_loss_max_) {
|
||||
average_loss_max_ = average_loss_;
|
||||
} else {
|
||||
average_loss_max_ +=
|
||||
ExponentialUpdate(config_.loss_max_window, time_passed) *
|
||||
(average_loss_ - average_loss_max_);
|
||||
}
|
||||
}
|
||||
|
||||
void LossBasedBandwidthEstimation::UpdateAcknowledgedBitrate(
|
||||
DataRate acknowledged_bitrate,
|
||||
Timestamp at_time) {
|
||||
const TimeDelta time_passed =
|
||||
acknowledged_bitrate_last_update_.IsFinite()
|
||||
? at_time - acknowledged_bitrate_last_update_
|
||||
: TimeDelta::seconds(1);
|
||||
acknowledged_bitrate_last_update_ = at_time;
|
||||
if (acknowledged_bitrate > acknowledged_bitrate_max_) {
|
||||
acknowledged_bitrate_max_ = acknowledged_bitrate;
|
||||
} else {
|
||||
acknowledged_bitrate_max_ +=
|
||||
ExponentialUpdate(config_.acknowledged_rate_max_window, time_passed) *
|
||||
(acknowledged_bitrate - acknowledged_bitrate_max_);
|
||||
}
|
||||
}
|
||||
|
||||
void LossBasedBandwidthEstimation::Update(Timestamp at_time,
|
||||
DataRate min_bitrate,
|
||||
TimeDelta last_round_trip_time) {
|
||||
// Only increase if loss has been low for some time.
|
||||
const double loss_estimate_for_increase = average_loss_max_;
|
||||
// Avoid multiple decreases from averaging over one loss spike.
|
||||
const double loss_estimate_for_decrease =
|
||||
std::min(average_loss_, last_loss_ratio_);
|
||||
|
||||
const double loss_increase_threshold = LossFromBitrate(
|
||||
loss_based_bitrate_, config_.loss_bandwidth_balance_increase,
|
||||
config_.loss_bandwidth_balance_exponent);
|
||||
const double loss_decrease_threshold = LossFromBitrate(
|
||||
loss_based_bitrate_, config_.loss_bandwidth_balance_decrease,
|
||||
config_.loss_bandwidth_balance_exponent);
|
||||
const bool allow_decrease =
|
||||
!has_decreased_since_last_loss_report_ &&
|
||||
(at_time - time_last_decrease_ >=
|
||||
last_round_trip_time + config_.decrease_interval);
|
||||
|
||||
if (loss_estimate_for_increase < loss_increase_threshold) {
|
||||
// Increase bitrate by RTT-adaptive ratio.
|
||||
DataRate new_increased_bitrate =
|
||||
min_bitrate * GetIncreaseFactor(config_, last_round_trip_time) +
|
||||
config_.increase_offset;
|
||||
// The bitrate that would make the loss "just high enough".
|
||||
const DataRate new_increased_bitrate_cap = BitrateFromLoss(
|
||||
loss_estimate_for_increase, config_.loss_bandwidth_balance_increase,
|
||||
config_.loss_bandwidth_balance_exponent);
|
||||
new_increased_bitrate =
|
||||
std::min(new_increased_bitrate, new_increased_bitrate_cap);
|
||||
loss_based_bitrate_ = std::max(new_increased_bitrate, loss_based_bitrate_);
|
||||
} else if (loss_estimate_for_decrease > loss_decrease_threshold &&
|
||||
allow_decrease) {
|
||||
DataRate new_decreased_bitrate =
|
||||
config_.decrease_factor * acknowledged_bitrate_max_;
|
||||
// The bitrate that would make the loss "just acceptable".
|
||||
const DataRate new_decreased_bitrate_floor = BitrateFromLoss(
|
||||
loss_estimate_for_decrease, config_.loss_bandwidth_balance_decrease,
|
||||
config_.loss_bandwidth_balance_exponent);
|
||||
new_decreased_bitrate =
|
||||
std::max(new_decreased_bitrate, new_decreased_bitrate_floor);
|
||||
if (new_decreased_bitrate < loss_based_bitrate_) {
|
||||
time_last_decrease_ = at_time;
|
||||
has_decreased_since_last_loss_report_ = true;
|
||||
loss_based_bitrate_ = new_decreased_bitrate;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
80
modules/bitrate_controller/loss_based_bandwidth_estimation.h
Normal file
80
modules/bitrate_controller/loss_based_bandwidth_estimation.h
Normal file
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright (c) 2018 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 MODULES_BITRATE_CONTROLLER_LOSS_BASED_BANDWIDTH_ESTIMATION_H_
|
||||
#define MODULES_BITRATE_CONTROLLER_LOSS_BASED_BANDWIDTH_ESTIMATION_H_
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "api/units/data_rate.h"
|
||||
#include "api/units/time_delta.h"
|
||||
#include "api/units/timestamp.h"
|
||||
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
|
||||
#include "rtc_base/experiments/field_trial_parser.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
struct LossBasedControlConfig {
|
||||
LossBasedControlConfig();
|
||||
LossBasedControlConfig(const LossBasedControlConfig&);
|
||||
LossBasedControlConfig& operator=(const LossBasedControlConfig&) = default;
|
||||
~LossBasedControlConfig();
|
||||
bool enabled;
|
||||
FieldTrialParameter<double> min_increase_factor;
|
||||
FieldTrialParameter<double> max_increase_factor;
|
||||
FieldTrialParameter<TimeDelta> increase_low_rtt;
|
||||
FieldTrialParameter<TimeDelta> increase_high_rtt;
|
||||
FieldTrialParameter<double> decrease_factor;
|
||||
FieldTrialParameter<TimeDelta> loss_window;
|
||||
FieldTrialParameter<TimeDelta> loss_max_window;
|
||||
FieldTrialParameter<TimeDelta> acknowledged_rate_max_window;
|
||||
FieldTrialParameter<DataRate> increase_offset;
|
||||
FieldTrialParameter<DataRate> loss_bandwidth_balance_increase;
|
||||
FieldTrialParameter<DataRate> loss_bandwidth_balance_decrease;
|
||||
FieldTrialParameter<double> loss_bandwidth_balance_exponent;
|
||||
FieldTrialParameter<bool> allow_resets;
|
||||
FieldTrialParameter<TimeDelta> decrease_interval;
|
||||
FieldTrialParameter<TimeDelta> loss_report_timeout;
|
||||
};
|
||||
|
||||
class LossBasedBandwidthEstimation {
|
||||
public:
|
||||
LossBasedBandwidthEstimation();
|
||||
void Update(Timestamp at_time,
|
||||
DataRate min_bitrate,
|
||||
TimeDelta last_round_trip_time);
|
||||
void UpdateAcknowledgedBitrate(DataRate acknowledged_bitrate,
|
||||
Timestamp at_time);
|
||||
void MaybeReset(DataRate bitrate) {
|
||||
if (config_.allow_resets)
|
||||
loss_based_bitrate_ = bitrate;
|
||||
}
|
||||
void SetInitialBitrate(DataRate bitrate) { loss_based_bitrate_ = bitrate; }
|
||||
bool Enabled() const { return config_.enabled; }
|
||||
void UpdateLossStatistics(const std::vector<PacketResult>& packet_results,
|
||||
Timestamp at_time);
|
||||
DataRate GetEstimate() const { return loss_based_bitrate_; }
|
||||
|
||||
private:
|
||||
LossBasedControlConfig config_;
|
||||
double average_loss_;
|
||||
double average_loss_max_;
|
||||
DataRate loss_based_bitrate_;
|
||||
DataRate acknowledged_bitrate_max_;
|
||||
Timestamp acknowledged_bitrate_last_update_;
|
||||
Timestamp time_last_decrease_;
|
||||
bool has_decreased_since_last_loss_report_;
|
||||
Timestamp last_loss_packet_report_;
|
||||
double last_loss_ratio_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // MODULES_BITRATE_CONTROLLER_LOSS_BASED_BANDWIDTH_ESTIMATION_H_
|
||||
@ -229,6 +229,9 @@ void SendSideBandwidthEstimation::SetSendBitrate(DataRate bitrate,
|
||||
RTC_DCHECK(bitrate > DataRate::Zero());
|
||||
// Reset to avoid being capped by the estimate.
|
||||
delay_based_bitrate_ = DataRate::Zero();
|
||||
if (loss_based_bandwidth_estimation_.Enabled()) {
|
||||
loss_based_bandwidth_estimation_.MaybeReset(bitrate);
|
||||
}
|
||||
CapBitrateToThresholds(at_time, bitrate);
|
||||
// Clear last sent bitrate history so the new value can be used directly
|
||||
// and not capped.
|
||||
@ -270,6 +273,20 @@ void SendSideBandwidthEstimation::UpdateDelayBasedEstimate(Timestamp at_time,
|
||||
CapBitrateToThresholds(at_time, current_bitrate_);
|
||||
}
|
||||
|
||||
void SendSideBandwidthEstimation::IncomingPacketFeedbackVector(
|
||||
const TransportPacketsFeedback& report,
|
||||
absl::optional<uint32_t> acked_bitrate_bps) {
|
||||
if (!loss_based_bandwidth_estimation_.Enabled())
|
||||
return;
|
||||
if (acked_bitrate_bps) {
|
||||
DataRate acked_bitrate = DataRate::bps(*acked_bitrate_bps);
|
||||
loss_based_bandwidth_estimation_.UpdateAcknowledgedBitrate(
|
||||
acked_bitrate, report.feedback_time);
|
||||
}
|
||||
loss_based_bandwidth_estimation_.UpdateLossStatistics(report.packet_feedbacks,
|
||||
report.feedback_time);
|
||||
}
|
||||
|
||||
void SendSideBandwidthEstimation::UpdateReceiverBlock(uint8_t fraction_loss,
|
||||
TimeDelta rtt,
|
||||
int number_of_packets,
|
||||
@ -372,6 +389,9 @@ void SendSideBandwidthEstimation::UpdateEstimate(Timestamp at_time) {
|
||||
if (last_fraction_loss_ == 0 && IsInStartPhase(at_time)) {
|
||||
new_bitrate = std::max(bwe_incoming_, new_bitrate);
|
||||
new_bitrate = std::max(delay_based_bitrate_, new_bitrate);
|
||||
if (loss_based_bandwidth_estimation_.Enabled()) {
|
||||
loss_based_bandwidth_estimation_.SetInitialBitrate(new_bitrate);
|
||||
}
|
||||
|
||||
if (new_bitrate != current_bitrate_) {
|
||||
min_bitrate_history_.clear();
|
||||
@ -386,6 +406,15 @@ void SendSideBandwidthEstimation::UpdateEstimate(Timestamp at_time) {
|
||||
CapBitrateToThresholds(at_time, current_bitrate_);
|
||||
return;
|
||||
}
|
||||
|
||||
if (loss_based_bandwidth_estimation_.Enabled()) {
|
||||
loss_based_bandwidth_estimation_.Update(
|
||||
at_time, min_bitrate_history_.front().second, last_round_trip_time_);
|
||||
new_bitrate = MaybeRampupOrBackoff(new_bitrate, at_time);
|
||||
CapBitrateToThresholds(at_time, new_bitrate);
|
||||
return;
|
||||
}
|
||||
|
||||
TimeDelta time_since_loss_packet_report = at_time - last_loss_packet_report_;
|
||||
TimeDelta time_since_loss_feedback = at_time - last_loss_feedback_;
|
||||
if (time_since_loss_packet_report < 1.2 * kMaxRtcpFeedbackInterval) {
|
||||
@ -400,7 +429,7 @@ void SendSideBandwidthEstimation::UpdateEstimate(Timestamp at_time) {
|
||||
// Note that by remembering the bitrate over the last second one can
|
||||
// rampup up one second faster than if only allowed to start ramping
|
||||
// at 8% per second rate now. E.g.:
|
||||
// If sending a constant 100kbps it can rampup immediatly to 108kbps
|
||||
// If sending a constant 100kbps it can rampup immediately to 108kbps
|
||||
// whenever a receiver report is received with lower packet loss.
|
||||
// If instead one would do: current_bitrate_ *= 1.08^(delta time),
|
||||
// it would take over one second since the lower packet loss to achieve
|
||||
@ -485,6 +514,35 @@ void SendSideBandwidthEstimation::UpdateMinHistory(Timestamp at_time) {
|
||||
min_bitrate_history_.push_back(std::make_pair(at_time, current_bitrate_));
|
||||
}
|
||||
|
||||
DataRate SendSideBandwidthEstimation::MaybeRampupOrBackoff(DataRate new_bitrate,
|
||||
Timestamp at_time) {
|
||||
// TODO(crodbro): reuse this code in UpdateEstimate instead of current
|
||||
// inlining of very similar functionality.
|
||||
const TimeDelta time_since_loss_packet_report =
|
||||
at_time - last_loss_packet_report_;
|
||||
const TimeDelta time_since_loss_feedback = at_time - last_loss_feedback_;
|
||||
if (time_since_loss_packet_report < 1.2 * kMaxRtcpFeedbackInterval) {
|
||||
new_bitrate = min_bitrate_history_.front().second * 1.08;
|
||||
new_bitrate += DataRate::bps(1000);
|
||||
} else if (time_since_loss_feedback >
|
||||
kFeedbackTimeoutIntervals * kMaxRtcpFeedbackInterval &&
|
||||
(last_timeout_.IsInfinite() ||
|
||||
at_time - last_timeout_ > kTimeoutInterval)) {
|
||||
if (in_timeout_experiment_) {
|
||||
RTC_LOG(LS_WARNING) << "Feedback timed out ("
|
||||
<< ToString(time_since_loss_feedback)
|
||||
<< "), reducing bitrate.";
|
||||
new_bitrate = new_bitrate * 0.8;
|
||||
// Reset accumulators since we've already acted on missing feedback and
|
||||
// shouldn't to act again on these old lost packets.
|
||||
lost_packets_since_last_loss_update_ = 0;
|
||||
expected_packets_since_last_loss_update_ = 0;
|
||||
last_timeout_ = at_time;
|
||||
}
|
||||
}
|
||||
return new_bitrate;
|
||||
}
|
||||
|
||||
void SendSideBandwidthEstimation::CapBitrateToThresholds(Timestamp at_time,
|
||||
DataRate bitrate) {
|
||||
if (bwe_incoming_ > DataRate::Zero() && bitrate > bwe_incoming_) {
|
||||
@ -494,6 +552,10 @@ void SendSideBandwidthEstimation::CapBitrateToThresholds(Timestamp at_time,
|
||||
bitrate > delay_based_bitrate_) {
|
||||
bitrate = delay_based_bitrate_;
|
||||
}
|
||||
if (loss_based_bandwidth_estimation_.Enabled() &&
|
||||
loss_based_bandwidth_estimation_.GetEstimate() > DataRate::Zero()) {
|
||||
bitrate = std::min(bitrate, loss_based_bandwidth_estimation_.GetEstimate());
|
||||
}
|
||||
if (bitrate > max_bitrate_configured_) {
|
||||
bitrate = max_bitrate_configured_;
|
||||
}
|
||||
|
||||
@ -23,6 +23,8 @@
|
||||
#include "api/units/data_rate.h"
|
||||
#include "api/units/time_delta.h"
|
||||
#include "api/units/timestamp.h"
|
||||
#include "modules/bitrate_controller/loss_based_bandwidth_estimation.h"
|
||||
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
|
||||
#include "rtc_base/experiments/field_trial_parser.h"
|
||||
|
||||
namespace webrtc {
|
||||
@ -88,6 +90,8 @@ class SendSideBandwidthEstimation {
|
||||
void SetSendBitrate(DataRate bitrate, Timestamp at_time);
|
||||
void SetMinMaxBitrate(DataRate min_bitrate, DataRate max_bitrate);
|
||||
int GetMinBitrate() const;
|
||||
void IncomingPacketFeedbackVector(const TransportPacketsFeedback& report,
|
||||
absl::optional<uint32_t> acked_bitrate_bps);
|
||||
|
||||
private:
|
||||
enum UmaState { kNoUpdate, kFirstDone, kDone };
|
||||
@ -101,6 +105,8 @@ class SendSideBandwidthEstimation {
|
||||
// min bitrate used during last kBweIncreaseIntervalMs.
|
||||
void UpdateMinHistory(Timestamp at_time);
|
||||
|
||||
DataRate MaybeRampupOrBackoff(DataRate new_bitrate, Timestamp at_time);
|
||||
|
||||
// Cap |bitrate| to [min_bitrate_configured_, max_bitrate_configured_] and
|
||||
// set |current_bitrate_| to the capped value and updates the event log.
|
||||
void CapBitrateToThresholds(Timestamp at_time, DataRate bitrate);
|
||||
@ -141,6 +147,7 @@ class SendSideBandwidthEstimation {
|
||||
float low_loss_threshold_;
|
||||
float high_loss_threshold_;
|
||||
DataRate bitrate_threshold_;
|
||||
LossBasedBandwidthEstimation loss_based_bandwidth_estimation_;
|
||||
};
|
||||
} // namespace webrtc
|
||||
#endif // MODULES_BITRATE_CONTROLLER_SEND_SIDE_BANDWIDTH_ESTIMATION_H_
|
||||
|
||||
@ -482,6 +482,9 @@ NetworkControlUpdate GoogCcNetworkController::OnTransportPacketsFeedback(
|
||||
acknowledged_bitrate_estimator_->IncomingPacketFeedbackVector(
|
||||
received_feedback_vector);
|
||||
auto acknowledged_bitrate = acknowledged_bitrate_estimator_->bitrate_bps();
|
||||
bandwidth_estimation_->IncomingPacketFeedbackVector(report,
|
||||
acknowledged_bitrate);
|
||||
|
||||
DelayBasedBwe::Result result;
|
||||
result = delay_based_bwe_->IncomingPacketFeedbackVector(
|
||||
received_feedback_vector, acknowledged_bitrate,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user