Skip to content

Commit

Permalink
Bug 1812154 - Vendor libwebrtc from 332810ab5d
Browse files Browse the repository at this point in the history
Upstream commit: https://webrtc.googlesource.com/src/+/332810ab5d41862b8f85ef30e84dbec4241f8b21
    Probing integration in loss based bwe 2.

    - Loss based bwe has 3 states: increasing (increasing when loss limited), decreasing (decreasing when loss limited), or delay based bwe (the same as delay based estimate).
    - When bandwidth is loss limited and decreasing, and probe result is available, GetLossBasedResult = min(estimate, probe result).
    - When bandwidth is loss limited and increasing, and the estimate is bounded by acked bitrate * a factor.
    - When bandwidth is loss limited and probe result is available, use probe bitrate as the current estimate, and reset probe bitrate.

    Bug: webrtc:12707
    Change-Id: I53cb82aa16397941c0cfaf1035116f775bdce72b
    Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/277400
    Commit-Queue: Diep Bui <[email protected]>
    Reviewed-by: Per Kjellander <[email protected]>
    Cr-Commit-Position: refs/heads/main@{#38382}
  • Loading branch information
Drekabi committed Feb 4, 2023
1 parent a237f43 commit ed6d82d
Show file tree
Hide file tree
Showing 8 changed files with 452 additions and 187 deletions.
3 changes: 3 additions & 0 deletions third_party/libwebrtc/README.moz-ff-commit
Original file line number Diff line number Diff line change
Expand Up @@ -18723,3 +18723,6 @@ f363d0d4d3
# MOZ_LIBWEBRTC_SRC=/Users/danielbaker/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh
# base of lastest vendoring
6c733eed8e
# MOZ_LIBWEBRTC_SRC=/Users/danielbaker/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh
# base of lastest vendoring
332810ab5d
2 changes: 2 additions & 0 deletions third_party/libwebrtc/README.mozilla
Original file line number Diff line number Diff line change
Expand Up @@ -12504,3 +12504,5 @@ libwebrtc updated from /Users/danielbaker/moz-libwebrtc commit mozpatches on 202
libwebrtc updated from /Users/danielbaker/moz-libwebrtc commit mozpatches on 2023-02-04T21:27:30.740625.
# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /Users/danielbaker/moz-libwebrtc --commit mozpatches libwebrtc
libwebrtc updated from /Users/danielbaker/moz-libwebrtc commit mozpatches on 2023-02-04T21:29:30.610306.
# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /Users/danielbaker/moz-libwebrtc --commit mozpatches libwebrtc
libwebrtc updated from /Users/danielbaker/moz-libwebrtc commit mozpatches on 2023-02-04T21:30:50.227411.
Original file line number Diff line number Diff line change
Expand Up @@ -549,8 +549,8 @@ NetworkControlUpdate GoogCcNetworkController::OnTransportPacketsFeedback(
bandwidth_estimation_->UpdateDelayBasedEstimate(report.feedback_time,
result.target_bitrate);
}
bandwidth_estimation_->UpdateLossBasedEstimator(report,
result.delay_detector_state);
bandwidth_estimation_->UpdateLossBasedEstimator(
report, result.delay_detector_state, probe_bitrate);
if (result.updated) {
// Update the estimate in the ProbeController, in case we want to probe.
MaybeTriggerOnNetworkChanged(&update, report.feedback_time);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ bool IsValid(DataRate datarate) {
return datarate.IsFinite();
}

bool IsValid(absl::optional<DataRate> datarate) {
return datarate.has_value() && IsValid(datarate.value());
}

bool IsValid(Timestamp timestamp) {
return timestamp.IsFinite();
}
Expand Down Expand Up @@ -134,8 +138,10 @@ bool LossBasedBweV2::IsReady() const {
num_observations_ > 0;
}

DataRate LossBasedBweV2::GetBandwidthEstimate(
LossBasedBweV2::Result LossBasedBweV2::GetLossBasedResult(
DataRate delay_based_limit) const {
Result result;
result.state = current_state_;
if (!IsReady()) {
if (!IsEnabled()) {
RTC_LOG(LS_WARNING)
Expand All @@ -150,17 +156,21 @@ DataRate LossBasedBweV2::GetBandwidthEstimate(
"statistics before it can be used.";
}
}
return IsValid(delay_based_limit) ? delay_based_limit
: DataRate::PlusInfinity();
result.bandwidth_estimate = IsValid(delay_based_limit)
? delay_based_limit
: DataRate::PlusInfinity();
return result;
}

if (delay_based_limit.IsFinite()) {
return std::min({current_estimate_.loss_limited_bandwidth,
GetInstantUpperBound(), delay_based_limit});
if (IsValid(delay_based_limit)) {
result.bandwidth_estimate =
std::min({current_estimate_.loss_limited_bandwidth,
GetInstantUpperBound(), delay_based_limit});
} else {
return std::min(current_estimate_.loss_limited_bandwidth,
GetInstantUpperBound());
result.bandwidth_estimate = std::min(
current_estimate_.loss_limited_bandwidth, GetInstantUpperBound());
}
return result;
}

void LossBasedBweV2::SetAcknowledgedBitrate(DataRate acknowledged_bitrate) {
Expand Down Expand Up @@ -190,15 +200,25 @@ void LossBasedBweV2::SetMinBitrate(DataRate min_bitrate) {
}
}

void LossBasedBweV2::SetProbeBitrate(absl::optional<DataRate> probe_bitrate) {
if (probe_bitrate.has_value() && IsValid(probe_bitrate.value())) {
if (!IsValid(probe_bitrate_) || probe_bitrate_ > probe_bitrate.value()) {
probe_bitrate_ = probe_bitrate.value();
}
}
}

void LossBasedBweV2::UpdateBandwidthEstimate(
rtc::ArrayView<const PacketResult> packet_results,
DataRate delay_based_estimate,
BandwidthUsage delay_detector_state) {
BandwidthUsage delay_detector_state,
absl::optional<DataRate> probe_bitrate) {
if (!IsEnabled()) {
RTC_LOG(LS_WARNING)
<< "The estimator must be enabled before it can be used.";
return;
}
SetProbeBitrate(probe_bitrate);
if (packet_results.empty()) {
RTC_LOG(LS_VERBOSE)
<< "The estimate cannot be updated without any loss statistics.";
Expand Down Expand Up @@ -241,34 +261,75 @@ void LossBasedBweV2::UpdateBandwidthEstimate(
current_estimate_.loss_limited_bandwidth;
}

// Bound the estimate increase if:
// 1. The estimate is limited due to loss, and
// 2. The estimate has been increased for less than `delayed_increase_window`
// ago, and
// 3. The best candidate is greater than bandwidth_limit_in_current_window.
if (limited_due_to_loss_candidate_ &&
recovering_after_loss_timestamp_.IsFinite() &&
recovering_after_loss_timestamp_ + config_->delayed_increase_window >
last_send_time_most_recent_observation_ &&
best_candidate.loss_limited_bandwidth >
bandwidth_limit_in_current_window_) {
best_candidate.loss_limited_bandwidth = bandwidth_limit_in_current_window_;
}
limited_due_to_loss_candidate_ =
delay_based_estimate.IsFinite() &&
best_candidate.loss_limited_bandwidth < delay_based_estimate;

if (limited_due_to_loss_candidate_ &&
if (IsBandwidthLimitedDueToLoss()) {
// Bound the estimate increase if:
// 1. The estimate has been increased for less than
// `delayed_increase_window` ago, and
// 2. The best candidate is greater than bandwidth_limit_in_current_window.
if (recovering_after_loss_timestamp_.IsFinite() &&
recovering_after_loss_timestamp_ + config_->delayed_increase_window >
last_send_time_most_recent_observation_ &&
best_candidate.loss_limited_bandwidth >
bandwidth_limit_in_current_window_) {
best_candidate.loss_limited_bandwidth =
bandwidth_limit_in_current_window_;
}

bool increasing_when_loss_limited =
IsEstimateIncreasingWhenLossLimited(best_candidate);
// Bound the best candidate by the acked bitrate unless there is a recent
// probe result.
if (increasing_when_loss_limited && !IsValid(probe_bitrate_) &&
IsValid(acknowledged_bitrate_)) {
best_candidate.loss_limited_bandwidth =
IsValid(best_candidate.loss_limited_bandwidth)
? std::min(best_candidate.loss_limited_bandwidth,
config_->bandwidth_rampup_upper_bound_factor *
(*acknowledged_bitrate_))
: config_->bandwidth_rampup_upper_bound_factor *
(*acknowledged_bitrate_);
}

// Use probe bitrate as the estimate as probe bitrate is trusted to be
// correct. After being used, the probe bitrate is reset.
if (config_->probe_integration_enabled && IsValid(probe_bitrate_)) {
best_candidate.loss_limited_bandwidth =
std::min(probe_bitrate_, best_candidate.loss_limited_bandwidth);
probe_bitrate_ = DataRate::MinusInfinity();
}
}

if (IsEstimateIncreasingWhenLossLimited(best_candidate)) {
current_state_ = LossBasedState::kIncreasing;
} else if (IsValid(delay_based_estimate) &&
best_candidate.loss_limited_bandwidth < delay_based_estimate) {
current_state_ = LossBasedState::kDecreasing;
} else if (IsValid(delay_based_estimate) &&
best_candidate.loss_limited_bandwidth == delay_based_estimate) {
current_state_ = LossBasedState::kDelayBasedEstimate;
}
current_estimate_ = best_candidate;

if (IsBandwidthLimitedDueToLoss() &&
(recovering_after_loss_timestamp_.IsInfinite() ||
recovering_after_loss_timestamp_ + config_->delayed_increase_window <
last_send_time_most_recent_observation_)) {
bandwidth_limit_in_current_window_ = std::max(
kCongestionControllerMinBitrate,
best_candidate.loss_limited_bandwidth * config_->max_increase_factor);
bandwidth_limit_in_current_window_ =
std::max(kCongestionControllerMinBitrate,
current_estimate_.loss_limited_bandwidth *
config_->max_increase_factor);
recovering_after_loss_timestamp_ = last_send_time_most_recent_observation_;
}
}

current_estimate_ = best_candidate;
bool LossBasedBweV2::IsEstimateIncreasingWhenLossLimited(
const ChannelParameters& best_candidate) {
return (current_estimate_.loss_limited_bandwidth <
best_candidate.loss_limited_bandwidth ||
(current_estimate_.loss_limited_bandwidth ==
best_candidate.loss_limited_bandwidth &&
current_state_ == LossBasedState::kIncreasing)) &&
IsBandwidthLimitedDueToLoss();
}

// Returns a `LossBasedBweV2::Config` iff the `key_value_config` specifies a
Expand Down Expand Up @@ -339,6 +400,8 @@ absl::optional<LossBasedBweV2::Config> LossBasedBweV2::CreateConfig(
"BandwidthCapAtHighLossRate", DataRate::KilobitsPerSec(500.0));
FieldTrialParameter<double> slope_of_bwe_high_loss_func(
"SlopeOfBweHighLossFunc", 1000);
FieldTrialParameter<bool> probe_integration_enabled("ProbeIntegrationEnabled",
false);
if (key_value_config) {
ParseFieldTrial({&enabled,
&bandwidth_rampup_upper_bound_factor,
Expand Down Expand Up @@ -371,6 +434,7 @@ absl::optional<LossBasedBweV2::Config> LossBasedBweV2::CreateConfig(
&delayed_increase_window,
&use_acked_bitrate_only_when_overusing,
&not_increase_if_inherent_loss_less_than_average_loss,
&probe_integration_enabled,
&high_loss_rate_threshold,
&bandwidth_cap_at_high_loss_rate,
&slope_of_bwe_high_loss_func},
Expand Down Expand Up @@ -433,6 +497,8 @@ absl::optional<LossBasedBweV2::Config> LossBasedBweV2::CreateConfig(
config->bandwidth_cap_at_high_loss_rate =
bandwidth_cap_at_high_loss_rate.Get();
config->slope_of_bwe_high_loss_func = slope_of_bwe_high_loss_func.Get();
config->probe_integration_enabled = probe_integration_enabled.Get();

return config;
}

Expand Down Expand Up @@ -645,7 +711,7 @@ double LossBasedBweV2::GetAverageReportedLossRatio() const {
DataRate LossBasedBweV2::GetCandidateBandwidthUpperBound(
DataRate delay_based_estimate) const {
DataRate candidate_bandwidth_upper_bound = DataRate::PlusInfinity();
if (limited_due_to_loss_candidate_) {
if (IsBandwidthLimitedDueToLoss()) {
candidate_bandwidth_upper_bound = bandwidth_limit_in_current_window_;
}

Expand All @@ -661,14 +727,6 @@ DataRate LossBasedBweV2::GetCandidateBandwidthUpperBound(
if (!acknowledged_bitrate_.has_value())
return candidate_bandwidth_upper_bound;

candidate_bandwidth_upper_bound =
IsValid(candidate_bandwidth_upper_bound)
? std::min(candidate_bandwidth_upper_bound,
config_->bandwidth_rampup_upper_bound_factor *
(*acknowledged_bitrate_))
: config_->bandwidth_rampup_upper_bound_factor *
(*acknowledged_bitrate_);

if (config_->rampup_acceleration_max_factor > 0.0) {
const TimeDelta time_since_bandwidth_reduced = std::min(
config_->rampup_acceleration_maxout_time,
Expand Down Expand Up @@ -995,4 +1053,8 @@ bool LossBasedBweV2::PushBackObservation(
return true;
}

bool LossBasedBweV2::IsBandwidthLimitedDueToLoss() const {
return current_state_ != LossBasedState::kDelayBasedEstimate;
}

} // namespace webrtc
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,21 @@

namespace webrtc {

// State of the loss based estimate, which can be either increasing/decreasing
// when network is loss limited, or equal to the delay based estimate.
enum class LossBasedState {
kIncreasing = 0,
kDecreasing = 1,
kDelayBasedEstimate = 2
};

class LossBasedBweV2 {
public:
struct Result {
~Result() = default;
DataRate bandwidth_estimate = DataRate::Zero();
LossBasedState state = LossBasedState::kDelayBasedEstimate;
};
// Creates a disabled `LossBasedBweV2` if the
// `key_value_config` is not valid.
explicit LossBasedBweV2(const FieldTrialsView* key_value_config);
Expand All @@ -44,15 +57,16 @@ class LossBasedBweV2 {
bool IsReady() const;

// Returns `DataRate::PlusInfinity` if no BWE can be calculated.
DataRate GetBandwidthEstimate(DataRate delay_based_limit) const;
Result GetLossBasedResult(DataRate delay_based_limit) const;

void SetAcknowledgedBitrate(DataRate acknowledged_bitrate);
void SetBandwidthEstimate(DataRate bandwidth_estimate);
void SetMinBitrate(DataRate min_bitrate);
void UpdateBandwidthEstimate(
rtc::ArrayView<const PacketResult> packet_results,
DataRate delay_based_estimate,
BandwidthUsage delay_detector_state);
BandwidthUsage delay_detector_state,
absl::optional<DataRate> probe_bitrate);

private:
struct ChannelParameters {
Expand Down Expand Up @@ -95,6 +109,7 @@ class LossBasedBweV2 {
double high_loss_rate_threshold = 1.0;
DataRate bandwidth_cap_at_high_loss_rate = DataRate::MinusInfinity();
double slope_of_bwe_high_loss_func = 1000.0;
bool probe_integration_enabled = false;
};

struct Derivatives {
Expand Down Expand Up @@ -155,6 +170,10 @@ class LossBasedBweV2 {
const std::vector<PacketResult>& packet_feedbacks,
Timestamp at_time);
void UpdateDelayDetector(BandwidthUsage delay_detector_state);
bool IsEstimateIncreasingWhenLossLimited(
const ChannelParameters& best_candidate);
bool IsBandwidthLimitedDueToLoss() const;
void SetProbeBitrate(absl::optional<DataRate> probe_bitrate);

absl::optional<DataRate> acknowledged_bitrate_;
absl::optional<Config> config_;
Expand All @@ -170,8 +189,9 @@ class LossBasedBweV2 {
std::deque<BandwidthUsage> delay_detector_states_;
Timestamp recovering_after_loss_timestamp_ = Timestamp::MinusInfinity();
DataRate bandwidth_limit_in_current_window_ = DataRate::PlusInfinity();
bool limited_due_to_loss_candidate_ = false;
DataRate min_bitrate_ = DataRate::KilobitsPerSec(1);
LossBasedState current_state_ = LossBasedState::kDelayBasedEstimate;
DataRate probe_bitrate_ = DataRate::PlusInfinity();
};

} // namespace webrtc
Expand Down
Loading

0 comments on commit ed6d82d

Please sign in to comment.