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