Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(30)

Side by Side Diff: webrtc/modules/audio_coding/audio_network_adaptor/fec_controller_rplr_based_unittest.cc

Issue 2672933003: Introduce FecControllerRplrBased (Closed)
Patch Set: Merged Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /*
2 * Copyright (c) 2017 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 <random>
12 #include <utility>
13
14 #include "webrtc/modules/audio_coding/audio_network_adaptor/fec_controller_rplr_ based.h"
15 #include "webrtc/test/gmock.h"
16 #include "webrtc/test/gtest.h"
17
18 namespace webrtc {
19
20 using ::testing::NiceMock;
21 using ::testing::Return;
22 using ::testing::_;
23
24 namespace {
25
26 // The test uses the following settings:
27 //
28 // recoverable ^
29 // packet-loss | | |
30 // | A| C| FEC
31 // | \ \ ON
32 // | FEC \ D\_______
33 // | OFF B\_________
34 // |-----------------> bandwidth
35 //
36 // A : (kDisablingBandwidthLow, kDisablingRecoverablePacketLossAtLowBw)
37 // B : (kDisablingBandwidthHigh, kDisablingRecoverablePacketLossAtHighBw)
38 // C : (kEnablingBandwidthLow, kEnablingRecoverablePacketLossAtLowBw)
39 // D : (kEnablingBandwidthHigh, kEnablingRecoverablePacketLossAtHighBw)
40
41 constexpr int kDisablingBandwidthLow = 15000;
42 constexpr float kDisablingRecoverablePacketLossAtLowBw = 0.08f;
43 constexpr int kDisablingBandwidthHigh = 64000;
44 constexpr float kDisablingRecoverablePacketLossAtHighBw = 0.01f;
45 constexpr int kEnablingBandwidthLow = 17000;
46 constexpr float kEnablingRecoverablePacketLossAtLowBw = 0.1f;
47 constexpr int kEnablingBandwidthHigh = 64000;
48 constexpr float kEnablingRecoverablePacketLossAtHighBw = 0.05f;
49
50 rtc::Optional<float> GetRandomProbabilityOrUnknown() {
51 std::random_device rd;
52 std::mt19937 generator(rd());
53 std::uniform_real_distribution<> distribution(0, 1);
54
55 if (distribution(generator) < 0.2) {
56 return rtc::Optional<float>();
57 } else {
58 return rtc::Optional<float>(distribution(generator));
59 }
60 }
61
62 std::unique_ptr<FecControllerRplrBased> CreateFecControllerRplrBased(
63 bool initial_fec_enabled) {
64 using Threshold = FecControllerRplrBased::Config::Threshold;
65 return std::unique_ptr<FecControllerRplrBased>(
66 new FecControllerRplrBased(FecControllerRplrBased::Config(
67 initial_fec_enabled,
68 Threshold(
69 kEnablingBandwidthLow, kEnablingRecoverablePacketLossAtLowBw,
70 kEnablingBandwidthHigh, kEnablingRecoverablePacketLossAtHighBw),
71 Threshold(
72 kDisablingBandwidthLow, kDisablingRecoverablePacketLossAtLowBw,
73 kDisablingBandwidthHigh, kDisablingRecoverablePacketLossAtHighBw),
74 0, nullptr)));
75 }
76
77 void UpdateNetworkMetrics(
78 FecControllerRplrBased* controller,
79 const rtc::Optional<int>& uplink_bandwidth_bps,
80 const rtc::Optional<float>& uplink_packet_loss,
81 const rtc::Optional<float>& uplink_recoveralbe_packet_loss) {
82 // UpdateNetworkMetrics can accept multiple network metric updates at once.
83 // However, currently, the most used case is to update one metric at a time.
84 // To reflect this fact, we separate the calls.
85 if (uplink_bandwidth_bps) {
86 Controller::NetworkMetrics network_metrics;
87 network_metrics.uplink_bandwidth_bps = uplink_bandwidth_bps;
88 controller->UpdateNetworkMetrics(network_metrics);
89 }
90 if (uplink_packet_loss) {
91 Controller::NetworkMetrics network_metrics;
92 network_metrics.uplink_packet_loss_fraction = uplink_packet_loss;
93 controller->UpdateNetworkMetrics(network_metrics);
94 }
95 if (uplink_recoveralbe_packet_loss) {
96 Controller::NetworkMetrics network_metrics;
97 network_metrics.uplink_recoverable_packet_loss_fraction =
98 uplink_recoveralbe_packet_loss;
99 controller->UpdateNetworkMetrics(network_metrics);
100 }
101 }
102
103 void UpdateNetworkMetrics(
104 FecControllerRplrBased* controller,
105 const rtc::Optional<int>& uplink_bandwidth_bps,
106 const rtc::Optional<float>& uplink_recoveralbe_packet_loss) {
107 // FecControllerRplrBased doesn't current use the PLR (general packet-loss
108 // rate) at all. (This might be changed in the future.) The unit-tests will
109 // use a random value (including unknown), to show this does not interfere.
110 UpdateNetworkMetrics(controller, uplink_bandwidth_bps,
111 GetRandomProbabilityOrUnknown(),
112 uplink_recoveralbe_packet_loss);
113 }
114
115 // Checks that the FEC decision and |uplink_packet_loss_fraction| given by
116 // |states->controller->MakeDecision| matches |expected_enable_fec| and
117 // |expected_uplink_packet_loss_fraction|, respectively.
118 void CheckDecision(FecControllerRplrBased* controller,
119 bool expected_enable_fec,
120 float expected_uplink_packet_loss_fraction) {
121 AudioNetworkAdaptor::EncoderRuntimeConfig config;
122 controller->MakeDecision(&config);
123
124 // Less compact than comparing optionals, but yields more readable errors.
125 EXPECT_TRUE(config.enable_fec);
126 if (config.enable_fec) {
127 EXPECT_EQ(expected_enable_fec, *config.enable_fec);
128 }
129 EXPECT_TRUE(config.uplink_packet_loss_fraction);
130 if (config.uplink_packet_loss_fraction) {
131 EXPECT_EQ(expected_uplink_packet_loss_fraction,
132 *config.uplink_packet_loss_fraction);
133 }
134 }
135
136 } // namespace
137
138 TEST(FecControllerRplrBasedTest, OutputInitValueWhenUplinkBandwidthUnknown) {
139 for (bool initial_fec_enabled : {false, true}) {
140 auto controller = CreateFecControllerRplrBased(initial_fec_enabled);
141 // Let uplink recoverable packet loss fraction be so low that it
142 // would cause FEC to turn off if uplink bandwidth was known.
143 UpdateNetworkMetrics(
144 controller.get(), rtc::Optional<int>(),
145 rtc::Optional<float>(kDisablingRecoverablePacketLossAtHighBw));
146 CheckDecision(controller.get(), initial_fec_enabled,
147 kDisablingRecoverablePacketLossAtHighBw);
148 }
149 }
150
151 TEST(FecControllerRplrBasedTest,
152 OutputInitValueWhenUplinkPacketLossFractionUnknown) {
153 for (bool initial_fec_enabled : {false, true}) {
154 auto controller = CreateFecControllerRplrBased(initial_fec_enabled);
155 // Let uplink bandwidth be so low that it would cause FEC to turn off
156 // if uplink bandwidth packet loss fraction was known.
157 UpdateNetworkMetrics(controller.get(),
158 rtc::Optional<int>(kDisablingBandwidthLow - 1),
159 rtc::Optional<float>());
160 CheckDecision(controller.get(), initial_fec_enabled, 0.0);
161 }
162 }
163
164 TEST(FecControllerRplrBasedTest, EnableFecForHighBandwidth) {
165 auto controller = CreateFecControllerRplrBased(false);
166 UpdateNetworkMetrics(
167 controller.get(), rtc::Optional<int>(kEnablingBandwidthHigh),
168 rtc::Optional<float>(kEnablingRecoverablePacketLossAtHighBw));
169 CheckDecision(controller.get(), true, kEnablingRecoverablePacketLossAtHighBw);
170 }
171
172 TEST(FecControllerRplrBasedTest, UpdateMultipleNetworkMetricsAtOnce) {
173 // This test is similar to EnableFecForHighBandwidth. But instead of
174 // using ::UpdateNetworkMetrics(...), which calls
175 // FecControllerRplrBasedTest::UpdateNetworkMetrics(...) multiple times, we
176 // we call it only once. This is to verify that
177 // FecControllerRplrBasedTest::UpdateNetworkMetrics(...) can handle multiple
178 // network updates at once. This is, however, not a common use case in current
179 // audio_network_adaptor_impl.cc.
180 auto controller = CreateFecControllerRplrBased(false);
181 Controller::NetworkMetrics network_metrics;
182 network_metrics.uplink_bandwidth_bps =
183 rtc::Optional<int>(kEnablingBandwidthHigh);
184 network_metrics.uplink_packet_loss_fraction =
185 rtc::Optional<float>(GetRandomProbabilityOrUnknown());
186 network_metrics.uplink_recoverable_packet_loss_fraction =
187 rtc::Optional<float>(kEnablingRecoverablePacketLossAtHighBw);
188 controller->UpdateNetworkMetrics(network_metrics);
189 CheckDecision(controller.get(), true, kEnablingRecoverablePacketLossAtHighBw);
190 }
191
192 TEST(FecControllerRplrBasedTest, MaintainFecOffForHighBandwidth) {
193 auto controller = CreateFecControllerRplrBased(false);
194 constexpr float kPacketLoss = kEnablingRecoverablePacketLossAtHighBw * 0.99f;
195 UpdateNetworkMetrics(controller.get(),
196 rtc::Optional<int>(kEnablingBandwidthHigh),
197 rtc::Optional<float>(kPacketLoss));
198 CheckDecision(controller.get(), false, kPacketLoss);
199 }
200
201 TEST(FecControllerRplrBasedTest, EnableFecForMediumBandwidth) {
202 auto controller = CreateFecControllerRplrBased(false);
203 constexpr float kPacketLoss = (kEnablingRecoverablePacketLossAtLowBw +
204 kEnablingRecoverablePacketLossAtHighBw) /
205 2.0;
206 UpdateNetworkMetrics(
207 controller.get(),
208 rtc::Optional<int>((kEnablingBandwidthHigh + kEnablingBandwidthLow) / 2),
209 rtc::Optional<float>(kPacketLoss));
210 CheckDecision(controller.get(), true, kPacketLoss);
211 }
212
213 TEST(FecControllerRplrBasedTest, MaintainFecOffForMediumBandwidth) {
214 auto controller = CreateFecControllerRplrBased(false);
215 constexpr float kPacketLoss = kEnablingRecoverablePacketLossAtLowBw * 0.49f +
216 kEnablingRecoverablePacketLossAtHighBw * 0.51f;
217 UpdateNetworkMetrics(
218 controller.get(),
219 rtc::Optional<int>((kEnablingBandwidthHigh + kEnablingBandwidthLow) / 2),
220 rtc::Optional<float>(kPacketLoss));
221 CheckDecision(controller.get(), false, kPacketLoss);
222 }
223
224 TEST(FecControllerRplrBasedTest, EnableFecForLowBandwidth) {
225 auto controller = CreateFecControllerRplrBased(false);
226 UpdateNetworkMetrics(
227 controller.get(), rtc::Optional<int>(kEnablingBandwidthLow),
228 rtc::Optional<float>(kEnablingRecoverablePacketLossAtLowBw));
229 CheckDecision(controller.get(), true, kEnablingRecoverablePacketLossAtLowBw);
230 }
231
232 TEST(FecControllerRplrBasedTest, MaintainFecOffForLowBandwidth) {
233 auto controller = CreateFecControllerRplrBased(false);
234 constexpr float kPacketLoss = kEnablingRecoverablePacketLossAtLowBw * 0.99f;
235 UpdateNetworkMetrics(controller.get(),
236 rtc::Optional<int>(kEnablingBandwidthLow),
237 rtc::Optional<float>(kPacketLoss));
238 CheckDecision(controller.get(), false, kPacketLoss);
239 }
240
241 TEST(FecControllerRplrBasedTest, MaintainFecOffForVeryLowBandwidth) {
242 auto controller = CreateFecControllerRplrBased(false);
243 // Below |kEnablingBandwidthLow|, no recoverable packet loss fraction can
244 // cause FEC to turn on.
245 UpdateNetworkMetrics(controller.get(),
246 rtc::Optional<int>(kEnablingBandwidthLow - 1),
247 rtc::Optional<float>(1.0));
248 CheckDecision(controller.get(), false, 1.0);
249 }
250
251 TEST(FecControllerRplrBasedTest, DisableFecForHighBandwidth) {
252 auto controller = CreateFecControllerRplrBased(true);
253 UpdateNetworkMetrics(
254 controller.get(), rtc::Optional<int>(kDisablingBandwidthHigh),
255 rtc::Optional<float>(kDisablingRecoverablePacketLossAtHighBw));
256 CheckDecision(controller.get(), false,
257 kDisablingRecoverablePacketLossAtHighBw);
258 }
259
260 TEST(FecControllerRplrBasedTest, MaintainFecOnForHighBandwidth) {
261 auto controller = CreateFecControllerRplrBased(true);
262 constexpr float kPacketLoss = kDisablingRecoverablePacketLossAtHighBw * 1.01f;
263 UpdateNetworkMetrics(controller.get(),
264 rtc::Optional<int>(kDisablingBandwidthHigh),
265 rtc::Optional<float>(kPacketLoss));
266 CheckDecision(controller.get(), true, kPacketLoss);
267 }
268
269 TEST(FecControllerRplrBasedTest, DisableFecOnMediumBandwidth) {
270 auto controller = CreateFecControllerRplrBased(true);
271 constexpr float kPacketLoss = (kDisablingRecoverablePacketLossAtLowBw +
272 kDisablingRecoverablePacketLossAtHighBw) /
273 2.0f;
274 UpdateNetworkMetrics(
275 controller.get(),
276 rtc::Optional<int>((kDisablingBandwidthHigh + kDisablingBandwidthLow) /
277 2),
278 rtc::Optional<float>(kPacketLoss));
279 CheckDecision(controller.get(), false, kPacketLoss);
280 }
281
282 TEST(FecControllerRplrBasedTest, MaintainFecOnForMediumBandwidth) {
283 auto controller = CreateFecControllerRplrBased(true);
284 constexpr float kPacketLoss = kDisablingRecoverablePacketLossAtLowBw * 0.51f +
285 kDisablingRecoverablePacketLossAtHighBw * 0.49f;
286 UpdateNetworkMetrics(
287 controller.get(),
288 rtc::Optional<int>((kEnablingBandwidthHigh + kDisablingBandwidthLow) / 2),
289 rtc::Optional<float>(kPacketLoss));
290 CheckDecision(controller.get(), true, kPacketLoss);
291 }
292
293 TEST(FecControllerRplrBasedTest, DisableFecForLowBandwidth) {
294 auto controller = CreateFecControllerRplrBased(true);
295 UpdateNetworkMetrics(
296 controller.get(), rtc::Optional<int>(kDisablingBandwidthLow),
297 rtc::Optional<float>(kDisablingRecoverablePacketLossAtLowBw));
298 CheckDecision(controller.get(), false,
299 kDisablingRecoverablePacketLossAtLowBw);
300 }
301
302 TEST(FecControllerRplrBasedTest, DisableFecForVeryLowBandwidth) {
303 auto controller = CreateFecControllerRplrBased(true);
304 // Below |kEnablingBandwidthLow|, any recoverable packet loss fraction can
305 // cause FEC to turn off.
306 UpdateNetworkMetrics(controller.get(),
307 rtc::Optional<int>(kDisablingBandwidthLow - 1),
308 rtc::Optional<float>(1.0));
309 CheckDecision(controller.get(), false, 1.0);
310 }
311
312 TEST(FecControllerRplrBasedTest, CheckBehaviorOnChangingNetworkMetrics) {
313 // In this test, we let the network metrics to traverse from 1 to 5.
314 //
315 // recoverable ^
316 // packet-loss | 1 | |
317 // | | 2|
318 // | \ \ 3
319 // | \4 \_______
320 // | \_________
321 // |---------5-------> bandwidth
322
323 auto controller = CreateFecControllerRplrBased(true);
324 UpdateNetworkMetrics(controller.get(),
325 rtc::Optional<int>(kDisablingBandwidthLow - 1),
326 rtc::Optional<float>(1.0));
327 CheckDecision(controller.get(), false, 1.0);
328
329 UpdateNetworkMetrics(
330 controller.get(), rtc::Optional<int>(kEnablingBandwidthLow),
331 rtc::Optional<float>(kEnablingRecoverablePacketLossAtLowBw * 0.99f));
332 CheckDecision(controller.get(), false,
333 kEnablingRecoverablePacketLossAtLowBw * 0.99f);
334
335 UpdateNetworkMetrics(
336 controller.get(), rtc::Optional<int>(kEnablingBandwidthHigh),
337 rtc::Optional<float>(kEnablingRecoverablePacketLossAtHighBw));
338 CheckDecision(controller.get(), true, kEnablingRecoverablePacketLossAtHighBw);
339
340 UpdateNetworkMetrics(
341 controller.get(), rtc::Optional<int>(kDisablingBandwidthHigh),
342 rtc::Optional<float>(kDisablingRecoverablePacketLossAtHighBw * 1.01f));
343 CheckDecision(controller.get(), true,
344 kDisablingRecoverablePacketLossAtHighBw * 1.01f);
345
346 UpdateNetworkMetrics(controller.get(),
347 rtc::Optional<int>(kDisablingBandwidthHigh + 1),
348 rtc::Optional<float>(0.0));
349 CheckDecision(controller.get(), false, 0.0);
350 }
351
352 TEST(FecControllerRplrBasedTest, CheckBehaviorOnSpecialCurves) {
353 // We test a special configuration, where the points to define the FEC
354 // enabling/disabling curves are placed like the following, otherwise the test
355 // is the same as CheckBehaviorOnChangingNetworkMetrics.
356 //
357 // recoverable ^
358 // packet-loss | | |
359 // | | C|
360 // | | |
361 // | | D|_______
362 // | A|___B______
363 // |-----------------> bandwidth
364
365 constexpr int kEnablingBandwidthHigh = kEnablingBandwidthLow;
366 constexpr float kDisablingRecoverablePacketLossAtLowBw =
367 kDisablingRecoverablePacketLossAtHighBw;
368 using Threshold = FecControllerRplrBased::Config::Threshold;
369 FecControllerRplrBased controller(FecControllerRplrBased::Config(
370 true,
371 Threshold(kEnablingBandwidthLow, kEnablingRecoverablePacketLossAtLowBw,
372 kEnablingBandwidthHigh, kEnablingRecoverablePacketLossAtHighBw),
373 Threshold(kDisablingBandwidthLow, kDisablingRecoverablePacketLossAtLowBw,
374 kDisablingBandwidthHigh,
375 kDisablingRecoverablePacketLossAtHighBw),
376 0, nullptr));
377
378 UpdateNetworkMetrics(&controller,
379 rtc::Optional<int>(kDisablingBandwidthLow - 1),
380 rtc::Optional<float>(1.0));
381 CheckDecision(&controller, false, 1.0);
382
383 UpdateNetworkMetrics(
384 &controller, rtc::Optional<int>(kEnablingBandwidthLow),
385 rtc::Optional<float>(kEnablingRecoverablePacketLossAtHighBw * 0.99f));
386 CheckDecision(&controller, false,
387 kEnablingRecoverablePacketLossAtHighBw * 0.99f);
388
389 UpdateNetworkMetrics(
390 &controller, rtc::Optional<int>(kEnablingBandwidthHigh),
391 rtc::Optional<float>(kEnablingRecoverablePacketLossAtHighBw));
392 CheckDecision(&controller, true, kEnablingRecoverablePacketLossAtHighBw);
393
394 UpdateNetworkMetrics(
395 &controller, rtc::Optional<int>(kDisablingBandwidthHigh),
396 rtc::Optional<float>(kDisablingRecoverablePacketLossAtHighBw * 1.01f));
397 CheckDecision(&controller, true,
398 kDisablingRecoverablePacketLossAtHighBw * 1.01f);
399
400 UpdateNetworkMetrics(&controller,
401 rtc::Optional<int>(kDisablingBandwidthHigh + 1),
402 rtc::Optional<float>(0.0));
403 CheckDecision(&controller, false, 0.0);
404 }
405
406 #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
407 TEST(FecControllerRplrBasedDeathTest, InvalidConfig) {
408 using Threshold = FecControllerRplrBased::Config::Threshold;
409 EXPECT_DEATH(
410 FecControllerRplrBased controller(FecControllerRplrBased::Config(
411 true,
412 Threshold(
413 kDisablingBandwidthLow - 1, kEnablingRecoverablePacketLossAtLowBw,
414 kEnablingBandwidthHigh, kEnablingRecoverablePacketLossAtHighBw),
415 Threshold(
416 kDisablingBandwidthLow, kDisablingRecoverablePacketLossAtLowBw,
417 kDisablingBandwidthHigh, kDisablingRecoverablePacketLossAtHighBw),
418 0, nullptr)),
419 "Check failed");
420 }
421 #endif
422
423 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698