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