xref: /aosp_15_r20/external/webrtc/video/quality_scaling_tests.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
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