1 /*
2 * Copyright (c) 2018 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 #include "call/rtp_bitrate_configurator.h"
11
12 #include <memory>
13
14 #include "test/gtest.h"
15
16 namespace webrtc {
17 using absl::nullopt;
18
19 class RtpBitrateConfiguratorTest : public ::testing::Test {
20 public:
RtpBitrateConfiguratorTest()21 RtpBitrateConfiguratorTest()
22 : configurator_(new RtpBitrateConfigurator(BitrateConstraints())) {}
23 std::unique_ptr<RtpBitrateConfigurator> configurator_;
UpdateConfigMatches(BitrateConstraints bitrate_config,absl::optional<int> min_bitrate_bps,absl::optional<int> start_bitrate_bps,absl::optional<int> max_bitrate_bps)24 void UpdateConfigMatches(BitrateConstraints bitrate_config,
25 absl::optional<int> min_bitrate_bps,
26 absl::optional<int> start_bitrate_bps,
27 absl::optional<int> max_bitrate_bps) {
28 absl::optional<BitrateConstraints> result =
29 configurator_->UpdateWithSdpParameters(bitrate_config);
30 EXPECT_TRUE(result.has_value());
31 if (start_bitrate_bps.has_value())
32 EXPECT_EQ(result->start_bitrate_bps, start_bitrate_bps);
33 if (min_bitrate_bps.has_value())
34 EXPECT_EQ(result->min_bitrate_bps, min_bitrate_bps);
35 if (max_bitrate_bps.has_value())
36 EXPECT_EQ(result->max_bitrate_bps, max_bitrate_bps);
37 }
38
UpdateMaskMatches(BitrateSettings bitrate_mask,absl::optional<int> min_bitrate_bps,absl::optional<int> start_bitrate_bps,absl::optional<int> max_bitrate_bps)39 void UpdateMaskMatches(BitrateSettings bitrate_mask,
40 absl::optional<int> min_bitrate_bps,
41 absl::optional<int> start_bitrate_bps,
42 absl::optional<int> max_bitrate_bps) {
43 absl::optional<BitrateConstraints> result =
44 configurator_->UpdateWithClientPreferences(bitrate_mask);
45 EXPECT_TRUE(result.has_value());
46 if (start_bitrate_bps.has_value())
47 EXPECT_EQ(result->start_bitrate_bps, start_bitrate_bps);
48 if (min_bitrate_bps.has_value())
49 EXPECT_EQ(result->min_bitrate_bps, min_bitrate_bps);
50 if (max_bitrate_bps.has_value())
51 EXPECT_EQ(result->max_bitrate_bps, max_bitrate_bps);
52 }
53 };
54
TEST_F(RtpBitrateConfiguratorTest,NewConfigWithValidConfigReturnsNewConfig)55 TEST_F(RtpBitrateConfiguratorTest, NewConfigWithValidConfigReturnsNewConfig) {
56 BitrateConstraints bitrate_config;
57 bitrate_config.min_bitrate_bps = 1;
58 bitrate_config.start_bitrate_bps = 2;
59 bitrate_config.max_bitrate_bps = 3;
60
61 UpdateConfigMatches(bitrate_config, 1, 2, 3);
62 }
63
TEST_F(RtpBitrateConfiguratorTest,NewConfigWithDifferentMinReturnsNewConfig)64 TEST_F(RtpBitrateConfiguratorTest, NewConfigWithDifferentMinReturnsNewConfig) {
65 BitrateConstraints bitrate_config;
66 bitrate_config.min_bitrate_bps = 10;
67 bitrate_config.start_bitrate_bps = 20;
68 bitrate_config.max_bitrate_bps = 30;
69 configurator_.reset(new RtpBitrateConfigurator(bitrate_config));
70
71 bitrate_config.min_bitrate_bps = 11;
72 UpdateConfigMatches(bitrate_config, 11, -1, 30);
73 }
74
TEST_F(RtpBitrateConfiguratorTest,NewConfigWithDifferentStartReturnsNewConfig)75 TEST_F(RtpBitrateConfiguratorTest,
76 NewConfigWithDifferentStartReturnsNewConfig) {
77 BitrateConstraints bitrate_config;
78 bitrate_config.min_bitrate_bps = 10;
79 bitrate_config.start_bitrate_bps = 20;
80 bitrate_config.max_bitrate_bps = 30;
81 configurator_.reset(new RtpBitrateConfigurator(bitrate_config));
82
83 bitrate_config.start_bitrate_bps = 21;
84 UpdateConfigMatches(bitrate_config, 10, 21, 30);
85 }
86
TEST_F(RtpBitrateConfiguratorTest,NewConfigWithDifferentMaxReturnsNewConfig)87 TEST_F(RtpBitrateConfiguratorTest, NewConfigWithDifferentMaxReturnsNewConfig) {
88 BitrateConstraints bitrate_config;
89 bitrate_config.min_bitrate_bps = 10;
90 bitrate_config.start_bitrate_bps = 20;
91 bitrate_config.max_bitrate_bps = 30;
92 configurator_.reset(new RtpBitrateConfigurator(bitrate_config));
93
94 bitrate_config.max_bitrate_bps = 31;
95 UpdateConfigMatches(bitrate_config, 10, -1, 31);
96 }
97
TEST_F(RtpBitrateConfiguratorTest,NewConfigWithSameConfigElidesSecondCall)98 TEST_F(RtpBitrateConfiguratorTest, NewConfigWithSameConfigElidesSecondCall) {
99 BitrateConstraints bitrate_config;
100 bitrate_config.min_bitrate_bps = 1;
101 bitrate_config.start_bitrate_bps = 2;
102 bitrate_config.max_bitrate_bps = 3;
103
104 UpdateConfigMatches(bitrate_config, 1, 2, 3);
105 EXPECT_FALSE(
106 configurator_->UpdateWithSdpParameters(bitrate_config).has_value());
107 }
108
TEST_F(RtpBitrateConfiguratorTest,NewConfigWithSameMinMaxAndNegativeStartElidesSecondCall)109 TEST_F(RtpBitrateConfiguratorTest,
110 NewConfigWithSameMinMaxAndNegativeStartElidesSecondCall) {
111 BitrateConstraints bitrate_config;
112 bitrate_config.min_bitrate_bps = 1;
113 bitrate_config.start_bitrate_bps = 2;
114 bitrate_config.max_bitrate_bps = 3;
115
116 UpdateConfigMatches(bitrate_config, 1, 2, 3);
117
118 bitrate_config.start_bitrate_bps = -1;
119 EXPECT_FALSE(
120 configurator_->UpdateWithSdpParameters(bitrate_config).has_value());
121 }
122
TEST_F(RtpBitrateConfiguratorTest,BiggerMaskMinUsed)123 TEST_F(RtpBitrateConfiguratorTest, BiggerMaskMinUsed) {
124 BitrateSettings mask;
125 mask.min_bitrate_bps = 1234;
126 UpdateMaskMatches(mask, *mask.min_bitrate_bps, nullopt, nullopt);
127 }
128
TEST_F(RtpBitrateConfiguratorTest,BiggerConfigMinUsed)129 TEST_F(RtpBitrateConfiguratorTest, BiggerConfigMinUsed) {
130 BitrateSettings mask;
131 mask.min_bitrate_bps = 1000;
132 UpdateMaskMatches(mask, 1000, nullopt, nullopt);
133
134 BitrateConstraints config;
135 config.min_bitrate_bps = 1234;
136 UpdateConfigMatches(config, 1234, nullopt, nullopt);
137 }
138
139 // The last call to set start should be used.
TEST_F(RtpBitrateConfiguratorTest,LatestStartMaskPreferred)140 TEST_F(RtpBitrateConfiguratorTest, LatestStartMaskPreferred) {
141 BitrateSettings mask;
142 mask.start_bitrate_bps = 1300;
143 UpdateMaskMatches(mask, nullopt, *mask.start_bitrate_bps, nullopt);
144
145 BitrateConstraints bitrate_config;
146 bitrate_config.start_bitrate_bps = 1200;
147
148 UpdateConfigMatches(bitrate_config, nullopt, bitrate_config.start_bitrate_bps,
149 nullopt);
150 }
151
TEST_F(RtpBitrateConfiguratorTest,SmallerMaskMaxUsed)152 TEST_F(RtpBitrateConfiguratorTest, SmallerMaskMaxUsed) {
153 BitrateConstraints bitrate_config;
154 bitrate_config.max_bitrate_bps = bitrate_config.start_bitrate_bps + 2000;
155 configurator_.reset(new RtpBitrateConfigurator(bitrate_config));
156
157 BitrateSettings mask;
158 mask.max_bitrate_bps = bitrate_config.start_bitrate_bps + 1000;
159
160 UpdateMaskMatches(mask, nullopt, nullopt, *mask.max_bitrate_bps);
161 }
162
TEST_F(RtpBitrateConfiguratorTest,SmallerConfigMaxUsed)163 TEST_F(RtpBitrateConfiguratorTest, SmallerConfigMaxUsed) {
164 BitrateConstraints bitrate_config;
165 bitrate_config.max_bitrate_bps = bitrate_config.start_bitrate_bps + 1000;
166 configurator_.reset(new RtpBitrateConfigurator(bitrate_config));
167
168 BitrateSettings mask;
169 mask.max_bitrate_bps = bitrate_config.start_bitrate_bps + 2000;
170
171 // Expect no return because nothing changes
172 EXPECT_FALSE(configurator_->UpdateWithClientPreferences(mask).has_value());
173 }
174
TEST_F(RtpBitrateConfiguratorTest,MaskStartLessThanConfigMinClamped)175 TEST_F(RtpBitrateConfiguratorTest, MaskStartLessThanConfigMinClamped) {
176 BitrateConstraints bitrate_config;
177 bitrate_config.min_bitrate_bps = 2000;
178 configurator_.reset(new RtpBitrateConfigurator(bitrate_config));
179
180 BitrateSettings mask;
181 mask.start_bitrate_bps = 1000;
182 UpdateMaskMatches(mask, 2000, 2000, nullopt);
183 }
184
TEST_F(RtpBitrateConfiguratorTest,MaskStartGreaterThanConfigMaxClamped)185 TEST_F(RtpBitrateConfiguratorTest, MaskStartGreaterThanConfigMaxClamped) {
186 BitrateConstraints bitrate_config;
187 bitrate_config.start_bitrate_bps = 2000;
188 configurator_.reset(new RtpBitrateConfigurator(bitrate_config));
189
190 BitrateSettings mask;
191 mask.max_bitrate_bps = 1000;
192
193 UpdateMaskMatches(mask, nullopt, -1, 1000);
194 }
195
TEST_F(RtpBitrateConfiguratorTest,MaskMinGreaterThanConfigMaxClamped)196 TEST_F(RtpBitrateConfiguratorTest, MaskMinGreaterThanConfigMaxClamped) {
197 BitrateConstraints bitrate_config;
198 bitrate_config.min_bitrate_bps = 2000;
199 configurator_.reset(new RtpBitrateConfigurator(bitrate_config));
200
201 BitrateSettings mask;
202 mask.max_bitrate_bps = 1000;
203
204 UpdateMaskMatches(mask, 1000, nullopt, 1000);
205 }
206
TEST_F(RtpBitrateConfiguratorTest,SettingMaskStartForcesUpdate)207 TEST_F(RtpBitrateConfiguratorTest, SettingMaskStartForcesUpdate) {
208 BitrateSettings mask;
209 mask.start_bitrate_bps = 1000;
210
211 // Config should be returned twice with the same params since
212 // start_bitrate_bps is set.
213 UpdateMaskMatches(mask, nullopt, 1000, nullopt);
214 UpdateMaskMatches(mask, nullopt, 1000, nullopt);
215 }
216
TEST_F(RtpBitrateConfiguratorTest,NewConfigWithNoChangesDoesNotCallNewConfig)217 TEST_F(RtpBitrateConfiguratorTest, NewConfigWithNoChangesDoesNotCallNewConfig) {
218 BitrateConstraints config1;
219 config1.min_bitrate_bps = 0;
220 config1.start_bitrate_bps = 1000;
221 config1.max_bitrate_bps = -1;
222
223 BitrateConstraints config2;
224 config2.min_bitrate_bps = 0;
225 config2.start_bitrate_bps = -1;
226 config2.max_bitrate_bps = -1;
227
228 // The second call should not return anything because it doesn't
229 // change any values.
230 UpdateConfigMatches(config1, 0, 1000, -1);
231 EXPECT_FALSE(configurator_->UpdateWithSdpParameters(config2).has_value());
232 }
233
234 // If config changes the max, but not the effective max,
235 // new config shouldn't be returned, to avoid unnecessary encoder
236 // reconfigurations.
TEST_F(RtpBitrateConfiguratorTest,NewConfigNotReturnedWhenEffectiveMaxUnchanged)237 TEST_F(RtpBitrateConfiguratorTest,
238 NewConfigNotReturnedWhenEffectiveMaxUnchanged) {
239 BitrateConstraints config;
240 config.min_bitrate_bps = 0;
241 config.start_bitrate_bps = -1;
242 config.max_bitrate_bps = 2000;
243 UpdateConfigMatches(config, nullopt, nullopt, 2000);
244
245 // Reduce effective max to 1000 with the mask.
246 BitrateSettings mask;
247 mask.max_bitrate_bps = 1000;
248 UpdateMaskMatches(mask, nullopt, nullopt, 1000);
249
250 // This leaves the effective max unchanged, so new config shouldn't be
251 // returned again.
252 config.max_bitrate_bps = 1000;
253 EXPECT_FALSE(configurator_->UpdateWithSdpParameters(config).has_value());
254 }
255
256 // When the "start bitrate" mask is removed, new config shouldn't be returned
257 // again, since nothing's changing.
TEST_F(RtpBitrateConfiguratorTest,NewConfigNotReturnedWhenStartMaskRemoved)258 TEST_F(RtpBitrateConfiguratorTest, NewConfigNotReturnedWhenStartMaskRemoved) {
259 BitrateSettings mask;
260 mask.start_bitrate_bps = 1000;
261 UpdateMaskMatches(mask, 0, 1000, -1);
262
263 mask.start_bitrate_bps.reset();
264 EXPECT_FALSE(configurator_->UpdateWithClientPreferences(mask).has_value());
265 }
266
267 // Test that if a new config is returned after BitrateSettings applies a
268 // "start" value, the new config won't return that start value a
269 // second time.
TEST_F(RtpBitrateConfiguratorTest,NewConfigAfterBitrateConfigMaskWithStart)270 TEST_F(RtpBitrateConfiguratorTest, NewConfigAfterBitrateConfigMaskWithStart) {
271 BitrateSettings mask;
272 mask.start_bitrate_bps = 1000;
273 UpdateMaskMatches(mask, 0, 1000, -1);
274
275 BitrateConstraints config;
276 config.min_bitrate_bps = 0;
277 config.start_bitrate_bps = -1;
278 config.max_bitrate_bps = 5000;
279 // The start value isn't changing, so new config should be returned with
280 // -1.
281 UpdateConfigMatches(config, 0, -1, 5000);
282 }
283
TEST_F(RtpBitrateConfiguratorTest,NewConfigNotReturnedWhenClampedMinUnchanged)284 TEST_F(RtpBitrateConfiguratorTest,
285 NewConfigNotReturnedWhenClampedMinUnchanged) {
286 BitrateConstraints bitrate_config;
287 bitrate_config.start_bitrate_bps = 500;
288 bitrate_config.max_bitrate_bps = 1000;
289 configurator_.reset(new RtpBitrateConfigurator(bitrate_config));
290
291 // Set min to 2000; it is clamped to the max (1000).
292 BitrateSettings mask;
293 mask.min_bitrate_bps = 2000;
294 UpdateMaskMatches(mask, 1000, -1, 1000);
295
296 // Set min to 3000; the clamped value stays the same so nothing happens.
297 mask.min_bitrate_bps = 3000;
298 EXPECT_FALSE(configurator_->UpdateWithClientPreferences(mask).has_value());
299 }
300 } // namespace webrtc
301