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/bitrate_controller.h"
12 
13 #include "rtc_base/numerics/safe_conversions.h"
14 #include "test/field_trial.h"
15 #include "test/gtest.h"
16 
17 namespace webrtc {
18 namespace audio_network_adaptor {
19 
20 namespace {
21 
UpdateNetworkMetrics(BitrateController * controller,const absl::optional<int> & target_audio_bitrate_bps,const absl::optional<size_t> & overhead_bytes_per_packet)22 void UpdateNetworkMetrics(
23     BitrateController* controller,
24     const absl::optional<int>& target_audio_bitrate_bps,
25     const absl::optional<size_t>& overhead_bytes_per_packet) {
26   // UpdateNetworkMetrics can accept multiple network metric updates at once.
27   // However, currently, the most used case is to update one metric at a time.
28   // To reflect this fact, we separate the calls.
29   if (target_audio_bitrate_bps) {
30     Controller::NetworkMetrics network_metrics;
31     network_metrics.target_audio_bitrate_bps = target_audio_bitrate_bps;
32     controller->UpdateNetworkMetrics(network_metrics);
33   }
34   if (overhead_bytes_per_packet) {
35     Controller::NetworkMetrics network_metrics;
36     network_metrics.overhead_bytes_per_packet = overhead_bytes_per_packet;
37     controller->UpdateNetworkMetrics(network_metrics);
38   }
39 }
40 
CheckDecision(BitrateController * controller,const absl::optional<int> & frame_length_ms,int expected_bitrate_bps)41 void CheckDecision(BitrateController* controller,
42                    const absl::optional<int>& frame_length_ms,
43                    int expected_bitrate_bps) {
44   AudioEncoderRuntimeConfig config;
45   config.frame_length_ms = frame_length_ms;
46   controller->MakeDecision(&config);
47   EXPECT_EQ(expected_bitrate_bps, config.bitrate_bps);
48 }
49 
50 }  // namespace
51 
52 // These tests are named AnaBitrateControllerTest to distinguish from
53 // BitrateControllerTest in
54 // modules/bitrate_controller/bitrate_controller_unittest.cc.
55 
TEST(AnaBitrateControllerTest,OutputInitValueWhenTargetBitrateUnknown)56 TEST(AnaBitrateControllerTest, OutputInitValueWhenTargetBitrateUnknown) {
57   constexpr int kInitialBitrateBps = 32000;
58   constexpr int kInitialFrameLengthMs = 20;
59   constexpr size_t kOverheadBytesPerPacket = 64;
60   BitrateController controller(BitrateController::Config(
61       kInitialBitrateBps, kInitialFrameLengthMs, 0, 0));
62   UpdateNetworkMetrics(&controller, absl::nullopt, kOverheadBytesPerPacket);
63   CheckDecision(&controller, kInitialFrameLengthMs * 2, kInitialBitrateBps);
64 }
65 
TEST(AnaBitrateControllerTest,OutputInitValueWhenOverheadUnknown)66 TEST(AnaBitrateControllerTest, OutputInitValueWhenOverheadUnknown) {
67   constexpr int kInitialBitrateBps = 32000;
68   constexpr int kInitialFrameLengthMs = 20;
69   constexpr int kTargetBitrateBps = 48000;
70   BitrateController controller(BitrateController::Config(
71       kInitialBitrateBps, kInitialFrameLengthMs, 0, 0));
72   UpdateNetworkMetrics(&controller, kTargetBitrateBps, absl::nullopt);
73   CheckDecision(&controller, kInitialFrameLengthMs * 2, kInitialBitrateBps);
74 }
75 
TEST(AnaBitrateControllerTest,ChangeBitrateOnTargetBitrateChanged)76 TEST(AnaBitrateControllerTest, ChangeBitrateOnTargetBitrateChanged) {
77   constexpr int kInitialFrameLengthMs = 20;
78   BitrateController controller(
79       BitrateController::Config(32000, kInitialFrameLengthMs, 0, 0));
80   constexpr int kTargetBitrateBps = 48000;
81   constexpr size_t kOverheadBytesPerPacket = 64;
82   constexpr int kBitrateBps = kTargetBitrateBps - kOverheadBytesPerPacket * 8 *
83                                                       1000 /
84                                                       kInitialFrameLengthMs;
85   // Frame length unchanged, bitrate changes in accordance with
86   // `metrics.target_audio_bitrate_bps` and `metrics.overhead_bytes_per_packet`.
87   UpdateNetworkMetrics(&controller, kTargetBitrateBps, kOverheadBytesPerPacket);
88   CheckDecision(&controller, kInitialFrameLengthMs, kBitrateBps);
89 }
90 
TEST(AnaBitrateControllerTest,UpdateMultipleNetworkMetricsAtOnce)91 TEST(AnaBitrateControllerTest, UpdateMultipleNetworkMetricsAtOnce) {
92   // This test is similar to ChangeBitrateOnTargetBitrateChanged. But instead of
93   // using ::UpdateNetworkMetrics(...), which calls
94   // BitrateController::UpdateNetworkMetrics(...) multiple times, we
95   // we call it only once. This is to verify that
96   // BitrateController::UpdateNetworkMetrics(...) can handle multiple
97   // network updates at once. This is, however, not a common use case in current
98   // audio_network_adaptor_impl.cc.
99   constexpr int kInitialFrameLengthMs = 20;
100   BitrateController controller(
101       BitrateController::Config(32000, kInitialFrameLengthMs, 0, 0));
102   constexpr int kTargetBitrateBps = 48000;
103   constexpr size_t kOverheadBytesPerPacket = 64;
104   constexpr int kBitrateBps = kTargetBitrateBps - kOverheadBytesPerPacket * 8 *
105                                                       1000 /
106                                                       kInitialFrameLengthMs;
107   Controller::NetworkMetrics network_metrics;
108   network_metrics.target_audio_bitrate_bps = kTargetBitrateBps;
109   network_metrics.overhead_bytes_per_packet = kOverheadBytesPerPacket;
110   controller.UpdateNetworkMetrics(network_metrics);
111   CheckDecision(&controller, kInitialFrameLengthMs, kBitrateBps);
112 }
113 
TEST(AnaBitrateControllerTest,TreatUnknownFrameLengthAsFrameLengthUnchanged)114 TEST(AnaBitrateControllerTest, TreatUnknownFrameLengthAsFrameLengthUnchanged) {
115   constexpr int kInitialFrameLengthMs = 20;
116   BitrateController controller(
117       BitrateController::Config(32000, kInitialFrameLengthMs, 0, 0));
118   constexpr int kTargetBitrateBps = 48000;
119   constexpr size_t kOverheadBytesPerPacket = 64;
120   constexpr int kBitrateBps = kTargetBitrateBps - kOverheadBytesPerPacket * 8 *
121                                                       1000 /
122                                                       kInitialFrameLengthMs;
123   UpdateNetworkMetrics(&controller, kTargetBitrateBps, kOverheadBytesPerPacket);
124   CheckDecision(&controller, absl::nullopt, kBitrateBps);
125 }
126 
TEST(AnaBitrateControllerTest,IncreaseBitrateOnFrameLengthIncreased)127 TEST(AnaBitrateControllerTest, IncreaseBitrateOnFrameLengthIncreased) {
128   constexpr int kInitialFrameLengthMs = 20;
129   BitrateController controller(
130       BitrateController::Config(32000, kInitialFrameLengthMs, 0, 0));
131 
132   constexpr int kTargetBitrateBps = 48000;
133   constexpr size_t kOverheadBytesPerPacket = 64;
134   constexpr int kBitrateBps = kTargetBitrateBps - kOverheadBytesPerPacket * 8 *
135                                                       1000 /
136                                                       kInitialFrameLengthMs;
137   UpdateNetworkMetrics(&controller, kTargetBitrateBps, kOverheadBytesPerPacket);
138   CheckDecision(&controller, absl::nullopt, kBitrateBps);
139 
140   constexpr int kFrameLengthMs = 60;
141   constexpr size_t kPacketOverheadRateDiff =
142       kOverheadBytesPerPacket * 8 * 1000 / 20 -
143       kOverheadBytesPerPacket * 8 * 1000 / 60;
144   UpdateNetworkMetrics(&controller, kTargetBitrateBps, kOverheadBytesPerPacket);
145   CheckDecision(&controller, kFrameLengthMs,
146                 kBitrateBps + kPacketOverheadRateDiff);
147 }
148 
TEST(AnaBitrateControllerTest,DecreaseBitrateOnFrameLengthDecreased)149 TEST(AnaBitrateControllerTest, DecreaseBitrateOnFrameLengthDecreased) {
150   constexpr int kInitialFrameLengthMs = 60;
151   BitrateController controller(
152       BitrateController::Config(32000, kInitialFrameLengthMs, 0, 0));
153 
154   constexpr int kTargetBitrateBps = 48000;
155   constexpr size_t kOverheadBytesPerPacket = 64;
156   constexpr int kBitrateBps = kTargetBitrateBps - kOverheadBytesPerPacket * 8 *
157                                                       1000 /
158                                                       kInitialFrameLengthMs;
159   UpdateNetworkMetrics(&controller, kTargetBitrateBps, kOverheadBytesPerPacket);
160   CheckDecision(&controller, absl::nullopt, kBitrateBps);
161 
162   constexpr int kFrameLengthMs = 20;
163   constexpr size_t kPacketOverheadRateDiff =
164       kOverheadBytesPerPacket * 8 * 1000 / 20 -
165       kOverheadBytesPerPacket * 8 * 1000 / 60;
166   UpdateNetworkMetrics(&controller, kTargetBitrateBps, kOverheadBytesPerPacket);
167   CheckDecision(&controller, kFrameLengthMs,
168                 kBitrateBps - kPacketOverheadRateDiff);
169 }
170 
TEST(AnaBitrateControllerTest,BitrateNeverBecomesNegative)171 TEST(AnaBitrateControllerTest, BitrateNeverBecomesNegative) {
172   BitrateController controller(BitrateController::Config(32000, 20, 0, 0));
173   constexpr size_t kOverheadBytesPerPacket = 64;
174   constexpr int kFrameLengthMs = 60;
175   // Set a target rate smaller than overhead rate, the bitrate is bounded by 0.
176   constexpr int kTargetBitrateBps =
177       kOverheadBytesPerPacket * 8 * 1000 / kFrameLengthMs - 1;
178   UpdateNetworkMetrics(&controller, kTargetBitrateBps, kOverheadBytesPerPacket);
179   CheckDecision(&controller, kFrameLengthMs, 0);
180 }
181 
TEST(AnaBitrateControllerTest,CheckBehaviorOnChangingCondition)182 TEST(AnaBitrateControllerTest, CheckBehaviorOnChangingCondition) {
183   BitrateController controller(BitrateController::Config(32000, 20, 0, 0));
184 
185   // Start from an arbitrary overall bitrate.
186   int overall_bitrate = 34567;
187   size_t overhead_bytes_per_packet = 64;
188   int frame_length_ms = 20;
189   int current_bitrate = rtc::checked_cast<int>(
190       overall_bitrate - overhead_bytes_per_packet * 8 * 1000 / frame_length_ms);
191 
192   UpdateNetworkMetrics(&controller, overall_bitrate, overhead_bytes_per_packet);
193   CheckDecision(&controller, frame_length_ms, current_bitrate);
194 
195   // Next: increase overall bitrate.
196   overall_bitrate += 100;
197   current_bitrate += 100;
198   UpdateNetworkMetrics(&controller, overall_bitrate, overhead_bytes_per_packet);
199   CheckDecision(&controller, frame_length_ms, current_bitrate);
200 
201   // Next: change frame length.
202   frame_length_ms = 60;
203   current_bitrate +=
204       rtc::checked_cast<int>(overhead_bytes_per_packet * 8 * 1000 / 20 -
205                              overhead_bytes_per_packet * 8 * 1000 / 60);
206   UpdateNetworkMetrics(&controller, overall_bitrate, overhead_bytes_per_packet);
207   CheckDecision(&controller, frame_length_ms, current_bitrate);
208 
209   // Next: change overhead.
210   overhead_bytes_per_packet -= 30;
211   current_bitrate += 30 * 8 * 1000 / frame_length_ms;
212   UpdateNetworkMetrics(&controller, overall_bitrate, overhead_bytes_per_packet);
213   CheckDecision(&controller, frame_length_ms, current_bitrate);
214 
215   // Next: change frame length.
216   frame_length_ms = 20;
217   current_bitrate -=
218       rtc::checked_cast<int>(overhead_bytes_per_packet * 8 * 1000 / 20 -
219                              overhead_bytes_per_packet * 8 * 1000 / 60);
220   UpdateNetworkMetrics(&controller, overall_bitrate, overhead_bytes_per_packet);
221   CheckDecision(&controller, frame_length_ms, current_bitrate);
222 
223   // Next: decrease overall bitrate and frame length.
224   overall_bitrate -= 100;
225   current_bitrate -= 100;
226   frame_length_ms = 60;
227   current_bitrate +=
228       rtc::checked_cast<int>(overhead_bytes_per_packet * 8 * 1000 / 20 -
229                              overhead_bytes_per_packet * 8 * 1000 / 60);
230 
231   UpdateNetworkMetrics(&controller, overall_bitrate, overhead_bytes_per_packet);
232   CheckDecision(&controller, frame_length_ms, current_bitrate);
233 }
234 
235 }  // namespace audio_network_adaptor
236 }  // namespace webrtc
237