Delay increasing estimate to the delay based estimate after loss happens.
The change bounds the estimate increment by MaxIncreaseFactor in DelayedIncreaseWindow after seeing loss. MaxIncreaseFactor is set to 1000 to disable the change by default. Improve trendline integration: always allow to decrease the estimate, and only allow to increase the estimate if overusing and underusing are not in the state window. Other improvement: bound candidates by delay based estimate, instance upper bound, and bandwidth limit in the current window. Clean: remove the flag BackoffWhenOverusing since it has negative impacts when experimenting. Bug: webrtc:12707 Change-Id: Ia4c1e58d692071967e8807a8b9d64b8ae4caf837 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/261240 Reviewed-by: Per Kjellander <perkj@webrtc.org> Commit-Queue: Diep Bui <diepbp@webrtc.org> Cr-Commit-Position: refs/heads/main@{#36847}
This commit is contained in:
parent
a59311cd6f
commit
f783b938fa
@ -162,6 +162,7 @@ rtc_library("loss_based_bwe_v2") {
|
||||
"../../../api/units:timestamp",
|
||||
"../../../rtc_base:logging",
|
||||
"../../../rtc_base/experiments:field_trial_parser",
|
||||
"../../remote_bitrate_estimator",
|
||||
]
|
||||
absl_deps = [
|
||||
"//third_party/abseil-cpp/absl/algorithm:container",
|
||||
|
||||
@ -28,6 +28,7 @@
|
||||
#include "api/units/data_size.h"
|
||||
#include "api/units/time_delta.h"
|
||||
#include "api/units/timestamp.h"
|
||||
#include "modules/remote_bitrate_estimator/include/bwe_defines.h"
|
||||
#include "rtc_base/experiments/field_trial_list.h"
|
||||
#include "rtc_base/experiments/field_trial_parser.h"
|
||||
#include "rtc_base/logging.h"
|
||||
@ -219,6 +220,34 @@ void LossBasedBweV2::UpdateBandwidthEstimate(
|
||||
current_estimate_.loss_limited_bandwidth) {
|
||||
last_time_estimate_reduced_ = last_send_time_most_recent_observation_;
|
||||
}
|
||||
|
||||
// Bound the estimate increasement 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_ &&
|
||||
(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(
|
||||
congestion_controller::GetMinBitrate(),
|
||||
best_candidate.loss_limited_bandwidth * config_->max_increase_factor);
|
||||
recovering_after_loss_timestamp_ = last_send_time_most_recent_observation_;
|
||||
}
|
||||
|
||||
current_estimate_ = best_candidate;
|
||||
}
|
||||
|
||||
@ -273,8 +302,11 @@ absl::optional<LossBasedBweV2::Config> LossBasedBweV2::CreateConfig(
|
||||
FieldTrialParameter<double> delay_based_limit_factor("DelayBasedLimitFactor",
|
||||
1.0);
|
||||
FieldTrialParameter<int> trendline_window_size("TrendlineWindowSize", 20);
|
||||
FieldTrialParameter<bool> backoff_when_overusing("BackoffWhenOverusing",
|
||||
false);
|
||||
FieldTrialParameter<double> max_increase_factor("MaxIncreaseFactor", 1000.0);
|
||||
FieldTrialParameter<TimeDelta> delayed_increase_window(
|
||||
"DelayedIncreaseWindow", TimeDelta::Millis(300));
|
||||
FieldTrialParameter<bool> use_acked_bitrate_only_when_overusing(
|
||||
"UseAckedBitrateOnlyWhenOverusing", false);
|
||||
|
||||
if (key_value_config) {
|
||||
ParseFieldTrial({&enabled,
|
||||
@ -303,7 +335,9 @@ absl::optional<LossBasedBweV2::Config> LossBasedBweV2::CreateConfig(
|
||||
&trendline_integration_enabled,
|
||||
&delay_based_limit_factor,
|
||||
&trendline_window_size,
|
||||
&backoff_when_overusing},
|
||||
&max_increase_factor,
|
||||
&delayed_increase_window,
|
||||
&use_acked_bitrate_only_when_overusing},
|
||||
key_value_config->Lookup("WebRTC-Bwe-LossBasedBweV2"));
|
||||
}
|
||||
|
||||
@ -349,7 +383,10 @@ absl::optional<LossBasedBweV2::Config> LossBasedBweV2::CreateConfig(
|
||||
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();
|
||||
config->max_increase_factor = max_increase_factor.Get();
|
||||
config->delayed_increase_window = delayed_increase_window.Get();
|
||||
config->use_acked_bitrate_only_when_overusing =
|
||||
use_acked_bitrate_only_when_overusing.Get();
|
||||
return config;
|
||||
}
|
||||
|
||||
@ -510,6 +547,16 @@ bool LossBasedBweV2::IsConfigValid() const {
|
||||
<< config_->trendline_window_size;
|
||||
valid = false;
|
||||
}
|
||||
if (config_->max_increase_factor <= 0.0) {
|
||||
RTC_LOG(LS_WARNING) << "The maximum increase factor must be positive: "
|
||||
<< config_->max_increase_factor;
|
||||
valid = false;
|
||||
}
|
||||
if (config_->delayed_increase_window <= TimeDelta::Zero()) {
|
||||
RTC_LOG(LS_WARNING) << "The delayed increase window must be positive: "
|
||||
<< config_->delayed_increase_window.ms();
|
||||
valid = false;
|
||||
}
|
||||
return valid;
|
||||
}
|
||||
|
||||
@ -535,12 +582,32 @@ double LossBasedBweV2::GetAverageReportedLossRatio() const {
|
||||
return static_cast<double>(num_lost_packets) / num_packets;
|
||||
}
|
||||
|
||||
DataRate LossBasedBweV2::GetCandidateBandwidthUpperBound() const {
|
||||
if (!acknowledged_bitrate_.has_value())
|
||||
return DataRate::PlusInfinity();
|
||||
DataRate LossBasedBweV2::GetCandidateBandwidthUpperBound(
|
||||
DataRate delay_based_estimate) const {
|
||||
DataRate candidate_bandwidth_upper_bound = DataRate::PlusInfinity();
|
||||
if (limited_due_to_loss_candidate_) {
|
||||
candidate_bandwidth_upper_bound = bandwidth_limit_in_current_window_;
|
||||
}
|
||||
|
||||
DataRate candidate_bandwidth_upper_bound =
|
||||
config_->bandwidth_rampup_upper_bound_factor * (*acknowledged_bitrate_);
|
||||
if (config_->trendline_integration_enabled) {
|
||||
candidate_bandwidth_upper_bound =
|
||||
std::min(GetInstantUpperBound(), candidate_bandwidth_upper_bound);
|
||||
if (IsValid(delay_based_estimate)) {
|
||||
candidate_bandwidth_upper_bound =
|
||||
std::min(delay_based_estimate, candidate_bandwidth_upper_bound);
|
||||
}
|
||||
}
|
||||
|
||||
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(
|
||||
@ -561,16 +628,8 @@ 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) {
|
||||
if (!can_increase_bitrate && candidate_factor > 1.0) {
|
||||
continue;
|
||||
}
|
||||
bandwidths.push_back(candidate_factor *
|
||||
@ -593,15 +652,20 @@ std::vector<LossBasedBweV2::ChannelParameters> LossBasedBweV2::GetCandidates(
|
||||
}
|
||||
|
||||
const DataRate candidate_bandwidth_upper_bound =
|
||||
GetCandidateBandwidthUpperBound();
|
||||
GetCandidateBandwidthUpperBound(delay_based_estimate);
|
||||
|
||||
std::vector<ChannelParameters> candidates;
|
||||
candidates.resize(bandwidths.size());
|
||||
for (size_t i = 0; i < bandwidths.size(); ++i) {
|
||||
ChannelParameters candidate = current_estimate_;
|
||||
candidate.loss_limited_bandwidth = std::min(
|
||||
bandwidths[i], std::max(current_estimate_.loss_limited_bandwidth,
|
||||
candidate_bandwidth_upper_bound));
|
||||
if (config_->trendline_integration_enabled) {
|
||||
candidate.loss_limited_bandwidth =
|
||||
std::min(bandwidths[i], candidate_bandwidth_upper_bound);
|
||||
} else {
|
||||
candidate.loss_limited_bandwidth = std::min(
|
||||
bandwidths[i], std::max(current_estimate_.loss_limited_bandwidth,
|
||||
candidate_bandwidth_upper_bound));
|
||||
}
|
||||
candidate.inherent_loss = GetFeasibleInherentLoss(candidate);
|
||||
candidates[i] = candidate;
|
||||
}
|
||||
@ -760,32 +824,14 @@ 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) {
|
||||
if (detector_state == BandwidthUsage::kBwOverusing ||
|
||||
detector_state == BandwidthUsage::kBwUnderusing) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -797,6 +843,10 @@ bool LossBasedBweV2::TrendlineEsimateAllowEmergencyBackoff() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!config_->use_acked_bitrate_only_when_overusing) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (const auto& detector_state : delay_detector_states_) {
|
||||
if (detector_state == BandwidthUsage::kBwOverusing) {
|
||||
return true;
|
||||
@ -836,11 +886,10 @@ bool LossBasedBweV2::PushBackObservation(
|
||||
const Timestamp last_send_time = packet_results_summary.last_send_time;
|
||||
const TimeDelta observation_duration =
|
||||
last_send_time - last_send_time_most_recent_observation_;
|
||||
|
||||
// Too small to be meaningful.
|
||||
if (observation_duration <= TimeDelta::Zero() ||
|
||||
(observation_duration < config_->observation_duration_lower_bound &&
|
||||
(delay_detector_state == BandwidthUsage::kBwNormal ||
|
||||
(delay_detector_state != BandwidthUsage::kBwOverusing ||
|
||||
!config_->trendline_integration_enabled))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -87,7 +87,9 @@ class LossBasedBweV2 {
|
||||
bool trendline_integration_enabled = false;
|
||||
double delay_based_limit_factor = 1.0;
|
||||
int trendline_window_size = 0;
|
||||
bool backoff_when_overusing = false;
|
||||
double max_increase_factor = 0.0;
|
||||
TimeDelta delayed_increase_window = TimeDelta::Zero();
|
||||
bool use_acked_bitrate_only_when_overusing = false;
|
||||
};
|
||||
|
||||
struct Derivatives {
|
||||
@ -119,7 +121,7 @@ class LossBasedBweV2 {
|
||||
double GetAverageReportedLossRatio() const;
|
||||
std::vector<ChannelParameters> GetCandidates(
|
||||
DataRate delay_based_estimate) const;
|
||||
DataRate GetCandidateBandwidthUpperBound() const;
|
||||
DataRate GetCandidateBandwidthUpperBound(DataRate delay_based_estimate) const;
|
||||
Derivatives GetDerivatives(const ChannelParameters& channel_parameters) const;
|
||||
double GetFeasibleInherentLoss(
|
||||
const ChannelParameters& channel_parameters) const;
|
||||
@ -132,12 +134,9 @@ 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.
|
||||
// Returns false if there exists a kBwOverusing or kBwUnderusing in the
|
||||
// window.
|
||||
bool TrendlineEsimateAllowBitrateIncrease() const;
|
||||
|
||||
// Returns true if there exists an overusing state in the window.
|
||||
@ -163,6 +162,9 @@ class LossBasedBweV2 {
|
||||
std::vector<double> instant_upper_bound_temporal_weights_;
|
||||
std::vector<double> temporal_weights_;
|
||||
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;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
#include "modules/congestion_controller/goog_cc/loss_based_bwe_v2.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "api/network_state_predictor.h"
|
||||
#include "api/transport/network_types.h"
|
||||
@ -29,71 +30,132 @@ namespace {
|
||||
using ::webrtc::test::ExplicitKeyValueConfig;
|
||||
|
||||
constexpr TimeDelta kObservationDurationLowerBound = TimeDelta::Millis(200);
|
||||
constexpr TimeDelta kDelayedIncreaseWindow = TimeDelta::Millis(300);
|
||||
constexpr double kMaxIncreaseFactor = 1.5;
|
||||
|
||||
std::string Config(bool enabled, bool valid) {
|
||||
char buffer[1024];
|
||||
rtc::SimpleStringBuilder config_string(buffer);
|
||||
class LossBasedBweV2Test : public ::testing::TestWithParam<bool> {
|
||||
protected:
|
||||
std::string Config(bool enabled,
|
||||
bool valid,
|
||||
bool trendline_integration_enabled) {
|
||||
char buffer[1024];
|
||||
rtc::SimpleStringBuilder config_string(buffer);
|
||||
|
||||
config_string << "WebRTC-Bwe-LossBasedBweV2/";
|
||||
config_string << "WebRTC-Bwe-LossBasedBweV2/";
|
||||
|
||||
if (enabled) {
|
||||
config_string << "Enabled:true";
|
||||
} else {
|
||||
config_string << "Enabled:false";
|
||||
if (enabled) {
|
||||
config_string << "Enabled:true";
|
||||
} else {
|
||||
config_string << "Enabled:false";
|
||||
}
|
||||
|
||||
if (valid) {
|
||||
config_string << ",BwRampupUpperBoundFactor:1.2";
|
||||
} else {
|
||||
config_string << ",BwRampupUpperBoundFactor:0.0";
|
||||
}
|
||||
|
||||
if (trendline_integration_enabled) {
|
||||
config_string << ",TrendlineIntegrationEnabled:true";
|
||||
} else {
|
||||
config_string << ",TrendlineIntegrationEnabled:false";
|
||||
}
|
||||
|
||||
config_string
|
||||
<< ",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";
|
||||
|
||||
config_string.AppendFormat(
|
||||
",ObservationDurationLowerBound:%dms",
|
||||
static_cast<int>(kObservationDurationLowerBound.ms()));
|
||||
config_string.AppendFormat(",MaxIncreaseFactor:%f", kMaxIncreaseFactor);
|
||||
config_string.AppendFormat(",DelayedIncreaseWindow:%dms",
|
||||
static_cast<int>(kDelayedIncreaseWindow.ms()));
|
||||
|
||||
config_string << "/";
|
||||
|
||||
return config_string.str();
|
||||
}
|
||||
|
||||
if (valid) {
|
||||
config_string << ",BwRampupUpperBoundFactor:1.2";
|
||||
} else {
|
||||
config_string << ",BwRampupUpperBoundFactor:0.0";
|
||||
std::vector<PacketResult> CreatePacketResultsWithReceivedPackets(
|
||||
Timestamp first_packet_timestamp) {
|
||||
std::vector<PacketResult> enough_feedback(2);
|
||||
enough_feedback[0].sent_packet.size = DataSize::Bytes(15'000);
|
||||
enough_feedback[1].sent_packet.size = DataSize::Bytes(15'000);
|
||||
enough_feedback[0].sent_packet.send_time = first_packet_timestamp;
|
||||
enough_feedback[1].sent_packet.send_time =
|
||||
first_packet_timestamp + kObservationDurationLowerBound;
|
||||
enough_feedback[0].receive_time =
|
||||
first_packet_timestamp + kObservationDurationLowerBound;
|
||||
enough_feedback[1].receive_time =
|
||||
first_packet_timestamp + 2 * kObservationDurationLowerBound;
|
||||
return enough_feedback;
|
||||
}
|
||||
|
||||
config_string
|
||||
<< ",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,"
|
||||
"BackoffWhenOverusing:true";
|
||||
std::vector<PacketResult> CreatePacketResultsWith50pLossRate(
|
||||
Timestamp first_packet_timestamp) {
|
||||
std::vector<PacketResult> enough_feedback(2);
|
||||
enough_feedback[0].sent_packet.size = DataSize::Bytes(15'000);
|
||||
enough_feedback[1].sent_packet.size = DataSize::Bytes(15'000);
|
||||
enough_feedback[0].sent_packet.send_time = first_packet_timestamp;
|
||||
enough_feedback[1].sent_packet.send_time =
|
||||
first_packet_timestamp + kObservationDurationLowerBound;
|
||||
enough_feedback[0].receive_time =
|
||||
first_packet_timestamp + kObservationDurationLowerBound;
|
||||
enough_feedback[1].receive_time = Timestamp::PlusInfinity();
|
||||
return enough_feedback;
|
||||
}
|
||||
|
||||
config_string.AppendFormat(
|
||||
",ObservationDurationLowerBound:%dms",
|
||||
static_cast<int>(kObservationDurationLowerBound.ms()));
|
||||
std::vector<PacketResult> CreatePacketResultsWith100pLossRate(
|
||||
Timestamp first_packet_timestamp) {
|
||||
std::vector<PacketResult> enough_feedback(2);
|
||||
enough_feedback[0].sent_packet.size = DataSize::Bytes(15'000);
|
||||
enough_feedback[1].sent_packet.size = DataSize::Bytes(15'000);
|
||||
enough_feedback[0].sent_packet.send_time = first_packet_timestamp;
|
||||
enough_feedback[1].sent_packet.send_time =
|
||||
first_packet_timestamp + kObservationDurationLowerBound;
|
||||
enough_feedback[0].receive_time = Timestamp::PlusInfinity();
|
||||
enough_feedback[1].receive_time = Timestamp::PlusInfinity();
|
||||
return enough_feedback;
|
||||
}
|
||||
};
|
||||
|
||||
config_string << "/";
|
||||
|
||||
return config_string.str();
|
||||
}
|
||||
|
||||
TEST(LossBasedBweV2Test, EnabledWhenGivenValidConfigurationValues) {
|
||||
TEST_P(LossBasedBweV2Test, EnabledWhenGivenValidConfigurationValues) {
|
||||
ExplicitKeyValueConfig key_value_config(
|
||||
Config(/*enabled=*/true, /*valid=*/true));
|
||||
Config(/*enabled=*/true, /*valid=*/true,
|
||||
/*trendline_integration_enabled=*/GetParam()));
|
||||
LossBasedBweV2 loss_based_bandwidth_estimator(&key_value_config);
|
||||
|
||||
EXPECT_TRUE(loss_based_bandwidth_estimator.IsEnabled());
|
||||
}
|
||||
|
||||
TEST(LossBasedBweV2Test, DisabledWhenGivenDisabledConfiguration) {
|
||||
TEST_P(LossBasedBweV2Test, DisabledWhenGivenDisabledConfiguration) {
|
||||
ExplicitKeyValueConfig key_value_config(
|
||||
Config(/*enabled=*/false, /*valid=*/true));
|
||||
Config(/*enabled=*/false, /*valid=*/true,
|
||||
/*trendline_integration_enabled=*/GetParam()));
|
||||
LossBasedBweV2 loss_based_bandwidth_estimator(&key_value_config);
|
||||
|
||||
EXPECT_FALSE(loss_based_bandwidth_estimator.IsEnabled());
|
||||
}
|
||||
|
||||
TEST(LossBasedBweV2Test, DisabledWhenGivenNonValidConfigurationValues) {
|
||||
TEST_P(LossBasedBweV2Test, DisabledWhenGivenNonValidConfigurationValues) {
|
||||
ExplicitKeyValueConfig key_value_config(
|
||||
Config(/*enabled=*/true, /*valid=*/false));
|
||||
Config(/*enabled=*/true, /*valid=*/false,
|
||||
/*trendline_integration_enabled=*/GetParam()));
|
||||
LossBasedBweV2 loss_based_bandwidth_estimator(&key_value_config);
|
||||
|
||||
EXPECT_FALSE(loss_based_bandwidth_estimator.IsEnabled());
|
||||
}
|
||||
|
||||
TEST(LossBasedBweV2Test, DisabledWhenGivenNonPositiveCandidateFactor) {
|
||||
TEST_P(LossBasedBweV2Test, DisabledWhenGivenNonPositiveCandidateFactor) {
|
||||
ExplicitKeyValueConfig key_value_config_negative_candidate_factor(
|
||||
"WebRTC-Bwe-LossBasedBweV2/Enabled:true,CandidateFactors:-1.3|1.1/");
|
||||
LossBasedBweV2 loss_based_bandwidth_estimator_1(
|
||||
@ -107,8 +169,8 @@ TEST(LossBasedBweV2Test, DisabledWhenGivenNonPositiveCandidateFactor) {
|
||||
EXPECT_FALSE(loss_based_bandwidth_estimator_2.IsEnabled());
|
||||
}
|
||||
|
||||
TEST(LossBasedBweV2Test,
|
||||
DisabledWhenGivenConfigurationThatDoesNotAllowGeneratingCandidates) {
|
||||
TEST_P(LossBasedBweV2Test,
|
||||
DisabledWhenGivenConfigurationThatDoesNotAllowGeneratingCandidates) {
|
||||
ExplicitKeyValueConfig key_value_config(
|
||||
"WebRTC-Bwe-LossBasedBweV2/"
|
||||
"Enabled:true,CandidateFactors:1.0,AckedRateCandidate:false,"
|
||||
@ -117,20 +179,15 @@ TEST(LossBasedBweV2Test,
|
||||
EXPECT_FALSE(loss_based_bandwidth_estimator.IsEnabled());
|
||||
}
|
||||
|
||||
TEST(LossBasedBweV2Test, BandwidthEstimateGivenInitializationAndThenFeedback) {
|
||||
PacketResult enough_feedback[2];
|
||||
enough_feedback[0].sent_packet.size = DataSize::Bytes(15'000);
|
||||
enough_feedback[1].sent_packet.size = DataSize::Bytes(15'000);
|
||||
enough_feedback[0].sent_packet.send_time = Timestamp::Zero();
|
||||
enough_feedback[1].sent_packet.send_time =
|
||||
Timestamp::Zero() + kObservationDurationLowerBound;
|
||||
enough_feedback[0].receive_time =
|
||||
Timestamp::Zero() + kObservationDurationLowerBound;
|
||||
enough_feedback[1].receive_time =
|
||||
Timestamp::Zero() + 2 * kObservationDurationLowerBound;
|
||||
TEST_P(LossBasedBweV2Test,
|
||||
BandwidthEstimateGivenInitializationAndThenFeedback) {
|
||||
std::vector<PacketResult> enough_feedback =
|
||||
CreatePacketResultsWithReceivedPackets(
|
||||
/*first_packet_timestamp=*/Timestamp::Zero());
|
||||
|
||||
ExplicitKeyValueConfig key_value_config(
|
||||
Config(/*enabled=*/true, /*valid=*/true));
|
||||
Config(/*enabled=*/true, /*valid=*/true,
|
||||
/*trendline_integration_enabled=*/GetParam()));
|
||||
LossBasedBweV2 loss_based_bandwidth_estimator(&key_value_config);
|
||||
|
||||
loss_based_bandwidth_estimator.SetBandwidthEstimate(
|
||||
@ -145,20 +202,13 @@ TEST(LossBasedBweV2Test, BandwidthEstimateGivenInitializationAndThenFeedback) {
|
||||
.IsFinite());
|
||||
}
|
||||
|
||||
TEST(LossBasedBweV2Test, NoBandwidthEstimateGivenNoInitialization) {
|
||||
PacketResult enough_feedback[2];
|
||||
enough_feedback[0].sent_packet.size = DataSize::Bytes(15'000);
|
||||
enough_feedback[1].sent_packet.size = DataSize::Bytes(15'000);
|
||||
enough_feedback[0].sent_packet.send_time = Timestamp::Zero();
|
||||
enough_feedback[1].sent_packet.send_time =
|
||||
Timestamp::Zero() + kObservationDurationLowerBound;
|
||||
enough_feedback[0].receive_time =
|
||||
Timestamp::Zero() + kObservationDurationLowerBound;
|
||||
enough_feedback[1].receive_time =
|
||||
Timestamp::Zero() + 2 * kObservationDurationLowerBound;
|
||||
|
||||
TEST_P(LossBasedBweV2Test, NoBandwidthEstimateGivenNoInitialization) {
|
||||
std::vector<PacketResult> enough_feedback =
|
||||
CreatePacketResultsWithReceivedPackets(
|
||||
/*first_packet_timestamp=*/Timestamp::Zero());
|
||||
ExplicitKeyValueConfig key_value_config(
|
||||
Config(/*enabled=*/true, /*valid=*/true));
|
||||
Config(/*enabled=*/true, /*valid=*/true,
|
||||
/*trendline_integration_enabled=*/GetParam()));
|
||||
LossBasedBweV2 loss_based_bandwidth_estimator(&key_value_config);
|
||||
|
||||
loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
|
||||
@ -171,7 +221,7 @@ TEST(LossBasedBweV2Test, NoBandwidthEstimateGivenNoInitialization) {
|
||||
.IsPlusInfinity());
|
||||
}
|
||||
|
||||
TEST(LossBasedBweV2Test, NoBandwidthEstimateGivenNotEnoughFeedback) {
|
||||
TEST_P(LossBasedBweV2Test, NoBandwidthEstimateGivenNotEnoughFeedback) {
|
||||
// Create packet results where the observation duration is less than the lower
|
||||
// bound.
|
||||
PacketResult not_enough_feedback[2];
|
||||
@ -186,7 +236,8 @@ TEST(LossBasedBweV2Test, NoBandwidthEstimateGivenNotEnoughFeedback) {
|
||||
Timestamp::Zero() + kObservationDurationLowerBound;
|
||||
|
||||
ExplicitKeyValueConfig key_value_config(
|
||||
Config(/*enabled=*/true, /*valid=*/true));
|
||||
Config(/*enabled=*/true, /*valid=*/true,
|
||||
/*trendline_integration_enabled=*/GetParam()));
|
||||
LossBasedBweV2 loss_based_bandwidth_estimator(&key_value_config);
|
||||
|
||||
loss_based_bandwidth_estimator.SetBandwidthEstimate(
|
||||
@ -208,32 +259,19 @@ TEST(LossBasedBweV2Test, NoBandwidthEstimateGivenNotEnoughFeedback) {
|
||||
.IsPlusInfinity());
|
||||
}
|
||||
|
||||
TEST(LossBasedBweV2Test,
|
||||
SetValueIsTheEstimateUntilAdditionalFeedbackHasBeenReceived) {
|
||||
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;
|
||||
TEST_P(LossBasedBweV2Test,
|
||||
SetValueIsTheEstimateUntilAdditionalFeedbackHasBeenReceived) {
|
||||
std::vector<PacketResult> enough_feedback_1 =
|
||||
CreatePacketResultsWithReceivedPackets(
|
||||
/*first_packet_timestamp=*/Timestamp::Zero());
|
||||
std::vector<PacketResult> enough_feedback_2 =
|
||||
CreatePacketResultsWithReceivedPackets(
|
||||
/*first_packet_timestamp=*/Timestamp::Zero() +
|
||||
2 * kObservationDurationLowerBound);
|
||||
|
||||
ExplicitKeyValueConfig key_value_config(
|
||||
Config(/*enabled=*/true, /*valid=*/true));
|
||||
Config(/*enabled=*/true, /*valid=*/true,
|
||||
/*trendline_integration_enabled=*/GetParam()));
|
||||
LossBasedBweV2 loss_based_bandwidth_estimator(&key_value_config);
|
||||
|
||||
loss_based_bandwidth_estimator.SetBandwidthEstimate(
|
||||
@ -260,32 +298,19 @@ TEST(LossBasedBweV2Test,
|
||||
DataRate::KilobitsPerSec(600));
|
||||
}
|
||||
|
||||
TEST(LossBasedBweV2Test,
|
||||
SetAcknowledgedBitrateOnlyAffectsTheBweWhenAdditionalFeedbackIsGiven) {
|
||||
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;
|
||||
TEST_P(LossBasedBweV2Test,
|
||||
SetAcknowledgedBitrateOnlyAffectsTheBweWhenAdditionalFeedbackIsGiven) {
|
||||
std::vector<PacketResult> enough_feedback_1 =
|
||||
CreatePacketResultsWithReceivedPackets(
|
||||
/*first_packet_timestamp=*/Timestamp::Zero());
|
||||
std::vector<PacketResult> enough_feedback_2 =
|
||||
CreatePacketResultsWithReceivedPackets(
|
||||
/*first_packet_timestamp=*/Timestamp::Zero() +
|
||||
2 * kObservationDurationLowerBound);
|
||||
|
||||
ExplicitKeyValueConfig key_value_config(
|
||||
Config(/*enabled=*/true, /*valid=*/true));
|
||||
Config(/*enabled=*/true, /*valid=*/true,
|
||||
/*trendline_integration_enabled=*/GetParam()));
|
||||
LossBasedBweV2 loss_based_bandwidth_estimator_1(&key_value_config);
|
||||
LossBasedBweV2 loss_based_bandwidth_estimator_2(&key_value_config);
|
||||
|
||||
@ -320,24 +345,15 @@ TEST(LossBasedBweV2Test,
|
||||
/*delay_based_limit=*/DataRate::PlusInfinity()));
|
||||
}
|
||||
|
||||
TEST(LossBasedBweV2Test,
|
||||
BandwidthEstimateIsCappedToBeTcpFairGivenTooHighLossRate) {
|
||||
PacketResult enough_feedback_no_received_packets[2];
|
||||
enough_feedback_no_received_packets[0].sent_packet.size =
|
||||
DataSize::Bytes(15'000);
|
||||
enough_feedback_no_received_packets[1].sent_packet.size =
|
||||
DataSize::Bytes(15'000);
|
||||
enough_feedback_no_received_packets[0].sent_packet.send_time =
|
||||
Timestamp::Zero();
|
||||
enough_feedback_no_received_packets[1].sent_packet.send_time =
|
||||
Timestamp::Zero() + kObservationDurationLowerBound;
|
||||
enough_feedback_no_received_packets[0].receive_time =
|
||||
Timestamp::PlusInfinity();
|
||||
enough_feedback_no_received_packets[1].receive_time =
|
||||
Timestamp::PlusInfinity();
|
||||
TEST_P(LossBasedBweV2Test,
|
||||
BandwidthEstimateIsCappedToBeTcpFairGivenTooHighLossRate) {
|
||||
std::vector<PacketResult> enough_feedback_no_received_packets =
|
||||
CreatePacketResultsWith100pLossRate(
|
||||
/*first_packet_timestamp=*/Timestamp::Zero());
|
||||
|
||||
ExplicitKeyValueConfig key_value_config(
|
||||
Config(/*enabled=*/true, /*valid=*/true));
|
||||
Config(/*enabled=*/true, /*valid=*/true,
|
||||
/*trendline_integration_enabled=*/GetParam()));
|
||||
LossBasedBweV2 loss_based_bandwidth_estimator(&key_value_config);
|
||||
|
||||
loss_based_bandwidth_estimator.SetBandwidthEstimate(
|
||||
@ -351,75 +367,22 @@ TEST(LossBasedBweV2Test,
|
||||
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;
|
||||
TEST_P(LossBasedBweV2Test, BandwidthEstimateNotIncreaseWhenNetworkUnderusing) {
|
||||
if (!GetParam()) {
|
||||
GTEST_SKIP() << "This test should run only if "
|
||||
"trendline_integration_enabled is enabled";
|
||||
}
|
||||
std::vector<PacketResult> enough_feedback_1 =
|
||||
CreatePacketResultsWithReceivedPackets(
|
||||
/*first_packet_timestamp=*/Timestamp::Zero());
|
||||
std::vector<PacketResult> enough_feedback_2 =
|
||||
CreatePacketResultsWithReceivedPackets(
|
||||
/*first_packet_timestamp=*/Timestamp::Zero() +
|
||||
2 * 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));
|
||||
Config(/*enabled=*/true, /*valid=*/true,
|
||||
/*trendline_integration_enabled=*/GetParam()));
|
||||
LossBasedBweV2 loss_based_bandwidth_estimator(&key_value_config);
|
||||
|
||||
loss_based_bandwidth_estimator.SetBandwidthEstimate(
|
||||
@ -427,53 +390,38 @@ TEST(LossBasedBweV2Test, BandwidthEstimateIncreasesWhenUnderusing) {
|
||||
loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
|
||||
enough_feedback_1, DataRate::PlusInfinity(),
|
||||
BandwidthUsage::kBwUnderusing);
|
||||
EXPECT_GT(loss_based_bandwidth_estimator.GetBandwidthEstimate(
|
||||
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_GT(loss_based_bandwidth_estimator.GetBandwidthEstimate(
|
||||
EXPECT_LE(loss_based_bandwidth_estimator.GetBandwidthEstimate(
|
||||
/*delay_based_limit=*/DataRate::PlusInfinity()),
|
||||
DataRate::KilobitsPerSec(600));
|
||||
}
|
||||
|
||||
// When network is underusing, estimate can increase but never be higher than
|
||||
// When network is normal, estimate can increase but never be higher than
|
||||
// the delay based estimate.
|
||||
TEST(LossBasedBweV2Test,
|
||||
BandwidthEstimateCappedByDelayBasedEstimateWhenUnderusing) {
|
||||
PacketResult enough_feedback_1[2];
|
||||
PacketResult enough_feedback_2[2];
|
||||
TEST_P(LossBasedBweV2Test,
|
||||
BandwidthEstimateCappedByDelayBasedEstimateWhenNetworkNormal) {
|
||||
// Create two packet results, network is in normal state, 100% packets are
|
||||
// received, and no delay increase.
|
||||
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;
|
||||
|
||||
std::vector<PacketResult> enough_feedback_1 =
|
||||
CreatePacketResultsWithReceivedPackets(
|
||||
/*first_packet_timestamp=*/Timestamp::Zero());
|
||||
std::vector<PacketResult> enough_feedback_2 =
|
||||
CreatePacketResultsWithReceivedPackets(
|
||||
/*first_packet_timestamp=*/Timestamp::Zero() +
|
||||
2 * kObservationDurationLowerBound);
|
||||
ExplicitKeyValueConfig key_value_config(
|
||||
Config(/*enabled=*/true, /*valid=*/true));
|
||||
Config(/*enabled=*/true, /*valid=*/true,
|
||||
/*trendline_integration_enabled=*/GetParam()));
|
||||
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);
|
||||
enough_feedback_1, DataRate::PlusInfinity(), BandwidthUsage::kBwNormal);
|
||||
// If the delay based estimate is infinity, then loss based estimate increases
|
||||
// and not bounded by delay based estimate.
|
||||
EXPECT_GT(loss_based_bandwidth_estimator.GetBandwidthEstimate(
|
||||
@ -490,30 +438,20 @@ TEST(LossBasedBweV2Test,
|
||||
|
||||
// When loss based bwe receives a strong signal of overusing and an increase in
|
||||
// loss rate, it should acked bitrate for emegency backoff.
|
||||
TEST(LossBasedBweV2Test, UseAckedBitrateForEmegencyBackOff) {
|
||||
PacketResult enough_feedback_1[2];
|
||||
PacketResult enough_feedback_2[2];
|
||||
TEST_P(LossBasedBweV2Test, UseAckedBitrateForEmegencyBackOff) {
|
||||
// Create two packet results, first packet has 50% loss rate, second packet
|
||||
// has 100% loss rate.
|
||||
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::PlusInfinity();
|
||||
std::vector<PacketResult> enough_feedback_1 =
|
||||
CreatePacketResultsWith50pLossRate(
|
||||
/*first_packet_timestamp=*/Timestamp::Zero());
|
||||
std::vector<PacketResult> enough_feedback_2 =
|
||||
CreatePacketResultsWith100pLossRate(
|
||||
/*first_packet_timestamp=*/Timestamp::Zero() +
|
||||
2 * kObservationDurationLowerBound);
|
||||
|
||||
ExplicitKeyValueConfig key_value_config(
|
||||
Config(/*enabled=*/true, /*valid=*/true));
|
||||
Config(/*enabled=*/true, /*valid=*/true,
|
||||
/*trendline_integration_enabled=*/GetParam()));
|
||||
LossBasedBweV2 loss_based_bandwidth_estimator(&key_value_config);
|
||||
|
||||
loss_based_bandwidth_estimator.SetBandwidthEstimate(
|
||||
@ -535,85 +473,298 @@ TEST(LossBasedBweV2Test, UseAckedBitrateForEmegencyBackOff) {
|
||||
acked_bitrate);
|
||||
}
|
||||
|
||||
// When network is in normal state, and if the acked bitrate is small, then the
|
||||
// loss based estimate is higher than the acked bitrate.
|
||||
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;
|
||||
|
||||
// When receiving the same packet feedback, loss based bwe ignores the feedback
|
||||
// and returns the current estimate.
|
||||
TEST_P(LossBasedBweV2Test, NoBweChangeIfObservationDurationUnchanged) {
|
||||
std::vector<PacketResult> enough_feedback_1 =
|
||||
CreatePacketResultsWithReceivedPackets(
|
||||
/*first_packet_timestamp=*/Timestamp::Zero());
|
||||
ExplicitKeyValueConfig key_value_config(
|
||||
Config(/*enabled=*/true, /*valid=*/true));
|
||||
Config(/*enabled=*/true, /*valid=*/true,
|
||||
/*trendline_integration_enabled=*/GetParam()));
|
||||
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.SetAcknowledgedBitrate(
|
||||
DataRate::KilobitsPerSec(300));
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
TEST(LossBasedBweV2Test, NoUpdateIfObservationDurationUnchanged) {
|
||||
PacketResult enough_feedback_1[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_1[0].sent_packet.send_time = Timestamp::Zero();
|
||||
enough_feedback_1[1].sent_packet.send_time =
|
||||
Timestamp::Zero() + kObservationDurationLowerBound;
|
||||
enough_feedback_1[0].receive_time =
|
||||
Timestamp::Zero() + kObservationDurationLowerBound;
|
||||
enough_feedback_1[1].receive_time =
|
||||
Timestamp::Zero() + 2 * 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);
|
||||
DataRate current_estimate =
|
||||
loss_based_bandwidth_estimator.GetBandwidthEstimate(
|
||||
/*delay_based_limit=*/DataRate::PlusInfinity());
|
||||
DataRate estimate_1 = loss_based_bandwidth_estimator.GetBandwidthEstimate(
|
||||
/*delay_based_limit=*/DataRate::PlusInfinity());
|
||||
|
||||
// Use the same feedback and check if the estimate is unchanged.
|
||||
loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
|
||||
enough_feedback_1, DataRate::PlusInfinity(), BandwidthUsage::kBwNormal);
|
||||
DataRate new_estimate = loss_based_bandwidth_estimator.GetBandwidthEstimate(
|
||||
DataRate estimate_2 = loss_based_bandwidth_estimator.GetBandwidthEstimate(
|
||||
/*delay_based_limit=*/DataRate::PlusInfinity());
|
||||
EXPECT_EQ(current_estimate, new_estimate);
|
||||
EXPECT_EQ(estimate_2, estimate_1);
|
||||
}
|
||||
|
||||
// When receiving feedback of packets that were sent within an observation
|
||||
// duration, and network is in the normal state, loss based bwe returns the
|
||||
// current estimate.
|
||||
TEST_P(LossBasedBweV2Test,
|
||||
NoBweChangeIfObservationDurationIsSmallAndNetworkNormal) {
|
||||
std::vector<PacketResult> enough_feedback_1 =
|
||||
CreatePacketResultsWithReceivedPackets(
|
||||
/*first_packet_timestamp=*/Timestamp::Zero());
|
||||
std::vector<PacketResult> enough_feedback_2 =
|
||||
CreatePacketResultsWithReceivedPackets(
|
||||
/*first_packet_timestamp=*/Timestamp::Zero() +
|
||||
kObservationDurationLowerBound - TimeDelta::Millis(1));
|
||||
ExplicitKeyValueConfig key_value_config(
|
||||
Config(/*enabled=*/true, /*valid=*/true,
|
||||
/*trendline_integration_enabled=*/GetParam()));
|
||||
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::kBwNormal);
|
||||
DataRate estimate_1 = loss_based_bandwidth_estimator.GetBandwidthEstimate(
|
||||
/*delay_based_limit=*/DataRate::PlusInfinity());
|
||||
|
||||
loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
|
||||
enough_feedback_2, DataRate::PlusInfinity(), BandwidthUsage::kBwNormal);
|
||||
DataRate estimate_2 = loss_based_bandwidth_estimator.GetBandwidthEstimate(
|
||||
/*delay_based_limit=*/DataRate::PlusInfinity());
|
||||
EXPECT_EQ(estimate_2, estimate_1);
|
||||
}
|
||||
|
||||
// When receiving feedback of packets that were sent within an observation
|
||||
// duration, and network is in the underusing state, loss based bwe returns the
|
||||
// current estimate.
|
||||
TEST_P(LossBasedBweV2Test,
|
||||
NoBweIncreaseIfObservationDurationIsSmallAndNetworkUnderusing) {
|
||||
std::vector<PacketResult> enough_feedback_1 =
|
||||
CreatePacketResultsWithReceivedPackets(
|
||||
/*first_packet_timestamp=*/Timestamp::Zero());
|
||||
std::vector<PacketResult> enough_feedback_2 =
|
||||
CreatePacketResultsWithReceivedPackets(
|
||||
/*first_packet_timestamp=*/Timestamp::Zero() +
|
||||
kObservationDurationLowerBound - TimeDelta::Millis(1));
|
||||
ExplicitKeyValueConfig key_value_config(
|
||||
Config(/*enabled=*/true, /*valid=*/true,
|
||||
/*trendline_integration_enabled=*/GetParam()));
|
||||
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::kBwNormal);
|
||||
DataRate estimate_1 = loss_based_bandwidth_estimator.GetBandwidthEstimate(
|
||||
/*delay_based_limit=*/DataRate::PlusInfinity());
|
||||
|
||||
loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
|
||||
enough_feedback_2, DataRate::PlusInfinity(),
|
||||
BandwidthUsage::kBwUnderusing);
|
||||
DataRate estimate_2 = loss_based_bandwidth_estimator.GetBandwidthEstimate(
|
||||
/*delay_based_limit=*/DataRate::PlusInfinity());
|
||||
EXPECT_LE(estimate_2, estimate_1);
|
||||
}
|
||||
|
||||
// When receiving feedback of packets that were sent within an observation
|
||||
// duration, network is overusing, and trendline integration is enabled, loss
|
||||
// based bwe updates its estimate.
|
||||
TEST_P(LossBasedBweV2Test,
|
||||
UpdateEstimateIfObservationDurationIsSmallAndNetworkOverusing) {
|
||||
if (!GetParam()) {
|
||||
GTEST_SKIP() << "This test should run only if "
|
||||
"trendline_integration_enabled is enabled";
|
||||
}
|
||||
std::vector<PacketResult> enough_feedback_1 =
|
||||
CreatePacketResultsWith50pLossRate(
|
||||
/*first_packet_timestamp=*/Timestamp::Zero());
|
||||
std::vector<PacketResult> enough_feedback_2 =
|
||||
CreatePacketResultsWith100pLossRate(
|
||||
/*first_packet_timestamp=*/Timestamp::Zero() +
|
||||
kObservationDurationLowerBound - TimeDelta::Millis(1));
|
||||
ExplicitKeyValueConfig key_value_config(
|
||||
Config(/*enabled=*/true, /*valid=*/true,
|
||||
/*trendline_integration_enabled=*/GetParam()));
|
||||
LossBasedBweV2 loss_based_bandwidth_estimator(&key_value_config);
|
||||
|
||||
loss_based_bandwidth_estimator.SetBandwidthEstimate(
|
||||
DataRate::KilobitsPerSec(600));
|
||||
loss_based_bandwidth_estimator.SetAcknowledgedBitrate(
|
||||
DataRate::KilobitsPerSec(300));
|
||||
loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
|
||||
enough_feedback_1, DataRate::PlusInfinity(), BandwidthUsage::kBwNormal);
|
||||
DataRate estimate_1 = loss_based_bandwidth_estimator.GetBandwidthEstimate(
|
||||
/*delay_based_limit=*/DataRate::PlusInfinity());
|
||||
|
||||
loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
|
||||
enough_feedback_2, DataRate::PlusInfinity(),
|
||||
BandwidthUsage::kBwOverusing);
|
||||
DataRate estimate_2 = loss_based_bandwidth_estimator.GetBandwidthEstimate(
|
||||
/*delay_based_limit=*/DataRate::PlusInfinity());
|
||||
EXPECT_LT(estimate_2, estimate_1);
|
||||
}
|
||||
|
||||
TEST_P(LossBasedBweV2Test,
|
||||
IncreaseToDelayBasedEstimateIfNoLossOrDelayIncrease) {
|
||||
std::vector<PacketResult> enough_feedback_1 =
|
||||
CreatePacketResultsWithReceivedPackets(
|
||||
/*first_packet_timestamp=*/Timestamp::Zero());
|
||||
std::vector<PacketResult> enough_feedback_2 =
|
||||
CreatePacketResultsWithReceivedPackets(
|
||||
/*first_packet_timestamp=*/Timestamp::Zero() +
|
||||
2 * kObservationDurationLowerBound);
|
||||
ExplicitKeyValueConfig key_value_config(
|
||||
Config(/*enabled=*/true, /*valid=*/true,
|
||||
/*trendline_integration_enabled=*/GetParam()));
|
||||
LossBasedBweV2 loss_based_bandwidth_estimator(&key_value_config);
|
||||
DataRate delay_based_estimate = DataRate::KilobitsPerSec(5000);
|
||||
loss_based_bandwidth_estimator.SetBandwidthEstimate(
|
||||
DataRate::KilobitsPerSec(600));
|
||||
|
||||
loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
|
||||
enough_feedback_1, delay_based_estimate, BandwidthUsage::kBwNormal);
|
||||
EXPECT_EQ(
|
||||
loss_based_bandwidth_estimator.GetBandwidthEstimate(delay_based_estimate),
|
||||
delay_based_estimate);
|
||||
loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
|
||||
enough_feedback_2, delay_based_estimate, BandwidthUsage::kBwNormal);
|
||||
EXPECT_EQ(
|
||||
loss_based_bandwidth_estimator.GetBandwidthEstimate(delay_based_estimate),
|
||||
delay_based_estimate);
|
||||
}
|
||||
|
||||
// After loss based bwe backs off, the next estimate is capped by
|
||||
// MaxIncreaseFactor * current estimate.
|
||||
TEST_P(LossBasedBweV2Test,
|
||||
IncreaseByMaxIncreaseFactorAfterLossBasedBweBacksOff) {
|
||||
std::vector<PacketResult> enough_feedback_1 =
|
||||
CreatePacketResultsWithReceivedPackets(
|
||||
/*first_packet_timestamp=*/Timestamp::Zero());
|
||||
std::vector<PacketResult> enough_feedback_2 =
|
||||
CreatePacketResultsWithReceivedPackets(
|
||||
/*first_packet_timestamp=*/Timestamp::Zero() +
|
||||
kObservationDurationLowerBound);
|
||||
ExplicitKeyValueConfig key_value_config(
|
||||
Config(/*enabled=*/true, /*valid=*/true,
|
||||
/*trendline_integration_enabled=*/GetParam()));
|
||||
LossBasedBweV2 loss_based_bandwidth_estimator(&key_value_config);
|
||||
DataRate delay_based_estimate = DataRate::KilobitsPerSec(5000);
|
||||
|
||||
loss_based_bandwidth_estimator.SetBandwidthEstimate(
|
||||
DataRate::KilobitsPerSec(600));
|
||||
loss_based_bandwidth_estimator.SetAcknowledgedBitrate(
|
||||
DataRate::KilobitsPerSec(300));
|
||||
loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
|
||||
enough_feedback_1, delay_based_estimate, BandwidthUsage::kBwNormal);
|
||||
DataRate estimate_1 =
|
||||
loss_based_bandwidth_estimator.GetBandwidthEstimate(delay_based_estimate);
|
||||
// Increase the acknowledged bitrate to make sure that the estimate is not
|
||||
// capped too low.
|
||||
loss_based_bandwidth_estimator.SetAcknowledgedBitrate(
|
||||
DataRate::KilobitsPerSec(5000));
|
||||
loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
|
||||
enough_feedback_2, delay_based_estimate, BandwidthUsage::kBwNormal);
|
||||
|
||||
// The estimate is capped by current_estimate * kMaxIncreaseFactor because it
|
||||
// recently backed off.
|
||||
DataRate estimate_2 =
|
||||
loss_based_bandwidth_estimator.GetBandwidthEstimate(delay_based_estimate);
|
||||
EXPECT_EQ(estimate_2, estimate_1 * kMaxIncreaseFactor);
|
||||
EXPECT_LE(estimate_2, delay_based_estimate);
|
||||
}
|
||||
|
||||
// After loss based bwe backs off, the estimate is bounded during the delayed
|
||||
// window.
|
||||
TEST_P(LossBasedBweV2Test,
|
||||
EstimateBitrateIsBoundedDuringDelayedWindowAfterLossBasedBweBacksOff) {
|
||||
std::vector<PacketResult> enough_feedback_1 =
|
||||
CreatePacketResultsWithReceivedPackets(
|
||||
/*first_packet_timestamp=*/Timestamp::Zero());
|
||||
std::vector<PacketResult> enough_feedback_2 =
|
||||
CreatePacketResultsWith50pLossRate(
|
||||
/*first_packet_timestamp=*/Timestamp::Zero() +
|
||||
kDelayedIncreaseWindow - TimeDelta::Millis(2));
|
||||
std::vector<PacketResult> enough_feedback_3 =
|
||||
CreatePacketResultsWithReceivedPackets(
|
||||
/*first_packet_timestamp=*/Timestamp::Zero() +
|
||||
kDelayedIncreaseWindow - TimeDelta::Millis(1));
|
||||
ExplicitKeyValueConfig key_value_config(
|
||||
Config(/*enabled=*/true, /*valid=*/true,
|
||||
/*trendline_integration_enabled=*/GetParam()));
|
||||
LossBasedBweV2 loss_based_bandwidth_estimator(&key_value_config);
|
||||
DataRate delay_based_estimate = DataRate::KilobitsPerSec(5000);
|
||||
|
||||
loss_based_bandwidth_estimator.SetBandwidthEstimate(
|
||||
DataRate::KilobitsPerSec(600));
|
||||
loss_based_bandwidth_estimator.SetAcknowledgedBitrate(
|
||||
DataRate::KilobitsPerSec(300));
|
||||
loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
|
||||
enough_feedback_1, delay_based_estimate, BandwidthUsage::kBwNormal);
|
||||
// Increase the acknowledged bitrate to make sure that the estimate is not
|
||||
// capped too low.
|
||||
loss_based_bandwidth_estimator.SetAcknowledgedBitrate(
|
||||
DataRate::KilobitsPerSec(5000));
|
||||
loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
|
||||
enough_feedback_2, delay_based_estimate, BandwidthUsage::kBwNormal);
|
||||
|
||||
// The estimate is capped by current_estimate * kMaxIncreaseFactor because
|
||||
// it recently backed off.
|
||||
DataRate estimate_2 =
|
||||
loss_based_bandwidth_estimator.GetBandwidthEstimate(delay_based_estimate);
|
||||
|
||||
loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
|
||||
enough_feedback_3, delay_based_estimate, BandwidthUsage::kBwNormal);
|
||||
// The latest estimate is the same as the previous estimate since the sent
|
||||
// packets were sent within the DelayedIncreaseWindow.
|
||||
EXPECT_EQ(
|
||||
loss_based_bandwidth_estimator.GetBandwidthEstimate(delay_based_estimate),
|
||||
estimate_2);
|
||||
}
|
||||
|
||||
// The estimate is not bounded after the delayed increase window.
|
||||
TEST_P(LossBasedBweV2Test, KeepIncreasingEstimateAfterDelayedIncreaseWindow) {
|
||||
std::vector<PacketResult> enough_feedback_1 =
|
||||
CreatePacketResultsWithReceivedPackets(
|
||||
/*first_packet_timestamp=*/Timestamp::Zero());
|
||||
std::vector<PacketResult> enough_feedback_2 =
|
||||
CreatePacketResultsWithReceivedPackets(
|
||||
/*first_packet_timestamp=*/Timestamp::Zero() +
|
||||
kDelayedIncreaseWindow - TimeDelta::Millis(1));
|
||||
std::vector<PacketResult> enough_feedback_3 =
|
||||
CreatePacketResultsWithReceivedPackets(
|
||||
/*first_packet_timestamp=*/Timestamp::Zero() +
|
||||
kDelayedIncreaseWindow + TimeDelta::Millis(1));
|
||||
ExplicitKeyValueConfig key_value_config(
|
||||
Config(/*enabled=*/true, /*valid=*/true,
|
||||
/*trendline_integration_enabled=*/GetParam()));
|
||||
LossBasedBweV2 loss_based_bandwidth_estimator(&key_value_config);
|
||||
DataRate delay_based_estimate = DataRate::KilobitsPerSec(5000);
|
||||
|
||||
loss_based_bandwidth_estimator.SetBandwidthEstimate(
|
||||
DataRate::KilobitsPerSec(600));
|
||||
loss_based_bandwidth_estimator.SetAcknowledgedBitrate(
|
||||
DataRate::KilobitsPerSec(300));
|
||||
loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
|
||||
enough_feedback_1, delay_based_estimate, BandwidthUsage::kBwNormal);
|
||||
// Increase the acknowledged bitrate to make sure that the estimate is not
|
||||
// capped too low.
|
||||
loss_based_bandwidth_estimator.SetAcknowledgedBitrate(
|
||||
DataRate::KilobitsPerSec(5000));
|
||||
loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
|
||||
enough_feedback_2, delay_based_estimate, BandwidthUsage::kBwNormal);
|
||||
|
||||
// The estimate is capped by current_estimate * kMaxIncreaseFactor because it
|
||||
// recently backed off.
|
||||
DataRate estimate_2 =
|
||||
loss_based_bandwidth_estimator.GetBandwidthEstimate(delay_based_estimate);
|
||||
|
||||
loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
|
||||
enough_feedback_3, delay_based_estimate, BandwidthUsage::kBwNormal);
|
||||
// The estimate can continue increasing after the DelayedIncreaseWindow.
|
||||
EXPECT_GE(
|
||||
loss_based_bandwidth_estimator.GetBandwidthEstimate(delay_based_estimate),
|
||||
estimate_2);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(LossBasedBweV2Tests,
|
||||
LossBasedBweV2Test,
|
||||
::testing::Bool());
|
||||
|
||||
} // namespace
|
||||
} // namespace webrtc
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user