Integrate trendline estimator into loss based bwe v2.
Bug: webrtc:12707 Change-Id: I510d3799c14599344d1714178e42b29e7c0c06d7 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/254380 Reviewed-by: Per Kjellander <perkj@webrtc.org> Commit-Queue: Diep Bui <diepbp@webrtc.org> Cr-Commit-Position: refs/heads/main@{#36236}
This commit is contained in:
@ -153,6 +153,7 @@ rtc_library("loss_based_bwe_v2") {
|
||||
]
|
||||
deps = [
|
||||
"../../../api:array_view",
|
||||
"../../../api:network_state_predictor_api",
|
||||
"../../../api/transport:network_control",
|
||||
"../../../api/transport:webrtc_key_value_config",
|
||||
"../../../api/units:data_rate",
|
||||
@ -195,6 +196,7 @@ rtc_library("send_side_bwe") {
|
||||
deps = [
|
||||
":loss_based_bwe_v1",
|
||||
":loss_based_bwe_v2",
|
||||
"../../../api:network_state_predictor_api",
|
||||
"../../../api/rtc_event_log",
|
||||
"../../../api/transport:network_control",
|
||||
"../../../api/transport:webrtc_key_value_config",
|
||||
@ -325,6 +327,7 @@ if (rtc_include_tests) {
|
||||
":probe_controller",
|
||||
":pushback_controller",
|
||||
":send_side_bwe",
|
||||
"../../../api:network_state_predictor_api",
|
||||
"../../../api/rtc_event_log",
|
||||
"../../../api/test/network_emulation",
|
||||
"../../../api/test/network_emulation:create_cross_traffic",
|
||||
|
@ -181,23 +181,22 @@ void DelayBasedBwe::IncomingPacketFeedback(const PacketResult& packet_feedback,
|
||||
}
|
||||
DataSize packet_size = packet_feedback.sent_packet.size;
|
||||
|
||||
TimeDelta send_delta = TimeDelta::Zero();
|
||||
TimeDelta recv_delta = TimeDelta::Zero();
|
||||
int size_delta = 0;
|
||||
TimeDelta send_delta = TimeDelta::Zero();
|
||||
TimeDelta recv_delta = TimeDelta::Zero();
|
||||
int size_delta = 0;
|
||||
|
||||
InterArrivalDelta* inter_arrival_for_packet =
|
||||
(separate_audio_.enabled && packet_feedback.sent_packet.audio)
|
||||
? video_inter_arrival_delta_.get()
|
||||
: audio_inter_arrival_delta_.get();
|
||||
bool calculated_deltas = inter_arrival_for_packet->ComputeDeltas(
|
||||
packet_feedback.sent_packet.send_time, packet_feedback.receive_time,
|
||||
at_time, packet_size.bytes(), &send_delta, &recv_delta, &size_delta);
|
||||
InterArrivalDelta* inter_arrival_for_packet =
|
||||
(separate_audio_.enabled && packet_feedback.sent_packet.audio)
|
||||
? video_inter_arrival_delta_.get()
|
||||
: audio_inter_arrival_delta_.get();
|
||||
bool calculated_deltas = inter_arrival_for_packet->ComputeDeltas(
|
||||
packet_feedback.sent_packet.send_time, packet_feedback.receive_time,
|
||||
at_time, packet_size.bytes(), &send_delta, &recv_delta, &size_delta);
|
||||
|
||||
delay_detector_for_packet->Update(
|
||||
recv_delta.ms(), send_delta.ms(),
|
||||
packet_feedback.sent_packet.send_time.ms(),
|
||||
packet_feedback.receive_time.ms(), packet_size.bytes(),
|
||||
calculated_deltas);
|
||||
delay_detector_for_packet->Update(recv_delta.ms(), send_delta.ms(),
|
||||
packet_feedback.sent_packet.send_time.ms(),
|
||||
packet_feedback.receive_time.ms(),
|
||||
packet_size.bytes(), calculated_deltas);
|
||||
}
|
||||
|
||||
DataRate DelayBasedBwe::TriggerOveruse(Timestamp at_time,
|
||||
@ -266,6 +265,8 @@ DelayBasedBwe::Result DelayBasedBwe::MaybeUpdateEstimate(
|
||||
prev_bitrate_ = bitrate;
|
||||
prev_state_ = detector_state;
|
||||
}
|
||||
|
||||
result.delay_detector_state = detector_state;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -56,6 +56,7 @@ class DelayBasedBwe {
|
||||
DataRate target_bitrate = DataRate::Zero();
|
||||
bool recovered_from_overuse;
|
||||
bool backoff_in_alr;
|
||||
BandwidthUsage delay_detector_state;
|
||||
};
|
||||
|
||||
explicit DelayBasedBwe(const WebRtcKeyValueConfig* key_value_config,
|
||||
|
@ -495,7 +495,6 @@ NetworkControlUpdate GoogCcNetworkController::OnTransportPacketsFeedback(
|
||||
auto acknowledged_bitrate = acknowledged_bitrate_estimator_->bitrate();
|
||||
bandwidth_estimation_->SetAcknowledgedRate(acknowledged_bitrate,
|
||||
report.feedback_time);
|
||||
bandwidth_estimation_->IncomingPacketFeedbackVector(report);
|
||||
for (const auto& feedback : report.SortedByReceiveTime()) {
|
||||
if (feedback.sent_packet.pacing_info.probe_cluster_id !=
|
||||
PacedPacketInfo::kNotAProbe) {
|
||||
@ -553,11 +552,13 @@ NetworkControlUpdate GoogCcNetworkController::OnTransportPacketsFeedback(
|
||||
}
|
||||
// Since SetSendBitrate now resets the delay-based estimate, we have to
|
||||
// call UpdateDelayBasedEstimate after SetSendBitrate.
|
||||
bandwidth_estimation_->UpdateDelayBasedEstimate(report.feedback_time,
|
||||
result.target_bitrate);
|
||||
bandwidth_estimation_->UpdateDelayBasedEstimate(
|
||||
report.feedback_time, result.target_bitrate,
|
||||
result.delay_detector_state);
|
||||
// Update the estimate in the ProbeController, in case we want to probe.
|
||||
MaybeTriggerOnNetworkChanged(&update, report.feedback_time);
|
||||
}
|
||||
bandwidth_estimation_->UpdateLossBasedEstimatorFromFeedbackVector(report);
|
||||
recovered_from_overuse = result.recovered_from_overuse;
|
||||
backoff_in_alr = result.backoff_in_alr;
|
||||
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "absl/algorithm/container.h"
|
||||
#include "absl/types/optional.h"
|
||||
#include "api/array_view.h"
|
||||
#include "api/network_state_predictor.h"
|
||||
#include "api/transport/network_types.h"
|
||||
#include "api/transport/webrtc_key_value_config.h"
|
||||
#include "api/units/data_rate.h"
|
||||
@ -89,18 +90,11 @@ double GetLossProbability(double inherent_loss,
|
||||
<< ToString(loss_limited_bandwidth);
|
||||
}
|
||||
|
||||
// We approximate the loss model
|
||||
// loss_probability = inherent_loss + (1 - inherent_loss) *
|
||||
// max(0, sending_rate - bandwidth) / sending_rate
|
||||
// by
|
||||
// loss_probability = inherent_loss +
|
||||
// max(0, sending_rate - bandwidth) / sending_rate
|
||||
// as it allows for simpler calculations and makes little difference in
|
||||
// practice.
|
||||
double loss_probability = inherent_loss;
|
||||
if (IsValid(sending_rate) && IsValid(loss_limited_bandwidth) &&
|
||||
(sending_rate > loss_limited_bandwidth)) {
|
||||
loss_probability += (sending_rate - loss_limited_bandwidth) / sending_rate;
|
||||
loss_probability += (1 - inherent_loss) *
|
||||
(sending_rate - loss_limited_bandwidth) / sending_rate;
|
||||
}
|
||||
return std::min(std::max(loss_probability, 1.0e-6), 1.0 - 1.0e-6);
|
||||
}
|
||||
@ -138,7 +132,8 @@ bool LossBasedBweV2::IsReady() const {
|
||||
num_observations_ > 0;
|
||||
}
|
||||
|
||||
DataRate LossBasedBweV2::GetBandwidthEstimate() const {
|
||||
DataRate LossBasedBweV2::GetBandwidthEstimate(
|
||||
DataRate delay_based_limit) const {
|
||||
if (!IsReady()) {
|
||||
if (!IsEnabled()) {
|
||||
RTC_LOG(LS_WARNING)
|
||||
@ -156,8 +151,14 @@ DataRate LossBasedBweV2::GetBandwidthEstimate() const {
|
||||
return DataRate::PlusInfinity();
|
||||
}
|
||||
|
||||
return std::min(current_estimate_.loss_limited_bandwidth,
|
||||
GetInstantUpperBound());
|
||||
if (delay_based_limit.IsFinite()) {
|
||||
return std::min({current_estimate_.loss_limited_bandwidth,
|
||||
GetInstantUpperBound(),
|
||||
delay_based_limit * config_->delay_based_limit_factor});
|
||||
} else {
|
||||
return std::min(current_estimate_.loss_limited_bandwidth,
|
||||
GetInstantUpperBound());
|
||||
}
|
||||
}
|
||||
|
||||
void LossBasedBweV2::SetAcknowledgedBitrate(DataRate acknowledged_bitrate) {
|
||||
@ -180,7 +181,8 @@ void LossBasedBweV2::SetBandwidthEstimate(DataRate bandwidth_estimate) {
|
||||
|
||||
void LossBasedBweV2::UpdateBandwidthEstimate(
|
||||
rtc::ArrayView<const PacketResult> packet_results,
|
||||
DataRate delay_based_estimate) {
|
||||
DataRate delay_based_estimate,
|
||||
BandwidthUsage delay_detector_state) {
|
||||
if (!IsEnabled()) {
|
||||
RTC_LOG(LS_WARNING)
|
||||
<< "The estimator must be enabled before it can be used.";
|
||||
@ -192,7 +194,7 @@ void LossBasedBweV2::UpdateBandwidthEstimate(
|
||||
return;
|
||||
}
|
||||
|
||||
if (!PushBackObservation(packet_results)) {
|
||||
if (!PushBackObservation(packet_results, delay_detector_state)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -264,6 +266,15 @@ absl::optional<LossBasedBweV2::Config> LossBasedBweV2::CreateConfig(
|
||||
"InstantUpperBoundLossOffset", 0.05);
|
||||
FieldTrialParameter<double> temporal_weight_factor("TemporalWeightFactor",
|
||||
0.99);
|
||||
FieldTrialParameter<double> bandwidth_backoff_lower_bound_factor(
|
||||
"BwBackoffLowerBoundFactor", 0.85);
|
||||
FieldTrialParameter<bool> trendline_integration_enabled(
|
||||
"TrendlineIntegrationEnabled", false);
|
||||
FieldTrialParameter<double> delay_based_limit_factor("DelayBasedLimitFactor",
|
||||
1.0);
|
||||
FieldTrialParameter<int> trendline_window_size("TrendlineWindowSize", 20);
|
||||
FieldTrialParameter<bool> backoff_when_overusing("BackoffWhenOverusing",
|
||||
false);
|
||||
|
||||
if (key_value_config) {
|
||||
ParseFieldTrial({&enabled,
|
||||
@ -287,7 +298,12 @@ absl::optional<LossBasedBweV2::Config> LossBasedBweV2::CreateConfig(
|
||||
&instant_upper_bound_temporal_weight_factor,
|
||||
&instant_upper_bound_bandwidth_balance,
|
||||
&instant_upper_bound_loss_offset,
|
||||
&temporal_weight_factor},
|
||||
&temporal_weight_factor,
|
||||
&bandwidth_backoff_lower_bound_factor,
|
||||
&trendline_integration_enabled,
|
||||
&delay_based_limit_factor,
|
||||
&trendline_window_size,
|
||||
&backoff_when_overusing},
|
||||
key_value_config->Lookup("WebRTC-Bwe-LossBasedBweV2"));
|
||||
}
|
||||
|
||||
@ -328,6 +344,12 @@ absl::optional<LossBasedBweV2::Config> LossBasedBweV2::CreateConfig(
|
||||
config->instant_upper_bound_loss_offset =
|
||||
instant_upper_bound_loss_offset.Get();
|
||||
config->temporal_weight_factor = temporal_weight_factor.Get();
|
||||
config->bandwidth_backoff_lower_bound_factor =
|
||||
bandwidth_backoff_lower_bound_factor.Get();
|
||||
config->trendline_integration_enabled = trendline_integration_enabled.Get();
|
||||
config->delay_based_limit_factor = delay_based_limit_factor.Get();
|
||||
config->trendline_window_size = trendline_window_size.Get();
|
||||
config->backoff_when_overusing = backoff_when_overusing.Get();
|
||||
return config;
|
||||
}
|
||||
|
||||
@ -470,7 +492,24 @@ bool LossBasedBweV2::IsConfigValid() const {
|
||||
<< config_->temporal_weight_factor;
|
||||
valid = false;
|
||||
}
|
||||
|
||||
if (config_->bandwidth_backoff_lower_bound_factor > 1.0) {
|
||||
RTC_LOG(LS_WARNING)
|
||||
<< "The bandwidth backoff lower bound factor must not be greater than "
|
||||
"1: "
|
||||
<< config_->bandwidth_backoff_lower_bound_factor;
|
||||
valid = false;
|
||||
}
|
||||
if (config_->delay_based_limit_factor < 1.0) {
|
||||
RTC_LOG(LS_WARNING)
|
||||
<< "The delay based limit factor must not be less than 1: "
|
||||
<< config_->delay_based_limit_factor;
|
||||
valid = false;
|
||||
}
|
||||
if (config_->trendline_window_size < 2) {
|
||||
RTC_LOG(LS_WARNING) << "The trendline window size must be at least 2: "
|
||||
<< config_->trendline_window_size;
|
||||
valid = false;
|
||||
}
|
||||
return valid;
|
||||
}
|
||||
|
||||
@ -521,19 +560,35 @@ DataRate LossBasedBweV2::GetCandidateBandwidthUpperBound() const {
|
||||
std::vector<LossBasedBweV2::ChannelParameters> LossBasedBweV2::GetCandidates(
|
||||
DataRate delay_based_estimate) const {
|
||||
std::vector<DataRate> bandwidths;
|
||||
bool can_increase_bitrate = TrendlineEsimateAllowBitrateIncrease();
|
||||
bool can_decrease_bitrate = TrendlineEsimateAllowBitrateDecrease();
|
||||
for (double candidate_factor : config_->candidate_factors) {
|
||||
if (!can_increase_bitrate && candidate_factor >= 1.0) {
|
||||
// When the network is overusing, the estimate is forced to decrease
|
||||
// even if there is no loss yet.
|
||||
if (candidate_factor > 1 || config_->backoff_when_overusing) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (!can_decrease_bitrate && candidate_factor < 1.0) {
|
||||
continue;
|
||||
}
|
||||
bandwidths.push_back(candidate_factor *
|
||||
current_estimate_.loss_limited_bandwidth);
|
||||
}
|
||||
|
||||
if (acknowledged_bitrate_.has_value() &&
|
||||
config_->append_acknowledged_rate_candidate) {
|
||||
bandwidths.push_back(*acknowledged_bitrate_);
|
||||
config_->append_acknowledged_rate_candidate && can_decrease_bitrate) {
|
||||
bandwidths.push_back(*acknowledged_bitrate_ *
|
||||
config_->bandwidth_backoff_lower_bound_factor);
|
||||
}
|
||||
|
||||
if (IsValid(delay_based_estimate) &&
|
||||
config_->append_delay_based_estimate_candidate) {
|
||||
bandwidths.push_back(delay_based_estimate);
|
||||
if (can_increase_bitrate &&
|
||||
delay_based_estimate > current_estimate_.loss_limited_bandwidth) {
|
||||
bandwidths.push_back(delay_based_estimate);
|
||||
}
|
||||
}
|
||||
|
||||
const DataRate candidate_bandwidth_upper_bound =
|
||||
@ -704,8 +759,47 @@ void LossBasedBweV2::NewtonsMethodUpdate(
|
||||
}
|
||||
}
|
||||
|
||||
bool LossBasedBweV2::TrendlineEsimateAllowBitrateDecrease() const {
|
||||
if (!config_->trendline_integration_enabled) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (const auto& detector_state : delay_detector_states_) {
|
||||
if (detector_state == BandwidthUsage::kBwOverusing) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& detector_state : delay_detector_states_) {
|
||||
if (detector_state == BandwidthUsage::kBwUnderusing) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LossBasedBweV2::TrendlineEsimateAllowBitrateIncrease() const {
|
||||
if (!config_->trendline_integration_enabled) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (const auto& detector_state : delay_detector_states_) {
|
||||
if (detector_state == BandwidthUsage::kBwOverusing) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LossBasedBweV2::PushBackObservation(
|
||||
rtc::ArrayView<const PacketResult> packet_results) {
|
||||
rtc::ArrayView<const PacketResult> packet_results,
|
||||
BandwidthUsage delay_detector_state) {
|
||||
delay_detector_states_.push_front(delay_detector_state);
|
||||
if (static_cast<int>(delay_detector_states_.size()) >
|
||||
config_->trendline_window_size) {
|
||||
delay_detector_states_.pop_back();
|
||||
}
|
||||
|
||||
if (packet_results.empty()) {
|
||||
return false;
|
||||
}
|
||||
@ -729,7 +823,9 @@ bool LossBasedBweV2::PushBackObservation(
|
||||
last_send_time - last_send_time_most_recent_observation_;
|
||||
|
||||
// Too small to be meaningful.
|
||||
if (observation_duration < config_->observation_duration_lower_bound) {
|
||||
if (observation_duration < config_->observation_duration_lower_bound &&
|
||||
(delay_detector_state == BandwidthUsage::kBwNormal ||
|
||||
!config_->trendline_integration_enabled)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -12,10 +12,12 @@
|
||||
#define MODULES_CONGESTION_CONTROLLER_GOOG_CC_LOSS_BASED_BWE_V2_H_
|
||||
|
||||
#include <cstddef>
|
||||
#include <deque>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
#include "api/array_view.h"
|
||||
#include "api/network_state_predictor.h"
|
||||
#include "api/transport/network_types.h"
|
||||
#include "api/transport/webrtc_key_value_config.h"
|
||||
#include "api/units/data_rate.h"
|
||||
@ -42,14 +44,15 @@ class LossBasedBweV2 {
|
||||
bool IsReady() const;
|
||||
|
||||
// Returns `DataRate::PlusInfinity` if no BWE can be calculated.
|
||||
DataRate GetBandwidthEstimate() const;
|
||||
DataRate GetBandwidthEstimate(DataRate delay_based_limit) const;
|
||||
|
||||
void SetAcknowledgedBitrate(DataRate acknowledged_bitrate);
|
||||
void SetBandwidthEstimate(DataRate bandwidth_estimate);
|
||||
|
||||
void UpdateBandwidthEstimate(
|
||||
rtc::ArrayView<const PacketResult> packet_results,
|
||||
DataRate delay_based_estimate);
|
||||
DataRate delay_based_estimate,
|
||||
BandwidthUsage delay_detector_state);
|
||||
|
||||
private:
|
||||
struct ChannelParameters {
|
||||
@ -80,6 +83,11 @@ class LossBasedBweV2 {
|
||||
DataRate instant_upper_bound_bandwidth_balance = DataRate::MinusInfinity();
|
||||
double instant_upper_bound_loss_offset = 0.0;
|
||||
double temporal_weight_factor = 0.0;
|
||||
double bandwidth_backoff_lower_bound_factor = 0.0;
|
||||
bool trendline_integration_enabled = false;
|
||||
double delay_based_limit_factor = 1.0;
|
||||
int trendline_window_size = 0;
|
||||
bool backoff_when_overusing = false;
|
||||
};
|
||||
|
||||
struct Derivatives {
|
||||
@ -124,9 +132,21 @@ class LossBasedBweV2 {
|
||||
|
||||
void CalculateTemporalWeights();
|
||||
void NewtonsMethodUpdate(ChannelParameters& channel_parameters) const;
|
||||
// Returns true if either
|
||||
// 1. At least one of states in the window is kBwOverusing, or
|
||||
// 2. There are no kBwUnderusing states in the window.
|
||||
bool TrendlineEsimateAllowBitrateDecrease() const;
|
||||
|
||||
// Returns false if there exists an overusing state in the window.
|
||||
bool TrendlineEsimateAllowBitrateIncrease() const;
|
||||
|
||||
// Returns false if no observation was created.
|
||||
bool PushBackObservation(rtc::ArrayView<const PacketResult> packet_results);
|
||||
bool PushBackObservation(rtc::ArrayView<const PacketResult> packet_results,
|
||||
BandwidthUsage delay_detector_state);
|
||||
void UpdateTrendlineEstimator(
|
||||
const std::vector<PacketResult>& packet_feedbacks,
|
||||
Timestamp at_time);
|
||||
void UpdateDelayDetector(BandwidthUsage delay_detector_state);
|
||||
|
||||
absl::optional<DataRate> acknowledged_bitrate_;
|
||||
absl::optional<Config> config_;
|
||||
@ -139,6 +159,7 @@ class LossBasedBweV2 {
|
||||
absl::optional<DataRate> cached_instant_upper_bound_;
|
||||
std::vector<double> instant_upper_bound_temporal_weights_;
|
||||
std::vector<double> temporal_weights_;
|
||||
std::deque<BandwidthUsage> delay_detector_states_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "api/network_state_predictor.h"
|
||||
#include "api/transport/network_types.h"
|
||||
#include "api/units/data_rate.h"
|
||||
#include "api/units/data_size.h"
|
||||
@ -48,14 +49,16 @@ std::string Config(bool enabled, bool valid) {
|
||||
}
|
||||
|
||||
config_string
|
||||
<< ",CandidateFactors:0.9|1.1,HigherBwBiasFactor:0.01,"
|
||||
<< ",CandidateFactors:1.1|1.0|0.95,HigherBwBiasFactor:0.01,"
|
||||
"DelayBasedCandidate:true,"
|
||||
"InherentLossLowerBound:0.001,InherentLossUpperBoundBwBalance:14kbps,"
|
||||
"InherentLossUpperBoundOffset:0.9,InitialInherentLossEstimate:0.01,"
|
||||
"NewtonIterations:2,NewtonStepSize:0.4,ObservationWindowSize:15,"
|
||||
"SendingRateSmoothingFactor:0.01,"
|
||||
"InstantUpperBoundTemporalWeightFactor:0.97,"
|
||||
"InstantUpperBoundBwBalance:90kbps,"
|
||||
"InstantUpperBoundLossOffset:0.1,TemporalWeightFactor:0.98";
|
||||
"InstantUpperBoundLossOffset:0.1,TemporalWeightFactor:0.98,"
|
||||
"BackoffWhenOverusing:true";
|
||||
|
||||
config_string.AppendFormat(
|
||||
",ObservationDurationLowerBound:%dms",
|
||||
@ -133,10 +136,13 @@ TEST(LossBasedBweV2Test, BandwidthEstimateGivenInitializationAndThenFeedback) {
|
||||
loss_based_bandwidth_estimator.SetBandwidthEstimate(
|
||||
DataRate::KilobitsPerSec(600));
|
||||
loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
|
||||
enough_feedback, DataRate::PlusInfinity());
|
||||
enough_feedback, DataRate::PlusInfinity(), BandwidthUsage::kBwNormal);
|
||||
|
||||
EXPECT_TRUE(loss_based_bandwidth_estimator.IsReady());
|
||||
EXPECT_TRUE(loss_based_bandwidth_estimator.GetBandwidthEstimate().IsFinite());
|
||||
EXPECT_TRUE(
|
||||
loss_based_bandwidth_estimator
|
||||
.GetBandwidthEstimate(/*delay_based_limit=*/DataRate::PlusInfinity())
|
||||
.IsFinite());
|
||||
}
|
||||
|
||||
TEST(LossBasedBweV2Test, NoBandwidthEstimateGivenNoInitialization) {
|
||||
@ -156,11 +162,13 @@ TEST(LossBasedBweV2Test, NoBandwidthEstimateGivenNoInitialization) {
|
||||
LossBasedBweV2 loss_based_bandwidth_estimator(&key_value_config);
|
||||
|
||||
loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
|
||||
enough_feedback, DataRate::PlusInfinity());
|
||||
enough_feedback, DataRate::PlusInfinity(), BandwidthUsage::kBwNormal);
|
||||
|
||||
EXPECT_FALSE(loss_based_bandwidth_estimator.IsReady());
|
||||
EXPECT_TRUE(
|
||||
loss_based_bandwidth_estimator.GetBandwidthEstimate().IsPlusInfinity());
|
||||
loss_based_bandwidth_estimator
|
||||
.GetBandwidthEstimate(/*delay_based_limit=*/DataRate::PlusInfinity())
|
||||
.IsPlusInfinity());
|
||||
}
|
||||
|
||||
TEST(LossBasedBweV2Test, NoBandwidthEstimateGivenNotEnoughFeedback) {
|
||||
@ -186,14 +194,18 @@ TEST(LossBasedBweV2Test, NoBandwidthEstimateGivenNotEnoughFeedback) {
|
||||
|
||||
EXPECT_FALSE(loss_based_bandwidth_estimator.IsReady());
|
||||
EXPECT_TRUE(
|
||||
loss_based_bandwidth_estimator.GetBandwidthEstimate().IsPlusInfinity());
|
||||
loss_based_bandwidth_estimator
|
||||
.GetBandwidthEstimate(/*delay_based_limit=*/DataRate::PlusInfinity())
|
||||
.IsPlusInfinity());
|
||||
|
||||
loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
|
||||
not_enough_feedback, DataRate::PlusInfinity());
|
||||
not_enough_feedback, DataRate::PlusInfinity(), BandwidthUsage::kBwNormal);
|
||||
|
||||
EXPECT_FALSE(loss_based_bandwidth_estimator.IsReady());
|
||||
EXPECT_TRUE(
|
||||
loss_based_bandwidth_estimator.GetBandwidthEstimate().IsPlusInfinity());
|
||||
loss_based_bandwidth_estimator
|
||||
.GetBandwidthEstimate(/*delay_based_limit=*/DataRate::PlusInfinity())
|
||||
.IsPlusInfinity());
|
||||
}
|
||||
|
||||
TEST(LossBasedBweV2Test,
|
||||
@ -227,21 +239,24 @@ TEST(LossBasedBweV2Test,
|
||||
loss_based_bandwidth_estimator.SetBandwidthEstimate(
|
||||
DataRate::KilobitsPerSec(600));
|
||||
loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
|
||||
enough_feedback_1, DataRate::PlusInfinity());
|
||||
enough_feedback_1, DataRate::PlusInfinity(), BandwidthUsage::kBwNormal);
|
||||
|
||||
EXPECT_NE(loss_based_bandwidth_estimator.GetBandwidthEstimate(),
|
||||
EXPECT_NE(loss_based_bandwidth_estimator.GetBandwidthEstimate(
|
||||
/*delay_based_limit=*/DataRate::PlusInfinity()),
|
||||
DataRate::KilobitsPerSec(600));
|
||||
|
||||
loss_based_bandwidth_estimator.SetBandwidthEstimate(
|
||||
DataRate::KilobitsPerSec(600));
|
||||
|
||||
EXPECT_EQ(loss_based_bandwidth_estimator.GetBandwidthEstimate(),
|
||||
EXPECT_EQ(loss_based_bandwidth_estimator.GetBandwidthEstimate(
|
||||
/*delay_based_limit=*/DataRate::PlusInfinity()),
|
||||
DataRate::KilobitsPerSec(600));
|
||||
|
||||
loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
|
||||
enough_feedback_2, DataRate::PlusInfinity());
|
||||
enough_feedback_2, DataRate::PlusInfinity(), BandwidthUsage::kBwNormal);
|
||||
|
||||
EXPECT_NE(loss_based_bandwidth_estimator.GetBandwidthEstimate(),
|
||||
EXPECT_NE(loss_based_bandwidth_estimator.GetBandwidthEstimate(
|
||||
/*delay_based_limit=*/DataRate::PlusInfinity()),
|
||||
DataRate::KilobitsPerSec(600));
|
||||
}
|
||||
|
||||
@ -279,26 +294,30 @@ TEST(LossBasedBweV2Test,
|
||||
loss_based_bandwidth_estimator_2.SetBandwidthEstimate(
|
||||
DataRate::KilobitsPerSec(600));
|
||||
loss_based_bandwidth_estimator_1.UpdateBandwidthEstimate(
|
||||
enough_feedback_1, DataRate::PlusInfinity());
|
||||
enough_feedback_1, DataRate::PlusInfinity(), BandwidthUsage::kBwNormal);
|
||||
loss_based_bandwidth_estimator_2.UpdateBandwidthEstimate(
|
||||
enough_feedback_1, DataRate::PlusInfinity());
|
||||
enough_feedback_1, DataRate::PlusInfinity(), BandwidthUsage::kBwNormal);
|
||||
|
||||
EXPECT_EQ(loss_based_bandwidth_estimator_1.GetBandwidthEstimate(),
|
||||
EXPECT_EQ(loss_based_bandwidth_estimator_1.GetBandwidthEstimate(
|
||||
/*delay_based_limit=*/DataRate::PlusInfinity()),
|
||||
DataRate::KilobitsPerSec(660));
|
||||
|
||||
loss_based_bandwidth_estimator_1.SetAcknowledgedBitrate(
|
||||
DataRate::KilobitsPerSec(600));
|
||||
|
||||
EXPECT_EQ(loss_based_bandwidth_estimator_1.GetBandwidthEstimate(),
|
||||
EXPECT_EQ(loss_based_bandwidth_estimator_1.GetBandwidthEstimate(
|
||||
/*delay_based_limit=*/DataRate::PlusInfinity()),
|
||||
DataRate::KilobitsPerSec(660));
|
||||
|
||||
loss_based_bandwidth_estimator_1.UpdateBandwidthEstimate(
|
||||
enough_feedback_2, DataRate::PlusInfinity());
|
||||
enough_feedback_2, DataRate::PlusInfinity(), BandwidthUsage::kBwNormal);
|
||||
loss_based_bandwidth_estimator_2.UpdateBandwidthEstimate(
|
||||
enough_feedback_2, DataRate::PlusInfinity());
|
||||
enough_feedback_2, DataRate::PlusInfinity(), BandwidthUsage::kBwNormal);
|
||||
|
||||
EXPECT_NE(loss_based_bandwidth_estimator_1.GetBandwidthEstimate(),
|
||||
loss_based_bandwidth_estimator_2.GetBandwidthEstimate());
|
||||
EXPECT_NE(loss_based_bandwidth_estimator_1.GetBandwidthEstimate(
|
||||
/*delay_based_limit=*/DataRate::PlusInfinity()),
|
||||
loss_based_bandwidth_estimator_2.GetBandwidthEstimate(
|
||||
/*delay_based_limit=*/DataRate::PlusInfinity()));
|
||||
}
|
||||
|
||||
TEST(LossBasedBweV2Test,
|
||||
@ -324,12 +343,187 @@ TEST(LossBasedBweV2Test,
|
||||
loss_based_bandwidth_estimator.SetBandwidthEstimate(
|
||||
DataRate::KilobitsPerSec(600));
|
||||
loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
|
||||
enough_feedback_no_received_packets, DataRate::PlusInfinity());
|
||||
enough_feedback_no_received_packets, DataRate::PlusInfinity(),
|
||||
BandwidthUsage::kBwNormal);
|
||||
|
||||
EXPECT_EQ(loss_based_bandwidth_estimator.GetBandwidthEstimate(),
|
||||
EXPECT_EQ(loss_based_bandwidth_estimator.GetBandwidthEstimate(
|
||||
/*delay_based_limit=*/DataRate::PlusInfinity()),
|
||||
DataRate::KilobitsPerSec(100));
|
||||
}
|
||||
|
||||
// When network is overusing and flag `BackoffWhenOverusing` is true,
|
||||
// the bandwidth estimate is forced to decrease even if there is no loss yet.
|
||||
TEST(LossBasedBweV2Test, BandwidthEstimateDecreasesWhenOverusing) {
|
||||
PacketResult enough_feedback_1[2];
|
||||
PacketResult enough_feedback_2[2];
|
||||
enough_feedback_1[0].sent_packet.size = DataSize::Bytes(15'000);
|
||||
enough_feedback_1[1].sent_packet.size = DataSize::Bytes(15'000);
|
||||
enough_feedback_2[0].sent_packet.size = DataSize::Bytes(15'000);
|
||||
enough_feedback_2[1].sent_packet.size = DataSize::Bytes(15'000);
|
||||
enough_feedback_1[0].sent_packet.send_time = Timestamp::Zero();
|
||||
enough_feedback_1[1].sent_packet.send_time =
|
||||
Timestamp::Zero() + kObservationDurationLowerBound;
|
||||
enough_feedback_2[0].sent_packet.send_time =
|
||||
Timestamp::Zero() + 2 * kObservationDurationLowerBound;
|
||||
enough_feedback_2[1].sent_packet.send_time =
|
||||
Timestamp::Zero() + 3 * kObservationDurationLowerBound;
|
||||
enough_feedback_1[0].receive_time = Timestamp::PlusInfinity();
|
||||
enough_feedback_1[1].receive_time =
|
||||
Timestamp::Zero() + 2 * kObservationDurationLowerBound;
|
||||
enough_feedback_2[0].receive_time = Timestamp::PlusInfinity();
|
||||
enough_feedback_2[1].receive_time =
|
||||
Timestamp::Zero() + 4 * kObservationDurationLowerBound;
|
||||
|
||||
ExplicitKeyValueConfig key_value_config(
|
||||
Config(/*enabled=*/true, /*valid=*/true));
|
||||
LossBasedBweV2 loss_based_bandwidth_estimator(&key_value_config);
|
||||
loss_based_bandwidth_estimator.SetAcknowledgedBitrate(
|
||||
DataRate::KilobitsPerSec(300));
|
||||
loss_based_bandwidth_estimator.SetBandwidthEstimate(
|
||||
DataRate::KilobitsPerSec(600));
|
||||
loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
|
||||
enough_feedback_1, DataRate::PlusInfinity(),
|
||||
BandwidthUsage::kBwOverusing);
|
||||
EXPECT_LE(loss_based_bandwidth_estimator.GetBandwidthEstimate(
|
||||
/*delay_based_limit=*/DataRate::PlusInfinity()),
|
||||
DataRate::KilobitsPerSec(600));
|
||||
|
||||
loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
|
||||
enough_feedback_2, DataRate::PlusInfinity(), BandwidthUsage::kBwNormal);
|
||||
EXPECT_LE(loss_based_bandwidth_estimator.GetBandwidthEstimate(
|
||||
/*delay_based_limit=*/DataRate::PlusInfinity()),
|
||||
DataRate::KilobitsPerSec(600));
|
||||
}
|
||||
|
||||
TEST(LossBasedBweV2Test, BandwidthEstimateIncreasesWhenUnderusing) {
|
||||
PacketResult enough_feedback_1[2];
|
||||
PacketResult enough_feedback_2[2];
|
||||
enough_feedback_1[0].sent_packet.size = DataSize::Bytes(15'000);
|
||||
enough_feedback_1[1].sent_packet.size = DataSize::Bytes(15'000);
|
||||
enough_feedback_2[0].sent_packet.size = DataSize::Bytes(15'000);
|
||||
enough_feedback_2[1].sent_packet.size = DataSize::Bytes(15'000);
|
||||
enough_feedback_1[0].sent_packet.send_time = Timestamp::Zero();
|
||||
enough_feedback_1[1].sent_packet.send_time =
|
||||
Timestamp::Zero() + kObservationDurationLowerBound;
|
||||
enough_feedback_2[0].sent_packet.send_time =
|
||||
Timestamp::Zero() + 2 * kObservationDurationLowerBound;
|
||||
enough_feedback_2[1].sent_packet.send_time =
|
||||
Timestamp::Zero() + 3 * kObservationDurationLowerBound;
|
||||
enough_feedback_1[0].receive_time =
|
||||
Timestamp::Zero() + kObservationDurationLowerBound;
|
||||
enough_feedback_1[1].receive_time =
|
||||
Timestamp::Zero() + 2 * kObservationDurationLowerBound;
|
||||
enough_feedback_2[0].receive_time =
|
||||
Timestamp::Zero() + 3 * kObservationDurationLowerBound;
|
||||
enough_feedback_2[1].receive_time =
|
||||
Timestamp::Zero() + 4 * kObservationDurationLowerBound;
|
||||
|
||||
ExplicitKeyValueConfig key_value_config(
|
||||
Config(/*enabled=*/true, /*valid=*/true));
|
||||
LossBasedBweV2 loss_based_bandwidth_estimator(&key_value_config);
|
||||
|
||||
loss_based_bandwidth_estimator.SetBandwidthEstimate(
|
||||
DataRate::KilobitsPerSec(600));
|
||||
loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
|
||||
enough_feedback_1, DataRate::PlusInfinity(),
|
||||
BandwidthUsage::kBwUnderusing);
|
||||
EXPECT_GT(loss_based_bandwidth_estimator.GetBandwidthEstimate(
|
||||
/*delay_based_limit=*/DataRate::PlusInfinity()),
|
||||
DataRate::KilobitsPerSec(600));
|
||||
loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
|
||||
enough_feedback_2, DataRate::PlusInfinity(), BandwidthUsage::kBwNormal);
|
||||
EXPECT_GT(loss_based_bandwidth_estimator.GetBandwidthEstimate(
|
||||
/*delay_based_limit=*/DataRate::PlusInfinity()),
|
||||
DataRate::KilobitsPerSec(600));
|
||||
}
|
||||
|
||||
TEST(LossBasedBweV2Test,
|
||||
BandwidthEstimateCappedByDelayBasedEstimateWhenUnderusing) {
|
||||
PacketResult enough_feedback_1[2];
|
||||
PacketResult enough_feedback_2[2];
|
||||
enough_feedback_1[0].sent_packet.size = DataSize::Bytes(15'000);
|
||||
enough_feedback_1[1].sent_packet.size = DataSize::Bytes(15'000);
|
||||
enough_feedback_2[0].sent_packet.size = DataSize::Bytes(15'000);
|
||||
enough_feedback_2[1].sent_packet.size = DataSize::Bytes(15'000);
|
||||
enough_feedback_1[0].sent_packet.send_time = Timestamp::Zero();
|
||||
enough_feedback_1[1].sent_packet.send_time =
|
||||
Timestamp::Zero() + kObservationDurationLowerBound;
|
||||
enough_feedback_2[0].sent_packet.send_time =
|
||||
Timestamp::Zero() + 2 * kObservationDurationLowerBound;
|
||||
enough_feedback_2[1].sent_packet.send_time =
|
||||
Timestamp::Zero() + 3 * kObservationDurationLowerBound;
|
||||
enough_feedback_1[0].receive_time =
|
||||
Timestamp::Zero() + kObservationDurationLowerBound;
|
||||
enough_feedback_1[1].receive_time =
|
||||
Timestamp::Zero() + 2 * kObservationDurationLowerBound;
|
||||
enough_feedback_2[0].receive_time =
|
||||
Timestamp::Zero() + 3 * kObservationDurationLowerBound;
|
||||
enough_feedback_2[1].receive_time =
|
||||
Timestamp::Zero() + 4 * kObservationDurationLowerBound;
|
||||
|
||||
ExplicitKeyValueConfig key_value_config(
|
||||
Config(/*enabled=*/true, /*valid=*/true));
|
||||
LossBasedBweV2 loss_based_bandwidth_estimator(&key_value_config);
|
||||
|
||||
loss_based_bandwidth_estimator.SetBandwidthEstimate(
|
||||
DataRate::KilobitsPerSec(600));
|
||||
loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
|
||||
enough_feedback_1, DataRate::PlusInfinity(),
|
||||
BandwidthUsage::kBwUnderusing);
|
||||
EXPECT_GT(loss_based_bandwidth_estimator.GetBandwidthEstimate(
|
||||
/*delay_based_limit=*/DataRate::PlusInfinity()),
|
||||
DataRate::KilobitsPerSec(600));
|
||||
loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
|
||||
enough_feedback_2, DataRate::PlusInfinity(), BandwidthUsage::kBwNormal);
|
||||
EXPECT_EQ(loss_based_bandwidth_estimator.GetBandwidthEstimate(
|
||||
/*delay_based_limit=*/DataRate::KilobitsPerSec(500)),
|
||||
DataRate::KilobitsPerSec(500));
|
||||
}
|
||||
|
||||
TEST(LossBasedBweV2Test, NotUseAckedBitrateInNormalState) {
|
||||
PacketResult enough_feedback_1[2];
|
||||
PacketResult enough_feedback_2[2];
|
||||
enough_feedback_1[0].sent_packet.size = DataSize::Bytes(15'000);
|
||||
enough_feedback_1[1].sent_packet.size = DataSize::Bytes(15'000);
|
||||
enough_feedback_2[0].sent_packet.size = DataSize::Bytes(15'000);
|
||||
enough_feedback_2[1].sent_packet.size = DataSize::Bytes(15'000);
|
||||
enough_feedback_1[0].sent_packet.send_time = Timestamp::Zero();
|
||||
enough_feedback_1[1].sent_packet.send_time =
|
||||
Timestamp::Zero() + kObservationDurationLowerBound;
|
||||
enough_feedback_2[0].sent_packet.send_time =
|
||||
Timestamp::Zero() + 2 * kObservationDurationLowerBound;
|
||||
enough_feedback_2[1].sent_packet.send_time =
|
||||
Timestamp::Zero() + 3 * kObservationDurationLowerBound;
|
||||
enough_feedback_1[0].receive_time =
|
||||
Timestamp::Zero() + kObservationDurationLowerBound;
|
||||
enough_feedback_1[1].receive_time =
|
||||
Timestamp::Zero() + 2 * kObservationDurationLowerBound;
|
||||
enough_feedback_2[0].receive_time =
|
||||
Timestamp::Zero() + 3 * kObservationDurationLowerBound;
|
||||
enough_feedback_2[1].receive_time =
|
||||
Timestamp::Zero() + 4 * kObservationDurationLowerBound;
|
||||
|
||||
ExplicitKeyValueConfig key_value_config(
|
||||
Config(/*enabled=*/true, /*valid=*/true));
|
||||
LossBasedBweV2 loss_based_bandwidth_estimator(&key_value_config);
|
||||
|
||||
loss_based_bandwidth_estimator.SetBandwidthEstimate(
|
||||
DataRate::KilobitsPerSec(600));
|
||||
DataRate acked_bitrate = DataRate::KilobitsPerSec(300);
|
||||
loss_based_bandwidth_estimator.SetAcknowledgedBitrate(acked_bitrate);
|
||||
loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
|
||||
enough_feedback_1, DataRate::PlusInfinity(), BandwidthUsage::kBwNormal);
|
||||
EXPECT_GT(loss_based_bandwidth_estimator.GetBandwidthEstimate(
|
||||
/*delay_based_limit=*/DataRate::PlusInfinity()),
|
||||
acked_bitrate);
|
||||
|
||||
loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
|
||||
enough_feedback_2, DataRate::PlusInfinity(), BandwidthUsage::kBwNormal);
|
||||
EXPECT_GT(loss_based_bandwidth_estimator.GetBandwidthEstimate(
|
||||
/*delay_based_limit=*/DataRate::PlusInfinity()),
|
||||
acked_bitrate);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
} // namespace webrtc
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include <string>
|
||||
|
||||
#include "absl/strings/match.h"
|
||||
#include "api/network_state_predictor.h"
|
||||
#include "api/rtc_event_log/rtc_event.h"
|
||||
#include "api/rtc_event_log/rtc_event_log.h"
|
||||
#include "api/transport/webrtc_key_value_config.h"
|
||||
@ -229,7 +230,8 @@ SendSideBandwidthEstimation::SendSideBandwidthEstimation(
|
||||
bitrate_threshold_(kDefaultBitrateThreshold),
|
||||
loss_based_bandwidth_estimator_v1_(key_value_config),
|
||||
loss_based_bandwidth_estimator_v2_(key_value_config),
|
||||
disable_receiver_limit_caps_only_("Disabled") {
|
||||
disable_receiver_limit_caps_only_("Disabled"),
|
||||
delay_detector_state_(BandwidthUsage::kBwNormal) {
|
||||
RTC_DCHECK(event_log);
|
||||
if (BweLossExperimentIsEnabled()) {
|
||||
uint32_t bitrate_threshold_kbps;
|
||||
@ -271,6 +273,7 @@ void SendSideBandwidthEstimation::OnRouteChange() {
|
||||
uma_update_state_ = kNoUpdate;
|
||||
uma_rtt_state_ = kNoUpdate;
|
||||
last_rtc_event_log_ = Timestamp::MinusInfinity();
|
||||
delay_detector_state_ = BandwidthUsage::kBwNormal;
|
||||
}
|
||||
|
||||
void SendSideBandwidthEstimation::SetBitrates(
|
||||
@ -330,9 +333,12 @@ void SendSideBandwidthEstimation::UpdateReceiverEstimate(Timestamp at_time,
|
||||
ApplyTargetLimits(at_time);
|
||||
}
|
||||
|
||||
void SendSideBandwidthEstimation::UpdateDelayBasedEstimate(Timestamp at_time,
|
||||
DataRate bitrate) {
|
||||
void SendSideBandwidthEstimation::UpdateDelayBasedEstimate(
|
||||
Timestamp at_time,
|
||||
DataRate bitrate,
|
||||
BandwidthUsage delay_detector_state) {
|
||||
link_capacity_.UpdateDelayBasedEstimate(at_time, bitrate);
|
||||
delay_detector_state_ = delay_detector_state;
|
||||
// TODO(srte): Ensure caller passes PlusInfinity, not zero, to represent no
|
||||
// limitation.
|
||||
delay_based_limit_ = bitrate.IsZero() ? DataRate::PlusInfinity() : bitrate;
|
||||
@ -356,7 +362,7 @@ void SendSideBandwidthEstimation::SetAcknowledgedRate(
|
||||
}
|
||||
}
|
||||
|
||||
void SendSideBandwidthEstimation::IncomingPacketFeedbackVector(
|
||||
void SendSideBandwidthEstimation::UpdateLossBasedEstimatorFromFeedbackVector(
|
||||
const TransportPacketsFeedback& report) {
|
||||
if (LossBasedBandwidthEstimatorV1Enabled()) {
|
||||
loss_based_bandwidth_estimator_v1_.UpdateLossStatistics(
|
||||
@ -364,7 +370,7 @@ void SendSideBandwidthEstimation::IncomingPacketFeedbackVector(
|
||||
}
|
||||
if (LossBasedBandwidthEstimatorV2Enabled()) {
|
||||
loss_based_bandwidth_estimator_v2_.UpdateBandwidthEstimate(
|
||||
report.packet_feedbacks, delay_based_limit_);
|
||||
report.packet_feedbacks, delay_based_limit_, delay_detector_state_);
|
||||
}
|
||||
}
|
||||
|
||||
@ -509,8 +515,8 @@ void SendSideBandwidthEstimation::UpdateEstimate(Timestamp at_time) {
|
||||
|
||||
if (LossBasedBandwidthEstimatorV2ReadyForUse()) {
|
||||
DataRate new_bitrate =
|
||||
loss_based_bandwidth_estimator_v2_.GetBandwidthEstimate();
|
||||
new_bitrate = std::min(new_bitrate, delay_based_limit_);
|
||||
loss_based_bandwidth_estimator_v2_.GetBandwidthEstimate(
|
||||
delay_based_limit_);
|
||||
UpdateTargetBitrate(new_bitrate, at_time);
|
||||
return;
|
||||
}
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
#include "api/network_state_predictor.h"
|
||||
#include "api/transport/network_types.h"
|
||||
#include "api/transport/webrtc_key_value_config.h"
|
||||
#include "api/units/data_rate.h"
|
||||
@ -97,7 +98,9 @@ class SendSideBandwidthEstimation {
|
||||
void UpdateReceiverEstimate(Timestamp at_time, DataRate bandwidth);
|
||||
|
||||
// Call when a new delay-based estimate is available.
|
||||
void UpdateDelayBasedEstimate(Timestamp at_time, DataRate bitrate);
|
||||
void UpdateDelayBasedEstimate(Timestamp at_time,
|
||||
DataRate bitrate,
|
||||
BandwidthUsage delay_detector_state);
|
||||
|
||||
// Call when we receive a RTCP message with a ReceiveBlock.
|
||||
void UpdatePacketsLost(int64_t packets_lost,
|
||||
@ -116,7 +119,8 @@ class SendSideBandwidthEstimation {
|
||||
int GetMinBitrate() const;
|
||||
void SetAcknowledgedRate(absl::optional<DataRate> acknowledged_rate,
|
||||
Timestamp at_time);
|
||||
void IncomingPacketFeedbackVector(const TransportPacketsFeedback& report);
|
||||
void UpdateLossBasedEstimatorFromFeedbackVector(
|
||||
const TransportPacketsFeedback& report);
|
||||
|
||||
private:
|
||||
friend class GoogCcStatePrinter;
|
||||
@ -199,6 +203,7 @@ class SendSideBandwidthEstimation {
|
||||
LossBasedBandwidthEstimation loss_based_bandwidth_estimator_v1_;
|
||||
LossBasedBweV2 loss_based_bandwidth_estimator_v2_;
|
||||
FieldTrialFlag disable_receiver_limit_caps_only_;
|
||||
BandwidthUsage delay_detector_state_;
|
||||
};
|
||||
} // namespace webrtc
|
||||
#endif // MODULES_CONGESTION_CONTROLLER_GOOG_CC_SEND_SIDE_BANDWIDTH_ESTIMATION_H_
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
#include "modules/congestion_controller/goog_cc/send_side_bandwidth_estimation.h"
|
||||
|
||||
#include "api/network_state_predictor.h"
|
||||
#include "api/rtc_event_log/rtc_event.h"
|
||||
#include "logging/rtc_event_log/events/rtc_event_bwe_update_loss_based.h"
|
||||
#include "logging/rtc_event_log/mock/mock_rtc_event_log.h"
|
||||
@ -54,7 +55,8 @@ void TestProbing(bool use_delay_based) {
|
||||
// Initial REMB applies immediately.
|
||||
if (use_delay_based) {
|
||||
bwe.UpdateDelayBasedEstimate(Timestamp::Millis(now_ms),
|
||||
DataRate::BitsPerSec(kRembBps));
|
||||
DataRate::BitsPerSec(kRembBps),
|
||||
BandwidthUsage::kBwNormal);
|
||||
} else {
|
||||
bwe.UpdateReceiverEstimate(Timestamp::Millis(now_ms),
|
||||
DataRate::BitsPerSec(kRembBps));
|
||||
@ -66,7 +68,8 @@ void TestProbing(bool use_delay_based) {
|
||||
now_ms += 2001;
|
||||
if (use_delay_based) {
|
||||
bwe.UpdateDelayBasedEstimate(Timestamp::Millis(now_ms),
|
||||
DataRate::BitsPerSec(kSecondRembBps));
|
||||
DataRate::BitsPerSec(kSecondRembBps),
|
||||
BandwidthUsage::kBwNormal);
|
||||
} else {
|
||||
bwe.UpdateReceiverEstimate(Timestamp::Millis(now_ms),
|
||||
DataRate::BitsPerSec(kSecondRembBps));
|
||||
@ -157,7 +160,8 @@ TEST(SendSideBweTest, SettingSendBitrateOverridesDelayBasedEstimate) {
|
||||
Timestamp::Millis(now_ms));
|
||||
|
||||
bwe.UpdateDelayBasedEstimate(Timestamp::Millis(now_ms),
|
||||
DataRate::BitsPerSec(kDelayBasedBitrateBps));
|
||||
DataRate::BitsPerSec(kDelayBasedBitrateBps),
|
||||
BandwidthUsage::kBwNormal);
|
||||
bwe.UpdateEstimate(Timestamp::Millis(now_ms));
|
||||
EXPECT_GE(bwe.target_rate().bps(), kInitialBitrateBps);
|
||||
EXPECT_LE(bwe.target_rate().bps(), kDelayBasedBitrateBps);
|
||||
|
Reference in New Issue
Block a user