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 test::ScopedFieldTrials override_field_trials(
78 "WebRTC-SendSideBwe-WithOverhead/Enabled/");
79 constexpr int kInitialFrameLengthMs = 20;
80 BitrateController controller(
81 BitrateController::Config(32000, kInitialFrameLengthMs, 0, 0));
82 constexpr int kTargetBitrateBps = 48000;
83 constexpr size_t kOverheadBytesPerPacket = 64;
84 constexpr int kBitrateBps = kTargetBitrateBps - kOverheadBytesPerPacket * 8 *
85 1000 /
86 kInitialFrameLengthMs;
87 // Frame length unchanged, bitrate changes in accordance with
88 // |metrics.target_audio_bitrate_bps| and |metrics.overhead_bytes_per_packet|.
89 UpdateNetworkMetrics(&controller, kTargetBitrateBps, kOverheadBytesPerPacket);
90 CheckDecision(&controller, kInitialFrameLengthMs, kBitrateBps);
91 }
92
TEST(AnaBitrateControllerTest,UpdateMultipleNetworkMetricsAtOnce)93 TEST(AnaBitrateControllerTest, UpdateMultipleNetworkMetricsAtOnce) {
94 // This test is similar to ChangeBitrateOnTargetBitrateChanged. But instead of
95 // using ::UpdateNetworkMetrics(...), which calls
96 // BitrateController::UpdateNetworkMetrics(...) multiple times, we
97 // we call it only once. This is to verify that
98 // BitrateController::UpdateNetworkMetrics(...) can handle multiple
99 // network updates at once. This is, however, not a common use case in current
100 // audio_network_adaptor_impl.cc.
101 test::ScopedFieldTrials override_field_trials(
102 "WebRTC-SendSideBwe-WithOverhead/Enabled/");
103 constexpr int kInitialFrameLengthMs = 20;
104 BitrateController controller(
105 BitrateController::Config(32000, kInitialFrameLengthMs, 0, 0));
106 constexpr int kTargetBitrateBps = 48000;
107 constexpr size_t kOverheadBytesPerPacket = 64;
108 constexpr int kBitrateBps = kTargetBitrateBps - kOverheadBytesPerPacket * 8 *
109 1000 /
110 kInitialFrameLengthMs;
111 Controller::NetworkMetrics network_metrics;
112 network_metrics.target_audio_bitrate_bps = kTargetBitrateBps;
113 network_metrics.overhead_bytes_per_packet = kOverheadBytesPerPacket;
114 controller.UpdateNetworkMetrics(network_metrics);
115 CheckDecision(&controller, kInitialFrameLengthMs, kBitrateBps);
116 }
117
TEST(AnaBitrateControllerTest,TreatUnknownFrameLengthAsFrameLengthUnchanged)118 TEST(AnaBitrateControllerTest, TreatUnknownFrameLengthAsFrameLengthUnchanged) {
119 test::ScopedFieldTrials override_field_trials(
120 "WebRTC-SendSideBwe-WithOverhead/Enabled/");
121 constexpr int kInitialFrameLengthMs = 20;
122 BitrateController controller(
123 BitrateController::Config(32000, kInitialFrameLengthMs, 0, 0));
124 constexpr int kTargetBitrateBps = 48000;
125 constexpr size_t kOverheadBytesPerPacket = 64;
126 constexpr int kBitrateBps = kTargetBitrateBps - kOverheadBytesPerPacket * 8 *
127 1000 /
128 kInitialFrameLengthMs;
129 UpdateNetworkMetrics(&controller, kTargetBitrateBps, kOverheadBytesPerPacket);
130 CheckDecision(&controller, absl::nullopt, kBitrateBps);
131 }
132
TEST(AnaBitrateControllerTest,IncreaseBitrateOnFrameLengthIncreased)133 TEST(AnaBitrateControllerTest, IncreaseBitrateOnFrameLengthIncreased) {
134 test::ScopedFieldTrials override_field_trials(
135 "WebRTC-SendSideBwe-WithOverhead/Enabled/");
136 constexpr int kInitialFrameLengthMs = 20;
137 BitrateController controller(
138 BitrateController::Config(32000, kInitialFrameLengthMs, 0, 0));
139
140 constexpr int kTargetBitrateBps = 48000;
141 constexpr size_t kOverheadBytesPerPacket = 64;
142 constexpr int kBitrateBps = kTargetBitrateBps - kOverheadBytesPerPacket * 8 *
143 1000 /
144 kInitialFrameLengthMs;
145 UpdateNetworkMetrics(&controller, kTargetBitrateBps, kOverheadBytesPerPacket);
146 CheckDecision(&controller, absl::nullopt, kBitrateBps);
147
148 constexpr int kFrameLengthMs = 60;
149 constexpr size_t kPacketOverheadRateDiff =
150 kOverheadBytesPerPacket * 8 * 1000 / 20 -
151 kOverheadBytesPerPacket * 8 * 1000 / 60;
152 UpdateNetworkMetrics(&controller, kTargetBitrateBps, kOverheadBytesPerPacket);
153 CheckDecision(&controller, kFrameLengthMs,
154 kBitrateBps + kPacketOverheadRateDiff);
155 }
156
TEST(AnaBitrateControllerTest,DecreaseBitrateOnFrameLengthDecreased)157 TEST(AnaBitrateControllerTest, DecreaseBitrateOnFrameLengthDecreased) {
158 test::ScopedFieldTrials override_field_trials(
159 "WebRTC-SendSideBwe-WithOverhead/Enabled/");
160 constexpr int kInitialFrameLengthMs = 60;
161 BitrateController controller(
162 BitrateController::Config(32000, kInitialFrameLengthMs, 0, 0));
163
164 constexpr int kTargetBitrateBps = 48000;
165 constexpr size_t kOverheadBytesPerPacket = 64;
166 constexpr int kBitrateBps = kTargetBitrateBps - kOverheadBytesPerPacket * 8 *
167 1000 /
168 kInitialFrameLengthMs;
169 UpdateNetworkMetrics(&controller, kTargetBitrateBps, kOverheadBytesPerPacket);
170 CheckDecision(&controller, absl::nullopt, kBitrateBps);
171
172 constexpr int kFrameLengthMs = 20;
173 constexpr size_t kPacketOverheadRateDiff =
174 kOverheadBytesPerPacket * 8 * 1000 / 20 -
175 kOverheadBytesPerPacket * 8 * 1000 / 60;
176 UpdateNetworkMetrics(&controller, kTargetBitrateBps, kOverheadBytesPerPacket);
177 CheckDecision(&controller, kFrameLengthMs,
178 kBitrateBps - kPacketOverheadRateDiff);
179 }
180
TEST(AnaBitrateControllerTest,BitrateNeverBecomesNegative)181 TEST(AnaBitrateControllerTest, BitrateNeverBecomesNegative) {
182 test::ScopedFieldTrials override_field_trials(
183 "WebRTC-SendSideBwe-WithOverhead/Enabled/");
184 BitrateController controller(BitrateController::Config(32000, 20, 0, 0));
185 constexpr size_t kOverheadBytesPerPacket = 64;
186 constexpr int kFrameLengthMs = 60;
187 // Set a target rate smaller than overhead rate, the bitrate is bounded by 0.
188 constexpr int kTargetBitrateBps =
189 kOverheadBytesPerPacket * 8 * 1000 / kFrameLengthMs - 1;
190 UpdateNetworkMetrics(&controller, kTargetBitrateBps, kOverheadBytesPerPacket);
191 CheckDecision(&controller, kFrameLengthMs, 0);
192 }
193
TEST(AnaBitrateControllerTest,CheckBehaviorOnChangingCondition)194 TEST(AnaBitrateControllerTest, CheckBehaviorOnChangingCondition) {
195 test::ScopedFieldTrials override_field_trials(
196 "WebRTC-SendSideBwe-WithOverhead/Enabled/");
197 BitrateController controller(BitrateController::Config(32000, 20, 0, 0));
198
199 // Start from an arbitrary overall bitrate.
200 int overall_bitrate = 34567;
201 size_t overhead_bytes_per_packet = 64;
202 int frame_length_ms = 20;
203 int current_bitrate = rtc::checked_cast<int>(
204 overall_bitrate - overhead_bytes_per_packet * 8 * 1000 / frame_length_ms);
205
206 UpdateNetworkMetrics(&controller, overall_bitrate, overhead_bytes_per_packet);
207 CheckDecision(&controller, frame_length_ms, current_bitrate);
208
209 // Next: increase overall bitrate.
210 overall_bitrate += 100;
211 current_bitrate += 100;
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 = 60;
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: change overhead.
224 overhead_bytes_per_packet -= 30;
225 current_bitrate += 30 * 8 * 1000 / frame_length_ms;
226 UpdateNetworkMetrics(&controller, overall_bitrate, overhead_bytes_per_packet);
227 CheckDecision(&controller, frame_length_ms, current_bitrate);
228
229 // Next: change frame length.
230 frame_length_ms = 20;
231 current_bitrate -=
232 rtc::checked_cast<int>(overhead_bytes_per_packet * 8 * 1000 / 20 -
233 overhead_bytes_per_packet * 8 * 1000 / 60);
234 UpdateNetworkMetrics(&controller, overall_bitrate, overhead_bytes_per_packet);
235 CheckDecision(&controller, frame_length_ms, current_bitrate);
236
237 // Next: decrease overall bitrate and frame length.
238 overall_bitrate -= 100;
239 current_bitrate -= 100;
240 frame_length_ms = 60;
241 current_bitrate +=
242 rtc::checked_cast<int>(overhead_bytes_per_packet * 8 * 1000 / 20 -
243 overhead_bytes_per_packet * 8 * 1000 / 60);
244
245 UpdateNetworkMetrics(&controller, overall_bitrate, overhead_bytes_per_packet);
246 CheckDecision(&controller, frame_length_ms, current_bitrate);
247 }
248
249 } // namespace audio_network_adaptor
250 } // namespace webrtc
251