blob: 6449a1a0f5db8b00e38155772e032c8becebbdcb [file] [log] [blame]
Sebastian Janssondf023aa2018-02-20 19:38:37 +01001/*
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 */
Jonas Olssona4d87372019-07-05 19:08:33 +020010#include "call/rtp_bitrate_configurator.h"
11
Sebastian Janssondf023aa2018-02-20 19:38:37 +010012#include <memory>
13
Sebastian Janssondf023aa2018-02-20 19:38:37 +010014#include "test/gtest.h"
15
16namespace webrtc {
Danil Chapovalovb9b146c2018-06-15 12:28:07 +020017using absl::nullopt;
Sebastian Janssondf023aa2018-02-20 19:38:37 +010018
Mirko Bonadei6a489f22019-04-09 15:11:12 +020019class RtpBitrateConfiguratorTest : public ::testing::Test {
Sebastian Janssondf023aa2018-02-20 19:38:37 +010020 public:
21 RtpBitrateConfiguratorTest()
22 : configurator_(new RtpBitrateConfigurator(BitrateConstraints())) {}
23 std::unique_ptr<RtpBitrateConfigurator> configurator_;
24 void UpdateConfigMatches(BitrateConstraints bitrate_config,
Danil Chapovalovb9b146c2018-06-15 12:28:07 +020025 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 =
Sebastian Janssondf023aa2018-02-20 19:38:37 +010029 configurator_->UpdateWithSdpParameters(bitrate_config);
Mirko Bonadeib408bb72020-01-10 15:34:49 +000030 EXPECT_TRUE(result.has_value());
Sebastian Janssondf023aa2018-02-20 19:38:37 +010031 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
Niels Möller0c4f7be2018-05-07 14:01:37 +020039 void UpdateMaskMatches(BitrateSettings bitrate_mask,
Danil Chapovalovb9b146c2018-06-15 12:28:07 +020040 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 =
Sebastian Janssondf023aa2018-02-20 19:38:37 +010044 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
55TEST_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
64TEST_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
75TEST_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
87TEST_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
98TEST_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
109TEST_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
123TEST_F(RtpBitrateConfiguratorTest, BiggerMaskMinUsed) {
Niels Möller0c4f7be2018-05-07 14:01:37 +0200124 BitrateSettings mask;
Sebastian Janssondf023aa2018-02-20 19:38:37 +0100125 mask.min_bitrate_bps = 1234;
126 UpdateMaskMatches(mask, *mask.min_bitrate_bps, nullopt, nullopt);
127}
128
129TEST_F(RtpBitrateConfiguratorTest, BiggerConfigMinUsed) {
Niels Möller0c4f7be2018-05-07 14:01:37 +0200130 BitrateSettings mask;
Sebastian Janssondf023aa2018-02-20 19:38:37 +0100131 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.
140TEST_F(RtpBitrateConfiguratorTest, LatestStartMaskPreferred) {
Niels Möller0c4f7be2018-05-07 14:01:37 +0200141 BitrateSettings mask;
Sebastian Janssondf023aa2018-02-20 19:38:37 +0100142 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
152TEST_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
Niels Möller0c4f7be2018-05-07 14:01:37 +0200157 BitrateSettings mask;
Sebastian Janssondf023aa2018-02-20 19:38:37 +0100158 mask.max_bitrate_bps = bitrate_config.start_bitrate_bps + 1000;
159
160 UpdateMaskMatches(mask, nullopt, nullopt, *mask.max_bitrate_bps);
161}
162
163TEST_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
Niels Möller0c4f7be2018-05-07 14:01:37 +0200168 BitrateSettings mask;
Sebastian Janssondf023aa2018-02-20 19:38:37 +0100169 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
175TEST_F(RtpBitrateConfiguratorTest, MaskStartLessThanConfigMinClamped) {
176 BitrateConstraints bitrate_config;
177 bitrate_config.min_bitrate_bps = 2000;
178 configurator_.reset(new RtpBitrateConfigurator(bitrate_config));
179
Niels Möller0c4f7be2018-05-07 14:01:37 +0200180 BitrateSettings mask;
Sebastian Janssondf023aa2018-02-20 19:38:37 +0100181 mask.start_bitrate_bps = 1000;
182 UpdateMaskMatches(mask, 2000, 2000, nullopt);
183}
184
185TEST_F(RtpBitrateConfiguratorTest, MaskStartGreaterThanConfigMaxClamped) {
186 BitrateConstraints bitrate_config;
187 bitrate_config.start_bitrate_bps = 2000;
188 configurator_.reset(new RtpBitrateConfigurator(bitrate_config));
189
Niels Möller0c4f7be2018-05-07 14:01:37 +0200190 BitrateSettings mask;
Sebastian Janssondf023aa2018-02-20 19:38:37 +0100191 mask.max_bitrate_bps = 1000;
192
193 UpdateMaskMatches(mask, nullopt, -1, 1000);
194}
195
196TEST_F(RtpBitrateConfiguratorTest, MaskMinGreaterThanConfigMaxClamped) {
197 BitrateConstraints bitrate_config;
198 bitrate_config.min_bitrate_bps = 2000;
199 configurator_.reset(new RtpBitrateConfigurator(bitrate_config));
200
Niels Möller0c4f7be2018-05-07 14:01:37 +0200201 BitrateSettings mask;
Sebastian Janssondf023aa2018-02-20 19:38:37 +0100202 mask.max_bitrate_bps = 1000;
203
204 UpdateMaskMatches(mask, 1000, nullopt, 1000);
205}
206
207TEST_F(RtpBitrateConfiguratorTest, SettingMaskStartForcesUpdate) {
Niels Möller0c4f7be2018-05-07 14:01:37 +0200208 BitrateSettings mask;
Sebastian Janssondf023aa2018-02-20 19:38:37 +0100209 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
217TEST_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.
237TEST_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.
Niels Möller0c4f7be2018-05-07 14:01:37 +0200246 BitrateSettings mask;
Sebastian Janssondf023aa2018-02-20 19:38:37 +0100247 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.
258TEST_F(RtpBitrateConfiguratorTest, NewConfigNotReturnedWhenStartMaskRemoved) {
Niels Möller0c4f7be2018-05-07 14:01:37 +0200259 BitrateSettings mask;
Sebastian Janssondf023aa2018-02-20 19:38:37 +0100260 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
Niels Möller0c4f7be2018-05-07 14:01:37 +0200267// Test that if a new config is returned after BitrateSettings applies a
Sebastian Janssondf023aa2018-02-20 19:38:37 +0100268// "start" value, the new config won't return that start value a
269// second time.
270TEST_F(RtpBitrateConfiguratorTest, NewConfigAfterBitrateConfigMaskWithStart) {
Niels Möller0c4f7be2018-05-07 14:01:37 +0200271 BitrateSettings mask;
Sebastian Janssondf023aa2018-02-20 19:38:37 +0100272 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
284TEST_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).
Niels Möller0c4f7be2018-05-07 14:01:37 +0200292 BitrateSettings mask;
Sebastian Janssondf023aa2018-02-20 19:38:37 +0100293 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