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/controller_manager.h"
12 
13 #include <string>
14 #include <utility>
15 
16 #include "absl/strings/string_view.h"
17 #include "modules/audio_coding/audio_network_adaptor/mock/mock_controller.h"
18 #include "modules/audio_coding/audio_network_adaptor/mock/mock_debug_dump_writer.h"
19 #include "rtc_base/fake_clock.h"
20 #include "rtc_base/ignore_wundef.h"
21 #include "test/gtest.h"
22 
23 #if WEBRTC_ENABLE_PROTOBUF
24 RTC_PUSH_IGNORING_WUNDEF()
25 #ifdef WEBRTC_ANDROID_PLATFORM_BUILD
26 #include "external/webrtc/webrtc/modules/audio_coding/audio_network_adaptor/config.pb.h"
27 #else
28 #include "modules/audio_coding/audio_network_adaptor/config.pb.h"
29 #endif
30 RTC_POP_IGNORING_WUNDEF()
31 #endif
32 
33 namespace webrtc {
34 
35 using ::testing::_;
36 using ::testing::NiceMock;
37 
38 namespace {
39 
40 constexpr size_t kNumControllers = 4;
41 constexpr int kChracteristicBandwithBps[2] = {15000, 0};
42 constexpr float kChracteristicPacketLossFraction[2] = {0.2f, 0.0f};
43 constexpr int kMinReorderingTimeMs = 200;
44 constexpr int kFactor = 100;
45 constexpr float kMinReorderingSquareDistance = 1.0f / kFactor / kFactor;
46 
47 // `kMinUplinkBandwidthBps` and `kMaxUplinkBandwidthBps` are copied from
48 // controller_manager.cc
49 constexpr int kMinUplinkBandwidthBps = 0;
50 constexpr int kMaxUplinkBandwidthBps = 120000;
51 constexpr int kMinBandwithChangeBps =
52     (kMaxUplinkBandwidthBps - kMinUplinkBandwidthBps) / kFactor;
53 
54 struct ControllerManagerStates {
55   std::unique_ptr<ControllerManager> controller_manager;
56   std::vector<MockController*> mock_controllers;
57 };
58 
CreateControllerManager()59 ControllerManagerStates CreateControllerManager() {
60   ControllerManagerStates states;
61   std::vector<std::unique_ptr<Controller>> controllers;
62   std::map<const Controller*, std::pair<int, float>> chracteristic_points;
63   for (size_t i = 0; i < kNumControllers; ++i) {
64     auto controller =
65         std::unique_ptr<MockController>(new NiceMock<MockController>());
66     EXPECT_CALL(*controller, Die());
67     states.mock_controllers.push_back(controller.get());
68     controllers.push_back(std::move(controller));
69   }
70 
71   // Assign characteristic points to the last two controllers.
72   chracteristic_points[states.mock_controllers[kNumControllers - 2]] =
73       std::make_pair(kChracteristicBandwithBps[0],
74                      kChracteristicPacketLossFraction[0]);
75   chracteristic_points[states.mock_controllers[kNumControllers - 1]] =
76       std::make_pair(kChracteristicBandwithBps[1],
77                      kChracteristicPacketLossFraction[1]);
78 
79   states.controller_manager.reset(new ControllerManagerImpl(
80       ControllerManagerImpl::Config(kMinReorderingTimeMs,
81                                     kMinReorderingSquareDistance),
82       std::move(controllers), chracteristic_points));
83   return states;
84 }
85 
86 // `expected_order` contains the expected indices of all controllers in the
87 // vector of controllers returned by GetSortedControllers(). A negative index
88 // means that we do not care about its exact place, but we do check that it
89 // exists in the vector.
CheckControllersOrder(ControllerManagerStates * states,const absl::optional<int> & uplink_bandwidth_bps,const absl::optional<float> & uplink_packet_loss_fraction,const std::vector<int> & expected_order)90 void CheckControllersOrder(
91     ControllerManagerStates* states,
92     const absl::optional<int>& uplink_bandwidth_bps,
93     const absl::optional<float>& uplink_packet_loss_fraction,
94     const std::vector<int>& expected_order) {
95   RTC_DCHECK_EQ(kNumControllers, expected_order.size());
96   Controller::NetworkMetrics metrics;
97   metrics.uplink_bandwidth_bps = uplink_bandwidth_bps;
98   metrics.uplink_packet_loss_fraction = uplink_packet_loss_fraction;
99   auto check = states->controller_manager->GetSortedControllers(metrics);
100   EXPECT_EQ(states->mock_controllers.size(), check.size());
101   for (size_t i = 0; i < states->mock_controllers.size(); ++i) {
102     if (expected_order[i] >= 0) {
103       EXPECT_EQ(states->mock_controllers[i], check[expected_order[i]]);
104     } else {
105       EXPECT_NE(check.end(), std::find(check.begin(), check.end(),
106                                        states->mock_controllers[i]));
107     }
108   }
109 }
110 
111 }  // namespace
112 
TEST(ControllerManagerTest,GetControllersReturnAllControllers)113 TEST(ControllerManagerTest, GetControllersReturnAllControllers) {
114   auto states = CreateControllerManager();
115   auto check = states.controller_manager->GetControllers();
116   // Verify that controllers in `check` are one-to-one mapped to those in
117   // `mock_controllers_`.
118   EXPECT_EQ(states.mock_controllers.size(), check.size());
119   for (auto& controller : check)
120     EXPECT_NE(states.mock_controllers.end(),
121               std::find(states.mock_controllers.begin(),
122                         states.mock_controllers.end(), controller));
123 }
124 
TEST(ControllerManagerTest,ControllersInDefaultOrderOnEmptyNetworkMetrics)125 TEST(ControllerManagerTest, ControllersInDefaultOrderOnEmptyNetworkMetrics) {
126   auto states = CreateControllerManager();
127   // `network_metrics` are empty, and the controllers are supposed to follow the
128   // default order.
129   CheckControllersOrder(&states, absl::nullopt, absl::nullopt, {0, 1, 2, 3});
130 }
131 
TEST(ControllerManagerTest,ControllersWithoutCharPointAtEndAndInDefaultOrder)132 TEST(ControllerManagerTest, ControllersWithoutCharPointAtEndAndInDefaultOrder) {
133   auto states = CreateControllerManager();
134   CheckControllersOrder(&states, 0, 0.0,
135                         {kNumControllers - 2, kNumControllers - 1, -1, -1});
136 }
137 
TEST(ControllerManagerTest,ControllersWithCharPointDependOnNetworkMetrics)138 TEST(ControllerManagerTest, ControllersWithCharPointDependOnNetworkMetrics) {
139   auto states = CreateControllerManager();
140   CheckControllersOrder(&states, kChracteristicBandwithBps[1],
141                         kChracteristicPacketLossFraction[1],
142                         {kNumControllers - 2, kNumControllers - 1, 1, 0});
143 }
144 
TEST(ControllerManagerTest,DoNotReorderBeforeMinReordingTime)145 TEST(ControllerManagerTest, DoNotReorderBeforeMinReordingTime) {
146   rtc::ScopedFakeClock fake_clock;
147   auto states = CreateControllerManager();
148   CheckControllersOrder(&states, kChracteristicBandwithBps[0],
149                         kChracteristicPacketLossFraction[0],
150                         {kNumControllers - 2, kNumControllers - 1, 0, 1});
151   fake_clock.AdvanceTime(TimeDelta::Millis(kMinReorderingTimeMs - 1));
152   // Move uplink bandwidth and packet loss fraction to the other controller's
153   // characteristic point, which would cause controller manager to reorder the
154   // controllers if time had reached min reordering time.
155   CheckControllersOrder(&states, kChracteristicBandwithBps[1],
156                         kChracteristicPacketLossFraction[1],
157                         {kNumControllers - 2, kNumControllers - 1, 0, 1});
158 }
159 
TEST(ControllerManagerTest,ReorderBeyondMinReordingTimeAndMinDistance)160 TEST(ControllerManagerTest, ReorderBeyondMinReordingTimeAndMinDistance) {
161   rtc::ScopedFakeClock fake_clock;
162   auto states = CreateControllerManager();
163   constexpr int kBandwidthBps =
164       (kChracteristicBandwithBps[0] + kChracteristicBandwithBps[1]) / 2;
165   constexpr float kPacketLossFraction = (kChracteristicPacketLossFraction[0] +
166                                          kChracteristicPacketLossFraction[1]) /
167                                         2.0f;
168   // Set network metrics to be in the middle between the characteristic points
169   // of two controllers.
170   CheckControllersOrder(&states, kBandwidthBps, kPacketLossFraction,
171                         {kNumControllers - 2, kNumControllers - 1, 0, 1});
172   fake_clock.AdvanceTime(TimeDelta::Millis(kMinReorderingTimeMs));
173   // Then let network metrics move a little towards the other controller.
174   CheckControllersOrder(&states, kBandwidthBps - kMinBandwithChangeBps - 1,
175                         kPacketLossFraction,
176                         {kNumControllers - 2, kNumControllers - 1, 1, 0});
177 }
178 
TEST(ControllerManagerTest,DoNotReorderIfNetworkMetricsChangeTooSmall)179 TEST(ControllerManagerTest, DoNotReorderIfNetworkMetricsChangeTooSmall) {
180   rtc::ScopedFakeClock fake_clock;
181   auto states = CreateControllerManager();
182   constexpr int kBandwidthBps =
183       (kChracteristicBandwithBps[0] + kChracteristicBandwithBps[1]) / 2;
184   constexpr float kPacketLossFraction = (kChracteristicPacketLossFraction[0] +
185                                          kChracteristicPacketLossFraction[1]) /
186                                         2.0f;
187   // Set network metrics to be in the middle between the characteristic points
188   // of two controllers.
189   CheckControllersOrder(&states, kBandwidthBps, kPacketLossFraction,
190                         {kNumControllers - 2, kNumControllers - 1, 0, 1});
191   fake_clock.AdvanceTime(TimeDelta::Millis(kMinReorderingTimeMs));
192   // Then let network metrics move a little towards the other controller.
193   CheckControllersOrder(&states, kBandwidthBps - kMinBandwithChangeBps + 1,
194                         kPacketLossFraction,
195                         {kNumControllers - 2, kNumControllers - 1, 0, 1});
196 }
197 
198 #if WEBRTC_ENABLE_PROTOBUF
199 
200 namespace {
201 
AddBitrateControllerConfig(audio_network_adaptor::config::ControllerManager * config)202 void AddBitrateControllerConfig(
203     audio_network_adaptor::config::ControllerManager* config) {
204   config->add_controllers()->mutable_bitrate_controller();
205 }
206 
AddChannelControllerConfig(audio_network_adaptor::config::ControllerManager * config)207 void AddChannelControllerConfig(
208     audio_network_adaptor::config::ControllerManager* config) {
209   auto controller_config =
210       config->add_controllers()->mutable_channel_controller();
211   controller_config->set_channel_1_to_2_bandwidth_bps(31000);
212   controller_config->set_channel_2_to_1_bandwidth_bps(29000);
213 }
214 
AddDtxControllerConfig(audio_network_adaptor::config::ControllerManager * config)215 void AddDtxControllerConfig(
216     audio_network_adaptor::config::ControllerManager* config) {
217   auto controller_config = config->add_controllers()->mutable_dtx_controller();
218   controller_config->set_dtx_enabling_bandwidth_bps(55000);
219   controller_config->set_dtx_disabling_bandwidth_bps(65000);
220 }
221 
AddFecControllerConfig(audio_network_adaptor::config::ControllerManager * config)222 void AddFecControllerConfig(
223     audio_network_adaptor::config::ControllerManager* config) {
224   auto controller_config_ext = config->add_controllers();
225   auto controller_config = controller_config_ext->mutable_fec_controller();
226   auto fec_enabling_threshold =
227       controller_config->mutable_fec_enabling_threshold();
228   fec_enabling_threshold->set_low_bandwidth_bps(17000);
229   fec_enabling_threshold->set_low_bandwidth_packet_loss(0.1f);
230   fec_enabling_threshold->set_high_bandwidth_bps(64000);
231   fec_enabling_threshold->set_high_bandwidth_packet_loss(0.05f);
232   auto fec_disabling_threshold =
233       controller_config->mutable_fec_disabling_threshold();
234   fec_disabling_threshold->set_low_bandwidth_bps(15000);
235   fec_disabling_threshold->set_low_bandwidth_packet_loss(0.08f);
236   fec_disabling_threshold->set_high_bandwidth_bps(64000);
237   fec_disabling_threshold->set_high_bandwidth_packet_loss(0.01f);
238   controller_config->set_time_constant_ms(500);
239 
240   auto scoring_point = controller_config_ext->mutable_scoring_point();
241   scoring_point->set_uplink_bandwidth_bps(kChracteristicBandwithBps[0]);
242   scoring_point->set_uplink_packet_loss_fraction(
243       kChracteristicPacketLossFraction[0]);
244 }
245 
AddFrameLengthControllerConfig(audio_network_adaptor::config::ControllerManager * config)246 void AddFrameLengthControllerConfig(
247     audio_network_adaptor::config::ControllerManager* config) {
248   auto controller_config_ext = config->add_controllers();
249   auto controller_config =
250       controller_config_ext->mutable_frame_length_controller();
251   controller_config->set_fl_decreasing_packet_loss_fraction(0.05f);
252   controller_config->set_fl_increasing_packet_loss_fraction(0.04f);
253   controller_config->set_fl_20ms_to_40ms_bandwidth_bps(80000);
254   controller_config->set_fl_40ms_to_20ms_bandwidth_bps(88000);
255   controller_config->set_fl_40ms_to_60ms_bandwidth_bps(72000);
256   controller_config->set_fl_60ms_to_40ms_bandwidth_bps(80000);
257 
258   auto scoring_point = controller_config_ext->mutable_scoring_point();
259   scoring_point->set_uplink_bandwidth_bps(kChracteristicBandwithBps[1]);
260   scoring_point->set_uplink_packet_loss_fraction(
261       kChracteristicPacketLossFraction[1]);
262 }
263 
AddFrameLengthControllerV2Config(audio_network_adaptor::config::ControllerManager * config)264 void AddFrameLengthControllerV2Config(
265     audio_network_adaptor::config::ControllerManager* config) {
266   auto controller =
267       config->add_controllers()->mutable_frame_length_controller_v2();
268   controller->set_min_payload_bitrate_bps(16000);
269   controller->set_use_slow_adaptation(true);
270 }
271 
272 constexpr int kInitialBitrateBps = 24000;
273 constexpr size_t kIntialChannelsToEncode = 1;
274 constexpr bool kInitialDtxEnabled = true;
275 constexpr bool kInitialFecEnabled = true;
276 constexpr int kInitialFrameLengthMs = 60;
277 constexpr int kMinBitrateBps = 6000;
278 
CreateControllerManager(absl::string_view config_string)279 ControllerManagerStates CreateControllerManager(
280     absl::string_view config_string) {
281   ControllerManagerStates states;
282   constexpr size_t kNumEncoderChannels = 2;
283   const std::vector<int> encoder_frame_lengths_ms = {20, 60};
284   states.controller_manager = ControllerManagerImpl::Create(
285       config_string, kNumEncoderChannels, encoder_frame_lengths_ms,
286       kMinBitrateBps, kIntialChannelsToEncode, kInitialFrameLengthMs,
287       kInitialBitrateBps, kInitialFecEnabled, kInitialDtxEnabled);
288   return states;
289 }
290 
291 enum class ControllerType : int8_t {
292   FEC,
293   CHANNEL,
294   DTX,
295   FRAME_LENGTH,
296   BIT_RATE
297 };
298 
CheckControllersOrder(const std::vector<Controller * > & controllers,const std::vector<ControllerType> & expected_types)299 void CheckControllersOrder(const std::vector<Controller*>& controllers,
300                            const std::vector<ControllerType>& expected_types) {
301   ASSERT_EQ(expected_types.size(), controllers.size());
302 
303   // We also check that the controllers follow the initial settings.
304   AudioEncoderRuntimeConfig encoder_config;
305 
306   for (size_t i = 0; i < controllers.size(); ++i) {
307     AudioEncoderRuntimeConfig encoder_config;
308     // We check the order of `controllers` by judging their decisions.
309     controllers[i]->MakeDecision(&encoder_config);
310 
311     // Since controllers are not provided with network metrics, they give the
312     // initial values.
313     switch (expected_types[i]) {
314       case ControllerType::FEC:
315         EXPECT_EQ(kInitialFecEnabled, encoder_config.enable_fec);
316         break;
317       case ControllerType::CHANNEL:
318         EXPECT_EQ(kIntialChannelsToEncode, encoder_config.num_channels);
319         break;
320       case ControllerType::DTX:
321         EXPECT_EQ(kInitialDtxEnabled, encoder_config.enable_dtx);
322         break;
323       case ControllerType::FRAME_LENGTH:
324         EXPECT_EQ(kInitialFrameLengthMs, encoder_config.frame_length_ms);
325         break;
326       case ControllerType::BIT_RATE:
327         EXPECT_EQ(kInitialBitrateBps, encoder_config.bitrate_bps);
328     }
329   }
330 }
331 
332 MATCHER_P(ControllerManagerEqual, value, "") {
333   std::string value_string;
334   std::string arg_string;
335   EXPECT_TRUE(arg.SerializeToString(&arg_string));
336   EXPECT_TRUE(value.SerializeToString(&value_string));
337   return arg_string == value_string;
338 }
339 
340 }  // namespace
341 
TEST(ControllerManagerTest,DebugDumpLoggedWhenCreateFromConfigString)342 TEST(ControllerManagerTest, DebugDumpLoggedWhenCreateFromConfigString) {
343   audio_network_adaptor::config::ControllerManager config;
344   config.set_min_reordering_time_ms(kMinReorderingTimeMs);
345   config.set_min_reordering_squared_distance(kMinReorderingSquareDistance);
346 
347   AddFecControllerConfig(&config);
348   AddChannelControllerConfig(&config);
349   AddDtxControllerConfig(&config);
350   AddFrameLengthControllerConfig(&config);
351   AddBitrateControllerConfig(&config);
352 
353   std::string config_string;
354   config.SerializeToString(&config_string);
355 
356   constexpr size_t kNumEncoderChannels = 2;
357   const std::vector<int> encoder_frame_lengths_ms = {20, 60};
358 
359   constexpr int64_t kClockInitialTimeMs = 12345678;
360   rtc::ScopedFakeClock fake_clock;
361   fake_clock.AdvanceTime(TimeDelta::Millis(kClockInitialTimeMs));
362   auto debug_dump_writer =
363       std::unique_ptr<MockDebugDumpWriter>(new NiceMock<MockDebugDumpWriter>());
364   EXPECT_CALL(*debug_dump_writer, Die());
365   EXPECT_CALL(*debug_dump_writer,
366               DumpControllerManagerConfig(ControllerManagerEqual(config),
367                                           kClockInitialTimeMs));
368 
369   ControllerManagerImpl::Create(config_string, kNumEncoderChannels,
370                                 encoder_frame_lengths_ms, kMinBitrateBps,
371                                 kIntialChannelsToEncode, kInitialFrameLengthMs,
372                                 kInitialBitrateBps, kInitialFecEnabled,
373                                 kInitialDtxEnabled, debug_dump_writer.get());
374 }
375 
TEST(ControllerManagerTest,CreateFromConfigStringAndCheckDefaultOrder)376 TEST(ControllerManagerTest, CreateFromConfigStringAndCheckDefaultOrder) {
377   audio_network_adaptor::config::ControllerManager config;
378   config.set_min_reordering_time_ms(kMinReorderingTimeMs);
379   config.set_min_reordering_squared_distance(kMinReorderingSquareDistance);
380 
381   AddFecControllerConfig(&config);
382   AddChannelControllerConfig(&config);
383   AddDtxControllerConfig(&config);
384   AddFrameLengthControllerConfig(&config);
385   AddBitrateControllerConfig(&config);
386 
387   std::string config_string;
388   config.SerializeToString(&config_string);
389 
390   auto states = CreateControllerManager(config_string);
391   Controller::NetworkMetrics metrics;
392 
393   auto controllers = states.controller_manager->GetSortedControllers(metrics);
394   CheckControllersOrder(
395       controllers,
396       std::vector<ControllerType>{
397           ControllerType::FEC, ControllerType::CHANNEL, ControllerType::DTX,
398           ControllerType::FRAME_LENGTH, ControllerType::BIT_RATE});
399 }
400 
TEST(ControllerManagerTest,CreateCharPointFreeConfigAndCheckDefaultOrder)401 TEST(ControllerManagerTest, CreateCharPointFreeConfigAndCheckDefaultOrder) {
402   audio_network_adaptor::config::ControllerManager config;
403 
404   // Following controllers have no characteristic points.
405   AddChannelControllerConfig(&config);
406   AddDtxControllerConfig(&config);
407   AddBitrateControllerConfig(&config);
408 
409   std::string config_string;
410   config.SerializeToString(&config_string);
411 
412   auto states = CreateControllerManager(config_string);
413   Controller::NetworkMetrics metrics;
414 
415   auto controllers = states.controller_manager->GetSortedControllers(metrics);
416   CheckControllersOrder(
417       controllers,
418       std::vector<ControllerType>{ControllerType::CHANNEL, ControllerType::DTX,
419                                   ControllerType::BIT_RATE});
420 }
421 
TEST(ControllerManagerTest,CreateFromConfigStringAndCheckReordering)422 TEST(ControllerManagerTest, CreateFromConfigStringAndCheckReordering) {
423   rtc::ScopedFakeClock fake_clock;
424   audio_network_adaptor::config::ControllerManager config;
425   config.set_min_reordering_time_ms(kMinReorderingTimeMs);
426   config.set_min_reordering_squared_distance(kMinReorderingSquareDistance);
427 
428   AddChannelControllerConfig(&config);
429 
430   // Internally associated with characteristic point 0.
431   AddFecControllerConfig(&config);
432 
433   AddDtxControllerConfig(&config);
434 
435   // Internally associated with characteristic point 1.
436   AddFrameLengthControllerConfig(&config);
437 
438   AddBitrateControllerConfig(&config);
439 
440   std::string config_string;
441   config.SerializeToString(&config_string);
442 
443   auto states = CreateControllerManager(config_string);
444 
445   Controller::NetworkMetrics metrics;
446   metrics.uplink_bandwidth_bps = kChracteristicBandwithBps[0];
447   metrics.uplink_packet_loss_fraction = kChracteristicPacketLossFraction[0];
448 
449   auto controllers = states.controller_manager->GetSortedControllers(metrics);
450   CheckControllersOrder(controllers,
451                         std::vector<ControllerType>{
452                             ControllerType::FEC, ControllerType::FRAME_LENGTH,
453                             ControllerType::CHANNEL, ControllerType::DTX,
454                             ControllerType::BIT_RATE});
455 
456   metrics.uplink_bandwidth_bps = kChracteristicBandwithBps[1];
457   metrics.uplink_packet_loss_fraction = kChracteristicPacketLossFraction[1];
458   fake_clock.AdvanceTime(TimeDelta::Millis(kMinReorderingTimeMs - 1));
459   controllers = states.controller_manager->GetSortedControllers(metrics);
460   // Should not reorder since min reordering time is not met.
461   CheckControllersOrder(controllers,
462                         std::vector<ControllerType>{
463                             ControllerType::FEC, ControllerType::FRAME_LENGTH,
464                             ControllerType::CHANNEL, ControllerType::DTX,
465                             ControllerType::BIT_RATE});
466 
467   fake_clock.AdvanceTime(TimeDelta::Millis(1));
468   controllers = states.controller_manager->GetSortedControllers(metrics);
469   // Reorder now.
470   CheckControllersOrder(controllers,
471                         std::vector<ControllerType>{
472                             ControllerType::FRAME_LENGTH, ControllerType::FEC,
473                             ControllerType::CHANNEL, ControllerType::DTX,
474                             ControllerType::BIT_RATE});
475 }
476 
TEST(ControllerManagerTest,CreateFrameLengthControllerV2)477 TEST(ControllerManagerTest, CreateFrameLengthControllerV2) {
478   audio_network_adaptor::config::ControllerManager config;
479   AddFrameLengthControllerV2Config(&config);
480   auto states = CreateControllerManager(config.SerializeAsString());
481   auto controllers = states.controller_manager->GetControllers();
482   EXPECT_TRUE(controllers.size() == 1);
483 }
484 #endif  // WEBRTC_ENABLE_PROTOBUF
485 
486 }  // namespace webrtc
487