1 /*
2 * Copyright (c) 2016 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/audio_coding/audio_network_adaptor/fec_controller_plr_based.h"
12
13 #include <utility>
14
15 #include "common_audio/mocks/mock_smoothing_filter.h"
16 #include "test/gtest.h"
17
18 namespace webrtc {
19
20 using ::testing::_;
21 using ::testing::NiceMock;
22 using ::testing::Return;
23
24 namespace {
25
26 // The test uses the following settings:
27 //
28 // packet-loss ^ | |
29 // | A| C| FEC
30 // | \ \ ON
31 // | FEC \ D\_______
32 // | OFF B\_________
33 // |-----------------> bandwidth
34 //
35 // A : (kDisablingBandwidthLow, kDisablingPacketLossAtLowBw)
36 // B : (kDisablingBandwidthHigh, kDisablingPacketLossAtHighBw)
37 // C : (kEnablingBandwidthLow, kEnablingPacketLossAtLowBw)
38 // D : (kEnablingBandwidthHigh, kEnablingPacketLossAtHighBw)
39
40 constexpr int kDisablingBandwidthLow = 15000;
41 constexpr float kDisablingPacketLossAtLowBw = 0.08f;
42 constexpr int kDisablingBandwidthHigh = 64000;
43 constexpr float kDisablingPacketLossAtHighBw = 0.01f;
44 constexpr int kEnablingBandwidthLow = 17000;
45 constexpr float kEnablingPacketLossAtLowBw = 0.1f;
46 constexpr int kEnablingBandwidthHigh = 64000;
47 constexpr float kEnablingPacketLossAtHighBw = 0.05f;
48
49 constexpr float kEpsilon = 1e-5f;
50
51 struct FecControllerPlrBasedTestStates {
52 std::unique_ptr<FecControllerPlrBased> controller;
53 MockSmoothingFilter* packet_loss_smoother;
54 };
55
CreateFecControllerPlrBased(bool initial_fec_enabled,const ThresholdCurve & enabling_curve,const ThresholdCurve & disabling_curve)56 FecControllerPlrBasedTestStates CreateFecControllerPlrBased(
57 bool initial_fec_enabled,
58 const ThresholdCurve& enabling_curve,
59 const ThresholdCurve& disabling_curve) {
60 FecControllerPlrBasedTestStates states;
61 std::unique_ptr<MockSmoothingFilter> mock_smoothing_filter(
62 new NiceMock<MockSmoothingFilter>());
63 states.packet_loss_smoother = mock_smoothing_filter.get();
64 states.controller.reset(new FecControllerPlrBased(
65 FecControllerPlrBased::Config(initial_fec_enabled, enabling_curve,
66 disabling_curve, 0),
67 std::move(mock_smoothing_filter)));
68 return states;
69 }
70
CreateFecControllerPlrBased(bool initial_fec_enabled)71 FecControllerPlrBasedTestStates CreateFecControllerPlrBased(
72 bool initial_fec_enabled) {
73 return CreateFecControllerPlrBased(
74 initial_fec_enabled,
75 ThresholdCurve(kEnablingBandwidthLow, kEnablingPacketLossAtLowBw,
76 kEnablingBandwidthHigh, kEnablingPacketLossAtHighBw),
77 ThresholdCurve(kDisablingBandwidthLow, kDisablingPacketLossAtLowBw,
78 kDisablingBandwidthHigh, kDisablingPacketLossAtHighBw));
79 }
80
UpdateNetworkMetrics(FecControllerPlrBasedTestStates * states,const absl::optional<int> & uplink_bandwidth_bps,const absl::optional<float> & uplink_packet_loss)81 void UpdateNetworkMetrics(FecControllerPlrBasedTestStates* states,
82 const absl::optional<int>& uplink_bandwidth_bps,
83 const absl::optional<float>& uplink_packet_loss) {
84 // UpdateNetworkMetrics can accept multiple network metric updates at once.
85 // However, currently, the most used case is to update one metric at a time.
86 // To reflect this fact, we separate the calls.
87 if (uplink_bandwidth_bps) {
88 Controller::NetworkMetrics network_metrics;
89 network_metrics.uplink_bandwidth_bps = uplink_bandwidth_bps;
90 states->controller->UpdateNetworkMetrics(network_metrics);
91 }
92 if (uplink_packet_loss) {
93 Controller::NetworkMetrics network_metrics;
94 network_metrics.uplink_packet_loss_fraction = uplink_packet_loss;
95 EXPECT_CALL(*states->packet_loss_smoother, AddSample(*uplink_packet_loss));
96 states->controller->UpdateNetworkMetrics(network_metrics);
97 // This is called during CheckDecision().
98 EXPECT_CALL(*states->packet_loss_smoother, GetAverage())
99 .WillOnce(Return(*uplink_packet_loss));
100 }
101 }
102
103 // Checks that the FEC decision and `uplink_packet_loss_fraction` given by
104 // `states->controller->MakeDecision` matches `expected_enable_fec` and
105 // `expected_uplink_packet_loss_fraction`, respectively.
CheckDecision(FecControllerPlrBasedTestStates * states,bool expected_enable_fec,float expected_uplink_packet_loss_fraction)106 void CheckDecision(FecControllerPlrBasedTestStates* states,
107 bool expected_enable_fec,
108 float expected_uplink_packet_loss_fraction) {
109 AudioEncoderRuntimeConfig config;
110 states->controller->MakeDecision(&config);
111 EXPECT_EQ(expected_enable_fec, config.enable_fec);
112 EXPECT_EQ(expected_uplink_packet_loss_fraction,
113 config.uplink_packet_loss_fraction);
114 }
115
116 } // namespace
117
TEST(FecControllerPlrBasedTest,OutputInitValueBeforeAnyInputsAreReceived)118 TEST(FecControllerPlrBasedTest, OutputInitValueBeforeAnyInputsAreReceived) {
119 for (bool initial_fec_enabled : {false, true}) {
120 auto states = CreateFecControllerPlrBased(initial_fec_enabled);
121 CheckDecision(&states, initial_fec_enabled, 0);
122 }
123 }
124
TEST(FecControllerPlrBasedTest,OutputInitValueWhenUplinkBandwidthUnknown)125 TEST(FecControllerPlrBasedTest, OutputInitValueWhenUplinkBandwidthUnknown) {
126 // Regardless of the initial FEC state and the packet-loss rate,
127 // the initial FEC state is maintained as long as the BWE is unknown.
128 for (bool initial_fec_enabled : {false, true}) {
129 for (float packet_loss :
130 {kDisablingPacketLossAtLowBw - kEpsilon, kDisablingPacketLossAtLowBw,
131 kDisablingPacketLossAtLowBw + kEpsilon,
132 kEnablingPacketLossAtLowBw - kEpsilon, kEnablingPacketLossAtLowBw,
133 kEnablingPacketLossAtLowBw + kEpsilon}) {
134 auto states = CreateFecControllerPlrBased(initial_fec_enabled);
135 UpdateNetworkMetrics(&states, absl::nullopt, packet_loss);
136 CheckDecision(&states, initial_fec_enabled, packet_loss);
137 }
138 }
139 }
140
TEST(FecControllerPlrBasedTest,OutputInitValueWhenUplinkPacketLossFractionUnknown)141 TEST(FecControllerPlrBasedTest,
142 OutputInitValueWhenUplinkPacketLossFractionUnknown) {
143 // Regardless of the initial FEC state and the BWE, the initial FEC state
144 // is maintained as long as the packet-loss rate is unknown.
145 for (bool initial_fec_enabled : {false, true}) {
146 for (int bandwidth : {kDisablingBandwidthLow - 1, kDisablingBandwidthLow,
147 kDisablingBandwidthLow + 1, kEnablingBandwidthLow - 1,
148 kEnablingBandwidthLow, kEnablingBandwidthLow + 1}) {
149 auto states = CreateFecControllerPlrBased(initial_fec_enabled);
150 UpdateNetworkMetrics(&states, bandwidth, absl::nullopt);
151 CheckDecision(&states, initial_fec_enabled, 0.0);
152 }
153 }
154 }
155
TEST(FecControllerPlrBasedTest,EnableFecForHighBandwidth)156 TEST(FecControllerPlrBasedTest, EnableFecForHighBandwidth) {
157 auto states = CreateFecControllerPlrBased(false);
158 UpdateNetworkMetrics(&states, kEnablingBandwidthHigh,
159 kEnablingPacketLossAtHighBw);
160 CheckDecision(&states, true, kEnablingPacketLossAtHighBw);
161 }
162
TEST(FecControllerPlrBasedTest,UpdateMultipleNetworkMetricsAtOnce)163 TEST(FecControllerPlrBasedTest, UpdateMultipleNetworkMetricsAtOnce) {
164 // This test is similar to EnableFecForHighBandwidth. But instead of
165 // using ::UpdateNetworkMetrics(...), which calls
166 // FecControllerPlrBased::UpdateNetworkMetrics(...) multiple times, we
167 // we call it only once. This is to verify that
168 // FecControllerPlrBased::UpdateNetworkMetrics(...) can handle multiple
169 // network updates at once. This is, however, not a common use case in current
170 // audio_network_adaptor_impl.cc.
171 auto states = CreateFecControllerPlrBased(false);
172 Controller::NetworkMetrics network_metrics;
173 network_metrics.uplink_bandwidth_bps = kEnablingBandwidthHigh;
174 network_metrics.uplink_packet_loss_fraction = kEnablingPacketLossAtHighBw;
175 EXPECT_CALL(*states.packet_loss_smoother, GetAverage())
176 .WillOnce(Return(kEnablingPacketLossAtHighBw));
177 states.controller->UpdateNetworkMetrics(network_metrics);
178 CheckDecision(&states, true, kEnablingPacketLossAtHighBw);
179 }
180
TEST(FecControllerPlrBasedTest,MaintainFecOffForHighBandwidth)181 TEST(FecControllerPlrBasedTest, MaintainFecOffForHighBandwidth) {
182 auto states = CreateFecControllerPlrBased(false);
183 constexpr float kPacketLoss = kEnablingPacketLossAtHighBw * 0.99f;
184 UpdateNetworkMetrics(&states, kEnablingBandwidthHigh, kPacketLoss);
185 CheckDecision(&states, false, kPacketLoss);
186 }
187
TEST(FecControllerPlrBasedTest,EnableFecForMediumBandwidth)188 TEST(FecControllerPlrBasedTest, EnableFecForMediumBandwidth) {
189 auto states = CreateFecControllerPlrBased(false);
190 constexpr float kPacketLoss =
191 (kEnablingPacketLossAtLowBw + kEnablingPacketLossAtHighBw) / 2.0;
192 UpdateNetworkMetrics(&states,
193 (kEnablingBandwidthHigh + kEnablingBandwidthLow) / 2,
194 kPacketLoss);
195 CheckDecision(&states, true, kPacketLoss);
196 }
197
TEST(FecControllerPlrBasedTest,MaintainFecOffForMediumBandwidth)198 TEST(FecControllerPlrBasedTest, MaintainFecOffForMediumBandwidth) {
199 auto states = CreateFecControllerPlrBased(false);
200 constexpr float kPacketLoss =
201 kEnablingPacketLossAtLowBw * 0.49f + kEnablingPacketLossAtHighBw * 0.51f;
202 UpdateNetworkMetrics(&states,
203 (kEnablingBandwidthHigh + kEnablingBandwidthLow) / 2,
204 kPacketLoss);
205 CheckDecision(&states, false, kPacketLoss);
206 }
207
TEST(FecControllerPlrBasedTest,EnableFecForLowBandwidth)208 TEST(FecControllerPlrBasedTest, EnableFecForLowBandwidth) {
209 auto states = CreateFecControllerPlrBased(false);
210 UpdateNetworkMetrics(&states, kEnablingBandwidthLow,
211 kEnablingPacketLossAtLowBw);
212 CheckDecision(&states, true, kEnablingPacketLossAtLowBw);
213 }
214
TEST(FecControllerPlrBasedTest,MaintainFecOffForLowBandwidth)215 TEST(FecControllerPlrBasedTest, MaintainFecOffForLowBandwidth) {
216 auto states = CreateFecControllerPlrBased(false);
217 constexpr float kPacketLoss = kEnablingPacketLossAtLowBw * 0.99f;
218 UpdateNetworkMetrics(&states, kEnablingBandwidthLow, kPacketLoss);
219 CheckDecision(&states, false, kPacketLoss);
220 }
221
TEST(FecControllerPlrBasedTest,MaintainFecOffForVeryLowBandwidth)222 TEST(FecControllerPlrBasedTest, MaintainFecOffForVeryLowBandwidth) {
223 auto states = CreateFecControllerPlrBased(false);
224 // Below `kEnablingBandwidthLow`, no packet loss fraction can cause FEC to
225 // turn on.
226 UpdateNetworkMetrics(&states, kEnablingBandwidthLow - 1, 1.0);
227 CheckDecision(&states, false, 1.0);
228 }
229
TEST(FecControllerPlrBasedTest,DisableFecForHighBandwidth)230 TEST(FecControllerPlrBasedTest, DisableFecForHighBandwidth) {
231 auto states = CreateFecControllerPlrBased(true);
232 constexpr float kPacketLoss = kDisablingPacketLossAtHighBw - kEpsilon;
233 UpdateNetworkMetrics(&states, kDisablingBandwidthHigh, kPacketLoss);
234 CheckDecision(&states, false, kPacketLoss);
235 }
236
TEST(FecControllerPlrBasedTest,MaintainFecOnForHighBandwidth)237 TEST(FecControllerPlrBasedTest, MaintainFecOnForHighBandwidth) {
238 // Note: Disabling happens when the value is strictly below the threshold.
239 auto states = CreateFecControllerPlrBased(true);
240 UpdateNetworkMetrics(&states, kDisablingBandwidthHigh,
241 kDisablingPacketLossAtHighBw);
242 CheckDecision(&states, true, kDisablingPacketLossAtHighBw);
243 }
244
TEST(FecControllerPlrBasedTest,DisableFecOnMediumBandwidth)245 TEST(FecControllerPlrBasedTest, DisableFecOnMediumBandwidth) {
246 auto states = CreateFecControllerPlrBased(true);
247 constexpr float kPacketLoss =
248 (kDisablingPacketLossAtLowBw + kDisablingPacketLossAtHighBw) / 2.0f -
249 kEpsilon;
250 UpdateNetworkMetrics(&states,
251 (kDisablingBandwidthHigh + kDisablingBandwidthLow) / 2,
252 kPacketLoss);
253 CheckDecision(&states, false, kPacketLoss);
254 }
255
TEST(FecControllerPlrBasedTest,MaintainFecOnForMediumBandwidth)256 TEST(FecControllerPlrBasedTest, MaintainFecOnForMediumBandwidth) {
257 auto states = CreateFecControllerPlrBased(true);
258 constexpr float kPacketLoss = kDisablingPacketLossAtLowBw * 0.51f +
259 kDisablingPacketLossAtHighBw * 0.49f - kEpsilon;
260 UpdateNetworkMetrics(&states,
261 (kEnablingBandwidthHigh + kDisablingBandwidthLow) / 2,
262 kPacketLoss);
263 CheckDecision(&states, true, kPacketLoss);
264 }
265
TEST(FecControllerPlrBasedTest,DisableFecForLowBandwidth)266 TEST(FecControllerPlrBasedTest, DisableFecForLowBandwidth) {
267 auto states = CreateFecControllerPlrBased(true);
268 constexpr float kPacketLoss = kDisablingPacketLossAtLowBw - kEpsilon;
269 UpdateNetworkMetrics(&states, kDisablingBandwidthLow, kPacketLoss);
270 CheckDecision(&states, false, kPacketLoss);
271 }
272
TEST(FecControllerPlrBasedTest,DisableFecForVeryLowBandwidth)273 TEST(FecControllerPlrBasedTest, DisableFecForVeryLowBandwidth) {
274 auto states = CreateFecControllerPlrBased(true);
275 // Below `kEnablingBandwidthLow`, any packet loss fraction can cause FEC to
276 // turn off.
277 UpdateNetworkMetrics(&states, kDisablingBandwidthLow - 1, 1.0);
278 CheckDecision(&states, false, 1.0);
279 }
280
TEST(FecControllerPlrBasedTest,CheckBehaviorOnChangingNetworkMetrics)281 TEST(FecControllerPlrBasedTest, CheckBehaviorOnChangingNetworkMetrics) {
282 // In this test, we let the network metrics to traverse from 1 to 5.
283 // packet-loss ^ 1 | |
284 // | | 2|
285 // | \ \ 3
286 // | \4 \_______
287 // | \_________
288 // |---------5-------> bandwidth
289
290 auto states = CreateFecControllerPlrBased(true);
291 UpdateNetworkMetrics(&states, kDisablingBandwidthLow - 1, 1.0);
292 CheckDecision(&states, false, 1.0);
293
294 UpdateNetworkMetrics(&states, kEnablingBandwidthLow,
295 kEnablingPacketLossAtLowBw * 0.99f);
296 CheckDecision(&states, false, kEnablingPacketLossAtLowBw * 0.99f);
297
298 UpdateNetworkMetrics(&states, kEnablingBandwidthHigh,
299 kEnablingPacketLossAtHighBw);
300 CheckDecision(&states, true, kEnablingPacketLossAtHighBw);
301
302 UpdateNetworkMetrics(&states, kDisablingBandwidthHigh,
303 kDisablingPacketLossAtHighBw);
304 CheckDecision(&states, true, kDisablingPacketLossAtHighBw);
305
306 UpdateNetworkMetrics(&states, kDisablingBandwidthHigh + 1, 0.0);
307 CheckDecision(&states, false, 0.0);
308 }
309
TEST(FecControllerPlrBasedTest,CheckBehaviorOnSpecialCurves)310 TEST(FecControllerPlrBasedTest, CheckBehaviorOnSpecialCurves) {
311 // We test a special configuration, where the points to define the FEC
312 // enabling/disabling curves are placed like the following, otherwise the test
313 // is the same as CheckBehaviorOnChangingNetworkMetrics.
314 //
315 // packet-loss ^ | |
316 // | | C|
317 // | | |
318 // | | D|_______
319 // | A|___B______
320 // |-----------------> bandwidth
321
322 constexpr int kEnablingBandwidthHigh = kEnablingBandwidthLow;
323 constexpr float kDisablingPacketLossAtLowBw = kDisablingPacketLossAtHighBw;
324 FecControllerPlrBasedTestStates states;
325 std::unique_ptr<MockSmoothingFilter> mock_smoothing_filter(
326 new NiceMock<MockSmoothingFilter>());
327 states.packet_loss_smoother = mock_smoothing_filter.get();
328 states.controller.reset(new FecControllerPlrBased(
329 FecControllerPlrBased::Config(
330 true,
331 ThresholdCurve(kEnablingBandwidthLow, kEnablingPacketLossAtLowBw,
332 kEnablingBandwidthHigh, kEnablingPacketLossAtHighBw),
333 ThresholdCurve(kDisablingBandwidthLow, kDisablingPacketLossAtLowBw,
334 kDisablingBandwidthHigh, kDisablingPacketLossAtHighBw),
335 0),
336 std::move(mock_smoothing_filter)));
337
338 UpdateNetworkMetrics(&states, kDisablingBandwidthLow - 1, 1.0);
339 CheckDecision(&states, false, 1.0);
340
341 UpdateNetworkMetrics(&states, kEnablingBandwidthLow,
342 kEnablingPacketLossAtHighBw * 0.99f);
343 CheckDecision(&states, false, kEnablingPacketLossAtHighBw * 0.99f);
344
345 UpdateNetworkMetrics(&states, kEnablingBandwidthHigh,
346 kEnablingPacketLossAtHighBw);
347 CheckDecision(&states, true, kEnablingPacketLossAtHighBw);
348
349 UpdateNetworkMetrics(&states, kDisablingBandwidthHigh,
350 kDisablingPacketLossAtHighBw);
351 CheckDecision(&states, true, kDisablingPacketLossAtHighBw);
352
353 UpdateNetworkMetrics(&states, kDisablingBandwidthHigh + 1, 0.0);
354 CheckDecision(&states, false, 0.0);
355 }
356
TEST(FecControllerPlrBasedTest,SingleThresholdCurveForEnablingAndDisabling)357 TEST(FecControllerPlrBasedTest, SingleThresholdCurveForEnablingAndDisabling) {
358 // Note: To avoid numerical errors, keep kPacketLossAtLowBw and
359 // kPacketLossAthighBw as (negative) integer powers of 2.
360 // This is mostly relevant for the O3 case.
361 constexpr int kBandwidthLow = 10000;
362 constexpr float kPacketLossAtLowBw = 0.25f;
363 constexpr int kBandwidthHigh = 20000;
364 constexpr float kPacketLossAtHighBw = 0.125f;
365 auto curve = ThresholdCurve(kBandwidthLow, kPacketLossAtLowBw, kBandwidthHigh,
366 kPacketLossAtHighBw);
367
368 // B* stands for "below-curve", O* for "on-curve", and A* for "above-curve".
369 //
370 // //
371 // packet-loss ^ //
372 // | | //
373 // | B1 O1 //
374 // | | //
375 // | O2 //
376 // | \ A1 //
377 // | \ //
378 // | O3 A2 //
379 // | B2 \ //
380 // | \ //
381 // | O4--O5---- //
382 // | //
383 // | B3 //
384 // |-----------------> bandwidth //
385
386 struct NetworkState {
387 int bandwidth;
388 float packet_loss;
389 };
390
391 std::vector<NetworkState> below{
392 {kBandwidthLow - 1, kPacketLossAtLowBw + 0.1f}, // B1
393 {(kBandwidthLow + kBandwidthHigh) / 2,
394 (kPacketLossAtLowBw + kPacketLossAtHighBw) / 2 - kEpsilon}, // B2
395 {kBandwidthHigh + 1, kPacketLossAtHighBw - kEpsilon} // B3
396 };
397
398 std::vector<NetworkState> on{
399 {kBandwidthLow, kPacketLossAtLowBw + 0.1f}, // O1
400 {kBandwidthLow, kPacketLossAtLowBw}, // O2
401 {(kBandwidthLow + kBandwidthHigh) / 2,
402 (kPacketLossAtLowBw + kPacketLossAtHighBw) / 2}, // O3
403 {kBandwidthHigh, kPacketLossAtHighBw}, // O4
404 {kBandwidthHigh + 1, kPacketLossAtHighBw}, // O5
405 };
406
407 std::vector<NetworkState> above{
408 {(kBandwidthLow + kBandwidthHigh) / 2,
409 (kPacketLossAtLowBw + kPacketLossAtHighBw) / 2 + kEpsilon}, // A1
410 {kBandwidthHigh + 1, kPacketLossAtHighBw + kEpsilon}, // A2
411 };
412
413 // Test that FEC is turned off whenever we're below the curve, independent
414 // of the starting FEC state.
415 for (NetworkState net_state : below) {
416 for (bool initial_fec_enabled : {false, true}) {
417 auto states =
418 CreateFecControllerPlrBased(initial_fec_enabled, curve, curve);
419 UpdateNetworkMetrics(&states, net_state.bandwidth, net_state.packet_loss);
420 CheckDecision(&states, false, net_state.packet_loss);
421 }
422 }
423
424 // Test that FEC is turned on whenever we're on the curve or above it,
425 // independent of the starting FEC state.
426 for (const std::vector<NetworkState>& states_list : {on, above}) {
427 for (NetworkState net_state : states_list) {
428 for (bool initial_fec_enabled : {false, true}) {
429 auto states =
430 CreateFecControllerPlrBased(initial_fec_enabled, curve, curve);
431 UpdateNetworkMetrics(&states, net_state.bandwidth,
432 net_state.packet_loss);
433 CheckDecision(&states, true, net_state.packet_loss);
434 }
435 }
436 }
437 }
438
TEST(FecControllerPlrBasedTest,FecAlwaysOff)439 TEST(FecControllerPlrBasedTest, FecAlwaysOff) {
440 ThresholdCurve always_off_curve(0, 1.0f + kEpsilon, 0, 1.0f + kEpsilon);
441 for (bool initial_fec_enabled : {false, true}) {
442 for (int bandwidth : {0, 10000}) {
443 for (float packet_loss : {0.0f, 0.5f, 1.0f}) {
444 auto states = CreateFecControllerPlrBased(
445 initial_fec_enabled, always_off_curve, always_off_curve);
446 UpdateNetworkMetrics(&states, bandwidth, packet_loss);
447 CheckDecision(&states, false, packet_loss);
448 }
449 }
450 }
451 }
452
TEST(FecControllerPlrBasedTest,FecAlwaysOn)453 TEST(FecControllerPlrBasedTest, FecAlwaysOn) {
454 ThresholdCurve always_on_curve(0, 0.0f, 0, 0.0f);
455 for (bool initial_fec_enabled : {false, true}) {
456 for (int bandwidth : {0, 10000}) {
457 for (float packet_loss : {0.0f, 0.5f, 1.0f}) {
458 auto states = CreateFecControllerPlrBased(
459 initial_fec_enabled, always_on_curve, always_on_curve);
460 UpdateNetworkMetrics(&states, bandwidth, packet_loss);
461 CheckDecision(&states, true, packet_loss);
462 }
463 }
464 }
465 }
466
467 #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
TEST(FecControllerPlrBasedDeathTest,InvalidConfig)468 TEST(FecControllerPlrBasedDeathTest, InvalidConfig) {
469 FecControllerPlrBasedTestStates states;
470 std::unique_ptr<MockSmoothingFilter> mock_smoothing_filter(
471 new NiceMock<MockSmoothingFilter>());
472 states.packet_loss_smoother = mock_smoothing_filter.get();
473 EXPECT_DEATH(
474 states.controller.reset(new FecControllerPlrBased(
475 FecControllerPlrBased::Config(
476 true,
477 ThresholdCurve(kDisablingBandwidthLow - 1,
478 kEnablingPacketLossAtLowBw, kEnablingBandwidthHigh,
479 kEnablingPacketLossAtHighBw),
480 ThresholdCurve(
481 kDisablingBandwidthLow, kDisablingPacketLossAtLowBw,
482 kDisablingBandwidthHigh, kDisablingPacketLossAtHighBw),
483 0),
484 std::move(mock_smoothing_filter))),
485 "Check failed");
486 }
487 #endif
488
489 } // namespace webrtc
490