blob: da2bc947b9664e5d7d0874560d484d9f091bd4d4 [file] [log] [blame]
Henrik Boström722fa4d2020-04-29 16:46:30 +02001/*
2 * Copyright (c) 2020 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 "call/adaptation/resource_adaptation_processor.h"
12
Henrik Boströme2e8c172020-06-03 09:24:06 +020013#include "api/adaptation/resource.h"
Henrik Boströmc55516d2020-05-11 16:29:22 +020014#include "api/scoped_refptr.h"
Henrik Boström722fa4d2020-04-29 16:46:30 +020015#include "api/video/video_adaptation_counters.h"
Henrik Boström722fa4d2020-04-29 16:46:30 +020016#include "call/adaptation/resource_adaptation_processor_interface.h"
17#include "call/adaptation/test/fake_frame_rate_provider.h"
18#include "call/adaptation/test/fake_resource.h"
19#include "call/adaptation/video_source_restrictions.h"
20#include "call/adaptation/video_stream_input_state_provider.h"
Henrik Boström381d1092020-05-12 18:49:07 +020021#include "rtc_base/event.h"
Henrik Boström39ab1b52020-06-03 09:21:34 +020022#include "rtc_base/gunit.h"
Markus Handell8fe932a2020-07-06 17:41:35 +020023#include "rtc_base/synchronization/mutex.h"
Henrik Boström381d1092020-05-12 18:49:07 +020024#include "rtc_base/task_queue_for_test.h"
Henrik Boström722fa4d2020-04-29 16:46:30 +020025#include "test/gtest.h"
Jonas Orelandc7f691a2022-03-09 15:12:07 +010026#include "test/scoped_key_value_config.h"
Henrik Boström722fa4d2020-04-29 16:46:30 +020027
28namespace webrtc {
29
30namespace {
31
32const int kDefaultFrameRate = 30;
33const int kDefaultFrameSize = 1280 * 720;
Henrik Boström39ab1b52020-06-03 09:21:34 +020034const int kDefaultTimeoutMs = 5000;
Henrik Boström722fa4d2020-04-29 16:46:30 +020035
Henrik Boström0f0aa9c2020-06-02 13:02:36 +020036class VideoSourceRestrictionsListenerForTesting
37 : public VideoSourceRestrictionsListener {
Henrik Boström722fa4d2020-04-29 16:46:30 +020038 public:
Henrik Boström0f0aa9c2020-06-02 13:02:36 +020039 VideoSourceRestrictionsListenerForTesting()
Henrik Boström722fa4d2020-04-29 16:46:30 +020040 : restrictions_updated_count_(0),
41 restrictions_(),
42 adaptation_counters_(),
43 reason_(nullptr) {}
Henrik Boström0f0aa9c2020-06-02 13:02:36 +020044 ~VideoSourceRestrictionsListenerForTesting() override {}
Henrik Boström722fa4d2020-04-29 16:46:30 +020045
46 size_t restrictions_updated_count() const {
Evan Shrubsolece971b02020-06-12 16:00:03 +020047 RTC_DCHECK_RUN_ON(&sequence_checker_);
Henrik Boström722fa4d2020-04-29 16:46:30 +020048 return restrictions_updated_count_;
49 }
Henrik Boström39ab1b52020-06-03 09:21:34 +020050 VideoSourceRestrictions restrictions() const {
Evan Shrubsolece971b02020-06-12 16:00:03 +020051 RTC_DCHECK_RUN_ON(&sequence_checker_);
Henrik Boström39ab1b52020-06-03 09:21:34 +020052 return restrictions_;
53 }
54 VideoAdaptationCounters adaptation_counters() const {
Evan Shrubsolece971b02020-06-12 16:00:03 +020055 RTC_DCHECK_RUN_ON(&sequence_checker_);
Henrik Boström722fa4d2020-04-29 16:46:30 +020056 return adaptation_counters_;
57 }
Henrik Boström39ab1b52020-06-03 09:21:34 +020058 rtc::scoped_refptr<Resource> reason() const {
Evan Shrubsolece971b02020-06-12 16:00:03 +020059 RTC_DCHECK_RUN_ON(&sequence_checker_);
Henrik Boström39ab1b52020-06-03 09:21:34 +020060 return reason_;
61 }
Henrik Boström722fa4d2020-04-29 16:46:30 +020062
Henrik Boström0f0aa9c2020-06-02 13:02:36 +020063 // VideoSourceRestrictionsListener implementation.
Henrik Boström722fa4d2020-04-29 16:46:30 +020064 void OnVideoSourceRestrictionsUpdated(
65 VideoSourceRestrictions restrictions,
66 const VideoAdaptationCounters& adaptation_counters,
Evan Shrubsoleec0af262020-07-01 11:47:46 +020067 rtc::scoped_refptr<Resource> reason,
68 const VideoSourceRestrictions& unfiltered_restrictions) override {
Evan Shrubsolece971b02020-06-12 16:00:03 +020069 RTC_DCHECK_RUN_ON(&sequence_checker_);
Henrik Boström722fa4d2020-04-29 16:46:30 +020070 ++restrictions_updated_count_;
71 restrictions_ = restrictions;
72 adaptation_counters_ = adaptation_counters;
73 reason_ = reason;
74 }
75
76 private:
Evan Shrubsolece971b02020-06-12 16:00:03 +020077 SequenceChecker sequence_checker_;
78 size_t restrictions_updated_count_ RTC_GUARDED_BY(&sequence_checker_);
79 VideoSourceRestrictions restrictions_ RTC_GUARDED_BY(&sequence_checker_);
80 VideoAdaptationCounters adaptation_counters_
81 RTC_GUARDED_BY(&sequence_checker_);
82 rtc::scoped_refptr<Resource> reason_ RTC_GUARDED_BY(&sequence_checker_);
Henrik Boström722fa4d2020-04-29 16:46:30 +020083};
84
85class ResourceAdaptationProcessorTest : public ::testing::Test {
86 public:
87 ResourceAdaptationProcessorTest()
Evan Shrubsole4d75d9c2020-06-03 14:09:09 +020088 : frame_rate_provider_(),
Henrik Boström722fa4d2020-04-29 16:46:30 +020089 input_state_provider_(&frame_rate_provider_),
Henrik Boström5cc28b02020-06-01 17:59:05 +020090 resource_(FakeResource::Create("FakeResource")),
91 other_resource_(FakeResource::Create("OtherFakeResource")),
Evan Shrubsole34b1a422020-07-02 14:42:09 +020092 video_stream_adapter_(
Evan Shrubsoled73d4212020-08-17 11:10:45 +020093 std::make_unique<VideoStreamAdapter>(&input_state_provider_,
Jonas Orelandc7f691a2022-03-09 15:12:07 +010094 &frame_rate_provider_,
95 field_trials_)),
Henrik Boström381d1092020-05-12 18:49:07 +020096 processor_(std::make_unique<ResourceAdaptationProcessor>(
Evan Shrubsoleec0af262020-07-01 11:47:46 +020097 video_stream_adapter_.get())) {
Evan Shrubsoleec0af262020-07-01 11:47:46 +020098 video_stream_adapter_->AddRestrictionsListener(&restrictions_listener_);
Evan Shrubsole4d75d9c2020-06-03 14:09:09 +020099 processor_->AddResource(resource_);
100 processor_->AddResource(other_resource_);
Henrik Boström722fa4d2020-04-29 16:46:30 +0200101 }
102 ~ResourceAdaptationProcessorTest() override {
Evan Shrubsole4d75d9c2020-06-03 14:09:09 +0200103 if (processor_) {
104 DestroyProcessor();
105 }
Henrik Boström722fa4d2020-04-29 16:46:30 +0200106 }
107
108 void SetInputStates(bool has_input, int fps, int frame_size) {
109 input_state_provider_.OnHasInputChanged(has_input);
110 frame_rate_provider_.set_fps(fps);
111 input_state_provider_.OnFrameSizeObserved(frame_size);
112 }
113
114 void RestrictSource(VideoSourceRestrictions restrictions) {
115 SetInputStates(
116 true, restrictions.max_frame_rate().value_or(kDefaultFrameRate),
117 restrictions.target_pixels_per_frame().has_value()
118 ? restrictions.target_pixels_per_frame().value()
119 : restrictions.max_pixels_per_frame().value_or(kDefaultFrameSize));
120 }
121
Henrik Boström39ab1b52020-06-03 09:21:34 +0200122 void DestroyProcessor() {
Evan Shrubsolece971b02020-06-12 16:00:03 +0200123 if (resource_) {
124 processor_->RemoveResource(resource_);
125 }
126 if (other_resource_) {
127 processor_->RemoveResource(other_resource_);
128 }
Evan Shrubsoleec0af262020-07-01 11:47:46 +0200129 video_stream_adapter_->RemoveRestrictionsListener(&restrictions_listener_);
Henrik Boström39ab1b52020-06-03 09:21:34 +0200130 processor_.reset();
131 }
132
Evan Shrubsolece971b02020-06-12 16:00:03 +0200133 static void WaitUntilTaskQueueIdle() {
134 ASSERT_TRUE(rtc::Thread::Current()->ProcessMessages(0));
135 }
136
Henrik Boström722fa4d2020-04-29 16:46:30 +0200137 protected:
Jonas Orelandc7f691a2022-03-09 15:12:07 +0100138 webrtc::test::ScopedKeyValueConfig field_trials_;
Henrik Boström722fa4d2020-04-29 16:46:30 +0200139 FakeFrameRateProvider frame_rate_provider_;
140 VideoStreamInputStateProvider input_state_provider_;
Henrik Boströmc55516d2020-05-11 16:29:22 +0200141 rtc::scoped_refptr<FakeResource> resource_;
142 rtc::scoped_refptr<FakeResource> other_resource_;
Evan Shrubsoleec0af262020-07-01 11:47:46 +0200143 std::unique_ptr<VideoStreamAdapter> video_stream_adapter_;
Henrik Boström381d1092020-05-12 18:49:07 +0200144 std::unique_ptr<ResourceAdaptationProcessor> processor_;
Henrik Boström0f0aa9c2020-06-02 13:02:36 +0200145 VideoSourceRestrictionsListenerForTesting restrictions_listener_;
Henrik Boström722fa4d2020-04-29 16:46:30 +0200146};
147
148} // namespace
149
150TEST_F(ResourceAdaptationProcessorTest, DisabledByDefault) {
Evan Shrubsole4d75d9c2020-06-03 14:09:09 +0200151 SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
Evan Shrubsole4d75d9c2020-06-03 14:09:09 +0200152 // Adaptation does not happen when disabled.
153 resource_->SetUsageState(ResourceUsageState::kOveruse);
154 EXPECT_EQ(0u, restrictions_listener_.restrictions_updated_count());
Henrik Boström722fa4d2020-04-29 16:46:30 +0200155}
156
157TEST_F(ResourceAdaptationProcessorTest, InsufficientInput) {
Evan Shrubsole3444a492020-07-07 09:04:34 +0200158 video_stream_adapter_->SetDegradationPreference(
Evan Shrubsole4d75d9c2020-06-03 14:09:09 +0200159 DegradationPreference::MAINTAIN_FRAMERATE);
Evan Shrubsole4d75d9c2020-06-03 14:09:09 +0200160 // Adaptation does not happen if input is insufficient.
161 // When frame size is missing (OnFrameSizeObserved not called yet).
162 input_state_provider_.OnHasInputChanged(true);
163 resource_->SetUsageState(ResourceUsageState::kOveruse);
164 EXPECT_EQ(0u, restrictions_listener_.restrictions_updated_count());
165 // When "has input" is missing.
166 SetInputStates(false, kDefaultFrameRate, kDefaultFrameSize);
167 resource_->SetUsageState(ResourceUsageState::kOveruse);
168 EXPECT_EQ(0u, restrictions_listener_.restrictions_updated_count());
169 // Note: frame rate cannot be missing, if unset it is 0.
Henrik Boström722fa4d2020-04-29 16:46:30 +0200170}
171
172// These tests verify that restrictions are applied, but not exactly how much
173// the source is restricted. This ensures that the VideoStreamAdapter is wired
174// up correctly but not exactly how the VideoStreamAdapter generates
175// restrictions. For that, see video_stream_adapter_unittest.cc.
176TEST_F(ResourceAdaptationProcessorTest,
177 OveruseTriggersRestrictingResolutionInMaintainFrameRate) {
Evan Shrubsole3444a492020-07-07 09:04:34 +0200178 video_stream_adapter_->SetDegradationPreference(
Evan Shrubsole4d75d9c2020-06-03 14:09:09 +0200179 DegradationPreference::MAINTAIN_FRAMERATE);
Evan Shrubsole4d75d9c2020-06-03 14:09:09 +0200180 SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
181 resource_->SetUsageState(ResourceUsageState::kOveruse);
182 EXPECT_EQ(1u, restrictions_listener_.restrictions_updated_count());
183 EXPECT_TRUE(
184 restrictions_listener_.restrictions().max_pixels_per_frame().has_value());
Henrik Boström722fa4d2020-04-29 16:46:30 +0200185}
186
187TEST_F(ResourceAdaptationProcessorTest,
188 OveruseTriggersRestrictingFrameRateInMaintainResolution) {
Evan Shrubsole3444a492020-07-07 09:04:34 +0200189 video_stream_adapter_->SetDegradationPreference(
Evan Shrubsole4d75d9c2020-06-03 14:09:09 +0200190 DegradationPreference::MAINTAIN_RESOLUTION);
Evan Shrubsole4d75d9c2020-06-03 14:09:09 +0200191 SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
192 resource_->SetUsageState(ResourceUsageState::kOveruse);
193 EXPECT_EQ(1u, restrictions_listener_.restrictions_updated_count());
194 EXPECT_TRUE(
195 restrictions_listener_.restrictions().max_frame_rate().has_value());
Henrik Boström722fa4d2020-04-29 16:46:30 +0200196}
197
198TEST_F(ResourceAdaptationProcessorTest,
199 OveruseTriggersRestrictingFrameRateAndResolutionInBalanced) {
Evan Shrubsole3444a492020-07-07 09:04:34 +0200200 video_stream_adapter_->SetDegradationPreference(
201 DegradationPreference::BALANCED);
Evan Shrubsole4d75d9c2020-06-03 14:09:09 +0200202 SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
203 // Adapting multiple times eventually resticts both frame rate and
204 // resolution. Exactly many times we need to adapt depends on
205 // BalancedDegradationSettings, VideoStreamAdapter and default input
206 // states. This test requires it to be achieved within 4 adaptations.
207 for (size_t i = 0; i < 4; ++i) {
208 resource_->SetUsageState(ResourceUsageState::kOveruse);
209 EXPECT_EQ(i + 1, restrictions_listener_.restrictions_updated_count());
210 RestrictSource(restrictions_listener_.restrictions());
211 }
212 EXPECT_TRUE(
213 restrictions_listener_.restrictions().max_pixels_per_frame().has_value());
214 EXPECT_TRUE(
215 restrictions_listener_.restrictions().max_frame_rate().has_value());
Henrik Boström722fa4d2020-04-29 16:46:30 +0200216}
217
218TEST_F(ResourceAdaptationProcessorTest, AwaitingPreviousAdaptation) {
Evan Shrubsole3444a492020-07-07 09:04:34 +0200219 video_stream_adapter_->SetDegradationPreference(
Evan Shrubsole4d75d9c2020-06-03 14:09:09 +0200220 DegradationPreference::MAINTAIN_FRAMERATE);
Evan Shrubsole4d75d9c2020-06-03 14:09:09 +0200221 SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
222 resource_->SetUsageState(ResourceUsageState::kOveruse);
223 EXPECT_EQ(1u, restrictions_listener_.restrictions_updated_count());
224 // If we don't restrict the source then adaptation will not happen again
225 // due to "awaiting previous adaptation". This prevents "double-adapt".
226 resource_->SetUsageState(ResourceUsageState::kOveruse);
227 EXPECT_EQ(1u, restrictions_listener_.restrictions_updated_count());
Henrik Boström722fa4d2020-04-29 16:46:30 +0200228}
229
230TEST_F(ResourceAdaptationProcessorTest, CannotAdaptUpWhenUnrestricted) {
Evan Shrubsole3444a492020-07-07 09:04:34 +0200231 video_stream_adapter_->SetDegradationPreference(
Evan Shrubsole4d75d9c2020-06-03 14:09:09 +0200232 DegradationPreference::MAINTAIN_FRAMERATE);
Evan Shrubsole4d75d9c2020-06-03 14:09:09 +0200233 SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
234 resource_->SetUsageState(ResourceUsageState::kUnderuse);
235 EXPECT_EQ(0u, restrictions_listener_.restrictions_updated_count());
Henrik Boström722fa4d2020-04-29 16:46:30 +0200236}
237
238TEST_F(ResourceAdaptationProcessorTest, UnderuseTakesUsBackToUnrestricted) {
Evan Shrubsole3444a492020-07-07 09:04:34 +0200239 video_stream_adapter_->SetDegradationPreference(
Evan Shrubsole4d75d9c2020-06-03 14:09:09 +0200240 DegradationPreference::MAINTAIN_FRAMERATE);
Evan Shrubsole4d75d9c2020-06-03 14:09:09 +0200241 SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
242 resource_->SetUsageState(ResourceUsageState::kOveruse);
243 EXPECT_EQ(1u, restrictions_listener_.restrictions_updated_count());
244 RestrictSource(restrictions_listener_.restrictions());
245 resource_->SetUsageState(ResourceUsageState::kUnderuse);
246 EXPECT_EQ(2u, restrictions_listener_.restrictions_updated_count());
247 EXPECT_EQ(VideoSourceRestrictions(), restrictions_listener_.restrictions());
Henrik Boström722fa4d2020-04-29 16:46:30 +0200248}
249
Evan Shrubsole0dcb4702020-05-07 13:45:14 +0200250TEST_F(ResourceAdaptationProcessorTest,
251 ResourcesCanNotAdaptUpIfNeverAdaptedDown) {
Evan Shrubsole3444a492020-07-07 09:04:34 +0200252 video_stream_adapter_->SetDegradationPreference(
Evan Shrubsole4d75d9c2020-06-03 14:09:09 +0200253 DegradationPreference::MAINTAIN_FRAMERATE);
Evan Shrubsole4d75d9c2020-06-03 14:09:09 +0200254 SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
255 resource_->SetUsageState(ResourceUsageState::kOveruse);
256 EXPECT_EQ(1u, restrictions_listener_.restrictions_updated_count());
257 RestrictSource(restrictions_listener_.restrictions());
Evan Shrubsole0dcb4702020-05-07 13:45:14 +0200258
Evan Shrubsole4d75d9c2020-06-03 14:09:09 +0200259 // Other resource signals under-use
260 other_resource_->SetUsageState(ResourceUsageState::kUnderuse);
261 EXPECT_EQ(1u, restrictions_listener_.restrictions_updated_count());
Evan Shrubsole0dcb4702020-05-07 13:45:14 +0200262}
263
264TEST_F(ResourceAdaptationProcessorTest,
265 ResourcesCanNotAdaptUpIfNotAdaptedDownAfterReset) {
Evan Shrubsole3444a492020-07-07 09:04:34 +0200266 video_stream_adapter_->SetDegradationPreference(
Evan Shrubsole4d75d9c2020-06-03 14:09:09 +0200267 DegradationPreference::MAINTAIN_FRAMERATE);
Evan Shrubsole4d75d9c2020-06-03 14:09:09 +0200268 SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
269 resource_->SetUsageState(ResourceUsageState::kOveruse);
270 EXPECT_EQ(1u, restrictions_listener_.restrictions_updated_count());
Evan Shrubsole0dcb4702020-05-07 13:45:14 +0200271
Evan Shrubsoleec0af262020-07-01 11:47:46 +0200272 video_stream_adapter_->ClearRestrictions();
Evan Shrubsole4d75d9c2020-06-03 14:09:09 +0200273 EXPECT_EQ(0, restrictions_listener_.adaptation_counters().Total());
274 other_resource_->SetUsageState(ResourceUsageState::kOveruse);
275 EXPECT_EQ(1, restrictions_listener_.adaptation_counters().Total());
276 RestrictSource(restrictions_listener_.restrictions());
Evan Shrubsole0dcb4702020-05-07 13:45:14 +0200277
Evan Shrubsole4d75d9c2020-06-03 14:09:09 +0200278 // resource_ did not overuse after we reset the restrictions, so adapt
279 // up should be disallowed.
280 resource_->SetUsageState(ResourceUsageState::kUnderuse);
281 EXPECT_EQ(1, restrictions_listener_.adaptation_counters().Total());
Evan Shrubsole0dcb4702020-05-07 13:45:14 +0200282}
283
Evan Shrubsole64469032020-06-11 10:45:29 +0200284TEST_F(ResourceAdaptationProcessorTest, OnlyMostLimitedResourceMayAdaptUp) {
Evan Shrubsole3444a492020-07-07 09:04:34 +0200285 video_stream_adapter_->SetDegradationPreference(
Evan Shrubsole64469032020-06-11 10:45:29 +0200286 DegradationPreference::MAINTAIN_FRAMERATE);
Evan Shrubsole64469032020-06-11 10:45:29 +0200287 SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
288 resource_->SetUsageState(ResourceUsageState::kOveruse);
289 EXPECT_EQ(1, restrictions_listener_.adaptation_counters().Total());
290 RestrictSource(restrictions_listener_.restrictions());
291 other_resource_->SetUsageState(ResourceUsageState::kOveruse);
292 EXPECT_EQ(2, restrictions_listener_.adaptation_counters().Total());
293 RestrictSource(restrictions_listener_.restrictions());
294
Artem Titovea240272021-07-26 12:40:21 +0200295 // `other_resource_` is most limited, resource_ can't adapt up.
Evan Shrubsole64469032020-06-11 10:45:29 +0200296 resource_->SetUsageState(ResourceUsageState::kUnderuse);
297 EXPECT_EQ(2, restrictions_listener_.adaptation_counters().Total());
298 RestrictSource(restrictions_listener_.restrictions());
299 other_resource_->SetUsageState(ResourceUsageState::kUnderuse);
300 EXPECT_EQ(1, restrictions_listener_.adaptation_counters().Total());
301 RestrictSource(restrictions_listener_.restrictions());
302
Artem Titovea240272021-07-26 12:40:21 +0200303 // `resource_` and `other_resource_` are now most limited, so both must
Evan Shrubsole64469032020-06-11 10:45:29 +0200304 // signal underuse to adapt up.
305 other_resource_->SetUsageState(ResourceUsageState::kUnderuse);
306 EXPECT_EQ(1, restrictions_listener_.adaptation_counters().Total());
307 RestrictSource(restrictions_listener_.restrictions());
308 resource_->SetUsageState(ResourceUsageState::kUnderuse);
309 EXPECT_EQ(0, restrictions_listener_.adaptation_counters().Total());
310 RestrictSource(restrictions_listener_.restrictions());
311}
312
Evan Shrubsole0dcb4702020-05-07 13:45:14 +0200313TEST_F(ResourceAdaptationProcessorTest,
314 MultipleResourcesCanTriggerMultipleAdaptations) {
Evan Shrubsole3444a492020-07-07 09:04:34 +0200315 video_stream_adapter_->SetDegradationPreference(
Evan Shrubsole4d75d9c2020-06-03 14:09:09 +0200316 DegradationPreference::MAINTAIN_FRAMERATE);
Evan Shrubsole4d75d9c2020-06-03 14:09:09 +0200317 SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
318 resource_->SetUsageState(ResourceUsageState::kOveruse);
319 EXPECT_EQ(1, restrictions_listener_.adaptation_counters().Total());
320 RestrictSource(restrictions_listener_.restrictions());
321 other_resource_->SetUsageState(ResourceUsageState::kOveruse);
322 EXPECT_EQ(2, restrictions_listener_.adaptation_counters().Total());
323 RestrictSource(restrictions_listener_.restrictions());
324 other_resource_->SetUsageState(ResourceUsageState::kOveruse);
325 EXPECT_EQ(3, restrictions_listener_.adaptation_counters().Total());
326 RestrictSource(restrictions_listener_.restrictions());
Evan Shrubsole0dcb4702020-05-07 13:45:14 +0200327
Evan Shrubsole64469032020-06-11 10:45:29 +0200328 // resource_ is not most limited so can't adapt from underuse.
Evan Shrubsole4d75d9c2020-06-03 14:09:09 +0200329 resource_->SetUsageState(ResourceUsageState::kUnderuse);
Evan Shrubsole64469032020-06-11 10:45:29 +0200330 EXPECT_EQ(3, restrictions_listener_.adaptation_counters().Total());
331 RestrictSource(restrictions_listener_.restrictions());
332 other_resource_->SetUsageState(ResourceUsageState::kUnderuse);
Evan Shrubsole4d75d9c2020-06-03 14:09:09 +0200333 EXPECT_EQ(2, restrictions_listener_.adaptation_counters().Total());
334 RestrictSource(restrictions_listener_.restrictions());
Evan Shrubsole64469032020-06-11 10:45:29 +0200335 // resource_ is still not most limited so can't adapt from underuse.
Evan Shrubsole4d75d9c2020-06-03 14:09:09 +0200336 resource_->SetUsageState(ResourceUsageState::kUnderuse);
337 EXPECT_EQ(2, restrictions_listener_.adaptation_counters().Total());
338 RestrictSource(restrictions_listener_.restrictions());
Evan Shrubsole0dcb4702020-05-07 13:45:14 +0200339
Evan Shrubsole64469032020-06-11 10:45:29 +0200340 // However it will be after overuse
341 resource_->SetUsageState(ResourceUsageState::kOveruse);
342 EXPECT_EQ(3, restrictions_listener_.adaptation_counters().Total());
343 RestrictSource(restrictions_listener_.restrictions());
344
345 // Now other_resource_ can't adapt up as it is not most restricted.
Evan Shrubsole4d75d9c2020-06-03 14:09:09 +0200346 other_resource_->SetUsageState(ResourceUsageState::kUnderuse);
Evan Shrubsole64469032020-06-11 10:45:29 +0200347 EXPECT_EQ(3, restrictions_listener_.adaptation_counters().Total());
348 RestrictSource(restrictions_listener_.restrictions());
349
350 // resource_ is limited at 3 adaptations and other_resource_ 2.
351 // With the most limited resource signalling underuse in the following
352 // order we get back to unrestricted video.
353 resource_->SetUsageState(ResourceUsageState::kUnderuse);
354 EXPECT_EQ(2, restrictions_listener_.adaptation_counters().Total());
355 RestrictSource(restrictions_listener_.restrictions());
356 // Both resource_ and other_resource_ are most limited.
357 other_resource_->SetUsageState(ResourceUsageState::kUnderuse);
358 EXPECT_EQ(2, restrictions_listener_.adaptation_counters().Total());
359 RestrictSource(restrictions_listener_.restrictions());
360 resource_->SetUsageState(ResourceUsageState::kUnderuse);
361 EXPECT_EQ(1, restrictions_listener_.adaptation_counters().Total());
362 RestrictSource(restrictions_listener_.restrictions());
363 // Again both are most limited.
364 resource_->SetUsageState(ResourceUsageState::kUnderuse);
Evan Shrubsole4d75d9c2020-06-03 14:09:09 +0200365 EXPECT_EQ(1, restrictions_listener_.adaptation_counters().Total());
366 RestrictSource(restrictions_listener_.restrictions());
367 other_resource_->SetUsageState(ResourceUsageState::kUnderuse);
368 EXPECT_EQ(0, restrictions_listener_.adaptation_counters().Total());
Evan Shrubsole64469032020-06-11 10:45:29 +0200369}
370
371TEST_F(ResourceAdaptationProcessorTest,
372 MostLimitedResourceAdaptationWorksAfterChangingDegradataionPreference) {
Evan Shrubsole3444a492020-07-07 09:04:34 +0200373 video_stream_adapter_->SetDegradationPreference(
Evan Shrubsole64469032020-06-11 10:45:29 +0200374 DegradationPreference::MAINTAIN_FRAMERATE);
Evan Shrubsole64469032020-06-11 10:45:29 +0200375 SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
376 // Adapt down until we can't anymore.
377 resource_->SetUsageState(ResourceUsageState::kOveruse);
Evan Shrubsole4d75d9c2020-06-03 14:09:09 +0200378 RestrictSource(restrictions_listener_.restrictions());
Evan Shrubsole64469032020-06-11 10:45:29 +0200379 resource_->SetUsageState(ResourceUsageState::kOveruse);
380 RestrictSource(restrictions_listener_.restrictions());
381 resource_->SetUsageState(ResourceUsageState::kOveruse);
382 RestrictSource(restrictions_listener_.restrictions());
383 resource_->SetUsageState(ResourceUsageState::kOveruse);
384 RestrictSource(restrictions_listener_.restrictions());
385 resource_->SetUsageState(ResourceUsageState::kOveruse);
386 RestrictSource(restrictions_listener_.restrictions());
387 int last_total = restrictions_listener_.adaptation_counters().Total();
388
Evan Shrubsole3444a492020-07-07 09:04:34 +0200389 video_stream_adapter_->SetDegradationPreference(
Evan Shrubsole64469032020-06-11 10:45:29 +0200390 DegradationPreference::MAINTAIN_RESOLUTION);
391 // resource_ can not adapt up since we have never reduced FPS.
392 resource_->SetUsageState(ResourceUsageState::kUnderuse);
393 EXPECT_EQ(last_total, restrictions_listener_.adaptation_counters().Total());
394
395 other_resource_->SetUsageState(ResourceUsageState::kOveruse);
396 EXPECT_EQ(last_total + 1,
397 restrictions_listener_.adaptation_counters().Total());
398 RestrictSource(restrictions_listener_.restrictions());
399 // other_resource_ is most limited so should be able to adapt up.
400 other_resource_->SetUsageState(ResourceUsageState::kUnderuse);
401 EXPECT_EQ(last_total, restrictions_listener_.adaptation_counters().Total());
Evan Shrubsole0dcb4702020-05-07 13:45:14 +0200402}
403
Ilya Nikolaevskiy8e321cd2020-05-11 15:33:23 +0200404TEST_F(ResourceAdaptationProcessorTest,
405 AdaptsDownWhenOtherResourceIsAlwaysUnderused) {
Evan Shrubsole3444a492020-07-07 09:04:34 +0200406 video_stream_adapter_->SetDegradationPreference(
Evan Shrubsole4d75d9c2020-06-03 14:09:09 +0200407 DegradationPreference::MAINTAIN_FRAMERATE);
Evan Shrubsole4d75d9c2020-06-03 14:09:09 +0200408 SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
409 other_resource_->SetUsageState(ResourceUsageState::kUnderuse);
410 // Does not trigger adapataion because there's no restriction.
411 EXPECT_EQ(0, restrictions_listener_.adaptation_counters().Total());
Ilya Nikolaevskiy8e321cd2020-05-11 15:33:23 +0200412
Evan Shrubsole4d75d9c2020-06-03 14:09:09 +0200413 RestrictSource(restrictions_listener_.restrictions());
414 resource_->SetUsageState(ResourceUsageState::kOveruse);
415 // Adapts down even if other resource asked for adapting up.
416 EXPECT_EQ(1, restrictions_listener_.adaptation_counters().Total());
Ilya Nikolaevskiy8e321cd2020-05-11 15:33:23 +0200417
Evan Shrubsole4d75d9c2020-06-03 14:09:09 +0200418 RestrictSource(restrictions_listener_.restrictions());
419 other_resource_->SetUsageState(ResourceUsageState::kUnderuse);
420 // Doesn't adapt up because adaptation is due to another resource.
421 EXPECT_EQ(1, restrictions_listener_.adaptation_counters().Total());
422 RestrictSource(restrictions_listener_.restrictions());
Ilya Nikolaevskiy8e321cd2020-05-11 15:33:23 +0200423}
424
Henrik Boström39ab1b52020-06-03 09:21:34 +0200425TEST_F(ResourceAdaptationProcessorTest,
426 TriggerOveruseNotOnAdaptationTaskQueue) {
Evan Shrubsole3444a492020-07-07 09:04:34 +0200427 video_stream_adapter_->SetDegradationPreference(
Evan Shrubsole4d75d9c2020-06-03 14:09:09 +0200428 DegradationPreference::MAINTAIN_FRAMERATE);
Evan Shrubsole4d75d9c2020-06-03 14:09:09 +0200429 SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
430
431 TaskQueueForTest resource_task_queue("ResourceTaskQueue");
432 resource_task_queue.PostTask(ToQueuedTask(
433 [&]() { resource_->SetUsageState(ResourceUsageState::kOveruse); }));
434
Henrik Boström39ab1b52020-06-03 09:21:34 +0200435 EXPECT_EQ_WAIT(1u, restrictions_listener_.restrictions_updated_count(),
436 kDefaultTimeoutMs);
437}
438
439TEST_F(ResourceAdaptationProcessorTest,
440 DestroyProcessorWhileResourceListenerDelegateHasTaskInFlight) {
Evan Shrubsole3444a492020-07-07 09:04:34 +0200441 video_stream_adapter_->SetDegradationPreference(
Evan Shrubsole4d75d9c2020-06-03 14:09:09 +0200442 DegradationPreference::MAINTAIN_FRAMERATE);
Evan Shrubsole4d75d9c2020-06-03 14:09:09 +0200443 SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
444
Artem Titovea240272021-07-26 12:40:21 +0200445 // Wait for `resource_` to signal oversue first so we know that the delegate
Evan Shrubsole4d75d9c2020-06-03 14:09:09 +0200446 // has passed it on to the processor's task queue.
447 rtc::Event resource_event;
448 TaskQueueForTest resource_task_queue("ResourceTaskQueue");
449 resource_task_queue.PostTask(ToQueuedTask([&]() {
450 resource_->SetUsageState(ResourceUsageState::kOveruse);
451 resource_event.Set();
452 }));
453
454 EXPECT_TRUE(resource_event.Wait(kDefaultTimeoutMs));
455 // Now destroy the processor while handling the overuse is in flight.
456 DestroyProcessor();
457
Henrik Boström39ab1b52020-06-03 09:21:34 +0200458 // Because the processor was destroyed by the time the delegate's task ran,
459 // the overuse signal must not have been handled.
460 EXPECT_EQ(0u, restrictions_listener_.restrictions_updated_count());
461}
462
Evan Shrubsolece971b02020-06-12 16:00:03 +0200463TEST_F(ResourceAdaptationProcessorTest,
464 ResourceOveruseIgnoredWhenSignalledDuringRemoval) {
Evan Shrubsole3444a492020-07-07 09:04:34 +0200465 video_stream_adapter_->SetDegradationPreference(
Evan Shrubsolece971b02020-06-12 16:00:03 +0200466 DegradationPreference::MAINTAIN_FRAMERATE);
467 SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
468
469 rtc::Event overuse_event;
470 TaskQueueForTest resource_task_queue("ResourceTaskQueue");
Artem Titovea240272021-07-26 12:40:21 +0200471 // Queues task for `resource_` overuse while `processor_` is still listening.
Evan Shrubsolece971b02020-06-12 16:00:03 +0200472 resource_task_queue.PostTask(ToQueuedTask([&]() {
473 resource_->SetUsageState(ResourceUsageState::kOveruse);
474 overuse_event.Set();
475 }));
476 EXPECT_TRUE(overuse_event.Wait(kDefaultTimeoutMs));
Artem Titovea240272021-07-26 12:40:21 +0200477 // Once we know the overuse task is queued, remove `resource_` so that
478 // `processor_` is not listening to it.
Evan Shrubsolece971b02020-06-12 16:00:03 +0200479 processor_->RemoveResource(resource_);
480
Artem Titovea240272021-07-26 12:40:21 +0200481 // Runs the queued task so `processor_` gets signalled kOveruse from
482 // `resource_` even though `processor_` was not listening.
Evan Shrubsolece971b02020-06-12 16:00:03 +0200483 WaitUntilTaskQueueIdle();
484
Artem Titovea240272021-07-26 12:40:21 +0200485 // No restrictions should change even though `resource_` signaled `kOveruse`.
Evan Shrubsolece971b02020-06-12 16:00:03 +0200486 EXPECT_EQ(0u, restrictions_listener_.restrictions_updated_count());
487
Artem Titovea240272021-07-26 12:40:21 +0200488 // Delete `resource_` for cleanup.
Evan Shrubsolece971b02020-06-12 16:00:03 +0200489 resource_ = nullptr;
490}
491
492TEST_F(ResourceAdaptationProcessorTest,
493 RemovingOnlyAdaptedResourceResetsAdaptation) {
Evan Shrubsole3444a492020-07-07 09:04:34 +0200494 video_stream_adapter_->SetDegradationPreference(
Evan Shrubsolece971b02020-06-12 16:00:03 +0200495 DegradationPreference::MAINTAIN_FRAMERATE);
496 SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
497
498 resource_->SetUsageState(ResourceUsageState::kOveruse);
499 EXPECT_EQ(1, restrictions_listener_.adaptation_counters().Total());
500 RestrictSource(restrictions_listener_.restrictions());
501
502 processor_->RemoveResource(resource_);
503 EXPECT_EQ(0, restrictions_listener_.adaptation_counters().Total());
504
Artem Titovea240272021-07-26 12:40:21 +0200505 // Delete `resource_` for cleanup.
Evan Shrubsolece971b02020-06-12 16:00:03 +0200506 resource_ = nullptr;
507}
508
509TEST_F(ResourceAdaptationProcessorTest,
510 RemovingMostLimitedResourceSetsAdaptationToNextLimitedLevel) {
Evan Shrubsole3444a492020-07-07 09:04:34 +0200511 video_stream_adapter_->SetDegradationPreference(
512 DegradationPreference::BALANCED);
Evan Shrubsolece971b02020-06-12 16:00:03 +0200513 SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
514
515 other_resource_->SetUsageState(ResourceUsageState::kOveruse);
516 RestrictSource(restrictions_listener_.restrictions());
517 EXPECT_EQ(1, restrictions_listener_.adaptation_counters().Total());
518 VideoSourceRestrictions next_limited_restrictions =
519 restrictions_listener_.restrictions();
520 VideoAdaptationCounters next_limited_counters =
521 restrictions_listener_.adaptation_counters();
522
523 resource_->SetUsageState(ResourceUsageState::kOveruse);
524 RestrictSource(restrictions_listener_.restrictions());
525 EXPECT_EQ(2, restrictions_listener_.adaptation_counters().Total());
526
Artem Titovea240272021-07-26 12:40:21 +0200527 // Removing most limited `resource_` should revert us back to
Evan Shrubsolece971b02020-06-12 16:00:03 +0200528 processor_->RemoveResource(resource_);
529 EXPECT_EQ(1, restrictions_listener_.adaptation_counters().Total());
530 EXPECT_EQ(next_limited_restrictions, restrictions_listener_.restrictions());
531 EXPECT_EQ(next_limited_counters,
532 restrictions_listener_.adaptation_counters());
533
Artem Titovea240272021-07-26 12:40:21 +0200534 // Delete `resource_` for cleanup.
Evan Shrubsolece971b02020-06-12 16:00:03 +0200535 resource_ = nullptr;
536}
537
538TEST_F(ResourceAdaptationProcessorTest,
539 RemovingMostLimitedResourceSetsAdaptationIfInputStateUnchanged) {
Evan Shrubsole3444a492020-07-07 09:04:34 +0200540 video_stream_adapter_->SetDegradationPreference(
Evan Shrubsolece971b02020-06-12 16:00:03 +0200541 DegradationPreference::MAINTAIN_FRAMERATE);
542 SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
543
544 other_resource_->SetUsageState(ResourceUsageState::kOveruse);
545 RestrictSource(restrictions_listener_.restrictions());
546 EXPECT_EQ(1, restrictions_listener_.adaptation_counters().Total());
547 VideoSourceRestrictions next_limited_restrictions =
548 restrictions_listener_.restrictions();
549 VideoAdaptationCounters next_limited_counters =
550 restrictions_listener_.adaptation_counters();
551
552 // Overuse twice and underuse once. After the underuse we don't restrict the
553 // source. Normally this would block future underuses.
554 resource_->SetUsageState(ResourceUsageState::kOveruse);
555 RestrictSource(restrictions_listener_.restrictions());
556 resource_->SetUsageState(ResourceUsageState::kOveruse);
557 RestrictSource(restrictions_listener_.restrictions());
558 resource_->SetUsageState(ResourceUsageState::kUnderuse);
559 EXPECT_EQ(2, restrictions_listener_.adaptation_counters().Total());
560
Artem Titovea240272021-07-26 12:40:21 +0200561 // Removing most limited `resource_` should revert us back to, even though we
562 // did not call RestrictSource() after `resource_` was overused. Normally
Evan Shrubsolece971b02020-06-12 16:00:03 +0200563 // adaptation for MAINTAIN_FRAMERATE would be blocked here but for removal we
564 // allow this anyways.
565 processor_->RemoveResource(resource_);
566 EXPECT_EQ(1, restrictions_listener_.adaptation_counters().Total());
567 EXPECT_EQ(next_limited_restrictions, restrictions_listener_.restrictions());
568 EXPECT_EQ(next_limited_counters,
569 restrictions_listener_.adaptation_counters());
570
Artem Titovea240272021-07-26 12:40:21 +0200571 // Delete `resource_` for cleanup.
Evan Shrubsolece971b02020-06-12 16:00:03 +0200572 resource_ = nullptr;
573}
574
575TEST_F(ResourceAdaptationProcessorTest,
576 RemovingResourceNotMostLimitedHasNoEffectOnLimitations) {
Evan Shrubsole3444a492020-07-07 09:04:34 +0200577 video_stream_adapter_->SetDegradationPreference(
578 DegradationPreference::BALANCED);
Evan Shrubsolece971b02020-06-12 16:00:03 +0200579 SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
580
581 other_resource_->SetUsageState(ResourceUsageState::kOveruse);
582 RestrictSource(restrictions_listener_.restrictions());
583 EXPECT_EQ(1, restrictions_listener_.adaptation_counters().Total());
584
585 resource_->SetUsageState(ResourceUsageState::kOveruse);
586 RestrictSource(restrictions_listener_.restrictions());
587 VideoSourceRestrictions current_restrictions =
588 restrictions_listener_.restrictions();
589 VideoAdaptationCounters current_counters =
590 restrictions_listener_.adaptation_counters();
591 EXPECT_EQ(2, restrictions_listener_.adaptation_counters().Total());
592
Artem Titovea240272021-07-26 12:40:21 +0200593 // Removing most limited `resource_` should revert us back to
Evan Shrubsolece971b02020-06-12 16:00:03 +0200594 processor_->RemoveResource(other_resource_);
595 EXPECT_EQ(current_restrictions, restrictions_listener_.restrictions());
596 EXPECT_EQ(current_counters, restrictions_listener_.adaptation_counters());
597
Artem Titovea240272021-07-26 12:40:21 +0200598 // Delete `other_resource_` for cleanup.
Evan Shrubsolece971b02020-06-12 16:00:03 +0200599 other_resource_ = nullptr;
600}
601
602TEST_F(ResourceAdaptationProcessorTest,
603 RemovingMostLimitedResourceAfterSwitchingDegradationPreferences) {
Evan Shrubsole3444a492020-07-07 09:04:34 +0200604 video_stream_adapter_->SetDegradationPreference(
Evan Shrubsolece971b02020-06-12 16:00:03 +0200605 DegradationPreference::MAINTAIN_FRAMERATE);
606 SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
607
608 other_resource_->SetUsageState(ResourceUsageState::kOveruse);
609 RestrictSource(restrictions_listener_.restrictions());
610 EXPECT_EQ(1, restrictions_listener_.adaptation_counters().Total());
611 VideoSourceRestrictions next_limited_restrictions =
612 restrictions_listener_.restrictions();
613 VideoAdaptationCounters next_limited_counters =
614 restrictions_listener_.adaptation_counters();
615
Evan Shrubsole3444a492020-07-07 09:04:34 +0200616 video_stream_adapter_->SetDegradationPreference(
Evan Shrubsolece971b02020-06-12 16:00:03 +0200617 DegradationPreference::MAINTAIN_RESOLUTION);
618 resource_->SetUsageState(ResourceUsageState::kOveruse);
619 RestrictSource(restrictions_listener_.restrictions());
620 EXPECT_EQ(2, restrictions_listener_.adaptation_counters().Total());
621
Artem Titovea240272021-07-26 12:40:21 +0200622 // Revert to `other_resource_` when removing `resource_` even though the
Evan Shrubsolece971b02020-06-12 16:00:03 +0200623 // degradation preference was different when it was overused.
624 processor_->RemoveResource(resource_);
625 EXPECT_EQ(next_limited_counters,
626 restrictions_listener_.adaptation_counters());
627
628 // After switching back to MAINTAIN_FRAMERATE, the next most limited settings
629 // are restored.
Evan Shrubsole3444a492020-07-07 09:04:34 +0200630 video_stream_adapter_->SetDegradationPreference(
Evan Shrubsolece971b02020-06-12 16:00:03 +0200631 DegradationPreference::MAINTAIN_FRAMERATE);
632 EXPECT_EQ(next_limited_restrictions, restrictions_listener_.restrictions());
633
Artem Titovea240272021-07-26 12:40:21 +0200634 // Delete `resource_` for cleanup.
Evan Shrubsolece971b02020-06-12 16:00:03 +0200635 resource_ = nullptr;
636}
637
638TEST_F(ResourceAdaptationProcessorTest,
639 RemovingMostLimitedResourceSetsNextLimitationsInDisabled) {
Evan Shrubsole3444a492020-07-07 09:04:34 +0200640 video_stream_adapter_->SetDegradationPreference(
Evan Shrubsolece971b02020-06-12 16:00:03 +0200641 DegradationPreference::MAINTAIN_FRAMERATE);
642 SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
643
644 other_resource_->SetUsageState(ResourceUsageState::kOveruse);
645 RestrictSource(restrictions_listener_.restrictions());
646 VideoSourceRestrictions next_limited_restrictions =
647 restrictions_listener_.restrictions();
648 VideoAdaptationCounters next_limited_counters =
649 restrictions_listener_.adaptation_counters();
650 EXPECT_EQ(1, restrictions_listener_.adaptation_counters().Total());
651 resource_->SetUsageState(ResourceUsageState::kOveruse);
652 RestrictSource(restrictions_listener_.restrictions());
653 EXPECT_EQ(2, restrictions_listener_.adaptation_counters().Total());
654
Evan Shrubsole3444a492020-07-07 09:04:34 +0200655 video_stream_adapter_->SetDegradationPreference(
656 DegradationPreference::DISABLED);
Evan Shrubsolece971b02020-06-12 16:00:03 +0200657
Artem Titovea240272021-07-26 12:40:21 +0200658 // Revert to `other_resource_` when removing `resource_` even though the
Evan Shrubsolece971b02020-06-12 16:00:03 +0200659 // current degradataion preference is disabled.
660 processor_->RemoveResource(resource_);
661
662 // After switching back to MAINTAIN_FRAMERATE, the next most limited settings
663 // are restored.
Evan Shrubsole3444a492020-07-07 09:04:34 +0200664 video_stream_adapter_->SetDegradationPreference(
Evan Shrubsolece971b02020-06-12 16:00:03 +0200665 DegradationPreference::MAINTAIN_FRAMERATE);
666 EXPECT_EQ(next_limited_restrictions, restrictions_listener_.restrictions());
667 EXPECT_EQ(next_limited_counters,
668 restrictions_listener_.adaptation_counters());
669
Artem Titovea240272021-07-26 12:40:21 +0200670 // Delete `resource_` for cleanup.
Evan Shrubsolece971b02020-06-12 16:00:03 +0200671 resource_ = nullptr;
672}
673
674TEST_F(ResourceAdaptationProcessorTest,
675 RemovedResourceSignalsIgnoredByProcessor) {
Evan Shrubsole3444a492020-07-07 09:04:34 +0200676 video_stream_adapter_->SetDegradationPreference(
Evan Shrubsolece971b02020-06-12 16:00:03 +0200677 DegradationPreference::MAINTAIN_FRAMERATE);
678 SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
679
680 processor_->RemoveResource(resource_);
681 resource_->SetUsageState(ResourceUsageState::kOveruse);
682 EXPECT_EQ(0u, restrictions_listener_.restrictions_updated_count());
683
Artem Titovea240272021-07-26 12:40:21 +0200684 // Delete `resource_` for cleanup.
Evan Shrubsolece971b02020-06-12 16:00:03 +0200685 resource_ = nullptr;
686}
687
688TEST_F(ResourceAdaptationProcessorTest,
689 RemovingResourceWhenMultipleMostLimtedHasNoEffect) {
Evan Shrubsole3444a492020-07-07 09:04:34 +0200690 video_stream_adapter_->SetDegradationPreference(
Evan Shrubsolece971b02020-06-12 16:00:03 +0200691 DegradationPreference::MAINTAIN_FRAMERATE);
692 SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
693
694 other_resource_->SetUsageState(ResourceUsageState::kOveruse);
695 RestrictSource(restrictions_listener_.restrictions());
696 EXPECT_EQ(1, restrictions_listener_.adaptation_counters().Total());
Artem Titovea240272021-07-26 12:40:21 +0200697 // Adapt `resource_` up and then down so that both resource's are most
Evan Shrubsolece971b02020-06-12 16:00:03 +0200698 // limited at 1 adaptation.
699 resource_->SetUsageState(ResourceUsageState::kOveruse);
700 RestrictSource(restrictions_listener_.restrictions());
701 resource_->SetUsageState(ResourceUsageState::kUnderuse);
702 RestrictSource(restrictions_listener_.restrictions());
703 EXPECT_EQ(1, restrictions_listener_.adaptation_counters().Total());
704
Artem Titovea240272021-07-26 12:40:21 +0200705 // Removing `resource_` has no effect since both `resource_` and
706 // `other_resource_` are most limited.
Evan Shrubsolece971b02020-06-12 16:00:03 +0200707 processor_->RemoveResource(resource_);
708 EXPECT_EQ(1, restrictions_listener_.adaptation_counters().Total());
709
Artem Titovea240272021-07-26 12:40:21 +0200710 // Delete `resource_` for cleanup.
Evan Shrubsolece971b02020-06-12 16:00:03 +0200711 resource_ = nullptr;
712}
713
Evan Shrubsolebd4a7182020-08-14 10:08:54 +0200714TEST_F(ResourceAdaptationProcessorTest,
715 ResourceOverusedAtLimitReachedWillShareMostLimited) {
716 video_stream_adapter_->SetDegradationPreference(
717 DegradationPreference::MAINTAIN_FRAMERATE);
718 SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize);
719
720 bool has_reached_min_pixels = false;
721 ON_CALL(frame_rate_provider_, OnMinPixelLimitReached())
722 .WillByDefault(testing::Assign(&has_reached_min_pixels, true));
723
724 // Adapt 10 times, which should make us hit the limit.
725 for (int i = 0; i < 10; ++i) {
726 resource_->SetUsageState(ResourceUsageState::kOveruse);
727 RestrictSource(restrictions_listener_.restrictions());
728 }
729 EXPECT_TRUE(has_reached_min_pixels);
730 auto last_update_count = restrictions_listener_.restrictions_updated_count();
731 other_resource_->SetUsageState(ResourceUsageState::kOveruse);
Artem Titovea240272021-07-26 12:40:21 +0200732 // Now both `resource_` and `other_resource_` are most limited. Underuse of
733 // `resource_` will not adapt up.
Evan Shrubsolebd4a7182020-08-14 10:08:54 +0200734 resource_->SetUsageState(ResourceUsageState::kUnderuse);
735 EXPECT_EQ(last_update_count,
736 restrictions_listener_.restrictions_updated_count());
737}
738
Henrik Boström722fa4d2020-04-29 16:46:30 +0200739} // namespace webrtc