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