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