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