xref: /aosp_15_r20/external/webrtc/modules/congestion_controller/goog_cc/loss_based_bwe_v2_test.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1 /*
2  *  Copyright 2021 The WebRTC project authors. All rights reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #include "modules/congestion_controller/goog_cc/loss_based_bwe_v2.h"
12 
13 #include <string>
14 #include <vector>
15 
16 #include "api/network_state_predictor.h"
17 #include "api/transport/network_types.h"
18 #include "api/units/data_rate.h"
19 #include "api/units/data_size.h"
20 #include "api/units/time_delta.h"
21 #include "api/units/timestamp.h"
22 #include "rtc_base/strings/string_builder.h"
23 #include "test/explicit_key_value_config.h"
24 #include "test/gtest.h"
25 
26 namespace webrtc {
27 
28 namespace {
29 
30 using ::webrtc::test::ExplicitKeyValueConfig;
31 
32 constexpr TimeDelta kObservationDurationLowerBound = TimeDelta::Millis(200);
33 constexpr TimeDelta kDelayedIncreaseWindow = TimeDelta::Millis(300);
34 constexpr double kMaxIncreaseFactor = 1.5;
35 
36 class LossBasedBweV2Test : public ::testing::TestWithParam<bool> {
37  protected:
Config(bool enabled,bool valid,bool trendline_integration_enabled)38   std::string Config(bool enabled,
39                      bool valid,
40                      bool trendline_integration_enabled) {
41     char buffer[1024];
42     rtc::SimpleStringBuilder config_string(buffer);
43 
44     config_string << "WebRTC-Bwe-LossBasedBweV2/";
45 
46     if (enabled) {
47       config_string << "Enabled:true";
48     } else {
49       config_string << "Enabled:false";
50     }
51 
52     if (valid) {
53       config_string << ",BwRampupUpperBoundFactor:1.2";
54     } else {
55       config_string << ",BwRampupUpperBoundFactor:0.0";
56     }
57 
58     if (trendline_integration_enabled) {
59       config_string << ",TrendlineIntegrationEnabled:true";
60     } else {
61       config_string << ",TrendlineIntegrationEnabled:false";
62     }
63 
64     config_string
65         << ",CandidateFactors:1.1|1.0|0.95,HigherBwBiasFactor:0.01,"
66            "DelayBasedCandidate:true,"
67            "InherentLossLowerBound:0.001,InherentLossUpperBoundBwBalance:"
68            "14kbps,"
69            "InherentLossUpperBoundOffset:0.9,InitialInherentLossEstimate:0.01,"
70            "NewtonIterations:2,NewtonStepSize:0.4,ObservationWindowSize:15,"
71            "SendingRateSmoothingFactor:0.01,"
72            "InstantUpperBoundTemporalWeightFactor:0.97,"
73            "InstantUpperBoundBwBalance:90kbps,"
74            "InstantUpperBoundLossOffset:0.1,TemporalWeightFactor:0.98";
75 
76     config_string.AppendFormat(
77         ",ObservationDurationLowerBound:%dms",
78         static_cast<int>(kObservationDurationLowerBound.ms()));
79     config_string.AppendFormat(",MaxIncreaseFactor:%f", kMaxIncreaseFactor);
80     config_string.AppendFormat(",DelayedIncreaseWindow:%dms",
81                                static_cast<int>(kDelayedIncreaseWindow.ms()));
82 
83     config_string << "/";
84 
85     return config_string.str();
86   }
87 
CreatePacketResultsWithReceivedPackets(Timestamp first_packet_timestamp)88   std::vector<PacketResult> CreatePacketResultsWithReceivedPackets(
89       Timestamp first_packet_timestamp) {
90     std::vector<PacketResult> enough_feedback(2);
91     enough_feedback[0].sent_packet.size = DataSize::Bytes(15'000);
92     enough_feedback[1].sent_packet.size = DataSize::Bytes(15'000);
93     enough_feedback[0].sent_packet.send_time = first_packet_timestamp;
94     enough_feedback[1].sent_packet.send_time =
95         first_packet_timestamp + kObservationDurationLowerBound;
96     enough_feedback[0].receive_time =
97         first_packet_timestamp + kObservationDurationLowerBound;
98     enough_feedback[1].receive_time =
99         first_packet_timestamp + 2 * kObservationDurationLowerBound;
100     return enough_feedback;
101   }
102 
CreatePacketResultsWith10pLossRate(Timestamp first_packet_timestamp)103   std::vector<PacketResult> CreatePacketResultsWith10pLossRate(
104       Timestamp first_packet_timestamp) {
105     std::vector<PacketResult> enough_feedback(10);
106     enough_feedback[0].sent_packet.size = DataSize::Bytes(15'000);
107     for (unsigned i = 0; i < enough_feedback.size(); ++i) {
108       enough_feedback[i].sent_packet.size = DataSize::Bytes(15'000);
109       enough_feedback[i].sent_packet.send_time =
110           first_packet_timestamp +
111           static_cast<int>(i) * kObservationDurationLowerBound;
112       enough_feedback[i].receive_time =
113           first_packet_timestamp +
114           static_cast<int>(i + 1) * kObservationDurationLowerBound;
115     }
116     enough_feedback[9].receive_time = Timestamp::PlusInfinity();
117     return enough_feedback;
118   }
119 
CreatePacketResultsWith50pLossRate(Timestamp first_packet_timestamp)120   std::vector<PacketResult> CreatePacketResultsWith50pLossRate(
121       Timestamp first_packet_timestamp) {
122     std::vector<PacketResult> enough_feedback(2);
123     enough_feedback[0].sent_packet.size = DataSize::Bytes(15'000);
124     enough_feedback[1].sent_packet.size = DataSize::Bytes(15'000);
125     enough_feedback[0].sent_packet.send_time = first_packet_timestamp;
126     enough_feedback[1].sent_packet.send_time =
127         first_packet_timestamp + kObservationDurationLowerBound;
128     enough_feedback[0].receive_time =
129         first_packet_timestamp + kObservationDurationLowerBound;
130     enough_feedback[1].receive_time = Timestamp::PlusInfinity();
131     return enough_feedback;
132   }
133 
CreatePacketResultsWith100pLossRate(Timestamp first_packet_timestamp)134   std::vector<PacketResult> CreatePacketResultsWith100pLossRate(
135       Timestamp first_packet_timestamp) {
136     std::vector<PacketResult> enough_feedback(2);
137     enough_feedback[0].sent_packet.size = DataSize::Bytes(15'000);
138     enough_feedback[1].sent_packet.size = DataSize::Bytes(15'000);
139     enough_feedback[0].sent_packet.send_time = first_packet_timestamp;
140     enough_feedback[1].sent_packet.send_time =
141         first_packet_timestamp + kObservationDurationLowerBound;
142     enough_feedback[0].receive_time = Timestamp::PlusInfinity();
143     enough_feedback[1].receive_time = Timestamp::PlusInfinity();
144     return enough_feedback;
145   }
146 };
147 
TEST_P(LossBasedBweV2Test,EnabledWhenGivenValidConfigurationValues)148 TEST_P(LossBasedBweV2Test, EnabledWhenGivenValidConfigurationValues) {
149   ExplicitKeyValueConfig key_value_config(
150       Config(/*enabled=*/true, /*valid=*/true,
151              /*trendline_integration_enabled=*/GetParam()));
152   LossBasedBweV2 loss_based_bandwidth_estimator(&key_value_config);
153 
154   EXPECT_TRUE(loss_based_bandwidth_estimator.IsEnabled());
155 }
156 
TEST_P(LossBasedBweV2Test,DisabledWhenGivenDisabledConfiguration)157 TEST_P(LossBasedBweV2Test, DisabledWhenGivenDisabledConfiguration) {
158   ExplicitKeyValueConfig key_value_config(
159       Config(/*enabled=*/false, /*valid=*/true,
160              /*trendline_integration_enabled=*/GetParam()));
161   LossBasedBweV2 loss_based_bandwidth_estimator(&key_value_config);
162 
163   EXPECT_FALSE(loss_based_bandwidth_estimator.IsEnabled());
164 }
165 
TEST_P(LossBasedBweV2Test,DisabledWhenGivenNonValidConfigurationValues)166 TEST_P(LossBasedBweV2Test, DisabledWhenGivenNonValidConfigurationValues) {
167   ExplicitKeyValueConfig key_value_config(
168       Config(/*enabled=*/true, /*valid=*/false,
169              /*trendline_integration_enabled=*/GetParam()));
170   LossBasedBweV2 loss_based_bandwidth_estimator(&key_value_config);
171 
172   EXPECT_FALSE(loss_based_bandwidth_estimator.IsEnabled());
173 }
174 
TEST_P(LossBasedBweV2Test,DisabledWhenGivenNonPositiveCandidateFactor)175 TEST_P(LossBasedBweV2Test, DisabledWhenGivenNonPositiveCandidateFactor) {
176   ExplicitKeyValueConfig key_value_config_negative_candidate_factor(
177       "WebRTC-Bwe-LossBasedBweV2/Enabled:true,CandidateFactors:-1.3|1.1/");
178   LossBasedBweV2 loss_based_bandwidth_estimator_1(
179       &key_value_config_negative_candidate_factor);
180   EXPECT_FALSE(loss_based_bandwidth_estimator_1.IsEnabled());
181 
182   ExplicitKeyValueConfig key_value_config_zero_candidate_factor(
183       "WebRTC-Bwe-LossBasedBweV2/Enabled:true,CandidateFactors:0.0|1.1/");
184   LossBasedBweV2 loss_based_bandwidth_estimator_2(
185       &key_value_config_zero_candidate_factor);
186   EXPECT_FALSE(loss_based_bandwidth_estimator_2.IsEnabled());
187 }
188 
TEST_P(LossBasedBweV2Test,DisabledWhenGivenConfigurationThatDoesNotAllowGeneratingCandidates)189 TEST_P(LossBasedBweV2Test,
190        DisabledWhenGivenConfigurationThatDoesNotAllowGeneratingCandidates) {
191   ExplicitKeyValueConfig key_value_config(
192       "WebRTC-Bwe-LossBasedBweV2/"
193       "Enabled:true,CandidateFactors:1.0,AckedRateCandidate:false,"
194       "DelayBasedCandidate:false/");
195   LossBasedBweV2 loss_based_bandwidth_estimator(&key_value_config);
196   EXPECT_FALSE(loss_based_bandwidth_estimator.IsEnabled());
197 }
198 
TEST_P(LossBasedBweV2Test,ReturnsDelayBasedEstimateWhenDisabled)199 TEST_P(LossBasedBweV2Test, ReturnsDelayBasedEstimateWhenDisabled) {
200   ExplicitKeyValueConfig key_value_config(
201       Config(/*enabled=*/false, /*valid=*/true,
202              /*trendline_integration_enabled=*/GetParam()));
203   LossBasedBweV2 loss_based_bandwidth_estimator(&key_value_config);
204   loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
205       /*packet_results=*/{},
206       /*delay_based_estimate=*/DataRate::KilobitsPerSec(100),
207       BandwidthUsage::kBwNormal,
208       /*probe_estimate=*/absl::nullopt,
209       /*upper_link_capacity=*/DataRate::PlusInfinity());
210   EXPECT_EQ(
211       loss_based_bandwidth_estimator.GetLossBasedResult().bandwidth_estimate,
212       DataRate::KilobitsPerSec(100));
213 }
214 
TEST_P(LossBasedBweV2Test,ReturnsDelayBasedEstimateWhenWhenGivenNonValidConfigurationValues)215 TEST_P(LossBasedBweV2Test,
216        ReturnsDelayBasedEstimateWhenWhenGivenNonValidConfigurationValues) {
217   ExplicitKeyValueConfig key_value_config(
218       Config(/*enabled=*/true, /*valid=*/false,
219              /*trendline_integration_enabled=*/GetParam()));
220   LossBasedBweV2 loss_based_bandwidth_estimator(&key_value_config);
221   loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
222       /*packet_results=*/{},
223       /*delay_based_estimate=*/DataRate::KilobitsPerSec(100),
224       BandwidthUsage::kBwNormal,
225       /*probe_estimate=*/absl::nullopt,
226       /*upper_link_capacity=*/DataRate::PlusInfinity());
227   EXPECT_EQ(
228       loss_based_bandwidth_estimator.GetLossBasedResult().bandwidth_estimate,
229       DataRate::KilobitsPerSec(100));
230 }
231 
TEST_P(LossBasedBweV2Test,BandwidthEstimateGivenInitializationAndThenFeedback)232 TEST_P(LossBasedBweV2Test,
233        BandwidthEstimateGivenInitializationAndThenFeedback) {
234   std::vector<PacketResult> enough_feedback =
235       CreatePacketResultsWithReceivedPackets(
236           /*first_packet_timestamp=*/Timestamp::Zero());
237 
238   ExplicitKeyValueConfig key_value_config(
239       Config(/*enabled=*/true, /*valid=*/true,
240              /*trendline_integration_enabled=*/GetParam()));
241   LossBasedBweV2 loss_based_bandwidth_estimator(&key_value_config);
242 
243   loss_based_bandwidth_estimator.SetBandwidthEstimate(
244       DataRate::KilobitsPerSec(600));
245   loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
246       enough_feedback, /*delay_based_estimate=*/DataRate::PlusInfinity(),
247       BandwidthUsage::kBwNormal,
248       /*probe_estimate=*/absl::nullopt,
249       /*upper_link_capacity=*/DataRate::PlusInfinity());
250 
251   EXPECT_TRUE(loss_based_bandwidth_estimator.IsReady());
252   EXPECT_TRUE(loss_based_bandwidth_estimator.GetLossBasedResult()
253                   .bandwidth_estimate.IsFinite());
254 }
255 
TEST_P(LossBasedBweV2Test,NoBandwidthEstimateGivenNoInitialization)256 TEST_P(LossBasedBweV2Test, NoBandwidthEstimateGivenNoInitialization) {
257   std::vector<PacketResult> enough_feedback =
258       CreatePacketResultsWithReceivedPackets(
259           /*first_packet_timestamp=*/Timestamp::Zero());
260   ExplicitKeyValueConfig key_value_config(
261       Config(/*enabled=*/true, /*valid=*/true,
262              /*trendline_integration_enabled=*/GetParam()));
263   LossBasedBweV2 loss_based_bandwidth_estimator(&key_value_config);
264 
265   loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
266       enough_feedback, /*delay_based_estimate=*/DataRate::PlusInfinity(),
267       BandwidthUsage::kBwNormal,
268       /*probe_estimate=*/absl::nullopt,
269       /*upper_link_capacity=*/DataRate::PlusInfinity());
270 
271   EXPECT_FALSE(loss_based_bandwidth_estimator.IsReady());
272   EXPECT_TRUE(loss_based_bandwidth_estimator.GetLossBasedResult()
273                   .bandwidth_estimate.IsPlusInfinity());
274 }
275 
TEST_P(LossBasedBweV2Test,NoBandwidthEstimateGivenNotEnoughFeedback)276 TEST_P(LossBasedBweV2Test, NoBandwidthEstimateGivenNotEnoughFeedback) {
277   // Create packet results where the observation duration is less than the lower
278   // bound.
279   PacketResult not_enough_feedback[2];
280   not_enough_feedback[0].sent_packet.size = DataSize::Bytes(15'000);
281   not_enough_feedback[1].sent_packet.size = DataSize::Bytes(15'000);
282   not_enough_feedback[0].sent_packet.send_time = Timestamp::Zero();
283   not_enough_feedback[1].sent_packet.send_time =
284       Timestamp::Zero() + kObservationDurationLowerBound / 2;
285   not_enough_feedback[0].receive_time =
286       Timestamp::Zero() + kObservationDurationLowerBound / 2;
287   not_enough_feedback[1].receive_time =
288       Timestamp::Zero() + kObservationDurationLowerBound;
289 
290   ExplicitKeyValueConfig key_value_config(
291       Config(/*enabled=*/true, /*valid=*/true,
292              /*trendline_integration_enabled=*/GetParam()));
293   LossBasedBweV2 loss_based_bandwidth_estimator(&key_value_config);
294 
295   loss_based_bandwidth_estimator.SetBandwidthEstimate(
296       DataRate::KilobitsPerSec(600));
297 
298   EXPECT_FALSE(loss_based_bandwidth_estimator.IsReady());
299   EXPECT_TRUE(loss_based_bandwidth_estimator.GetLossBasedResult()
300                   .bandwidth_estimate.IsPlusInfinity());
301 
302   loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
303       not_enough_feedback, /*delay_based_estimate=*/DataRate::PlusInfinity(),
304       BandwidthUsage::kBwNormal,
305       /*probe_estimate=*/absl::nullopt,
306       /*upper_link_capacity=*/DataRate::PlusInfinity());
307 
308   EXPECT_FALSE(loss_based_bandwidth_estimator.IsReady());
309   EXPECT_TRUE(loss_based_bandwidth_estimator.GetLossBasedResult()
310                   .bandwidth_estimate.IsPlusInfinity());
311 }
312 
TEST_P(LossBasedBweV2Test,SetValueIsTheEstimateUntilAdditionalFeedbackHasBeenReceived)313 TEST_P(LossBasedBweV2Test,
314        SetValueIsTheEstimateUntilAdditionalFeedbackHasBeenReceived) {
315   std::vector<PacketResult> enough_feedback_1 =
316       CreatePacketResultsWithReceivedPackets(
317           /*first_packet_timestamp=*/Timestamp::Zero());
318   std::vector<PacketResult> enough_feedback_2 =
319       CreatePacketResultsWithReceivedPackets(
320           /*first_packet_timestamp=*/Timestamp::Zero() +
321           2 * kObservationDurationLowerBound);
322 
323   ExplicitKeyValueConfig key_value_config(
324       Config(/*enabled=*/true, /*valid=*/true,
325              /*trendline_integration_enabled=*/GetParam()));
326   LossBasedBweV2 loss_based_bandwidth_estimator(&key_value_config);
327 
328   loss_based_bandwidth_estimator.SetBandwidthEstimate(
329       DataRate::KilobitsPerSec(600));
330   loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
331       enough_feedback_1, /*delay_based_estimate=*/DataRate::PlusInfinity(),
332       BandwidthUsage::kBwNormal,
333       /*probe_estimate=*/absl::nullopt,
334       /*upper_link_capacity=*/DataRate::PlusInfinity());
335 
336   EXPECT_NE(
337       loss_based_bandwidth_estimator.GetLossBasedResult().bandwidth_estimate,
338       DataRate::KilobitsPerSec(600));
339 
340   loss_based_bandwidth_estimator.SetBandwidthEstimate(
341       DataRate::KilobitsPerSec(600));
342 
343   EXPECT_EQ(
344       loss_based_bandwidth_estimator.GetLossBasedResult().bandwidth_estimate,
345       DataRate::KilobitsPerSec(600));
346 
347   loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
348       enough_feedback_2, /*delay_based_estimate=*/DataRate::PlusInfinity(),
349       BandwidthUsage::kBwNormal,
350       /*probe_estimate=*/absl::nullopt,
351       /*upper_link_capacity=*/DataRate::PlusInfinity());
352 
353   EXPECT_NE(
354       loss_based_bandwidth_estimator.GetLossBasedResult().bandwidth_estimate,
355       DataRate::KilobitsPerSec(600));
356 }
357 
TEST_P(LossBasedBweV2Test,SetAcknowledgedBitrateOnlyAffectsTheBweWhenAdditionalFeedbackIsGiven)358 TEST_P(LossBasedBweV2Test,
359        SetAcknowledgedBitrateOnlyAffectsTheBweWhenAdditionalFeedbackIsGiven) {
360   std::vector<PacketResult> enough_feedback_1 =
361       CreatePacketResultsWithReceivedPackets(
362           /*first_packet_timestamp=*/Timestamp::Zero());
363   std::vector<PacketResult> enough_feedback_2 =
364       CreatePacketResultsWithReceivedPackets(
365           /*first_packet_timestamp=*/Timestamp::Zero() +
366           2 * kObservationDurationLowerBound);
367 
368   ExplicitKeyValueConfig key_value_config(
369       Config(/*enabled=*/true, /*valid=*/true,
370              /*trendline_integration_enabled=*/GetParam()));
371   LossBasedBweV2 loss_based_bandwidth_estimator_1(&key_value_config);
372   LossBasedBweV2 loss_based_bandwidth_estimator_2(&key_value_config);
373 
374   loss_based_bandwidth_estimator_1.SetBandwidthEstimate(
375       DataRate::KilobitsPerSec(600));
376   loss_based_bandwidth_estimator_2.SetBandwidthEstimate(
377       DataRate::KilobitsPerSec(600));
378   loss_based_bandwidth_estimator_1.UpdateBandwidthEstimate(
379       enough_feedback_1, /*delay_based_estimate=*/DataRate::PlusInfinity(),
380       BandwidthUsage::kBwNormal,
381       /*probe_estimate=*/absl::nullopt,
382       /*upper_link_capacity=*/DataRate::PlusInfinity());
383   loss_based_bandwidth_estimator_2.UpdateBandwidthEstimate(
384       enough_feedback_1, /*delay_based_estimate=*/DataRate::PlusInfinity(),
385       BandwidthUsage::kBwNormal,
386       /*probe_estimate=*/absl::nullopt,
387       /*upper_link_capacity=*/DataRate::PlusInfinity());
388 
389   EXPECT_EQ(
390       loss_based_bandwidth_estimator_1.GetLossBasedResult().bandwidth_estimate,
391       DataRate::KilobitsPerSec(660));
392 
393   loss_based_bandwidth_estimator_1.SetAcknowledgedBitrate(
394       DataRate::KilobitsPerSec(900));
395 
396   EXPECT_EQ(
397       loss_based_bandwidth_estimator_1.GetLossBasedResult().bandwidth_estimate,
398       DataRate::KilobitsPerSec(660));
399 
400   loss_based_bandwidth_estimator_1.UpdateBandwidthEstimate(
401       enough_feedback_2, /*delay_based_estimate=*/DataRate::PlusInfinity(),
402       BandwidthUsage::kBwNormal,
403       /*probe_estimate=*/absl::nullopt,
404       /*upper_link_capacity=*/DataRate::PlusInfinity());
405   loss_based_bandwidth_estimator_2.UpdateBandwidthEstimate(
406       enough_feedback_2, /*delay_based_estimate=*/DataRate::PlusInfinity(),
407       BandwidthUsage::kBwNormal,
408       /*probe_estimate=*/absl::nullopt,
409       /*upper_link_capacity=*/DataRate::PlusInfinity());
410 
411   EXPECT_NE(
412       loss_based_bandwidth_estimator_1.GetLossBasedResult().bandwidth_estimate,
413       loss_based_bandwidth_estimator_2.GetLossBasedResult().bandwidth_estimate);
414 }
415 
TEST_P(LossBasedBweV2Test,BandwidthEstimateIsCappedToBeTcpFairGivenTooHighLossRate)416 TEST_P(LossBasedBweV2Test,
417        BandwidthEstimateIsCappedToBeTcpFairGivenTooHighLossRate) {
418   std::vector<PacketResult> enough_feedback_no_received_packets =
419       CreatePacketResultsWith100pLossRate(
420           /*first_packet_timestamp=*/Timestamp::Zero());
421 
422   ExplicitKeyValueConfig key_value_config(
423       Config(/*enabled=*/true, /*valid=*/true,
424              /*trendline_integration_enabled=*/GetParam()));
425   LossBasedBweV2 loss_based_bandwidth_estimator(&key_value_config);
426 
427   loss_based_bandwidth_estimator.SetBandwidthEstimate(
428       DataRate::KilobitsPerSec(600));
429   loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
430       enough_feedback_no_received_packets,
431       /*delay_based_estimate=*/DataRate::PlusInfinity(),
432       BandwidthUsage::kBwNormal, /*probe_estimate=*/absl::nullopt,
433       /*upper_link_capacity=*/DataRate::PlusInfinity());
434 
435   EXPECT_EQ(
436       loss_based_bandwidth_estimator.GetLossBasedResult().bandwidth_estimate,
437       DataRate::KilobitsPerSec(100));
438 }
439 
TEST_P(LossBasedBweV2Test,BandwidthEstimateNotIncreaseWhenNetworkUnderusing)440 TEST_P(LossBasedBweV2Test, BandwidthEstimateNotIncreaseWhenNetworkUnderusing) {
441   if (!GetParam()) {
442     GTEST_SKIP() << "This test should run only if "
443                     "trendline_integration_enabled is enabled";
444   }
445   std::vector<PacketResult> enough_feedback_1 =
446       CreatePacketResultsWithReceivedPackets(
447           /*first_packet_timestamp=*/Timestamp::Zero());
448   std::vector<PacketResult> enough_feedback_2 =
449       CreatePacketResultsWithReceivedPackets(
450           /*first_packet_timestamp=*/Timestamp::Zero() +
451           2 * kObservationDurationLowerBound);
452 
453   ExplicitKeyValueConfig key_value_config(
454       Config(/*enabled=*/true, /*valid=*/true,
455              /*trendline_integration_enabled=*/GetParam()));
456   LossBasedBweV2 loss_based_bandwidth_estimator(&key_value_config);
457 
458   loss_based_bandwidth_estimator.SetBandwidthEstimate(
459       DataRate::KilobitsPerSec(600));
460   loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
461       enough_feedback_1, /*delay_based_estimate=*/DataRate::PlusInfinity(),
462       BandwidthUsage::kBwUnderusing, /*probe_estimate=*/absl::nullopt,
463       /*upper_link_capacity=*/DataRate::PlusInfinity());
464   EXPECT_LE(
465       loss_based_bandwidth_estimator.GetLossBasedResult().bandwidth_estimate,
466       DataRate::KilobitsPerSec(600));
467   loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
468       enough_feedback_2, /*delay_based_estimate=*/DataRate::PlusInfinity(),
469       BandwidthUsage::kBwNormal,
470       /*probe_estimate=*/absl::nullopt,
471       /*upper_link_capacity=*/DataRate::PlusInfinity());
472   EXPECT_LE(
473       loss_based_bandwidth_estimator.GetLossBasedResult().bandwidth_estimate,
474       DataRate::KilobitsPerSec(600));
475 }
476 
477 // When network is normal, estimate can increase but never be higher than
478 // the delay based estimate.
TEST_P(LossBasedBweV2Test,BandwidthEstimateCappedByDelayBasedEstimateWhenNetworkNormal)479 TEST_P(LossBasedBweV2Test,
480        BandwidthEstimateCappedByDelayBasedEstimateWhenNetworkNormal) {
481   // Create two packet results, network is in normal state, 100% packets are
482   // received, and no delay increase.
483   std::vector<PacketResult> enough_feedback_1 =
484       CreatePacketResultsWithReceivedPackets(
485           /*first_packet_timestamp=*/Timestamp::Zero());
486   std::vector<PacketResult> enough_feedback_2 =
487       CreatePacketResultsWithReceivedPackets(
488           /*first_packet_timestamp=*/Timestamp::Zero() +
489           2 * kObservationDurationLowerBound);
490   ExplicitKeyValueConfig key_value_config(
491       Config(/*enabled=*/true, /*valid=*/true,
492              /*trendline_integration_enabled=*/GetParam()));
493   LossBasedBweV2 loss_based_bandwidth_estimator(&key_value_config);
494 
495   loss_based_bandwidth_estimator.SetBandwidthEstimate(
496       DataRate::KilobitsPerSec(600));
497   loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
498       enough_feedback_1, /*delay_based_estimate=*/DataRate::PlusInfinity(),
499       BandwidthUsage::kBwNormal,
500       /*probe_estimate=*/absl::nullopt,
501       /*upper_link_capacity=*/DataRate::PlusInfinity());
502   // If the delay based estimate is infinity, then loss based estimate increases
503   // and not bounded by delay based estimate.
504   EXPECT_GT(
505       loss_based_bandwidth_estimator.GetLossBasedResult().bandwidth_estimate,
506       DataRate::KilobitsPerSec(600));
507   loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
508       enough_feedback_2, /*delay_based_estimate=*/DataRate::KilobitsPerSec(500),
509       BandwidthUsage::kBwNormal,
510       /*probe_estimate=*/absl::nullopt,
511       /*upper_link_capacity=*/DataRate::PlusInfinity());
512   // If the delay based estimate is not infinity, then loss based estimate is
513   // bounded by delay based estimate.
514   EXPECT_EQ(
515       loss_based_bandwidth_estimator.GetLossBasedResult().bandwidth_estimate,
516       DataRate::KilobitsPerSec(500));
517 }
518 
519 // When loss based bwe receives a strong signal of overusing and an increase in
520 // loss rate, it should acked bitrate for emegency backoff.
TEST_P(LossBasedBweV2Test,UseAckedBitrateForEmegencyBackOff)521 TEST_P(LossBasedBweV2Test, UseAckedBitrateForEmegencyBackOff) {
522   // Create two packet results, first packet has 50% loss rate, second packet
523   // has 100% loss rate.
524   std::vector<PacketResult> enough_feedback_1 =
525       CreatePacketResultsWith50pLossRate(
526           /*first_packet_timestamp=*/Timestamp::Zero());
527   std::vector<PacketResult> enough_feedback_2 =
528       CreatePacketResultsWith100pLossRate(
529           /*first_packet_timestamp=*/Timestamp::Zero() +
530           2 * kObservationDurationLowerBound);
531 
532   ExplicitKeyValueConfig key_value_config(
533       Config(/*enabled=*/true, /*valid=*/true,
534              /*trendline_integration_enabled=*/GetParam()));
535   LossBasedBweV2 loss_based_bandwidth_estimator(&key_value_config);
536 
537   loss_based_bandwidth_estimator.SetBandwidthEstimate(
538       DataRate::KilobitsPerSec(600));
539   DataRate acked_bitrate = DataRate::KilobitsPerSec(300);
540   loss_based_bandwidth_estimator.SetAcknowledgedBitrate(acked_bitrate);
541   // Update estimate when network is overusing, and 50% loss rate.
542   loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
543       enough_feedback_1, /*delay_based_estimate=*/DataRate::PlusInfinity(),
544       BandwidthUsage::kBwOverusing,
545       /*probe_estimate=*/absl::nullopt,
546       /*upper_link_capacity=*/DataRate::PlusInfinity());
547   // Update estimate again when network is continuously overusing, and 100%
548   // loss rate.
549   loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
550       enough_feedback_2, /*delay_based_estimate=*/DataRate::PlusInfinity(),
551       BandwidthUsage::kBwOverusing,
552       /*probe_estimate=*/absl::nullopt,
553       /*upper_link_capacity=*/DataRate::PlusInfinity());
554   // The estimate bitrate now is backed off based on acked bitrate.
555   EXPECT_LE(
556       loss_based_bandwidth_estimator.GetLossBasedResult().bandwidth_estimate,
557       acked_bitrate);
558 }
559 
560 // When receiving the same packet feedback, loss based bwe ignores the feedback
561 // and returns the current estimate.
TEST_P(LossBasedBweV2Test,NoBweChangeIfObservationDurationUnchanged)562 TEST_P(LossBasedBweV2Test, NoBweChangeIfObservationDurationUnchanged) {
563   std::vector<PacketResult> enough_feedback_1 =
564       CreatePacketResultsWithReceivedPackets(
565           /*first_packet_timestamp=*/Timestamp::Zero());
566   ExplicitKeyValueConfig key_value_config(
567       Config(/*enabled=*/true, /*valid=*/true,
568              /*trendline_integration_enabled=*/GetParam()));
569   LossBasedBweV2 loss_based_bandwidth_estimator(&key_value_config);
570   loss_based_bandwidth_estimator.SetBandwidthEstimate(
571       DataRate::KilobitsPerSec(600));
572   loss_based_bandwidth_estimator.SetAcknowledgedBitrate(
573       DataRate::KilobitsPerSec(300));
574 
575   loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
576       enough_feedback_1, /*delay_based_estimate=*/DataRate::PlusInfinity(),
577       BandwidthUsage::kBwNormal,
578       /*probe_estimate=*/absl::nullopt,
579       /*upper_link_capacity=*/DataRate::PlusInfinity());
580   DataRate estimate_1 =
581       loss_based_bandwidth_estimator.GetLossBasedResult().bandwidth_estimate;
582 
583   // Use the same feedback and check if the estimate is unchanged.
584   loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
585       enough_feedback_1, /*delay_based_estimate=*/DataRate::PlusInfinity(),
586       BandwidthUsage::kBwNormal,
587       /*probe_estimate=*/absl::nullopt,
588       /*upper_link_capacity=*/DataRate::PlusInfinity());
589   DataRate estimate_2 =
590       loss_based_bandwidth_estimator.GetLossBasedResult().bandwidth_estimate;
591   EXPECT_EQ(estimate_2, estimate_1);
592 }
593 
594 // When receiving feedback of packets that were sent within an observation
595 // duration, and network is in the normal state, loss based bwe returns the
596 // current estimate.
TEST_P(LossBasedBweV2Test,NoBweChangeIfObservationDurationIsSmallAndNetworkNormal)597 TEST_P(LossBasedBweV2Test,
598        NoBweChangeIfObservationDurationIsSmallAndNetworkNormal) {
599   std::vector<PacketResult> enough_feedback_1 =
600       CreatePacketResultsWithReceivedPackets(
601           /*first_packet_timestamp=*/Timestamp::Zero());
602   std::vector<PacketResult> enough_feedback_2 =
603       CreatePacketResultsWithReceivedPackets(
604           /*first_packet_timestamp=*/Timestamp::Zero() +
605           kObservationDurationLowerBound - TimeDelta::Millis(1));
606   ExplicitKeyValueConfig key_value_config(
607       Config(/*enabled=*/true, /*valid=*/true,
608              /*trendline_integration_enabled=*/GetParam()));
609   LossBasedBweV2 loss_based_bandwidth_estimator(&key_value_config);
610   loss_based_bandwidth_estimator.SetBandwidthEstimate(
611       DataRate::KilobitsPerSec(600));
612   loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
613       enough_feedback_1, /*delay_based_estimate=*/DataRate::PlusInfinity(),
614       BandwidthUsage::kBwNormal,
615       /*probe_estimate=*/absl::nullopt,
616       /*upper_link_capacity=*/DataRate::PlusInfinity());
617   DataRate estimate_1 =
618       loss_based_bandwidth_estimator.GetLossBasedResult().bandwidth_estimate;
619 
620   loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
621       enough_feedback_2, /*delay_based_estimate=*/DataRate::PlusInfinity(),
622       BandwidthUsage::kBwNormal,
623       /*probe_estimate=*/absl::nullopt,
624       /*upper_link_capacity=*/DataRate::PlusInfinity());
625   DataRate estimate_2 =
626       loss_based_bandwidth_estimator.GetLossBasedResult().bandwidth_estimate;
627   EXPECT_EQ(estimate_2, estimate_1);
628 }
629 
630 // When receiving feedback of packets that were sent within an observation
631 // duration, and network is in the underusing state, loss based bwe returns the
632 // current estimate.
TEST_P(LossBasedBweV2Test,NoBweIncreaseIfObservationDurationIsSmallAndNetworkUnderusing)633 TEST_P(LossBasedBweV2Test,
634        NoBweIncreaseIfObservationDurationIsSmallAndNetworkUnderusing) {
635   std::vector<PacketResult> enough_feedback_1 =
636       CreatePacketResultsWithReceivedPackets(
637           /*first_packet_timestamp=*/Timestamp::Zero());
638   std::vector<PacketResult> enough_feedback_2 =
639       CreatePacketResultsWithReceivedPackets(
640           /*first_packet_timestamp=*/Timestamp::Zero() +
641           kObservationDurationLowerBound - TimeDelta::Millis(1));
642   ExplicitKeyValueConfig key_value_config(
643       Config(/*enabled=*/true, /*valid=*/true,
644              /*trendline_integration_enabled=*/GetParam()));
645   LossBasedBweV2 loss_based_bandwidth_estimator(&key_value_config);
646   loss_based_bandwidth_estimator.SetBandwidthEstimate(
647       DataRate::KilobitsPerSec(600));
648   loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
649       enough_feedback_1, /*delay_based_estimate=*/DataRate::PlusInfinity(),
650       BandwidthUsage::kBwNormal,
651       /*probe_estimate=*/absl::nullopt,
652       /*upper_link_capacity=*/DataRate::PlusInfinity());
653   DataRate estimate_1 =
654       loss_based_bandwidth_estimator.GetLossBasedResult().bandwidth_estimate;
655 
656   loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
657       enough_feedback_2, /*delay_based_estimate=*/DataRate::PlusInfinity(),
658       BandwidthUsage::kBwUnderusing, /*probe_estimate=*/absl::nullopt,
659       /*upper_link_capacity=*/DataRate::PlusInfinity());
660   DataRate estimate_2 =
661       loss_based_bandwidth_estimator.GetLossBasedResult().bandwidth_estimate;
662   EXPECT_LE(estimate_2, estimate_1);
663 }
664 
665 // When receiving feedback of packets that were sent within an observation
666 // duration, network is overusing, and trendline integration is enabled, loss
667 // based bwe updates its estimate.
TEST_P(LossBasedBweV2Test,UpdateEstimateIfObservationDurationIsSmallAndNetworkOverusing)668 TEST_P(LossBasedBweV2Test,
669        UpdateEstimateIfObservationDurationIsSmallAndNetworkOverusing) {
670   if (!GetParam()) {
671     GTEST_SKIP() << "This test should run only if "
672                     "trendline_integration_enabled is enabled";
673   }
674   std::vector<PacketResult> enough_feedback_1 =
675       CreatePacketResultsWith50pLossRate(
676           /*first_packet_timestamp=*/Timestamp::Zero());
677   std::vector<PacketResult> enough_feedback_2 =
678       CreatePacketResultsWith100pLossRate(
679           /*first_packet_timestamp=*/Timestamp::Zero() +
680           kObservationDurationLowerBound - TimeDelta::Millis(1));
681   ExplicitKeyValueConfig key_value_config(
682       Config(/*enabled=*/true, /*valid=*/true,
683              /*trendline_integration_enabled=*/GetParam()));
684   LossBasedBweV2 loss_based_bandwidth_estimator(&key_value_config);
685 
686   loss_based_bandwidth_estimator.SetBandwidthEstimate(
687       DataRate::KilobitsPerSec(600));
688   loss_based_bandwidth_estimator.SetAcknowledgedBitrate(
689       DataRate::KilobitsPerSec(300));
690   loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
691       enough_feedback_1, /*delay_based_estimate=*/DataRate::PlusInfinity(),
692       BandwidthUsage::kBwNormal,
693       /*probe_estimate=*/absl::nullopt,
694       /*upper_link_capacity=*/DataRate::PlusInfinity());
695   DataRate estimate_1 =
696       loss_based_bandwidth_estimator.GetLossBasedResult().bandwidth_estimate;
697 
698   loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
699       enough_feedback_2, /*delay_based_estimate=*/DataRate::PlusInfinity(),
700       BandwidthUsage::kBwOverusing,
701       /*probe_estimate=*/absl::nullopt,
702       /*upper_link_capacity=*/DataRate::PlusInfinity());
703   DataRate estimate_2 =
704       loss_based_bandwidth_estimator.GetLossBasedResult().bandwidth_estimate;
705   EXPECT_LT(estimate_2, estimate_1);
706 }
707 
TEST_P(LossBasedBweV2Test,IncreaseToDelayBasedEstimateIfNoLossOrDelayIncrease)708 TEST_P(LossBasedBweV2Test,
709        IncreaseToDelayBasedEstimateIfNoLossOrDelayIncrease) {
710   std::vector<PacketResult> enough_feedback_1 =
711       CreatePacketResultsWithReceivedPackets(
712           /*first_packet_timestamp=*/Timestamp::Zero());
713   std::vector<PacketResult> enough_feedback_2 =
714       CreatePacketResultsWithReceivedPackets(
715           /*first_packet_timestamp=*/Timestamp::Zero() +
716           2 * kObservationDurationLowerBound);
717   ExplicitKeyValueConfig key_value_config(
718       Config(/*enabled=*/true, /*valid=*/true,
719              /*trendline_integration_enabled=*/GetParam()));
720   LossBasedBweV2 loss_based_bandwidth_estimator(&key_value_config);
721   DataRate delay_based_estimate = DataRate::KilobitsPerSec(5000);
722   loss_based_bandwidth_estimator.SetBandwidthEstimate(
723       DataRate::KilobitsPerSec(600));
724 
725   loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
726       enough_feedback_1, delay_based_estimate, BandwidthUsage::kBwNormal,
727       /*probe_estimate=*/absl::nullopt,
728       /*upper_link_capacity=*/DataRate::PlusInfinity());
729   EXPECT_EQ(
730       loss_based_bandwidth_estimator.GetLossBasedResult().bandwidth_estimate,
731       delay_based_estimate);
732   loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
733       enough_feedback_2, delay_based_estimate, BandwidthUsage::kBwNormal,
734       /*probe_estimate=*/absl::nullopt,
735       /*upper_link_capacity=*/DataRate::PlusInfinity());
736   EXPECT_EQ(
737       loss_based_bandwidth_estimator.GetLossBasedResult().bandwidth_estimate,
738       delay_based_estimate);
739 }
740 
TEST_P(LossBasedBweV2Test,IncreaseByMaxIncreaseFactorAfterLossBasedBweBacksOff)741 TEST_P(LossBasedBweV2Test,
742        IncreaseByMaxIncreaseFactorAfterLossBasedBweBacksOff) {
743   ExplicitKeyValueConfig key_value_config(
744       "WebRTC-Bwe-LossBasedBweV2/"
745       "Enabled:true,CandidateFactors:1.2|1|0.5,AckedRateCandidate:true,"
746       "ObservationWindowSize:2,ObservationDurationLowerBound:200ms,"
747       "InstantUpperBoundBwBalance:10000kbps,"
748       "DelayBasedCandidate:true,MaxIncreaseFactor:1.5,BwRampupUpperBoundFactor:"
749       "2.0/");
750   LossBasedBweV2 loss_based_bandwidth_estimator(&key_value_config);
751   DataRate delay_based_estimate = DataRate::KilobitsPerSec(5000);
752   DataRate acked_rate = DataRate::KilobitsPerSec(300);
753   loss_based_bandwidth_estimator.SetBandwidthEstimate(
754       DataRate::KilobitsPerSec(600));
755   loss_based_bandwidth_estimator.SetAcknowledgedBitrate(acked_rate);
756 
757   // Create some loss to create the loss limited scenario.
758   std::vector<PacketResult> enough_feedback_1 =
759       CreatePacketResultsWith100pLossRate(
760           /*first_packet_timestamp=*/Timestamp::Zero());
761   loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
762       enough_feedback_1, delay_based_estimate, BandwidthUsage::kBwNormal,
763       /*probe_estimate=*/absl::nullopt,
764       /*upper_link_capacity=*/DataRate::PlusInfinity());
765   LossBasedBweV2::Result result_at_loss =
766       loss_based_bandwidth_estimator.GetLossBasedResult();
767 
768   // Network recovers after loss.
769   std::vector<PacketResult> enough_feedback_2 =
770       CreatePacketResultsWithReceivedPackets(
771           /*first_packet_timestamp=*/Timestamp::Zero() +
772           kObservationDurationLowerBound);
773   loss_based_bandwidth_estimator.SetAcknowledgedBitrate(
774       DataRate::KilobitsPerSec(600));
775   loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
776       enough_feedback_2, delay_based_estimate, BandwidthUsage::kBwNormal,
777       /*probe_estimate=*/absl::nullopt,
778       /*upper_link_capacity=*/DataRate::PlusInfinity());
779 
780   LossBasedBweV2::Result result_after_recovery =
781       loss_based_bandwidth_estimator.GetLossBasedResult();
782   EXPECT_EQ(result_after_recovery.bandwidth_estimate,
783             result_at_loss.bandwidth_estimate * 1.5);
784 }
785 
TEST_P(LossBasedBweV2Test,LossBasedStateIsDelayBasedEstimateAfterNetworkRecovering)786 TEST_P(LossBasedBweV2Test,
787        LossBasedStateIsDelayBasedEstimateAfterNetworkRecovering) {
788   ExplicitKeyValueConfig key_value_config(
789       "WebRTC-Bwe-LossBasedBweV2/"
790       "Enabled:true,CandidateFactors:100|1|0.5,AckedRateCandidate:true,"
791       "ObservationWindowSize:2,ObservationDurationLowerBound:200ms,"
792       "InstantUpperBoundBwBalance:10000kbps,"
793       "DelayBasedCandidate:true,MaxIncreaseFactor:100,"
794       "BwRampupUpperBoundFactor:"
795       "2.0/");
796   LossBasedBweV2 loss_based_bandwidth_estimator(&key_value_config);
797   DataRate delay_based_estimate = DataRate::KilobitsPerSec(600);
798   DataRate acked_rate = DataRate::KilobitsPerSec(300);
799   loss_based_bandwidth_estimator.SetBandwidthEstimate(
800       DataRate::KilobitsPerSec(600));
801   loss_based_bandwidth_estimator.SetAcknowledgedBitrate(acked_rate);
802 
803   // Create some loss to create the loss limited scenario.
804   std::vector<PacketResult> enough_feedback_1 =
805       CreatePacketResultsWith100pLossRate(
806           /*first_packet_timestamp=*/Timestamp::Zero());
807   loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
808       enough_feedback_1, delay_based_estimate, BandwidthUsage::kBwNormal,
809       /*probe_estimate=*/absl::nullopt,
810       /*upper_link_capacity=*/DataRate::PlusInfinity());
811   ASSERT_EQ(loss_based_bandwidth_estimator.GetLossBasedResult().state,
812             LossBasedState::kDecreasing);
813 
814   // Network recovers after loss.
815   std::vector<PacketResult> enough_feedback_2 =
816       CreatePacketResultsWithReceivedPackets(
817           /*first_packet_timestamp=*/Timestamp::Zero() +
818           kObservationDurationLowerBound);
819   loss_based_bandwidth_estimator.SetAcknowledgedBitrate(
820       DataRate::KilobitsPerSec(600));
821   loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
822       enough_feedback_2, delay_based_estimate, BandwidthUsage::kBwNormal,
823       /*probe_estimate=*/absl::nullopt,
824       /*upper_link_capacity=*/DataRate::PlusInfinity());
825   EXPECT_EQ(loss_based_bandwidth_estimator.GetLossBasedResult().state,
826             LossBasedState::kDelayBasedEstimate);
827 
828   // Network recovers continuing.
829   std::vector<PacketResult> enough_feedback_3 =
830       CreatePacketResultsWithReceivedPackets(
831           /*first_packet_timestamp=*/Timestamp::Zero() +
832           kObservationDurationLowerBound * 2);
833   loss_based_bandwidth_estimator.SetAcknowledgedBitrate(
834       DataRate::KilobitsPerSec(600));
835   loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
836       enough_feedback_3, delay_based_estimate, BandwidthUsage::kBwNormal,
837       /*probe_estimate=*/absl::nullopt,
838       /*upper_link_capacity=*/DataRate::PlusInfinity());
839   EXPECT_EQ(loss_based_bandwidth_estimator.GetLossBasedResult().state,
840             LossBasedState::kDelayBasedEstimate);
841 }
842 
TEST_P(LossBasedBweV2Test,LossBasedStateIsNotDelayBasedEstimateIfDelayBasedEsimtateInfinite)843 TEST_P(LossBasedBweV2Test,
844        LossBasedStateIsNotDelayBasedEstimateIfDelayBasedEsimtateInfinite) {
845   ExplicitKeyValueConfig key_value_config(
846       "WebRTC-Bwe-LossBasedBweV2/"
847       "Enabled:true,CandidateFactors:100|1|0.5,AckedRateCandidate:true,"
848       "ObservationWindowSize:2,ObservationDurationLowerBound:200ms,"
849       "InstantUpperBoundBwBalance:10000kbps,"
850       "DelayBasedCandidate:true,MaxIncreaseFactor:100,"
851       "BwRampupUpperBoundFactor:"
852       "2.0/");
853   LossBasedBweV2 loss_based_bandwidth_estimator(&key_value_config);
854   DataRate delay_based_estimate = DataRate::PlusInfinity();
855   DataRate acked_rate = DataRate::KilobitsPerSec(300);
856   loss_based_bandwidth_estimator.SetBandwidthEstimate(
857       DataRate::KilobitsPerSec(600));
858   loss_based_bandwidth_estimator.SetAcknowledgedBitrate(acked_rate);
859 
860   // Create some loss to create the loss limited scenario.
861   std::vector<PacketResult> enough_feedback_1 =
862       CreatePacketResultsWith100pLossRate(
863           /*first_packet_timestamp=*/Timestamp::Zero());
864   loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
865       enough_feedback_1, delay_based_estimate, BandwidthUsage::kBwNormal,
866       /*probe_estimate=*/absl::nullopt,
867       /*upper_link_capacity=*/DataRate::PlusInfinity());
868   ASSERT_EQ(loss_based_bandwidth_estimator.GetLossBasedResult().state,
869             LossBasedState::kDecreasing);
870 
871   // Network recovers after loss.
872   std::vector<PacketResult> enough_feedback_2 =
873       CreatePacketResultsWithReceivedPackets(
874           /*first_packet_timestamp=*/Timestamp::Zero() +
875           kObservationDurationLowerBound);
876   loss_based_bandwidth_estimator.SetAcknowledgedBitrate(
877       DataRate::KilobitsPerSec(600));
878   loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
879       enough_feedback_2, delay_based_estimate, BandwidthUsage::kBwNormal,
880       /*probe_estimate=*/absl::nullopt,
881       /*upper_link_capacity=*/DataRate::PlusInfinity());
882   EXPECT_EQ(loss_based_bandwidth_estimator.GetLossBasedResult().state,
883             LossBasedState::kIncreasing);
884 }
885 
886 // After loss based bwe backs off, the next estimate is capped by
887 // a factor of acked bitrate.
TEST_P(LossBasedBweV2Test,IncreaseByFactorOfAckedBitrateAfterLossBasedBweBacksOff)888 TEST_P(LossBasedBweV2Test,
889        IncreaseByFactorOfAckedBitrateAfterLossBasedBweBacksOff) {
890   std::vector<PacketResult> enough_feedback_1 =
891       CreatePacketResultsWith100pLossRate(
892           /*first_packet_timestamp=*/Timestamp::Zero());
893   std::vector<PacketResult> enough_feedback_2 =
894       CreatePacketResultsWith10pLossRate(
895           /*first_packet_timestamp=*/Timestamp::Zero() +
896           kObservationDurationLowerBound);
897   ExplicitKeyValueConfig key_value_config(
898       Config(/*enabled=*/true, /*valid=*/true,
899              /*trendline_integration_enabled=*/GetParam()));
900   LossBasedBweV2 loss_based_bandwidth_estimator(&key_value_config);
901   DataRate delay_based_estimate = DataRate::KilobitsPerSec(5000);
902 
903   loss_based_bandwidth_estimator.SetBandwidthEstimate(
904       DataRate::KilobitsPerSec(600));
905   loss_based_bandwidth_estimator.SetAcknowledgedBitrate(
906       DataRate::KilobitsPerSec(300));
907   loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
908       enough_feedback_1, delay_based_estimate, BandwidthUsage::kBwNormal,
909       /*probe_estimate=*/absl::nullopt,
910       /*upper_link_capacity=*/DataRate::PlusInfinity());
911 
912   // Change the acked bitrate to make sure that the estimate is bounded by a
913   // factor of acked bitrate.
914   DataRate acked_bitrate = DataRate::KilobitsPerSec(50);
915   loss_based_bandwidth_estimator.SetAcknowledgedBitrate(acked_bitrate);
916   loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
917       enough_feedback_2, delay_based_estimate, BandwidthUsage::kBwNormal,
918       /*probe_estimate=*/absl::nullopt,
919       /*upper_link_capacity=*/DataRate::PlusInfinity());
920 
921   // The estimate is capped by acked_bitrate * BwRampupUpperBoundFactor.
922   DataRate estimate_2 =
923       loss_based_bandwidth_estimator.GetLossBasedResult().bandwidth_estimate;
924   EXPECT_EQ(estimate_2, acked_bitrate * 1.2);
925 }
926 
927 // After loss based bwe backs off, the estimate is bounded during the delayed
928 // window.
TEST_P(LossBasedBweV2Test,EstimateBitrateIsBoundedDuringDelayedWindowAfterLossBasedBweBacksOff)929 TEST_P(LossBasedBweV2Test,
930        EstimateBitrateIsBoundedDuringDelayedWindowAfterLossBasedBweBacksOff) {
931   std::vector<PacketResult> enough_feedback_1 =
932       CreatePacketResultsWithReceivedPackets(
933           /*first_packet_timestamp=*/Timestamp::Zero());
934   std::vector<PacketResult> enough_feedback_2 =
935       CreatePacketResultsWith50pLossRate(
936           /*first_packet_timestamp=*/Timestamp::Zero() +
937           kDelayedIncreaseWindow - TimeDelta::Millis(2));
938   std::vector<PacketResult> enough_feedback_3 =
939       CreatePacketResultsWithReceivedPackets(
940           /*first_packet_timestamp=*/Timestamp::Zero() +
941           kDelayedIncreaseWindow - TimeDelta::Millis(1));
942   ExplicitKeyValueConfig key_value_config(
943       Config(/*enabled=*/true, /*valid=*/true,
944              /*trendline_integration_enabled=*/GetParam()));
945   LossBasedBweV2 loss_based_bandwidth_estimator(&key_value_config);
946   DataRate delay_based_estimate = DataRate::KilobitsPerSec(5000);
947 
948   loss_based_bandwidth_estimator.SetBandwidthEstimate(
949       DataRate::KilobitsPerSec(600));
950   loss_based_bandwidth_estimator.SetAcknowledgedBitrate(
951       DataRate::KilobitsPerSec(300));
952   loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
953       enough_feedback_1, delay_based_estimate, BandwidthUsage::kBwNormal,
954       /*probe_estimate=*/absl::nullopt,
955       /*upper_link_capacity=*/DataRate::PlusInfinity());
956   // Increase the acknowledged bitrate to make sure that the estimate is not
957   // capped too low.
958   loss_based_bandwidth_estimator.SetAcknowledgedBitrate(
959       DataRate::KilobitsPerSec(5000));
960   loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
961       enough_feedback_2, delay_based_estimate, BandwidthUsage::kBwNormal,
962       /*probe_estimate=*/absl::nullopt,
963       /*upper_link_capacity=*/DataRate::PlusInfinity());
964 
965   // The estimate is capped by current_estimate * kMaxIncreaseFactor because
966   // it recently backed off.
967   DataRate estimate_2 =
968       loss_based_bandwidth_estimator.GetLossBasedResult().bandwidth_estimate;
969 
970   loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
971       enough_feedback_3, delay_based_estimate, BandwidthUsage::kBwNormal,
972       /*probe_estimate=*/absl::nullopt,
973       /*upper_link_capacity=*/DataRate::PlusInfinity());
974   // The latest estimate is the same as the previous estimate since the sent
975   // packets were sent within the DelayedIncreaseWindow.
976   EXPECT_EQ(
977       loss_based_bandwidth_estimator.GetLossBasedResult().bandwidth_estimate,
978       estimate_2);
979 }
980 
981 // The estimate is not bounded after the delayed increase window.
TEST_P(LossBasedBweV2Test,KeepIncreasingEstimateAfterDelayedIncreaseWindow)982 TEST_P(LossBasedBweV2Test, KeepIncreasingEstimateAfterDelayedIncreaseWindow) {
983   std::vector<PacketResult> enough_feedback_1 =
984       CreatePacketResultsWithReceivedPackets(
985           /*first_packet_timestamp=*/Timestamp::Zero());
986   std::vector<PacketResult> enough_feedback_2 =
987       CreatePacketResultsWithReceivedPackets(
988           /*first_packet_timestamp=*/Timestamp::Zero() +
989           kDelayedIncreaseWindow - TimeDelta::Millis(1));
990   std::vector<PacketResult> enough_feedback_3 =
991       CreatePacketResultsWithReceivedPackets(
992           /*first_packet_timestamp=*/Timestamp::Zero() +
993           kDelayedIncreaseWindow + TimeDelta::Millis(1));
994   ExplicitKeyValueConfig key_value_config(
995       Config(/*enabled=*/true, /*valid=*/true,
996              /*trendline_integration_enabled=*/GetParam()));
997   LossBasedBweV2 loss_based_bandwidth_estimator(&key_value_config);
998   DataRate delay_based_estimate = DataRate::KilobitsPerSec(5000);
999 
1000   loss_based_bandwidth_estimator.SetBandwidthEstimate(
1001       DataRate::KilobitsPerSec(600));
1002   loss_based_bandwidth_estimator.SetAcknowledgedBitrate(
1003       DataRate::KilobitsPerSec(300));
1004   loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
1005       enough_feedback_1, delay_based_estimate, BandwidthUsage::kBwNormal,
1006       /*probe_estimate=*/absl::nullopt,
1007       /*upper_link_capacity=*/DataRate::PlusInfinity());
1008   // Increase the acknowledged bitrate to make sure that the estimate is not
1009   // capped too low.
1010   loss_based_bandwidth_estimator.SetAcknowledgedBitrate(
1011       DataRate::KilobitsPerSec(5000));
1012   loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
1013       enough_feedback_2, delay_based_estimate, BandwidthUsage::kBwNormal,
1014       /*probe_estimate=*/absl::nullopt,
1015       /*upper_link_capacity=*/DataRate::PlusInfinity());
1016 
1017   // The estimate is capped by current_estimate * kMaxIncreaseFactor because it
1018   // recently backed off.
1019   DataRate estimate_2 =
1020       loss_based_bandwidth_estimator.GetLossBasedResult().bandwidth_estimate;
1021 
1022   loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
1023       enough_feedback_3, delay_based_estimate, BandwidthUsage::kBwNormal,
1024       /*probe_estimate=*/absl::nullopt,
1025       /*upper_link_capacity=*/DataRate::PlusInfinity());
1026   // The estimate can continue increasing after the DelayedIncreaseWindow.
1027   EXPECT_GE(
1028       loss_based_bandwidth_estimator.GetLossBasedResult().bandwidth_estimate,
1029       estimate_2);
1030 }
1031 
TEST_P(LossBasedBweV2Test,NotIncreaseIfInherentLossLessThanAverageLoss)1032 TEST_P(LossBasedBweV2Test, NotIncreaseIfInherentLossLessThanAverageLoss) {
1033   ExplicitKeyValueConfig key_value_config(
1034       "WebRTC-Bwe-LossBasedBweV2/"
1035       "Enabled:true,CandidateFactors:1.2,AckedRateCandidate:false,"
1036       "ObservationWindowSize:2,"
1037       "DelayBasedCandidate:true,InstantUpperBoundBwBalance:100kbps,"
1038       "ObservationDurationLowerBound:200ms,"
1039       "NotIncreaseIfInherentLossLessThanAverageLoss:true/");
1040   LossBasedBweV2 loss_based_bandwidth_estimator(&key_value_config);
1041   DataRate delay_based_estimate = DataRate::KilobitsPerSec(5000);
1042 
1043   loss_based_bandwidth_estimator.SetBandwidthEstimate(
1044       DataRate::KilobitsPerSec(600));
1045 
1046   std::vector<PacketResult> enough_feedback_10p_loss_1 =
1047       CreatePacketResultsWith10pLossRate(
1048           /*first_packet_timestamp=*/Timestamp::Zero());
1049   loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
1050       enough_feedback_10p_loss_1, delay_based_estimate,
1051       BandwidthUsage::kBwNormal, /*probe_estimate=*/absl::nullopt,
1052       /*upper_link_capacity=*/DataRate::PlusInfinity());
1053 
1054   std::vector<PacketResult> enough_feedback_10p_loss_2 =
1055       CreatePacketResultsWith10pLossRate(
1056           /*first_packet_timestamp=*/Timestamp::Zero() +
1057           kObservationDurationLowerBound);
1058   loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
1059       enough_feedback_10p_loss_2, delay_based_estimate,
1060       BandwidthUsage::kBwNormal, /*probe_estimate=*/absl::nullopt,
1061       /*upper_link_capacity=*/DataRate::PlusInfinity());
1062 
1063   // Do not increase the bitrate because inherent loss is less than average loss
1064   EXPECT_EQ(
1065       loss_based_bandwidth_estimator.GetLossBasedResult().bandwidth_estimate,
1066       DataRate::KilobitsPerSec(600));
1067 }
1068 
TEST_P(LossBasedBweV2Test,SelectHighBandwidthCandidateIfLossRateIsLessThanThreshold)1069 TEST_P(LossBasedBweV2Test,
1070        SelectHighBandwidthCandidateIfLossRateIsLessThanThreshold) {
1071   ExplicitKeyValueConfig key_value_config(
1072       "WebRTC-Bwe-LossBasedBweV2/"
1073       "Enabled:true,CandidateFactors:1.2|0.8,AckedRateCandidate:false,"
1074       "ObservationWindowSize:2,"
1075       "DelayBasedCandidate:true,InstantUpperBoundBwBalance:100kbps,"
1076       "ObservationDurationLowerBound:200ms,HigherBwBiasFactor:1000,"
1077       "HigherLogBwBiasFactor:1000,LossThresholdOfHighBandwidthPreference:0."
1078       "20/");
1079   LossBasedBweV2 loss_based_bandwidth_estimator(&key_value_config);
1080   DataRate delay_based_estimate = DataRate::KilobitsPerSec(5000);
1081 
1082   loss_based_bandwidth_estimator.SetBandwidthEstimate(
1083       DataRate::KilobitsPerSec(600));
1084 
1085   std::vector<PacketResult> enough_feedback_10p_loss_1 =
1086       CreatePacketResultsWith10pLossRate(
1087           /*first_packet_timestamp=*/Timestamp::Zero());
1088   loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
1089       enough_feedback_10p_loss_1, delay_based_estimate,
1090       BandwidthUsage::kBwNormal, /*probe_estimate=*/absl::nullopt,
1091       /*upper_link_capacity=*/DataRate::PlusInfinity());
1092 
1093   std::vector<PacketResult> enough_feedback_10p_loss_2 =
1094       CreatePacketResultsWith10pLossRate(
1095           /*first_packet_timestamp=*/Timestamp::Zero() +
1096           kObservationDurationLowerBound);
1097   loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
1098       enough_feedback_10p_loss_2, delay_based_estimate,
1099       BandwidthUsage::kBwNormal, /*probe_estimate=*/absl::nullopt,
1100       /*upper_link_capacity=*/DataRate::PlusInfinity());
1101 
1102   // Because LossThresholdOfHighBandwidthPreference is 20%, the average loss is
1103   // 10%, bandwidth estimate should increase.
1104   EXPECT_GT(
1105       loss_based_bandwidth_estimator.GetLossBasedResult().bandwidth_estimate,
1106       DataRate::KilobitsPerSec(600));
1107 }
1108 
TEST_P(LossBasedBweV2Test,SelectLowBandwidthCandidateIfLossRateIsIsHigherThanThreshold)1109 TEST_P(LossBasedBweV2Test,
1110        SelectLowBandwidthCandidateIfLossRateIsIsHigherThanThreshold) {
1111   ExplicitKeyValueConfig key_value_config(
1112       "WebRTC-Bwe-LossBasedBweV2/"
1113       "Enabled:true,CandidateFactors:1.2|0.8,AckedRateCandidate:false,"
1114       "ObservationWindowSize:2,"
1115       "DelayBasedCandidate:true,InstantUpperBoundBwBalance:100kbps,"
1116       "ObservationDurationLowerBound:200ms,HigherBwBiasFactor:1000,"
1117       "HigherLogBwBiasFactor:1000,LossThresholdOfHighBandwidthPreference:0."
1118       "05/");
1119   LossBasedBweV2 loss_based_bandwidth_estimator(&key_value_config);
1120   DataRate delay_based_estimate = DataRate::KilobitsPerSec(5000);
1121 
1122   loss_based_bandwidth_estimator.SetBandwidthEstimate(
1123       DataRate::KilobitsPerSec(600));
1124 
1125   std::vector<PacketResult> enough_feedback_10p_loss_1 =
1126       CreatePacketResultsWith10pLossRate(
1127           /*first_packet_timestamp=*/Timestamp::Zero());
1128   loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
1129       enough_feedback_10p_loss_1, delay_based_estimate,
1130       BandwidthUsage::kBwNormal, /*probe_estimate=*/absl::nullopt,
1131       /*upper_link_capacity=*/DataRate::PlusInfinity());
1132 
1133   std::vector<PacketResult> enough_feedback_10p_loss_2 =
1134       CreatePacketResultsWith10pLossRate(
1135           /*first_packet_timestamp=*/Timestamp::Zero() +
1136           kObservationDurationLowerBound);
1137   loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
1138       enough_feedback_10p_loss_2, delay_based_estimate,
1139       BandwidthUsage::kBwNormal, /*probe_estimate=*/absl::nullopt,
1140       /*upper_link_capacity=*/DataRate::PlusInfinity());
1141 
1142   // Because LossThresholdOfHighBandwidthPreference is 5%, the average loss is
1143   // 10%, bandwidth estimate should decrease.
1144   EXPECT_LT(
1145       loss_based_bandwidth_estimator.GetLossBasedResult().bandwidth_estimate,
1146       DataRate::KilobitsPerSec(600));
1147 }
1148 
TEST_P(LossBasedBweV2Test,UseProbeResultWhenRecoveringFromLoss)1149 TEST_P(LossBasedBweV2Test, UseProbeResultWhenRecoveringFromLoss) {
1150   ExplicitKeyValueConfig key_value_config(
1151       "WebRTC-Bwe-LossBasedBweV2/"
1152       "Enabled:true,CandidateFactors:1.2|1|0.5,AckedRateCandidate:true,"
1153       "ObservationWindowSize:2,ObservationDurationLowerBound:200ms,"
1154       "InstantUpperBoundBwBalance:10000kbps,"
1155       "DelayBasedCandidate:true,MaxIncreaseFactor:1000,"
1156       "BwRampupUpperBoundFactor:2.0,ProbeIntegrationEnabled:true/");
1157   LossBasedBweV2 loss_based_bandwidth_estimator(&key_value_config);
1158   DataRate delay_based_estimate = DataRate::KilobitsPerSec(5000);
1159   DataRate acked_rate = DataRate::KilobitsPerSec(300);
1160   loss_based_bandwidth_estimator.SetBandwidthEstimate(
1161       DataRate::KilobitsPerSec(600));
1162   loss_based_bandwidth_estimator.SetAcknowledgedBitrate(acked_rate);
1163 
1164   // Create some loss to create the loss limited scenario.
1165   std::vector<PacketResult> enough_feedback_1 =
1166       CreatePacketResultsWith100pLossRate(
1167           /*first_packet_timestamp=*/Timestamp::Zero());
1168   loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
1169       enough_feedback_1, delay_based_estimate, BandwidthUsage::kBwNormal,
1170       /*probe_estimate=*/absl::nullopt,
1171       /*upper_link_capacity=*/DataRate::PlusInfinity());
1172 
1173   // Network recovers after loss.
1174   DataRate probe_estimate = DataRate::KilobitsPerSec(300);
1175   std::vector<PacketResult> enough_feedback_2 =
1176       CreatePacketResultsWithReceivedPackets(
1177           /*first_packet_timestamp=*/Timestamp::Zero() +
1178           kObservationDurationLowerBound);
1179   loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
1180       enough_feedback_2, delay_based_estimate, BandwidthUsage::kBwNormal,
1181       probe_estimate, /*upper_link_capacity=*/DataRate::PlusInfinity());
1182 
1183   LossBasedBweV2::Result result_after_recovery =
1184       loss_based_bandwidth_estimator.GetLossBasedResult();
1185   EXPECT_EQ(result_after_recovery.bandwidth_estimate, probe_estimate);
1186 }
1187 
1188 // If BoundByUpperLinkCapacityWhenLossLimited is enabled, the estimate is
1189 // bounded by the upper link capacity when bandwidth is loss limited.
TEST_P(LossBasedBweV2Test,BoundEstimateByUpperLinkCapacityWhenLossLimited)1190 TEST_P(LossBasedBweV2Test, BoundEstimateByUpperLinkCapacityWhenLossLimited) {
1191   ExplicitKeyValueConfig key_value_config(
1192       "WebRTC-Bwe-LossBasedBweV2/"
1193       "Enabled:true,CandidateFactors:1.2|1|0.5,AckedRateCandidate:true,"
1194       "ObservationWindowSize:2,ObservationDurationLowerBound:200ms,"
1195       "InstantUpperBoundBwBalance:10000kbps,"
1196       "DelayBasedCandidate:true,MaxIncreaseFactor:1000,"
1197       "BwRampupUpperBoundFactor:2.0,BoundByUpperLinkCapacityWhenLossLimited:"
1198       "true/");
1199   LossBasedBweV2 loss_based_bandwidth_estimator(&key_value_config);
1200   DataRate delay_based_estimate = DataRate::KilobitsPerSec(5000);
1201   DataRate acked_rate = DataRate::KilobitsPerSec(300);
1202   loss_based_bandwidth_estimator.SetBandwidthEstimate(
1203       DataRate::KilobitsPerSec(600));
1204   loss_based_bandwidth_estimator.SetAcknowledgedBitrate(acked_rate);
1205 
1206   // Create some loss to create the loss limited scenario.
1207   std::vector<PacketResult> enough_feedback_1 =
1208       CreatePacketResultsWith100pLossRate(
1209           /*first_packet_timestamp=*/Timestamp::Zero());
1210   loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
1211       enough_feedback_1, delay_based_estimate, BandwidthUsage::kBwNormal,
1212       /*probe_estimate=*/absl::nullopt,
1213       /*upper_link_capacity=*/DataRate::PlusInfinity());
1214 
1215   // Network recovers after loss.
1216   DataRate upper_link_capacity = DataRate::KilobitsPerSec(10);
1217   std::vector<PacketResult> enough_feedback_2 =
1218       CreatePacketResultsWithReceivedPackets(
1219           /*first_packet_timestamp=*/Timestamp::Zero() +
1220           kObservationDurationLowerBound);
1221   loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
1222       enough_feedback_2, delay_based_estimate, BandwidthUsage::kBwNormal,
1223       /*probe_estimate=*/absl::nullopt, upper_link_capacity);
1224 
1225   LossBasedBweV2::Result result_after_recovery =
1226       loss_based_bandwidth_estimator.GetLossBasedResult();
1227   EXPECT_EQ(result_after_recovery.bandwidth_estimate, upper_link_capacity);
1228 }
1229 
1230 // If BoundByUpperLinkCapacityWhenLossLimited is enabled, the estimate is not
1231 // bounded by the upper link capacity when bandwidth is not loss limited.
TEST_P(LossBasedBweV2Test,NotBoundEstimateByUpperLinkCapacityWhenNotLossLimited)1232 TEST_P(LossBasedBweV2Test,
1233        NotBoundEstimateByUpperLinkCapacityWhenNotLossLimited) {
1234   ExplicitKeyValueConfig key_value_config(
1235       "WebRTC-Bwe-LossBasedBweV2/"
1236       "Enabled:true,CandidateFactors:1.2|1|0.5,AckedRateCandidate:true,"
1237       "ObservationWindowSize:2,ObservationDurationLowerBound:200ms,"
1238       "InstantUpperBoundBwBalance:10000kbps,"
1239       "DelayBasedCandidate:true,MaxIncreaseFactor:1000,"
1240       "BwRampupUpperBoundFactor:2.0,BoundByUpperLinkCapacityWhenLossLimited:"
1241       "true/");
1242   LossBasedBweV2 loss_based_bandwidth_estimator(&key_value_config);
1243   DataRate delay_based_estimate = DataRate::KilobitsPerSec(5000);
1244   DataRate acked_rate = DataRate::KilobitsPerSec(300);
1245   loss_based_bandwidth_estimator.SetBandwidthEstimate(
1246       DataRate::KilobitsPerSec(600));
1247   loss_based_bandwidth_estimator.SetAcknowledgedBitrate(acked_rate);
1248 
1249   // Create a normal network without loss
1250   std::vector<PacketResult> enough_feedback_1 =
1251       CreatePacketResultsWithReceivedPackets(
1252           /*first_packet_timestamp=*/Timestamp::Zero());
1253   loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
1254       enough_feedback_1, delay_based_estimate, BandwidthUsage::kBwNormal,
1255       /*probe_estimate=*/absl::nullopt,
1256       /*upper_link_capacity=*/DataRate::PlusInfinity());
1257 
1258   DataRate upper_link_capacity = DataRate::KilobitsPerSec(10);
1259   std::vector<PacketResult> enough_feedback_2 =
1260       CreatePacketResultsWithReceivedPackets(
1261           /*first_packet_timestamp=*/Timestamp::Zero() +
1262           kObservationDurationLowerBound);
1263   loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
1264       enough_feedback_2, delay_based_estimate, BandwidthUsage::kBwNormal,
1265       /*probe_estimate=*/absl::nullopt, upper_link_capacity);
1266 
1267   LossBasedBweV2::Result loss_based_result =
1268       loss_based_bandwidth_estimator.GetLossBasedResult();
1269   EXPECT_GT(loss_based_result.bandwidth_estimate, upper_link_capacity);
1270 }
1271 
1272 // If BoundByUpperLinkCapacityWhenLossLimited is disabled, the estimate is not
1273 // bounded by the upper link capacity.
TEST_P(LossBasedBweV2Test,NotBoundEstimateByUpperLinkCapacity)1274 TEST_P(LossBasedBweV2Test, NotBoundEstimateByUpperLinkCapacity) {
1275   ExplicitKeyValueConfig key_value_config(
1276       "WebRTC-Bwe-LossBasedBweV2/"
1277       "Enabled:true,CandidateFactors:1.2|1|0.5,AckedRateCandidate:true,"
1278       "ObservationWindowSize:2,ObservationDurationLowerBound:200ms,"
1279       "InstantUpperBoundBwBalance:10000kbps,"
1280       "DelayBasedCandidate:true,MaxIncreaseFactor:1000,"
1281       "BwRampupUpperBoundFactor:2.0,BoundByUpperLinkCapacityWhenLossLimited:"
1282       "false/");
1283   LossBasedBweV2 loss_based_bandwidth_estimator(&key_value_config);
1284   DataRate delay_based_estimate = DataRate::KilobitsPerSec(5000);
1285   DataRate acked_rate = DataRate::KilobitsPerSec(300);
1286   loss_based_bandwidth_estimator.SetBandwidthEstimate(
1287       DataRate::KilobitsPerSec(600));
1288   loss_based_bandwidth_estimator.SetAcknowledgedBitrate(acked_rate);
1289 
1290   // Create some loss to create the loss limited scenario.
1291   std::vector<PacketResult> enough_feedback_1 =
1292       CreatePacketResultsWith100pLossRate(
1293           /*first_packet_timestamp=*/Timestamp::Zero());
1294   loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
1295       enough_feedback_1, delay_based_estimate, BandwidthUsage::kBwNormal,
1296       /*probe_estimate=*/absl::nullopt,
1297       /*upper_link_capacity=*/DataRate::PlusInfinity());
1298 
1299   // Network recovers after loss.
1300   DataRate upper_link_capacity = DataRate::KilobitsPerSec(10);
1301   std::vector<PacketResult> enough_feedback_2 =
1302       CreatePacketResultsWithReceivedPackets(
1303           /*first_packet_timestamp=*/Timestamp::Zero() +
1304           kObservationDurationLowerBound);
1305   loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
1306       enough_feedback_2, delay_based_estimate, BandwidthUsage::kBwNormal,
1307       /*probe_estimate=*/absl::nullopt, upper_link_capacity);
1308 
1309   LossBasedBweV2::Result result_after_recovery =
1310       loss_based_bandwidth_estimator.GetLossBasedResult();
1311   EXPECT_GT(result_after_recovery.bandwidth_estimate, upper_link_capacity);
1312 }
1313 
TEST_P(LossBasedBweV2Test,StricterBoundUsingHighLossRateThresholdAt10pLossRate)1314 TEST_P(LossBasedBweV2Test,
1315        StricterBoundUsingHighLossRateThresholdAt10pLossRate) {
1316   ExplicitKeyValueConfig key_value_config(
1317       "WebRTC-Bwe-LossBasedBweV2/"
1318       "Enabled:true,CandidateFactors:1.0,AckedRateCandidate:false,"
1319       "ObservationWindowSize:2,"
1320       "DelayBasedCandidate:true,InstantUpperBoundBwBalance:100kbps,"
1321       "ObservationDurationLowerBound:200ms,HigherBwBiasFactor:1000,"
1322       "HigherLogBwBiasFactor:1000,LossThresholdOfHighBandwidthPreference:0."
1323       "05,HighLossRateThreshold:0.09/");
1324   LossBasedBweV2 loss_based_bandwidth_estimator(&key_value_config);
1325   loss_based_bandwidth_estimator.SetMinMaxBitrate(
1326       /*min_bitrate=*/DataRate::KilobitsPerSec(10),
1327       /*max_bitrate=*/DataRate::KilobitsPerSec(1000000));
1328   DataRate delay_based_estimate = DataRate::KilobitsPerSec(5000);
1329   loss_based_bandwidth_estimator.SetBandwidthEstimate(
1330       DataRate::KilobitsPerSec(600));
1331 
1332   std::vector<PacketResult> enough_feedback_10p_loss_1 =
1333       CreatePacketResultsWith10pLossRate(
1334           /*first_packet_timestamp=*/Timestamp::Zero());
1335   loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
1336       enough_feedback_10p_loss_1, delay_based_estimate,
1337       BandwidthUsage::kBwNormal, /*probe_estimate=*/absl::nullopt,
1338       /*upper_link_capacity=*/DataRate::PlusInfinity());
1339 
1340   std::vector<PacketResult> enough_feedback_10p_loss_2 =
1341       CreatePacketResultsWith10pLossRate(
1342           /*first_packet_timestamp=*/Timestamp::Zero() +
1343           kObservationDurationLowerBound);
1344   loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
1345       enough_feedback_10p_loss_2, delay_based_estimate,
1346       BandwidthUsage::kBwNormal, /*probe_estimate=*/absl::nullopt,
1347       /*upper_link_capacity=*/DataRate::PlusInfinity());
1348 
1349   // At 10% loss rate and high loss rate threshold to be 10%, cap the estimate
1350   // to be 500 * 1000-0.1 = 400kbps.
1351   EXPECT_EQ(
1352       loss_based_bandwidth_estimator.GetLossBasedResult().bandwidth_estimate,
1353       DataRate::KilobitsPerSec(400));
1354 }
1355 
TEST_P(LossBasedBweV2Test,StricterBoundUsingHighLossRateThresholdAt50pLossRate)1356 TEST_P(LossBasedBweV2Test,
1357        StricterBoundUsingHighLossRateThresholdAt50pLossRate) {
1358   ExplicitKeyValueConfig key_value_config(
1359       "WebRTC-Bwe-LossBasedBweV2/"
1360       "Enabled:true,CandidateFactors:1.0,AckedRateCandidate:false,"
1361       "ObservationWindowSize:2,"
1362       "DelayBasedCandidate:true,InstantUpperBoundBwBalance:100kbps,"
1363       "ObservationDurationLowerBound:200ms,HigherBwBiasFactor:1000,"
1364       "HigherLogBwBiasFactor:1000,LossThresholdOfHighBandwidthPreference:0."
1365       "05,HighLossRateThreshold:0.3/");
1366   LossBasedBweV2 loss_based_bandwidth_estimator(&key_value_config);
1367   loss_based_bandwidth_estimator.SetMinMaxBitrate(
1368       /*min_bitrate=*/DataRate::KilobitsPerSec(10),
1369       /*max_bitrate=*/DataRate::KilobitsPerSec(1000000));
1370   DataRate delay_based_estimate = DataRate::KilobitsPerSec(5000);
1371   loss_based_bandwidth_estimator.SetBandwidthEstimate(
1372       DataRate::KilobitsPerSec(600));
1373 
1374   std::vector<PacketResult> enough_feedback_50p_loss_1 =
1375       CreatePacketResultsWith50pLossRate(
1376           /*first_packet_timestamp=*/Timestamp::Zero());
1377   loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
1378       enough_feedback_50p_loss_1, delay_based_estimate,
1379       BandwidthUsage::kBwNormal, /*probe_estimate=*/absl::nullopt,
1380       /*upper_link_capacity=*/DataRate::PlusInfinity());
1381 
1382   std::vector<PacketResult> enough_feedback_50p_loss_2 =
1383       CreatePacketResultsWith50pLossRate(
1384           /*first_packet_timestamp=*/Timestamp::Zero() +
1385           kObservationDurationLowerBound);
1386   loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
1387       enough_feedback_50p_loss_2, delay_based_estimate,
1388       BandwidthUsage::kBwNormal, /*probe_estimate=*/absl::nullopt,
1389       /*upper_link_capacity=*/DataRate::PlusInfinity());
1390 
1391   // At 50% loss rate and high loss rate threshold to be 30%, cap the estimate
1392   // to be the min bitrate.
1393   EXPECT_EQ(
1394       loss_based_bandwidth_estimator.GetLossBasedResult().bandwidth_estimate,
1395       DataRate::KilobitsPerSec(10));
1396 }
1397 
TEST_P(LossBasedBweV2Test,StricterBoundUsingHighLossRateThresholdAt100pLossRate)1398 TEST_P(LossBasedBweV2Test,
1399        StricterBoundUsingHighLossRateThresholdAt100pLossRate) {
1400   ExplicitKeyValueConfig key_value_config(
1401       "WebRTC-Bwe-LossBasedBweV2/"
1402       "Enabled:true,CandidateFactors:1.0,AckedRateCandidate:false,"
1403       "ObservationWindowSize:2,"
1404       "DelayBasedCandidate:true,InstantUpperBoundBwBalance:100kbps,"
1405       "ObservationDurationLowerBound:200ms,HigherBwBiasFactor:1000,"
1406       "HigherLogBwBiasFactor:1000,LossThresholdOfHighBandwidthPreference:0."
1407       "05,HighLossRateThreshold:0.3/");
1408   LossBasedBweV2 loss_based_bandwidth_estimator(&key_value_config);
1409   loss_based_bandwidth_estimator.SetMinMaxBitrate(
1410       /*min_bitrate=*/DataRate::KilobitsPerSec(10),
1411       /*max_bitrate=*/DataRate::KilobitsPerSec(1000000));
1412   DataRate delay_based_estimate = DataRate::KilobitsPerSec(5000);
1413   loss_based_bandwidth_estimator.SetBandwidthEstimate(
1414       DataRate::KilobitsPerSec(600));
1415 
1416   std::vector<PacketResult> enough_feedback_100p_loss_1 =
1417       CreatePacketResultsWith100pLossRate(
1418           /*first_packet_timestamp=*/Timestamp::Zero());
1419   loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
1420       enough_feedback_100p_loss_1, delay_based_estimate,
1421       BandwidthUsage::kBwNormal, /*probe_estimate=*/absl::nullopt,
1422       /*upper_link_capacity=*/DataRate::PlusInfinity());
1423 
1424   std::vector<PacketResult> enough_feedback_100p_loss_2 =
1425       CreatePacketResultsWith100pLossRate(
1426           /*first_packet_timestamp=*/Timestamp::Zero() +
1427           kObservationDurationLowerBound);
1428   loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
1429       enough_feedback_100p_loss_2, delay_based_estimate,
1430       BandwidthUsage::kBwNormal, /*probe_estimate=*/absl::nullopt,
1431       /*upper_link_capacity=*/DataRate::PlusInfinity());
1432 
1433   // At 100% loss rate and high loss rate threshold to be 30%, cap the estimate
1434   // to be the min bitrate.
1435   EXPECT_EQ(
1436       loss_based_bandwidth_estimator.GetLossBasedResult().bandwidth_estimate,
1437       DataRate::KilobitsPerSec(10));
1438 }
1439 
TEST_P(LossBasedBweV2Test,EstimateRecoversAfterHighLoss)1440 TEST_P(LossBasedBweV2Test, EstimateRecoversAfterHighLoss) {
1441   ExplicitKeyValueConfig key_value_config(
1442       "WebRTC-Bwe-LossBasedBweV2/"
1443       "Enabled:true,CandidateFactors:1.1|1.0|0.9,AckedRateCandidate:false,"
1444       "ObservationWindowSize:2,"
1445       "DelayBasedCandidate:true,InstantUpperBoundBwBalance:100kbps,"
1446       "ObservationDurationLowerBound:200ms,HigherBwBiasFactor:1000,"
1447       "HigherLogBwBiasFactor:1000,LossThresholdOfHighBandwidthPreference:0."
1448       "05,HighLossRateThreshold:0.3/");
1449   LossBasedBweV2 loss_based_bandwidth_estimator(&key_value_config);
1450   loss_based_bandwidth_estimator.SetMinMaxBitrate(
1451       /*min_bitrate=*/DataRate::KilobitsPerSec(10),
1452       /*max_bitrate=*/DataRate::KilobitsPerSec(1000000));
1453   DataRate delay_based_estimate = DataRate::KilobitsPerSec(5000);
1454   loss_based_bandwidth_estimator.SetBandwidthEstimate(
1455       DataRate::KilobitsPerSec(600));
1456 
1457   std::vector<PacketResult> enough_feedback_100p_loss_1 =
1458       CreatePacketResultsWith100pLossRate(
1459           /*first_packet_timestamp=*/Timestamp::Zero());
1460   loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
1461       enough_feedback_100p_loss_1, delay_based_estimate,
1462       BandwidthUsage::kBwNormal, /*probe_estimate=*/absl::nullopt,
1463       /*upper_link_capacity=*/DataRate::PlusInfinity());
1464 
1465   // Make sure that the estimate is set to min bitrate because of 100% loss
1466   // rate.
1467   EXPECT_EQ(
1468       loss_based_bandwidth_estimator.GetLossBasedResult().bandwidth_estimate,
1469       DataRate::KilobitsPerSec(10));
1470 
1471   // Create some feedbacks with 0 loss rate to simulate network recovering.
1472   std::vector<PacketResult> enough_feedback_0p_loss_1 =
1473       CreatePacketResultsWithReceivedPackets(
1474           /*first_packet_timestamp=*/Timestamp::Zero() +
1475           kObservationDurationLowerBound);
1476   loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
1477       enough_feedback_0p_loss_1, delay_based_estimate,
1478       BandwidthUsage::kBwNormal, /*probe_estimate=*/absl::nullopt,
1479       /*upper_link_capacity=*/DataRate::PlusInfinity());
1480 
1481   std::vector<PacketResult> enough_feedback_0p_loss_2 =
1482       CreatePacketResultsWithReceivedPackets(
1483           /*first_packet_timestamp=*/Timestamp::Zero() +
1484           kObservationDurationLowerBound * 2);
1485   loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
1486       enough_feedback_0p_loss_2, delay_based_estimate,
1487       BandwidthUsage::kBwNormal, /*probe_estimate=*/absl::nullopt,
1488       /*upper_link_capacity=*/DataRate::PlusInfinity());
1489 
1490   // The estimate increases as network recovers.
1491   EXPECT_GT(
1492       loss_based_bandwidth_estimator.GetLossBasedResult().bandwidth_estimate,
1493       DataRate::KilobitsPerSec(10));
1494 }
1495 
TEST_P(LossBasedBweV2Test,EstimateIsNotHigherThanMaxBitrate)1496 TEST_P(LossBasedBweV2Test, EstimateIsNotHigherThanMaxBitrate) {
1497   ExplicitKeyValueConfig key_value_config(
1498       Config(/*enabled=*/true, /*valid=*/true,
1499              /*trendline_integration_enabled=*/GetParam()));
1500   LossBasedBweV2 loss_based_bandwidth_estimator(&key_value_config);
1501   loss_based_bandwidth_estimator.SetMinMaxBitrate(
1502       /*min_bitrate=*/DataRate::KilobitsPerSec(10),
1503       /*max_bitrate=*/DataRate::KilobitsPerSec(1000));
1504   loss_based_bandwidth_estimator.SetBandwidthEstimate(
1505       DataRate::KilobitsPerSec(1000));
1506   std::vector<PacketResult> enough_feedback =
1507       CreatePacketResultsWithReceivedPackets(
1508           /*first_packet_timestamp=*/Timestamp::Zero());
1509   loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
1510       enough_feedback, /*delay_based_estimate=*/DataRate::PlusInfinity(),
1511       BandwidthUsage::kBwNormal, /*probe_estimate=*/absl::nullopt,
1512       /*upper_link_capacity=*/DataRate::PlusInfinity());
1513 
1514   EXPECT_LE(
1515       loss_based_bandwidth_estimator.GetLossBasedResult().bandwidth_estimate,
1516       DataRate::KilobitsPerSec(1000));
1517 }
1518 
1519 INSTANTIATE_TEST_SUITE_P(LossBasedBweV2Tests,
1520                          LossBasedBweV2Test,
1521                          ::testing::Bool());
1522 
1523 }  // namespace
1524 }  // namespace webrtc
1525