xref: /aosp_15_r20/external/webrtc/video/adaptation/bitrate_constraint_unittest.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1 /*
2  *  Copyright 2021 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 "video/adaptation/bitrate_constraint.h"
12 
13 #include <utility>
14 #include <vector>
15 
16 #include "api/video_codecs/scalability_mode.h"
17 #include "api/video_codecs/video_encoder.h"
18 #include "call/adaptation/encoder_settings.h"
19 #include "call/adaptation/test/fake_frame_rate_provider.h"
20 #include "call/adaptation/video_source_restrictions.h"
21 #include "call/adaptation/video_stream_input_state_provider.h"
22 #include "test/gtest.h"
23 
24 namespace webrtc {
25 
26 namespace {
27 const VideoSourceRestrictions k180p{/*max_pixels_per_frame=*/320 * 180,
28                                     /*target_pixels_per_frame=*/320 * 180,
29                                     /*max_frame_rate=*/30};
30 const VideoSourceRestrictions k360p{/*max_pixels_per_frame=*/640 * 360,
31                                     /*target_pixels_per_frame=*/640 * 360,
32                                     /*max_frame_rate=*/30};
33 const VideoSourceRestrictions k720p{/*max_pixels_per_frame=*/1280 * 720,
34                                     /*target_pixels_per_frame=*/1280 * 720,
35                                     /*max_frame_rate=*/30};
36 
37 struct TestParams {
38   bool active;
39   absl::optional<ScalabilityMode> scalability_mode;
40 };
41 
FillCodecConfig(VideoCodec * video_codec,VideoEncoderConfig * encoder_config,int width_px,int height_px,const std::vector<TestParams> & params,bool svc)42 void FillCodecConfig(VideoCodec* video_codec,
43                      VideoEncoderConfig* encoder_config,
44                      int width_px,
45                      int height_px,
46                      const std::vector<TestParams>& params,
47                      bool svc) {
48   size_t num_layers = params.size();
49   video_codec->codecType = kVideoCodecVP8;
50   video_codec->numberOfSimulcastStreams = num_layers;
51 
52   encoder_config->number_of_streams = svc ? 1 : num_layers;
53   encoder_config->simulcast_layers.resize(num_layers);
54 
55   for (size_t layer_idx = 0; layer_idx < num_layers; ++layer_idx) {
56     int layer_width_px = width_px >> (num_layers - 1 - layer_idx);
57     int layer_height_px = height_px >> (num_layers - 1 - layer_idx);
58 
59     if (params[layer_idx].scalability_mode)
60       video_codec->SetScalabilityMode(*params[layer_idx].scalability_mode);
61     video_codec->simulcastStream[layer_idx].active = params[layer_idx].active;
62     video_codec->simulcastStream[layer_idx].width = layer_width_px;
63     video_codec->simulcastStream[layer_idx].height = layer_height_px;
64 
65     encoder_config->simulcast_layers[layer_idx].scalability_mode =
66         params[layer_idx].scalability_mode;
67     encoder_config->simulcast_layers[layer_idx].active =
68         params[layer_idx].active;
69     encoder_config->simulcast_layers[layer_idx].width = layer_width_px;
70     encoder_config->simulcast_layers[layer_idx].height = layer_height_px;
71   }
72 }
73 
74 constexpr int kStartBitrateBps360p = 500000;
75 constexpr int kStartBitrateBps720p = 1000000;
76 
MakeEncoderInfo()77 VideoEncoder::EncoderInfo MakeEncoderInfo() {
78   VideoEncoder::EncoderInfo encoder_info;
79   encoder_info.resolution_bitrate_limits = {
80       {640 * 360, kStartBitrateBps360p, 0, 5000000},
81       {1280 * 720, kStartBitrateBps720p, 0, 5000000},
82       {1920 * 1080, 2000000, 0, 5000000}};
83   return encoder_info;
84 }
85 
86 }  // namespace
87 
88 class BitrateConstraintTest : public ::testing::Test {
89  public:
BitrateConstraintTest()90   BitrateConstraintTest()
91       : frame_rate_provider_(), input_state_provider_(&frame_rate_provider_) {}
92 
93  protected:
OnEncoderSettingsUpdated(int width_px,int height_px,const std::vector<TestParams> & params,bool svc=false)94   void OnEncoderSettingsUpdated(int width_px,
95                                 int height_px,
96                                 const std::vector<TestParams>& params,
97                                 bool svc = false) {
98     VideoCodec video_codec;
99     VideoEncoderConfig encoder_config;
100     FillCodecConfig(&video_codec, &encoder_config, width_px, height_px, params,
101                     svc);
102 
103     EncoderSettings encoder_settings(MakeEncoderInfo(),
104                                      std::move(encoder_config), video_codec);
105     bitrate_constraint_.OnEncoderSettingsUpdated(encoder_settings);
106     input_state_provider_.OnEncoderSettingsChanged(encoder_settings);
107   }
108 
109   FakeFrameRateProvider frame_rate_provider_;
110   VideoStreamInputStateProvider input_state_provider_;
111   BitrateConstraint bitrate_constraint_;
112 };
113 
TEST_F(BitrateConstraintTest,AdaptUpAllowedAtSinglecastIfBitrateIsEnough)114 TEST_F(BitrateConstraintTest, AdaptUpAllowedAtSinglecastIfBitrateIsEnough) {
115   OnEncoderSettingsUpdated(/*width_px=*/640, /*height_px=*/360,
116                            {{.active = true}});
117 
118   bitrate_constraint_.OnEncoderTargetBitrateUpdated(kStartBitrateBps720p);
119 
120   EXPECT_TRUE(bitrate_constraint_.IsAdaptationUpAllowed(
121       input_state_provider_.InputState(),
122       /*restrictions_before=*/k360p,
123       /*restrictions_after=*/k720p));
124 }
125 
TEST_F(BitrateConstraintTest,AdaptUpDisallowedAtSinglecastIfBitrateIsNotEnough)126 TEST_F(BitrateConstraintTest,
127        AdaptUpDisallowedAtSinglecastIfBitrateIsNotEnough) {
128   OnEncoderSettingsUpdated(/*width_px=*/640, /*height_px=*/360,
129                            {{.active = true}});
130 
131   // 1 bps less than needed for 720p.
132   bitrate_constraint_.OnEncoderTargetBitrateUpdated(kStartBitrateBps720p - 1);
133 
134   EXPECT_FALSE(bitrate_constraint_.IsAdaptationUpAllowed(
135       input_state_provider_.InputState(),
136       /*restrictions_before=*/k360p,
137       /*restrictions_after=*/k720p));
138 }
139 
TEST_F(BitrateConstraintTest,AdaptUpAllowedAtSinglecastIfBitrateIsEnoughForOneSpatialLayer)140 TEST_F(BitrateConstraintTest,
141        AdaptUpAllowedAtSinglecastIfBitrateIsEnoughForOneSpatialLayer) {
142   OnEncoderSettingsUpdated(
143       /*width_px=*/640, /*height_px=*/360,
144       {{.active = true, .scalability_mode = ScalabilityMode::kL1T1}});
145 
146   bitrate_constraint_.OnEncoderTargetBitrateUpdated(kStartBitrateBps720p);
147 
148   EXPECT_TRUE(bitrate_constraint_.IsAdaptationUpAllowed(
149       input_state_provider_.InputState(),
150       /*restrictions_before=*/k360p,
151       /*restrictions_after=*/k720p));
152 }
153 
TEST_F(BitrateConstraintTest,AdaptUpDisallowedAtSinglecastIfBitrateIsNotEnoughForOneSpatialLayer)154 TEST_F(BitrateConstraintTest,
155        AdaptUpDisallowedAtSinglecastIfBitrateIsNotEnoughForOneSpatialLayer) {
156   OnEncoderSettingsUpdated(
157       /*width_px=*/640, /*height_px=*/360,
158       {{.active = true, .scalability_mode = ScalabilityMode::kL1T1}});
159 
160   // 1 bps less than needed for 720p.
161   bitrate_constraint_.OnEncoderTargetBitrateUpdated(kStartBitrateBps720p - 1);
162 
163   EXPECT_FALSE(bitrate_constraint_.IsAdaptationUpAllowed(
164       input_state_provider_.InputState(),
165       /*restrictions_before=*/k360p,
166       /*restrictions_after=*/k720p));
167 }
168 
TEST_F(BitrateConstraintTest,AdaptUpAllowedAtSinglecastIfBitrateIsNotEnoughForMultipleSpatialLayers)169 TEST_F(BitrateConstraintTest,
170        AdaptUpAllowedAtSinglecastIfBitrateIsNotEnoughForMultipleSpatialLayers) {
171   OnEncoderSettingsUpdated(
172       /*width_px=*/640, /*height_px=*/360,
173       {{.active = true, .scalability_mode = ScalabilityMode::kL2T1}});
174 
175   // 1 bps less than needed for 720p.
176   bitrate_constraint_.OnEncoderTargetBitrateUpdated(kStartBitrateBps720p - 1);
177 
178   EXPECT_TRUE(bitrate_constraint_.IsAdaptationUpAllowed(
179       input_state_provider_.InputState(),
180       /*restrictions_before=*/k360p,
181       /*restrictions_after=*/k720p));
182 }
183 
TEST_F(BitrateConstraintTest,AdaptUpAllowedAtSinglecastUpperLayerActiveIfBitrateIsEnough)184 TEST_F(BitrateConstraintTest,
185        AdaptUpAllowedAtSinglecastUpperLayerActiveIfBitrateIsEnough) {
186   OnEncoderSettingsUpdated(
187       /*width_px=*/640, /*height_px=*/360,
188       {{.active = false, .scalability_mode = ScalabilityMode::kL2T1},
189        {.active = true}});
190 
191   bitrate_constraint_.OnEncoderTargetBitrateUpdated(kStartBitrateBps720p);
192 
193   EXPECT_TRUE(bitrate_constraint_.IsAdaptationUpAllowed(
194       input_state_provider_.InputState(),
195       /*restrictions_before=*/k360p,
196       /*restrictions_after=*/k720p));
197 }
198 
TEST_F(BitrateConstraintTest,AdaptUpDisallowedAtSinglecastUpperLayerActiveIfBitrateIsNotEnough)199 TEST_F(BitrateConstraintTest,
200        AdaptUpDisallowedAtSinglecastUpperLayerActiveIfBitrateIsNotEnough) {
201   OnEncoderSettingsUpdated(
202       /*width_px=*/640, /*height_px=*/360,
203       {{.active = false, .scalability_mode = ScalabilityMode::kL2T1},
204        {.active = true}});
205 
206   // 1 bps less than needed for 720p.
207   bitrate_constraint_.OnEncoderTargetBitrateUpdated(kStartBitrateBps720p - 1);
208 
209   EXPECT_FALSE(bitrate_constraint_.IsAdaptationUpAllowed(
210       input_state_provider_.InputState(),
211       /*restrictions_before=*/k360p,
212       /*restrictions_after=*/k720p));
213 }
214 
TEST_F(BitrateConstraintTest,AdaptUpAllowedLowestActiveIfBitrateIsNotEnough)215 TEST_F(BitrateConstraintTest, AdaptUpAllowedLowestActiveIfBitrateIsNotEnough) {
216   OnEncoderSettingsUpdated(/*width_px=*/640, /*height_px=*/360,
217                            {{.active = true}, {.active = false}});
218 
219   // 1 bps less than needed for 360p.
220   bitrate_constraint_.OnEncoderTargetBitrateUpdated(kStartBitrateBps360p - 1);
221 
222   EXPECT_TRUE(bitrate_constraint_.IsAdaptationUpAllowed(
223       input_state_provider_.InputState(),
224       /*restrictions_before=*/k180p,
225       /*restrictions_after=*/k360p));
226 }
227 
TEST_F(BitrateConstraintTest,AdaptUpAllowedLowestActiveIfBitrateIsNotEnoughForOneSpatialLayer)228 TEST_F(BitrateConstraintTest,
229        AdaptUpAllowedLowestActiveIfBitrateIsNotEnoughForOneSpatialLayer) {
230   OnEncoderSettingsUpdated(
231       /*width_px=*/640, /*height_px=*/360,
232       {{.active = true, .scalability_mode = ScalabilityMode::kL1T2},
233        {.active = false}});
234 
235   // 1 bps less than needed for 360p.
236   bitrate_constraint_.OnEncoderTargetBitrateUpdated(kStartBitrateBps360p - 1);
237 
238   EXPECT_TRUE(bitrate_constraint_.IsAdaptationUpAllowed(
239       input_state_provider_.InputState(),
240       /*restrictions_before=*/k180p,
241       /*restrictions_after=*/k360p));
242 }
243 
TEST_F(BitrateConstraintTest,AdaptUpAllowedLowestActiveIfBitrateIsEnoughForOneSpatialLayerSvc)244 TEST_F(BitrateConstraintTest,
245        AdaptUpAllowedLowestActiveIfBitrateIsEnoughForOneSpatialLayerSvc) {
246   OnEncoderSettingsUpdated(
247       /*width_px=*/640, /*height_px=*/360,
248       {{.active = true, .scalability_mode = ScalabilityMode::kL1T1},
249        {.active = false}},
250       /*svc=*/true);
251 
252   bitrate_constraint_.OnEncoderTargetBitrateUpdated(kStartBitrateBps360p);
253 
254   EXPECT_TRUE(bitrate_constraint_.IsAdaptationUpAllowed(
255       input_state_provider_.InputState(),
256       /*restrictions_before=*/k180p,
257       /*restrictions_after=*/k360p));
258 }
259 
TEST_F(BitrateConstraintTest,AdaptUpDisallowedLowestActiveIfBitrateIsNotEnoughForOneSpatialLayerSvc)260 TEST_F(BitrateConstraintTest,
261        AdaptUpDisallowedLowestActiveIfBitrateIsNotEnoughForOneSpatialLayerSvc) {
262   OnEncoderSettingsUpdated(
263       /*width_px=*/640, /*height_px=*/360,
264       {{.active = true, .scalability_mode = ScalabilityMode::kL1T1},
265        {.active = false}},
266       /*svc=*/true);
267 
268   // 1 bps less than needed for 360p.
269   bitrate_constraint_.OnEncoderTargetBitrateUpdated(kStartBitrateBps360p - 1);
270 
271   EXPECT_FALSE(bitrate_constraint_.IsAdaptationUpAllowed(
272       input_state_provider_.InputState(),
273       /*restrictions_before=*/k180p,
274       /*restrictions_after=*/k360p));
275 }
276 
TEST_F(BitrateConstraintTest,AdaptUpAllowedLowestActiveIfBitrateIsNotEnoughForTwoSpatialLayersSvc)277 TEST_F(BitrateConstraintTest,
278        AdaptUpAllowedLowestActiveIfBitrateIsNotEnoughForTwoSpatialLayersSvc) {
279   OnEncoderSettingsUpdated(
280       /*width_px=*/640, /*height_px=*/360,
281       {{.active = true, .scalability_mode = ScalabilityMode::kL2T1},
282        {.active = false}},
283       /*svc=*/true);
284 
285   // 1 bps less than needed for 360p.
286   bitrate_constraint_.OnEncoderTargetBitrateUpdated(kStartBitrateBps360p - 1);
287 
288   EXPECT_TRUE(bitrate_constraint_.IsAdaptationUpAllowed(
289       input_state_provider_.InputState(),
290       /*restrictions_before=*/k180p,
291       /*restrictions_after=*/k360p));
292 }
293 
TEST_F(BitrateConstraintTest,AdaptUpAllowedAtSimulcastIfBitrateIsNotEnough)294 TEST_F(BitrateConstraintTest, AdaptUpAllowedAtSimulcastIfBitrateIsNotEnough) {
295   OnEncoderSettingsUpdated(/*width_px=*/640, /*height_px=*/360,
296                            {{.active = true}, {.active = true}});
297 
298   // 1 bps less than needed for 720p.
299   bitrate_constraint_.OnEncoderTargetBitrateUpdated(kStartBitrateBps720p - 1);
300 
301   EXPECT_TRUE(bitrate_constraint_.IsAdaptationUpAllowed(
302       input_state_provider_.InputState(),
303       /*restrictions_before=*/k360p,
304       /*restrictions_after=*/k720p));
305 }
306 
TEST_F(BitrateConstraintTest,AdaptUpInFpsAllowedAtNoResolutionIncreaseIfBitrateIsNotEnough)307 TEST_F(BitrateConstraintTest,
308        AdaptUpInFpsAllowedAtNoResolutionIncreaseIfBitrateIsNotEnough) {
309   OnEncoderSettingsUpdated(/*width_px=*/640, /*height_px=*/360,
310                            {{.active = true}});
311 
312   bitrate_constraint_.OnEncoderTargetBitrateUpdated(1);
313 
314   EXPECT_TRUE(bitrate_constraint_.IsAdaptationUpAllowed(
315       input_state_provider_.InputState(),
316       /*restrictions_before=*/k360p,
317       /*restrictions_after=*/k360p));
318 }
319 
320 }  // namespace webrtc
321