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
11 #include <string>
12
13 #include "api/test/video/function_video_encoder_factory.h"
14 #include "media/engine/internal_encoder_factory.h"
15 #include "modules/video_coding/codecs/h264/include/h264.h"
16 #include "modules/video_coding/codecs/vp8/include/vp8.h"
17 #include "modules/video_coding/codecs/vp9/include/vp9.h"
18 #include "rtc_base/experiments/encoder_info_settings.h"
19 #include "test/call_test.h"
20 #include "test/field_trial.h"
21 #include "test/frame_generator_capturer.h"
22 #include "video/config/encoder_stream_factory.h"
23
24 namespace webrtc {
25 namespace {
26 constexpr int kInitialWidth = 1280;
27 constexpr int kInitialHeight = 720;
28 constexpr int kLowStartBps = 100000;
29 constexpr int kHighStartBps = 1000000;
30 constexpr int kDefaultVgaMinStartBps = 500000; // From video_stream_encoder.cc
31 constexpr TimeDelta kTimeout =
32 TimeDelta::Seconds(10); // Some tests are expected to time out.
33
SetEncoderSpecific(VideoEncoderConfig * encoder_config,VideoCodecType type,bool automatic_resize,size_t num_spatial_layers)34 void SetEncoderSpecific(VideoEncoderConfig* encoder_config,
35 VideoCodecType type,
36 bool automatic_resize,
37 size_t num_spatial_layers) {
38 if (type == kVideoCodecVP8) {
39 VideoCodecVP8 vp8 = VideoEncoder::GetDefaultVp8Settings();
40 vp8.automaticResizeOn = automatic_resize;
41 encoder_config->encoder_specific_settings =
42 rtc::make_ref_counted<VideoEncoderConfig::Vp8EncoderSpecificSettings>(
43 vp8);
44 } else if (type == kVideoCodecVP9) {
45 VideoCodecVP9 vp9 = VideoEncoder::GetDefaultVp9Settings();
46 vp9.automaticResizeOn = automatic_resize;
47 vp9.numberOfSpatialLayers = num_spatial_layers;
48 encoder_config->encoder_specific_settings =
49 rtc::make_ref_counted<VideoEncoderConfig::Vp9EncoderSpecificSettings>(
50 vp9);
51 }
52 }
53 } // namespace
54
55 class QualityScalingTest : public test::CallTest {
56 protected:
57 const std::string kPrefix = "WebRTC-Video-QualityScaling/Enabled-";
58 const std::string kEnd = ",0,0,0.9995,0.9999,1/";
59 const absl::optional<VideoEncoder::ResolutionBitrateLimits>
60 kSinglecastLimits720pVp8 =
61 EncoderInfoSettings::GetDefaultSinglecastBitrateLimitsForResolution(
62 kVideoCodecVP8,
63 1280 * 720);
64 const absl::optional<VideoEncoder::ResolutionBitrateLimits>
65 kSinglecastLimits360pVp9 =
66 EncoderInfoSettings::GetDefaultSinglecastBitrateLimitsForResolution(
67 kVideoCodecVP9,
68 640 * 360);
69 const absl::optional<VideoEncoder::ResolutionBitrateLimits>
70 kSinglecastLimits720pVp9 =
71 EncoderInfoSettings::GetDefaultSinglecastBitrateLimitsForResolution(
72 kVideoCodecVP9,
73 1280 * 720);
74 };
75
76 class ScalingObserver : public test::SendTest {
77 protected:
78 struct TestParams {
79 bool active;
80 absl::optional<ScalabilityMode> scalability_mode;
81 };
ScalingObserver(const std::string & payload_name,const std::vector<TestParams> & test_params,int start_bps,bool automatic_resize,bool expect_scaling)82 ScalingObserver(const std::string& payload_name,
83 const std::vector<TestParams>& test_params,
84 int start_bps,
85 bool automatic_resize,
86 bool expect_scaling)
87 : SendTest(expect_scaling ? kTimeout * 4 : kTimeout),
88 encoder_factory_(
89 [](const SdpVideoFormat& format) -> std::unique_ptr<VideoEncoder> {
90 if (format.name == "VP8")
91 return VP8Encoder::Create();
92 if (format.name == "VP9")
93 return VP9Encoder::Create();
94 if (format.name == "H264")
95 return H264Encoder::Create(cricket::VideoCodec("H264"));
96 RTC_DCHECK_NOTREACHED() << format.name;
97 return nullptr;
98 }),
99 payload_name_(payload_name),
100 test_params_(test_params),
101 start_bps_(start_bps),
102 automatic_resize_(automatic_resize),
103 expect_scaling_(expect_scaling) {}
104
105 DegradationPreference degradation_preference_ =
106 DegradationPreference::MAINTAIN_FRAMERATE;
107
108 private:
ModifySenderBitrateConfig(BitrateConstraints * bitrate_config)109 void ModifySenderBitrateConfig(BitrateConstraints* bitrate_config) override {
110 bitrate_config->start_bitrate_bps = start_bps_;
111 }
112
ModifyVideoDegradationPreference(DegradationPreference * degradation_preference)113 void ModifyVideoDegradationPreference(
114 DegradationPreference* degradation_preference) override {
115 *degradation_preference = degradation_preference_;
116 }
117
GetNumVideoStreams() const118 size_t GetNumVideoStreams() const override {
119 return (payload_name_ == "VP9") ? 1 : test_params_.size();
120 }
121
ModifyVideoConfigs(VideoSendStream::Config * send_config,std::vector<VideoReceiveStreamInterface::Config> * receive_configs,VideoEncoderConfig * encoder_config)122 void ModifyVideoConfigs(
123 VideoSendStream::Config* send_config,
124 std::vector<VideoReceiveStreamInterface::Config>* receive_configs,
125 VideoEncoderConfig* encoder_config) override {
126 VideoEncoder::EncoderInfo encoder_info;
127 send_config->encoder_settings.encoder_factory = &encoder_factory_;
128 send_config->rtp.payload_name = payload_name_;
129 send_config->rtp.payload_type = test::CallTest::kVideoSendPayloadType;
130 encoder_config->video_format.name = payload_name_;
131 const VideoCodecType codec_type = PayloadStringToCodecType(payload_name_);
132 encoder_config->codec_type = codec_type;
133 encoder_config->video_stream_factory =
134 rtc::make_ref_counted<cricket::EncoderStreamFactory>(
135 payload_name_, /*max_qp=*/0, /*is_screenshare=*/false,
136 /*conference_mode=*/false, encoder_info);
137 encoder_config->max_bitrate_bps =
138 std::max(start_bps_, encoder_config->max_bitrate_bps);
139 if (payload_name_ == "VP9") {
140 // Simulcast layers indicates which spatial layers are active.
141 encoder_config->simulcast_layers.resize(test_params_.size());
142 encoder_config->simulcast_layers[0].max_bitrate_bps =
143 encoder_config->max_bitrate_bps;
144 }
145 double scale_factor = 1.0;
146 for (int i = test_params_.size() - 1; i >= 0; --i) {
147 VideoStream& stream = encoder_config->simulcast_layers[i];
148 stream.active = test_params_[i].active;
149 stream.scalability_mode = test_params_[i].scalability_mode;
150 stream.scale_resolution_down_by = scale_factor;
151 scale_factor *= (payload_name_ == "VP9") ? 1.0 : 2.0;
152 }
153 encoder_config->frame_drop_enabled = true;
154 SetEncoderSpecific(encoder_config, codec_type, automatic_resize_,
155 test_params_.size());
156 }
157
PerformTest()158 void PerformTest() override { EXPECT_EQ(expect_scaling_, Wait()); }
159
160 test::FunctionVideoEncoderFactory encoder_factory_;
161 const std::string payload_name_;
162 const std::vector<TestParams> test_params_;
163 const int start_bps_;
164 const bool automatic_resize_;
165 const bool expect_scaling_;
166 };
167
168 class DownscalingObserver
169 : public ScalingObserver,
170 public test::FrameGeneratorCapturer::SinkWantsObserver {
171 public:
DownscalingObserver(const std::string & payload_name,const std::vector<TestParams> & test_params,int start_bps,bool automatic_resize,bool expect_downscale)172 DownscalingObserver(const std::string& payload_name,
173 const std::vector<TestParams>& test_params,
174 int start_bps,
175 bool automatic_resize,
176 bool expect_downscale)
177 : ScalingObserver(payload_name,
178 test_params,
179 start_bps,
180 automatic_resize,
181 expect_downscale) {}
182
183 private:
OnFrameGeneratorCapturerCreated(test::FrameGeneratorCapturer * frame_generator_capturer)184 void OnFrameGeneratorCapturerCreated(
185 test::FrameGeneratorCapturer* frame_generator_capturer) override {
186 frame_generator_capturer->SetSinkWantsObserver(this);
187 frame_generator_capturer->ChangeResolution(kInitialWidth, kInitialHeight);
188 }
189
OnSinkWantsChanged(rtc::VideoSinkInterface<VideoFrame> * sink,const rtc::VideoSinkWants & wants)190 void OnSinkWantsChanged(rtc::VideoSinkInterface<VideoFrame>* sink,
191 const rtc::VideoSinkWants& wants) override {
192 if (wants.max_pixel_count < kInitialWidth * kInitialHeight)
193 observation_complete_.Set();
194 }
195 };
196
197 class UpscalingObserver
198 : public ScalingObserver,
199 public test::FrameGeneratorCapturer::SinkWantsObserver {
200 public:
UpscalingObserver(const std::string & payload_name,const std::vector<TestParams> & test_params,int start_bps,bool automatic_resize,bool expect_upscale)201 UpscalingObserver(const std::string& payload_name,
202 const std::vector<TestParams>& test_params,
203 int start_bps,
204 bool automatic_resize,
205 bool expect_upscale)
206 : ScalingObserver(payload_name,
207 test_params,
208 start_bps,
209 automatic_resize,
210 expect_upscale) {}
211
SetDegradationPreference(DegradationPreference preference)212 void SetDegradationPreference(DegradationPreference preference) {
213 degradation_preference_ = preference;
214 }
215
216 private:
OnFrameGeneratorCapturerCreated(test::FrameGeneratorCapturer * frame_generator_capturer)217 void OnFrameGeneratorCapturerCreated(
218 test::FrameGeneratorCapturer* frame_generator_capturer) override {
219 frame_generator_capturer->SetSinkWantsObserver(this);
220 frame_generator_capturer->ChangeResolution(kInitialWidth, kInitialHeight);
221 }
222
OnSinkWantsChanged(rtc::VideoSinkInterface<VideoFrame> * sink,const rtc::VideoSinkWants & wants)223 void OnSinkWantsChanged(rtc::VideoSinkInterface<VideoFrame>* sink,
224 const rtc::VideoSinkWants& wants) override {
225 if (wants.max_pixel_count > last_wants_.max_pixel_count) {
226 if (wants.max_pixel_count == std::numeric_limits<int>::max())
227 observation_complete_.Set();
228 }
229 last_wants_ = wants;
230 }
231
232 rtc::VideoSinkWants last_wants_;
233 };
234
TEST_F(QualityScalingTest,AdaptsDownForHighQp_Vp8)235 TEST_F(QualityScalingTest, AdaptsDownForHighQp_Vp8) {
236 // qp_low:1, qp_high:1 -> kHighQp
237 test::ScopedKeyValueConfig field_trials(field_trials_,
238 kPrefix + "1,1,0,0,0,0" + kEnd);
239
240 DownscalingObserver test("VP8", {{.active = true}}, kHighStartBps,
241 /*automatic_resize=*/true,
242 /*expect_downscale=*/true);
243 RunBaseTest(&test);
244 }
245
TEST_F(QualityScalingTest,NoAdaptDownForHighQpIfScalingOff_Vp8)246 TEST_F(QualityScalingTest, NoAdaptDownForHighQpIfScalingOff_Vp8) {
247 // qp_low:1, qp_high:1 -> kHighQp
248 test::ScopedKeyValueConfig field_trials(field_trials_,
249 kPrefix + "1,1,0,0,0,0" + kEnd);
250
251 DownscalingObserver test("VP8", {{.active = true}}, kHighStartBps,
252 /*automatic_resize=*/false,
253 /*expect_downscale=*/false);
254 RunBaseTest(&test);
255 }
256
TEST_F(QualityScalingTest,NoAdaptDownForNormalQp_Vp8)257 TEST_F(QualityScalingTest, NoAdaptDownForNormalQp_Vp8) {
258 // qp_low:1, qp_high:127 -> kNormalQp
259 test::ScopedKeyValueConfig field_trials(field_trials_,
260 kPrefix + "1,127,0,0,0,0" + kEnd);
261
262 DownscalingObserver test("VP8", {{.active = true}}, kHighStartBps,
263 /*automatic_resize=*/true,
264 /*expect_downscale=*/false);
265 RunBaseTest(&test);
266 }
267
TEST_F(QualityScalingTest,AdaptsDownForLowStartBitrate_Vp8)268 TEST_F(QualityScalingTest, AdaptsDownForLowStartBitrate_Vp8) {
269 // qp_low:1, qp_high:127 -> kNormalQp
270 test::ScopedKeyValueConfig field_trials(field_trials_,
271 kPrefix + "1,127,0,0,0,0" + kEnd);
272
273 DownscalingObserver test("VP8", {{.active = true}}, kLowStartBps,
274 /*automatic_resize=*/true,
275 /*expect_downscale=*/true);
276 RunBaseTest(&test);
277 }
278
TEST_F(QualityScalingTest,AdaptsDownForLowStartBitrateAndThenUp)279 TEST_F(QualityScalingTest, AdaptsDownForLowStartBitrateAndThenUp) {
280 // qp_low:127, qp_high:127 -> kLowQp
281 test::ScopedKeyValueConfig field_trials(
282 field_trials_,
283 kPrefix + "127,127,0,0,0,0" + kEnd +
284 "WebRTC-Video-BalancedDegradationSettings/"
285 "pixels:230400|921600,fps:20|30,kbps:300|500/"); // should not affect
286
287 UpscalingObserver test("VP8", {{.active = true}}, kDefaultVgaMinStartBps - 1,
288 /*automatic_resize=*/true, /*expect_upscale=*/true);
289 RunBaseTest(&test);
290 }
291
TEST_F(QualityScalingTest,AdaptsDownAndThenUpWithBalanced)292 TEST_F(QualityScalingTest, AdaptsDownAndThenUpWithBalanced) {
293 // qp_low:127, qp_high:127 -> kLowQp
294 test::ScopedKeyValueConfig field_trials(
295 field_trials_, kPrefix + "127,127,0,0,0,0" + kEnd +
296 "WebRTC-Video-BalancedDegradationSettings/"
297 "pixels:230400|921600,fps:20|30,kbps:300|499/");
298
299 UpscalingObserver test("VP8", {{.active = true}}, kDefaultVgaMinStartBps - 1,
300 /*automatic_resize=*/true, /*expect_upscale=*/true);
301 test.SetDegradationPreference(DegradationPreference::BALANCED);
302 RunBaseTest(&test);
303 }
304
TEST_F(QualityScalingTest,AdaptsDownButNotUpWithBalancedIfBitrateNotEnough)305 TEST_F(QualityScalingTest, AdaptsDownButNotUpWithBalancedIfBitrateNotEnough) {
306 // qp_low:127, qp_high:127 -> kLowQp
307 test::ScopedKeyValueConfig field_trials(
308 field_trials_, kPrefix + "127,127,0,0,0,0" + kEnd +
309 "WebRTC-Video-BalancedDegradationSettings/"
310 "pixels:230400|921600,fps:20|30,kbps:300|500/");
311
312 UpscalingObserver test("VP8", {{.active = true}}, kDefaultVgaMinStartBps - 1,
313 /*automatic_resize=*/true, /*expect_upscale=*/false);
314 test.SetDegradationPreference(DegradationPreference::BALANCED);
315 RunBaseTest(&test);
316 }
317
TEST_F(QualityScalingTest,NoAdaptDownForLowStartBitrate_Simulcast)318 TEST_F(QualityScalingTest, NoAdaptDownForLowStartBitrate_Simulcast) {
319 // qp_low:1, qp_high:127 -> kNormalQp
320 test::ScopedKeyValueConfig field_trials(field_trials_,
321 kPrefix + "1,127,0,0,0,0" + kEnd);
322
323 DownscalingObserver test("VP8", {{.active = true}, {.active = true}},
324 kLowStartBps,
325 /*automatic_resize=*/false,
326 /*expect_downscale=*/false);
327 RunBaseTest(&test);
328 }
329
TEST_F(QualityScalingTest,AdaptsDownForHighQp_HighestStreamActive_Vp8)330 TEST_F(QualityScalingTest, AdaptsDownForHighQp_HighestStreamActive_Vp8) {
331 // qp_low:1, qp_high:1 -> kHighQp
332 test::ScopedKeyValueConfig field_trials(field_trials_,
333 kPrefix + "1,1,0,0,0,0" + kEnd);
334
335 DownscalingObserver test(
336 "VP8", {{.active = false}, {.active = false}, {.active = true}},
337 kHighStartBps,
338 /*automatic_resize=*/true,
339 /*expect_downscale=*/true);
340 RunBaseTest(&test);
341 }
342
TEST_F(QualityScalingTest,AdaptsDownForLowStartBitrate_HighestStreamActive_Vp8)343 TEST_F(QualityScalingTest,
344 AdaptsDownForLowStartBitrate_HighestStreamActive_Vp8) {
345 // qp_low:1, qp_high:127 -> kNormalQp
346 test::ScopedKeyValueConfig field_trials(field_trials_,
347 kPrefix + "1,127,0,0,0,0" + kEnd);
348
349 DownscalingObserver test(
350 "VP8", {{.active = false}, {.active = false}, {.active = true}},
351 kSinglecastLimits720pVp8->min_start_bitrate_bps - 1,
352 /*automatic_resize=*/true,
353 /*expect_downscale=*/true);
354 RunBaseTest(&test);
355 }
356
TEST_F(QualityScalingTest,AdaptsDownButNotUpWithMinStartBitrateLimit)357 TEST_F(QualityScalingTest, AdaptsDownButNotUpWithMinStartBitrateLimit) {
358 // qp_low:127, qp_high:127 -> kLowQp
359 test::ScopedKeyValueConfig field_trials(field_trials_,
360 kPrefix + "127,127,0,0,0,0" + kEnd);
361
362 UpscalingObserver test("VP8", {{.active = false}, {.active = true}},
363 kSinglecastLimits720pVp8->min_start_bitrate_bps - 1,
364 /*automatic_resize=*/true, /*expect_upscale=*/false);
365 RunBaseTest(&test);
366 }
367
TEST_F(QualityScalingTest,NoAdaptDownForLowStartBitrateIfBitrateEnough_Vp8)368 TEST_F(QualityScalingTest, NoAdaptDownForLowStartBitrateIfBitrateEnough_Vp8) {
369 // qp_low:1, qp_high:127 -> kNormalQp
370 test::ScopedKeyValueConfig field_trials(field_trials_,
371 kPrefix + "1,127,0,0,0,0" + kEnd);
372
373 DownscalingObserver test(
374 "VP8", {{.active = false}, {.active = false}, {.active = true}},
375 kSinglecastLimits720pVp8->min_start_bitrate_bps,
376 /*automatic_resize=*/true,
377 /*expect_downscale=*/false);
378 RunBaseTest(&test);
379 }
380
TEST_F(QualityScalingTest,NoAdaptDownForLowStartBitrateIfDefaultLimitsDisabled_Vp8)381 TEST_F(QualityScalingTest,
382 NoAdaptDownForLowStartBitrateIfDefaultLimitsDisabled_Vp8) {
383 // qp_low:1, qp_high:127 -> kNormalQp
384 test::ScopedKeyValueConfig field_trials(
385 field_trials_, kPrefix + "1,127,0,0,0,0" + kEnd +
386 "WebRTC-DefaultBitrateLimitsKillSwitch/Enabled/");
387
388 DownscalingObserver test(
389 "VP8", {{.active = false}, {.active = false}, {.active = true}},
390 kSinglecastLimits720pVp8->min_start_bitrate_bps - 1,
391 /*automatic_resize=*/true,
392 /*expect_downscale=*/false);
393 RunBaseTest(&test);
394 }
395
TEST_F(QualityScalingTest,NoAdaptDownForLowStartBitrate_OneStreamSinglecastLimitsNotUsed_Vp8)396 TEST_F(QualityScalingTest,
397 NoAdaptDownForLowStartBitrate_OneStreamSinglecastLimitsNotUsed_Vp8) {
398 // qp_low:1, qp_high:127 -> kNormalQp
399 test::ScopedKeyValueConfig field_trials(field_trials_,
400 kPrefix + "1,127,0,0,0,0" + kEnd);
401
402 DownscalingObserver test("VP8", {{.active = true}},
403 kSinglecastLimits720pVp8->min_start_bitrate_bps - 1,
404 /*automatic_resize=*/true,
405 /*expect_downscale=*/false);
406 RunBaseTest(&test);
407 }
408
TEST_F(QualityScalingTest,NoAdaptDownForHighQp_LowestStreamActive_Vp8)409 TEST_F(QualityScalingTest, NoAdaptDownForHighQp_LowestStreamActive_Vp8) {
410 // qp_low:1, qp_high:1 -> kHighQp
411 test::ScopedKeyValueConfig field_trials(field_trials_,
412 kPrefix + "1,1,0,0,0,0" + kEnd);
413
414 DownscalingObserver test(
415 "VP8", {{.active = true}, {.active = false}, {.active = false}},
416 kHighStartBps,
417 /*automatic_resize=*/true,
418 /*expect_downscale=*/false);
419 RunBaseTest(&test);
420 }
421
TEST_F(QualityScalingTest,NoAdaptDownForLowStartBitrate_LowestStreamActive_Vp8)422 TEST_F(QualityScalingTest,
423 NoAdaptDownForLowStartBitrate_LowestStreamActive_Vp8) {
424 // qp_low:1, qp_high:127 -> kNormalQp
425 test::ScopedKeyValueConfig field_trials(field_trials_,
426 kPrefix + "1,127,0,0,0,0" + kEnd);
427
428 DownscalingObserver test(
429 "VP8", {{.active = true}, {.active = false}, {.active = false}},
430 kLowStartBps,
431 /*automatic_resize=*/true,
432 /*expect_downscale=*/false);
433 RunBaseTest(&test);
434 }
435
TEST_F(QualityScalingTest,NoAdaptDownForLowStartBitrateIfScalingOff_Vp8)436 TEST_F(QualityScalingTest, NoAdaptDownForLowStartBitrateIfScalingOff_Vp8) {
437 // qp_low:1, qp_high:127 -> kNormalQp
438 test::ScopedKeyValueConfig field_trials(field_trials_,
439 kPrefix + "1,127,0,0,0,0" + kEnd);
440
441 DownscalingObserver test("VP8", {{.active = true}}, kLowStartBps,
442 /*automatic_resize=*/false,
443 /*expect_downscale=*/false);
444 RunBaseTest(&test);
445 }
446
TEST_F(QualityScalingTest,AdaptsDownForHighQp_Vp9)447 TEST_F(QualityScalingTest, AdaptsDownForHighQp_Vp9) {
448 // qp_low:1, qp_high:1 -> kHighQp
449 test::ScopedKeyValueConfig field_trials(field_trials_,
450 kPrefix + "0,0,1,1,0,0" + kEnd);
451
452 DownscalingObserver test("VP9", {{.active = true}}, kHighStartBps,
453 /*automatic_resize=*/true,
454 /*expect_downscale=*/true);
455 RunBaseTest(&test);
456 }
457
TEST_F(QualityScalingTest,NoAdaptDownForHighQpIfScalingOff_Vp9)458 TEST_F(QualityScalingTest, NoAdaptDownForHighQpIfScalingOff_Vp9) {
459 // qp_low:1, qp_high:1 -> kHighQp
460 test::ScopedKeyValueConfig field_trials(
461 field_trials_,
462 kPrefix + "0,0,1,1,0,0" + kEnd + "WebRTC-VP9QualityScaler/Disabled/");
463
464 DownscalingObserver test("VP9", {{.active = true}}, kHighStartBps,
465 /*automatic_resize=*/true,
466 /*expect_downscale=*/false);
467 RunBaseTest(&test);
468 }
469
TEST_F(QualityScalingTest,AdaptsDownForLowStartBitrate_Vp9)470 TEST_F(QualityScalingTest, AdaptsDownForLowStartBitrate_Vp9) {
471 // qp_low:1, qp_high:255 -> kNormalQp
472 test::ScopedKeyValueConfig field_trials(field_trials_,
473 kPrefix + "0,0,1,255,0,0" + kEnd);
474
475 DownscalingObserver test("VP9", {{.active = true}}, kLowStartBps,
476 /*automatic_resize=*/true,
477 /*expect_downscale=*/true);
478 RunBaseTest(&test);
479 }
480
TEST_F(QualityScalingTest,NoAdaptDownForHighStartBitrate_Vp9)481 TEST_F(QualityScalingTest, NoAdaptDownForHighStartBitrate_Vp9) {
482 DownscalingObserver test(
483 "VP9", {{.active = false}, {.active = false}, {.active = true}},
484 kHighStartBps,
485 /*automatic_resize=*/true,
486 /*expect_downscale=*/false);
487 RunBaseTest(&test);
488 }
489
TEST_F(QualityScalingTest,NoAdaptDownForHighQp_LowestStreamActive_Vp9)490 TEST_F(QualityScalingTest, NoAdaptDownForHighQp_LowestStreamActive_Vp9) {
491 // qp_low:1, qp_high:1 -> kHighQp
492 test::ScopedKeyValueConfig field_trials(field_trials_,
493 kPrefix + "0,0,1,1,0,0" + kEnd);
494
495 DownscalingObserver test(
496 "VP9", {{.active = true}, {.active = false}, {.active = false}},
497 kHighStartBps,
498 /*automatic_resize=*/true,
499 /*expect_downscale=*/false);
500 RunBaseTest(&test);
501 }
502
TEST_F(QualityScalingTest,NoAdaptDownForLowStartBitrate_LowestStreamActive_Vp9)503 TEST_F(QualityScalingTest,
504 NoAdaptDownForLowStartBitrate_LowestStreamActive_Vp9) {
505 // qp_low:1, qp_high:255 -> kNormalQp
506 test::ScopedKeyValueConfig field_trials(field_trials_,
507 kPrefix + "0,0,1,255,0,0" + kEnd);
508
509 DownscalingObserver test(
510 "VP9", {{.active = true}, {.active = false}, {.active = false}},
511 kLowStartBps,
512 /*automatic_resize=*/true,
513 /*expect_downscale=*/false);
514 RunBaseTest(&test);
515 }
516
TEST_F(QualityScalingTest,AdaptsDownForHighQp_MiddleStreamActive_Vp9)517 TEST_F(QualityScalingTest, AdaptsDownForHighQp_MiddleStreamActive_Vp9) {
518 // qp_low:1, qp_high:1 -> kHighQp
519 test::ScopedKeyValueConfig field_trials(field_trials_,
520 kPrefix + "0,0,1,1,0,0" + kEnd);
521
522 DownscalingObserver test(
523 "VP9", {{.active = false}, {.active = true}, {.active = false}},
524 kHighStartBps,
525 /*automatic_resize=*/true,
526 /*expect_downscale=*/true);
527 RunBaseTest(&test);
528 }
529
TEST_F(QualityScalingTest,AdaptsDownForLowStartBitrate_MiddleStreamActive_Vp9)530 TEST_F(QualityScalingTest,
531 AdaptsDownForLowStartBitrate_MiddleStreamActive_Vp9) {
532 // qp_low:1, qp_high:255 -> kNormalQp
533 test::ScopedKeyValueConfig field_trials(field_trials_,
534 kPrefix + "0,0,1,255,0,0" + kEnd);
535
536 DownscalingObserver test(
537 "VP9", {{.active = false}, {.active = true}, {.active = false}},
538 kSinglecastLimits360pVp9->min_start_bitrate_bps - 1,
539 /*automatic_resize=*/true,
540 /*expect_downscale=*/true);
541 RunBaseTest(&test);
542 }
543
TEST_F(QualityScalingTest,NoAdaptDownForLowStartBitrateIfBitrateEnough_Vp9)544 TEST_F(QualityScalingTest, NoAdaptDownForLowStartBitrateIfBitrateEnough_Vp9) {
545 // qp_low:1, qp_high:255 -> kNormalQp
546 test::ScopedKeyValueConfig field_trials(field_trials_,
547 kPrefix + "0,0,1,255,0,0" + kEnd);
548
549 DownscalingObserver test(
550 "VP9", {{.active = false}, {.active = true}, {.active = false}},
551 kSinglecastLimits360pVp9->min_start_bitrate_bps,
552 /*automatic_resize=*/true,
553 /*expect_downscale=*/false);
554 RunBaseTest(&test);
555 }
556
TEST_F(QualityScalingTest,AdaptsDownButNotUpWithMinStartBitrateLimitWithScalabilityMode_VP9)557 TEST_F(QualityScalingTest,
558 AdaptsDownButNotUpWithMinStartBitrateLimitWithScalabilityMode_VP9) {
559 // qp_low:255, qp_high:255 -> kLowQp
560 test::ScopedKeyValueConfig field_trials(field_trials_,
561 kPrefix + "0,0,255,255,0,0" + kEnd);
562
563 UpscalingObserver test(
564 "VP9",
565 {{.active = true, .scalability_mode = ScalabilityMode::kL1T3},
566 {.active = false}},
567 kSinglecastLimits720pVp9->min_start_bitrate_bps - 1,
568 /*automatic_resize=*/true, /*expect_upscale=*/false);
569 RunBaseTest(&test);
570 }
571
TEST_F(QualityScalingTest,NoAdaptDownForLowStartBitrateIfBitrateEnoughWithScalabilityMode_Vp9)572 TEST_F(QualityScalingTest,
573 NoAdaptDownForLowStartBitrateIfBitrateEnoughWithScalabilityMode_Vp9) {
574 // qp_low:1, qp_high:255 -> kNormalQp
575 test::ScopedKeyValueConfig field_trials(field_trials_,
576 kPrefix + "0,0,1,255,0,0" + kEnd);
577
578 DownscalingObserver test(
579 "VP9",
580 {{.active = true, .scalability_mode = ScalabilityMode::kL1T3},
581 {.active = false},
582 {.active = false}},
583 kSinglecastLimits720pVp9->min_start_bitrate_bps,
584 /*automatic_resize=*/true,
585 /*expect_downscale=*/false);
586 RunBaseTest(&test);
587 }
588
589 #if defined(WEBRTC_USE_H264)
TEST_F(QualityScalingTest,AdaptsDownForHighQp_H264)590 TEST_F(QualityScalingTest, AdaptsDownForHighQp_H264) {
591 // qp_low:1, qp_high:1 -> kHighQp
592 test::ScopedKeyValueConfig field_trials(field_trials_,
593 kPrefix + "0,0,0,0,1,1" + kEnd);
594
595 DownscalingObserver test("H264", {{.active = true}}, kHighStartBps,
596 /*automatic_resize=*/true,
597 /*expect_downscale=*/true);
598 RunBaseTest(&test);
599 }
600
TEST_F(QualityScalingTest,AdaptsDownForLowStartBitrate_H264)601 TEST_F(QualityScalingTest, AdaptsDownForLowStartBitrate_H264) {
602 // qp_low:1, qp_high:51 -> kNormalQp
603 test::ScopedKeyValueConfig field_trials(field_trials_,
604 kPrefix + "0,0,0,0,1,51" + kEnd);
605
606 DownscalingObserver test("H264", {{.active = true}}, kLowStartBps,
607 /*automatic_resize=*/true,
608 /*expect_downscale=*/true);
609 RunBaseTest(&test);
610 }
611 #endif // defined(WEBRTC_USE_H264)
612
613 } // namespace webrtc
614