xref: /aosp_15_r20/external/webrtc/video/cpu_scaling_tests.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker  *  Copyright (c) 2018 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 <limits>
12*d9f75844SAndroid Build Coastguard Worker #include <vector>
13*d9f75844SAndroid Build Coastguard Worker 
14*d9f75844SAndroid Build Coastguard Worker #include "api/rtp_parameters.h"
15*d9f75844SAndroid Build Coastguard Worker #include "api/video/video_frame.h"
16*d9f75844SAndroid Build Coastguard Worker #include "api/video/video_sink_interface.h"
17*d9f75844SAndroid Build Coastguard Worker #include "api/video/video_source_interface.h"
18*d9f75844SAndroid Build Coastguard Worker #include "call/video_receive_stream.h"
19*d9f75844SAndroid Build Coastguard Worker #include "call/video_send_stream.h"
20*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/checks.h"
21*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/event.h"
22*d9f75844SAndroid Build Coastguard Worker #include "test/call_test.h"
23*d9f75844SAndroid Build Coastguard Worker #include "test/field_trial.h"
24*d9f75844SAndroid Build Coastguard Worker #include "test/frame_generator_capturer.h"
25*d9f75844SAndroid Build Coastguard Worker #include "test/gtest.h"
26*d9f75844SAndroid Build Coastguard Worker #include "video/config/video_encoder_config.h"
27*d9f75844SAndroid Build Coastguard Worker 
28*d9f75844SAndroid Build Coastguard Worker namespace webrtc {
29*d9f75844SAndroid Build Coastguard Worker namespace {
30*d9f75844SAndroid Build Coastguard Worker constexpr int kWidth = 1280;
31*d9f75844SAndroid Build Coastguard Worker constexpr int kHeight = 720;
32*d9f75844SAndroid Build Coastguard Worker constexpr int kFps = 28;
33*d9f75844SAndroid Build Coastguard Worker }  // namespace
34*d9f75844SAndroid Build Coastguard Worker 
35*d9f75844SAndroid Build Coastguard Worker // Minimal normal usage at start, then 60s overuse.
36*d9f75844SAndroid Build Coastguard Worker class CpuOveruseTest : public test::CallTest {
37*d9f75844SAndroid Build Coastguard Worker  protected:
CpuOveruseTest()38*d9f75844SAndroid Build Coastguard Worker   CpuOveruseTest()
39*d9f75844SAndroid Build Coastguard Worker       : field_trials_("WebRTC-ForceSimulatedOveruseIntervalMs/1-60000-60000/") {
40*d9f75844SAndroid Build Coastguard Worker   }
41*d9f75844SAndroid Build Coastguard Worker 
42*d9f75844SAndroid Build Coastguard Worker   void RunTestAndCheckForAdaptation(
43*d9f75844SAndroid Build Coastguard Worker       const DegradationPreference& degradation_preference,
44*d9f75844SAndroid Build Coastguard Worker       bool expect_adaptation);
45*d9f75844SAndroid Build Coastguard Worker 
46*d9f75844SAndroid Build Coastguard Worker   test::ScopedFieldTrials field_trials_;
47*d9f75844SAndroid Build Coastguard Worker };
48*d9f75844SAndroid Build Coastguard Worker 
RunTestAndCheckForAdaptation(const DegradationPreference & degradation_preference,bool expect_adaptation)49*d9f75844SAndroid Build Coastguard Worker void CpuOveruseTest::RunTestAndCheckForAdaptation(
50*d9f75844SAndroid Build Coastguard Worker     const DegradationPreference& degradation_preference,
51*d9f75844SAndroid Build Coastguard Worker     bool expect_adaptation) {
52*d9f75844SAndroid Build Coastguard Worker   class OveruseObserver
53*d9f75844SAndroid Build Coastguard Worker       : public test::SendTest,
54*d9f75844SAndroid Build Coastguard Worker         public test::FrameGeneratorCapturer::SinkWantsObserver {
55*d9f75844SAndroid Build Coastguard Worker    public:
56*d9f75844SAndroid Build Coastguard Worker     OveruseObserver(const DegradationPreference& degradation_preference,
57*d9f75844SAndroid Build Coastguard Worker                     bool expect_adaptation)
58*d9f75844SAndroid Build Coastguard Worker         : SendTest(expect_adaptation ? kLongTimeout : kDefaultTimeout),
59*d9f75844SAndroid Build Coastguard Worker           degradation_preference_(degradation_preference),
60*d9f75844SAndroid Build Coastguard Worker           expect_adaptation_(expect_adaptation) {}
61*d9f75844SAndroid Build Coastguard Worker 
62*d9f75844SAndroid Build Coastguard Worker    private:
63*d9f75844SAndroid Build Coastguard Worker     void OnFrameGeneratorCapturerCreated(
64*d9f75844SAndroid Build Coastguard Worker         test::FrameGeneratorCapturer* frame_generator_capturer) override {
65*d9f75844SAndroid Build Coastguard Worker       frame_generator_capturer->SetSinkWantsObserver(this);
66*d9f75844SAndroid Build Coastguard Worker       // Set initial resolution.
67*d9f75844SAndroid Build Coastguard Worker       frame_generator_capturer->ChangeResolution(kWidth, kHeight);
68*d9f75844SAndroid Build Coastguard Worker     }
69*d9f75844SAndroid Build Coastguard Worker 
70*d9f75844SAndroid Build Coastguard Worker     // Called when FrameGeneratorCapturer::AddOrUpdateSink is called.
71*d9f75844SAndroid Build Coastguard Worker     void OnSinkWantsChanged(rtc::VideoSinkInterface<VideoFrame>* sink,
72*d9f75844SAndroid Build Coastguard Worker                             const rtc::VideoSinkWants& wants) override {
73*d9f75844SAndroid Build Coastguard Worker       if (wants.max_pixel_count == std::numeric_limits<int>::max() &&
74*d9f75844SAndroid Build Coastguard Worker           wants.max_framerate_fps == kFps) {
75*d9f75844SAndroid Build Coastguard Worker         // Max configured framerate is initially set.
76*d9f75844SAndroid Build Coastguard Worker         return;
77*d9f75844SAndroid Build Coastguard Worker       }
78*d9f75844SAndroid Build Coastguard Worker       switch (degradation_preference_) {
79*d9f75844SAndroid Build Coastguard Worker         case DegradationPreference::MAINTAIN_FRAMERATE:
80*d9f75844SAndroid Build Coastguard Worker           EXPECT_LT(wants.max_pixel_count, kWidth * kHeight);
81*d9f75844SAndroid Build Coastguard Worker           observation_complete_.Set();
82*d9f75844SAndroid Build Coastguard Worker           break;
83*d9f75844SAndroid Build Coastguard Worker         case DegradationPreference::MAINTAIN_RESOLUTION:
84*d9f75844SAndroid Build Coastguard Worker           EXPECT_LT(wants.max_framerate_fps, kFps);
85*d9f75844SAndroid Build Coastguard Worker           observation_complete_.Set();
86*d9f75844SAndroid Build Coastguard Worker           break;
87*d9f75844SAndroid Build Coastguard Worker         case DegradationPreference::BALANCED:
88*d9f75844SAndroid Build Coastguard Worker           if (wants.max_pixel_count == std::numeric_limits<int>::max() &&
89*d9f75844SAndroid Build Coastguard Worker               wants.max_framerate_fps == std::numeric_limits<int>::max()) {
90*d9f75844SAndroid Build Coastguard Worker             // `adapt_counters_` map in VideoStreamEncoder is reset when
91*d9f75844SAndroid Build Coastguard Worker             // balanced mode is set.
92*d9f75844SAndroid Build Coastguard Worker             break;
93*d9f75844SAndroid Build Coastguard Worker           }
94*d9f75844SAndroid Build Coastguard Worker           EXPECT_TRUE(wants.max_pixel_count < kWidth * kHeight ||
95*d9f75844SAndroid Build Coastguard Worker                       wants.max_framerate_fps < kFps);
96*d9f75844SAndroid Build Coastguard Worker           observation_complete_.Set();
97*d9f75844SAndroid Build Coastguard Worker           break;
98*d9f75844SAndroid Build Coastguard Worker         default:
99*d9f75844SAndroid Build Coastguard Worker           RTC_DCHECK_NOTREACHED();
100*d9f75844SAndroid Build Coastguard Worker       }
101*d9f75844SAndroid Build Coastguard Worker     }
102*d9f75844SAndroid Build Coastguard Worker 
103*d9f75844SAndroid Build Coastguard Worker     void ModifyVideoConfigs(
104*d9f75844SAndroid Build Coastguard Worker         VideoSendStream::Config* send_config,
105*d9f75844SAndroid Build Coastguard Worker         std::vector<VideoReceiveStreamInterface::Config>* receive_configs,
106*d9f75844SAndroid Build Coastguard Worker         VideoEncoderConfig* encoder_config) override {
107*d9f75844SAndroid Build Coastguard Worker       EXPECT_FALSE(encoder_config->simulcast_layers.empty());
108*d9f75844SAndroid Build Coastguard Worker       encoder_config->simulcast_layers[0].max_framerate = kFps;
109*d9f75844SAndroid Build Coastguard Worker     }
110*d9f75844SAndroid Build Coastguard Worker 
111*d9f75844SAndroid Build Coastguard Worker     void ModifyVideoDegradationPreference(
112*d9f75844SAndroid Build Coastguard Worker         DegradationPreference* degradation_preference) override {
113*d9f75844SAndroid Build Coastguard Worker       *degradation_preference = degradation_preference_;
114*d9f75844SAndroid Build Coastguard Worker     }
115*d9f75844SAndroid Build Coastguard Worker 
116*d9f75844SAndroid Build Coastguard Worker     void PerformTest() override {
117*d9f75844SAndroid Build Coastguard Worker       EXPECT_EQ(expect_adaptation_, Wait())
118*d9f75844SAndroid Build Coastguard Worker           << "Timed out while waiting for a scale down.";
119*d9f75844SAndroid Build Coastguard Worker     }
120*d9f75844SAndroid Build Coastguard Worker 
121*d9f75844SAndroid Build Coastguard Worker     const DegradationPreference degradation_preference_;
122*d9f75844SAndroid Build Coastguard Worker     const bool expect_adaptation_;
123*d9f75844SAndroid Build Coastguard Worker   } test(degradation_preference, expect_adaptation);
124*d9f75844SAndroid Build Coastguard Worker 
125*d9f75844SAndroid Build Coastguard Worker   RunBaseTest(&test);
126*d9f75844SAndroid Build Coastguard Worker }
127*d9f75844SAndroid Build Coastguard Worker 
TEST_F(CpuOveruseTest,AdaptsDownInResolutionOnOveruse)128*d9f75844SAndroid Build Coastguard Worker TEST_F(CpuOveruseTest, AdaptsDownInResolutionOnOveruse) {
129*d9f75844SAndroid Build Coastguard Worker   RunTestAndCheckForAdaptation(DegradationPreference::MAINTAIN_FRAMERATE, true);
130*d9f75844SAndroid Build Coastguard Worker }
131*d9f75844SAndroid Build Coastguard Worker 
TEST_F(CpuOveruseTest,AdaptsDownInFpsOnOveruse)132*d9f75844SAndroid Build Coastguard Worker TEST_F(CpuOveruseTest, AdaptsDownInFpsOnOveruse) {
133*d9f75844SAndroid Build Coastguard Worker   RunTestAndCheckForAdaptation(DegradationPreference::MAINTAIN_RESOLUTION,
134*d9f75844SAndroid Build Coastguard Worker                                true);
135*d9f75844SAndroid Build Coastguard Worker }
136*d9f75844SAndroid Build Coastguard Worker 
TEST_F(CpuOveruseTest,AdaptsDownInResolutionOrFpsOnOveruse)137*d9f75844SAndroid Build Coastguard Worker TEST_F(CpuOveruseTest, AdaptsDownInResolutionOrFpsOnOveruse) {
138*d9f75844SAndroid Build Coastguard Worker   RunTestAndCheckForAdaptation(DegradationPreference::BALANCED, true);
139*d9f75844SAndroid Build Coastguard Worker }
140*d9f75844SAndroid Build Coastguard Worker 
TEST_F(CpuOveruseTest,NoAdaptDownOnOveruse)141*d9f75844SAndroid Build Coastguard Worker TEST_F(CpuOveruseTest, NoAdaptDownOnOveruse) {
142*d9f75844SAndroid Build Coastguard Worker   RunTestAndCheckForAdaptation(DegradationPreference::DISABLED, false);
143*d9f75844SAndroid Build Coastguard Worker }
144*d9f75844SAndroid Build Coastguard Worker }  // namespace webrtc
145