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