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

Side by Side Diff: webrtc/modules/audio_coding/audio_network_adaptor/fec_controller_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
« no previous file with comments | « webrtc/modules/audio_coding/audio_network_adaptor/fec_controller_rplr_based_unittest.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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 <utility>
12
13 #include "webrtc/common_audio/mocks/mock_smoothing_filter.h"
14 #include "webrtc/modules/audio_coding/audio_network_adaptor/fec_controller.h"
15 #include "webrtc/test/gtest.h"
16
17 namespace webrtc {
18
19 using ::testing::NiceMock;
20 using ::testing::Return;
21 using ::testing::_;
22
23 namespace {
24
25 // The test uses the following settings:
26 //
27 // packet-loss ^ | |
28 // | A| C| FEC
29 // | \ \ ON
30 // | FEC \ D\_______
31 // | OFF B\_________
32 // |-----------------> bandwidth
33 //
34 // A : (kDisablingBandwidthLow, kDisablingPacketLossAtLowBw)
35 // B : (kDisablingBandwidthHigh, kDisablingPacketLossAtHighBw)
36 // C : (kEnablingBandwidthLow, kEnablingPacketLossAtLowBw)
37 // D : (kEnablingBandwidthHigh, kEnablingPacketLossAtHighBw)
38
39 constexpr int kDisablingBandwidthLow = 15000;
40 constexpr float kDisablingPacketLossAtLowBw = 0.08f;
41 constexpr int kDisablingBandwidthHigh = 64000;
42 constexpr float kDisablingPacketLossAtHighBw = 0.01f;
43 constexpr int kEnablingBandwidthLow = 17000;
44 constexpr float kEnablingPacketLossAtLowBw = 0.1f;
45 constexpr int kEnablingBandwidthHigh = 64000;
46 constexpr float kEnablingPacketLossAtHighBw = 0.05f;
47
48 struct FecControllerStates {
49 std::unique_ptr<FecController> controller;
50 MockSmoothingFilter* packet_loss_smoother;
51 };
52
53 FecControllerStates CreateFecController(bool initial_fec_enabled) {
54 FecControllerStates states;
55 std::unique_ptr<MockSmoothingFilter> mock_smoothing_filter(
56 new NiceMock<MockSmoothingFilter>());
57 states.packet_loss_smoother = mock_smoothing_filter.get();
58 using Threshold = FecController::Config::Threshold;
59 states.controller.reset(new FecController(
60 FecController::Config(
61 initial_fec_enabled,
62 Threshold(kEnablingBandwidthLow, kEnablingPacketLossAtLowBw,
63 kEnablingBandwidthHigh, kEnablingPacketLossAtHighBw),
64 Threshold(kDisablingBandwidthLow, kDisablingPacketLossAtLowBw,
65 kDisablingBandwidthHigh, kDisablingPacketLossAtHighBw),
66 0, nullptr),
67 std::move(mock_smoothing_filter)));
68 return states;
69 }
70
71 void UpdateNetworkMetrics(FecControllerStates* states,
72 const rtc::Optional<int>& uplink_bandwidth_bps,
73 const rtc::Optional<float>& uplink_packet_loss) {
74 // UpdateNetworkMetrics can accept multiple network metric updates at once.
75 // However, currently, the most used case is to update one metric at a time.
76 // To reflect this fact, we separate the calls.
77 if (uplink_bandwidth_bps) {
78 Controller::NetworkMetrics network_metrics;
79 network_metrics.uplink_bandwidth_bps = uplink_bandwidth_bps;
80 states->controller->UpdateNetworkMetrics(network_metrics);
81 }
82 if (uplink_packet_loss) {
83 Controller::NetworkMetrics network_metrics;
84 network_metrics.uplink_packet_loss_fraction = uplink_packet_loss;
85 EXPECT_CALL(*states->packet_loss_smoother, AddSample(*uplink_packet_loss));
86 states->controller->UpdateNetworkMetrics(network_metrics);
87 // This is called during CheckDecision().
88 EXPECT_CALL(*states->packet_loss_smoother, GetAverage())
89 .WillOnce(Return(rtc::Optional<float>(*uplink_packet_loss)));
90 }
91 }
92
93 // Checks that the FEC decision and |uplink_packet_loss_fraction| given by
94 // |states->controller->MakeDecision| matches |expected_enable_fec| and
95 // |expected_uplink_packet_loss_fraction|, respectively.
96 void CheckDecision(FecControllerStates* states,
97 bool expected_enable_fec,
98 float expected_uplink_packet_loss_fraction) {
99 AudioNetworkAdaptor::EncoderRuntimeConfig config;
100 states->controller->MakeDecision(&config);
101 EXPECT_EQ(rtc::Optional<bool>(expected_enable_fec), config.enable_fec);
102 EXPECT_EQ(rtc::Optional<float>(expected_uplink_packet_loss_fraction),
103 config.uplink_packet_loss_fraction);
104 }
105
106 } // namespace
107
108 TEST(FecControllerTest, OutputInitValueWhenUplinkBandwidthUnknown) {
109 constexpr bool kInitialFecEnabled = true;
110 auto states = CreateFecController(kInitialFecEnabled);
111 // Let uplink packet loss fraction be so low that would cause FEC to turn off
112 // if uplink bandwidth was known.
113 UpdateNetworkMetrics(&states, rtc::Optional<int>(),
114 rtc::Optional<float>(kDisablingPacketLossAtHighBw));
115 CheckDecision(&states, kInitialFecEnabled, kDisablingPacketLossAtHighBw);
116 }
117
118 TEST(FecControllerTest, OutputInitValueWhenUplinkPacketLossFractionUnknown) {
119 constexpr bool kInitialFecEnabled = true;
120 auto states = CreateFecController(kInitialFecEnabled);
121 // Let uplink bandwidth be so low that would cause FEC to turn off if uplink
122 // bandwidth packet loss fraction was known.
123 UpdateNetworkMetrics(&states, rtc::Optional<int>(kDisablingBandwidthLow - 1),
124 rtc::Optional<float>());
125 CheckDecision(&states, kInitialFecEnabled, 0.0);
126 }
127
128 TEST(FecControllerTest, EnableFecForHighBandwidth) {
129 auto states = CreateFecController(false);
130 UpdateNetworkMetrics(&states, rtc::Optional<int>(kEnablingBandwidthHigh),
131 rtc::Optional<float>(kEnablingPacketLossAtHighBw));
132 CheckDecision(&states, true, kEnablingPacketLossAtHighBw);
133 }
134
135 TEST(FecControllerTest, UpdateMultipleNetworkMetricsAtOnce) {
136 // This test is similar to EnableFecForHighBandwidth. But instead of
137 // using ::UpdateNetworkMetrics(...), which calls
138 // FecController::UpdateNetworkMetrics(...) multiple times, we
139 // we call it only once. This is to verify that
140 // FecController::UpdateNetworkMetrics(...) can handle multiple
141 // network updates at once. This is, however, not a common use case in current
142 // audio_network_adaptor_impl.cc.
143 auto states = CreateFecController(false);
144 Controller::NetworkMetrics network_metrics;
145 network_metrics.uplink_bandwidth_bps =
146 rtc::Optional<int>(kEnablingBandwidthHigh);
147 network_metrics.uplink_packet_loss_fraction =
148 rtc::Optional<float>(kEnablingPacketLossAtHighBw);
149 EXPECT_CALL(*states.packet_loss_smoother, GetAverage())
150 .WillOnce(Return(rtc::Optional<float>(kEnablingPacketLossAtHighBw)));
151 states.controller->UpdateNetworkMetrics(network_metrics);
152 CheckDecision(&states, true, kEnablingPacketLossAtHighBw);
153 }
154
155 TEST(FecControllerTest, MaintainFecOffForHighBandwidth) {
156 auto states = CreateFecController(false);
157 constexpr float kPacketLoss = kEnablingPacketLossAtHighBw * 0.99f;
158 UpdateNetworkMetrics(&states, rtc::Optional<int>(kEnablingBandwidthHigh),
159 rtc::Optional<float>(kPacketLoss));
160 CheckDecision(&states, false, kPacketLoss);
161 }
162
163 TEST(FecControllerTest, EnableFecForMediumBandwidth) {
164 auto states = CreateFecController(false);
165 constexpr float kPacketLoss =
166 (kEnablingPacketLossAtLowBw + kEnablingPacketLossAtHighBw) / 2.0;
167 UpdateNetworkMetrics(
168 &states,
169 rtc::Optional<int>((kEnablingBandwidthHigh + kEnablingBandwidthLow) / 2),
170 rtc::Optional<float>(kPacketLoss));
171 CheckDecision(&states, true, kPacketLoss);
172 }
173
174 TEST(FecControllerTest, MaintainFecOffForMediumBandwidth) {
175 auto states = CreateFecController(false);
176 constexpr float kPacketLoss =
177 kEnablingPacketLossAtLowBw * 0.49f + kEnablingPacketLossAtHighBw * 0.51f;
178 UpdateNetworkMetrics(
179 &states,
180 rtc::Optional<int>((kEnablingBandwidthHigh + kEnablingBandwidthLow) / 2),
181 rtc::Optional<float>(kPacketLoss));
182 CheckDecision(&states, false, kPacketLoss);
183 }
184
185 TEST(FecControllerTest, EnableFecForLowBandwidth) {
186 auto states = CreateFecController(false);
187 UpdateNetworkMetrics(&states, rtc::Optional<int>(kEnablingBandwidthLow),
188 rtc::Optional<float>(kEnablingPacketLossAtLowBw));
189 CheckDecision(&states, true, kEnablingPacketLossAtLowBw);
190 }
191
192 TEST(FecControllerTest, MaintainFecOffForLowBandwidth) {
193 auto states = CreateFecController(false);
194 constexpr float kPacketLoss = kEnablingPacketLossAtLowBw * 0.99f;
195 UpdateNetworkMetrics(&states, rtc::Optional<int>(kEnablingBandwidthLow),
196 rtc::Optional<float>(kPacketLoss));
197 CheckDecision(&states, false, kPacketLoss);
198 }
199
200 TEST(FecControllerTest, MaintainFecOffForVeryLowBandwidth) {
201 auto states = CreateFecController(false);
202 // Below |kEnablingBandwidthLow|, no packet loss fraction can cause FEC to
203 // turn on.
204 UpdateNetworkMetrics(&states, rtc::Optional<int>(kEnablingBandwidthLow - 1),
205 rtc::Optional<float>(1.0));
206 CheckDecision(&states, false, 1.0);
207 }
208
209 TEST(FecControllerTest, DisableFecForHighBandwidth) {
210 auto states = CreateFecController(true);
211 UpdateNetworkMetrics(&states, rtc::Optional<int>(kDisablingBandwidthHigh),
212 rtc::Optional<float>(kDisablingPacketLossAtHighBw));
213 CheckDecision(&states, false, kDisablingPacketLossAtHighBw);
214 }
215
216 TEST(FecControllerTest, MaintainFecOnForHighBandwidth) {
217 auto states = CreateFecController(true);
218 constexpr float kPacketLoss = kDisablingPacketLossAtHighBw * 1.01f;
219 UpdateNetworkMetrics(&states, rtc::Optional<int>(kDisablingBandwidthHigh),
220 rtc::Optional<float>(kPacketLoss));
221 CheckDecision(&states, true, kPacketLoss);
222 }
223
224 TEST(FecControllerTest, DisableFecOnMediumBandwidth) {
225 auto states = CreateFecController(true);
226 constexpr float kPacketLoss =
227 (kDisablingPacketLossAtLowBw + kDisablingPacketLossAtHighBw) / 2.0f;
228 UpdateNetworkMetrics(
229 &states, rtc::Optional<int>(
230 (kDisablingBandwidthHigh + kDisablingBandwidthLow) / 2),
231 rtc::Optional<float>(kPacketLoss));
232 CheckDecision(&states, false, kPacketLoss);
233 }
234
235 TEST(FecControllerTest, MaintainFecOnForMediumBandwidth) {
236 auto states = CreateFecController(true);
237 constexpr float kPacketLoss = kDisablingPacketLossAtLowBw * 0.51f +
238 kDisablingPacketLossAtHighBw * 0.49f;
239 UpdateNetworkMetrics(
240 &states,
241 rtc::Optional<int>((kEnablingBandwidthHigh + kDisablingBandwidthLow) / 2),
242 rtc::Optional<float>(kPacketLoss));
243 CheckDecision(&states, true, kPacketLoss);
244 }
245
246 TEST(FecControllerTest, DisableFecForLowBandwidth) {
247 auto states = CreateFecController(true);
248 UpdateNetworkMetrics(&states, rtc::Optional<int>(kDisablingBandwidthLow),
249 rtc::Optional<float>(kDisablingPacketLossAtLowBw));
250 CheckDecision(&states, false, kDisablingPacketLossAtLowBw);
251 }
252
253 TEST(FecControllerTest, DisableFecForVeryLowBandwidth) {
254 auto states = CreateFecController(true);
255 // Below |kEnablingBandwidthLow|, any packet loss fraction can cause FEC to
256 // turn off.
257 UpdateNetworkMetrics(&states, rtc::Optional<int>(kDisablingBandwidthLow - 1),
258 rtc::Optional<float>(1.0));
259 CheckDecision(&states, false, 1.0);
260 }
261
262 TEST(FecControllerTest, CheckBehaviorOnChangingNetworkMetrics) {
263 // In this test, we let the network metrics to traverse from 1 to 5.
264 // packet-loss ^ 1 | |
265 // | | 2|
266 // | \ \ 3
267 // | \4 \_______
268 // | \_________
269 // |---------5-------> bandwidth
270
271 auto states = CreateFecController(true);
272 UpdateNetworkMetrics(&states, rtc::Optional<int>(kDisablingBandwidthLow - 1),
273 rtc::Optional<float>(1.0));
274 CheckDecision(&states, false, 1.0);
275
276 UpdateNetworkMetrics(
277 &states, rtc::Optional<int>(kEnablingBandwidthLow),
278 rtc::Optional<float>(kEnablingPacketLossAtLowBw * 0.99f));
279 CheckDecision(&states, false, kEnablingPacketLossAtLowBw * 0.99f);
280
281 UpdateNetworkMetrics(&states, rtc::Optional<int>(kEnablingBandwidthHigh),
282 rtc::Optional<float>(kEnablingPacketLossAtHighBw));
283 CheckDecision(&states, true, kEnablingPacketLossAtHighBw);
284
285 UpdateNetworkMetrics(
286 &states, rtc::Optional<int>(kDisablingBandwidthHigh),
287 rtc::Optional<float>(kDisablingPacketLossAtHighBw * 1.01f));
288 CheckDecision(&states, true, kDisablingPacketLossAtHighBw * 1.01f);
289
290 UpdateNetworkMetrics(&states, rtc::Optional<int>(kDisablingBandwidthHigh + 1),
291 rtc::Optional<float>(0.0));
292 CheckDecision(&states, false, 0.0);
293 }
294
295 TEST(FecControllerTest, CheckBehaviorOnSpecialCurves) {
296 // We test a special configuration, where the points to define the FEC
297 // enabling/disabling curves are placed like the following, otherwise the test
298 // is the same as CheckBehaviorOnChangingNetworkMetrics.
299 //
300 // packet-loss ^ | |
301 // | | C|
302 // | | |
303 // | | D|_______
304 // | A|___B______
305 // |-----------------> bandwidth
306
307 constexpr int kEnablingBandwidthHigh = kEnablingBandwidthLow;
308 constexpr float kDisablingPacketLossAtLowBw = kDisablingPacketLossAtHighBw;
309 FecControllerStates states;
310 std::unique_ptr<MockSmoothingFilter> mock_smoothing_filter(
311 new NiceMock<MockSmoothingFilter>());
312 states.packet_loss_smoother = mock_smoothing_filter.get();
313 using Threshold = FecController::Config::Threshold;
314 states.controller.reset(new FecController(
315 FecController::Config(
316 true, Threshold(kEnablingBandwidthLow, kEnablingPacketLossAtLowBw,
317 kEnablingBandwidthHigh, kEnablingPacketLossAtHighBw),
318 Threshold(kDisablingBandwidthLow, kDisablingPacketLossAtLowBw,
319 kDisablingBandwidthHigh, kDisablingPacketLossAtHighBw),
320 0, nullptr),
321 std::move(mock_smoothing_filter)));
322
323 UpdateNetworkMetrics(&states, rtc::Optional<int>(kDisablingBandwidthLow - 1),
324 rtc::Optional<float>(1.0));
325 CheckDecision(&states, false, 1.0);
326
327 UpdateNetworkMetrics(
328 &states, rtc::Optional<int>(kEnablingBandwidthLow),
329 rtc::Optional<float>(kEnablingPacketLossAtHighBw * 0.99f));
330 CheckDecision(&states, false, kEnablingPacketLossAtHighBw * 0.99f);
331
332 UpdateNetworkMetrics(&states, rtc::Optional<int>(kEnablingBandwidthHigh),
333 rtc::Optional<float>(kEnablingPacketLossAtHighBw));
334 CheckDecision(&states, true, kEnablingPacketLossAtHighBw);
335
336 UpdateNetworkMetrics(
337 &states, rtc::Optional<int>(kDisablingBandwidthHigh),
338 rtc::Optional<float>(kDisablingPacketLossAtHighBw * 1.01f));
339 CheckDecision(&states, true, kDisablingPacketLossAtHighBw * 1.01f);
340
341 UpdateNetworkMetrics(&states, rtc::Optional<int>(kDisablingBandwidthHigh + 1),
342 rtc::Optional<float>(0.0));
343 CheckDecision(&states, false, 0.0);
344 }
345
346 #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
347 TEST(FecControllerDeathTest, InvalidConfig) {
348 FecControllerStates states;
349 std::unique_ptr<MockSmoothingFilter> mock_smoothing_filter(
350 new NiceMock<MockSmoothingFilter>());
351 states.packet_loss_smoother = mock_smoothing_filter.get();
352 using Threshold = FecController::Config::Threshold;
353 EXPECT_DEATH(
354 states.controller.reset(new FecController(
355 FecController::Config(
356 true,
357 Threshold(kDisablingBandwidthLow - 1, kEnablingPacketLossAtLowBw,
358 kEnablingBandwidthHigh, kEnablingPacketLossAtHighBw),
359 Threshold(kDisablingBandwidthLow, kDisablingPacketLossAtLowBw,
360 kDisablingBandwidthHigh, kDisablingPacketLossAtHighBw),
361 0, nullptr),
362 std::move(mock_smoothing_filter))),
363 "Check failed");
364 }
365 #endif
366
367 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/modules/audio_coding/audio_network_adaptor/fec_controller_rplr_based_unittest.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698