Henrik Boström | 722fa4d | 2020-04-29 16:46:30 +0200 | [diff] [blame] | 1 | /* |
| 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öm | e2e8c17 | 2020-06-03 09:24:06 +0200 | [diff] [blame] | 13 | #include "api/adaptation/resource.h" |
Henrik Boström | c55516d | 2020-05-11 16:29:22 +0200 | [diff] [blame] | 14 | #include "api/scoped_refptr.h" |
Henrik Boström | 722fa4d | 2020-04-29 16:46:30 +0200 | [diff] [blame] | 15 | #include "api/video/video_adaptation_counters.h" |
Henrik Boström | 722fa4d | 2020-04-29 16:46:30 +0200 | [diff] [blame] | 16 | #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öm | 381d109 | 2020-05-12 18:49:07 +0200 | [diff] [blame] | 21 | #include "rtc_base/event.h" |
Henrik Boström | 39ab1b5 | 2020-06-03 09:21:34 +0200 | [diff] [blame] | 22 | #include "rtc_base/gunit.h" |
Markus Handell | 8fe932a | 2020-07-06 17:41:35 +0200 | [diff] [blame] | 23 | #include "rtc_base/synchronization/mutex.h" |
Henrik Boström | 381d109 | 2020-05-12 18:49:07 +0200 | [diff] [blame] | 24 | #include "rtc_base/task_queue_for_test.h" |
Henrik Boström | 722fa4d | 2020-04-29 16:46:30 +0200 | [diff] [blame] | 25 | #include "test/gtest.h" |
Jonas Oreland | c7f691a | 2022-03-09 15:12:07 +0100 | [diff] [blame] | 26 | #include "test/scoped_key_value_config.h" |
Henrik Boström | 722fa4d | 2020-04-29 16:46:30 +0200 | [diff] [blame] | 27 | |
| 28 | namespace webrtc { |
| 29 | |
| 30 | namespace { |
| 31 | |
| 32 | const int kDefaultFrameRate = 30; |
| 33 | const int kDefaultFrameSize = 1280 * 720; |
Henrik Boström | 39ab1b5 | 2020-06-03 09:21:34 +0200 | [diff] [blame] | 34 | const int kDefaultTimeoutMs = 5000; |
Henrik Boström | 722fa4d | 2020-04-29 16:46:30 +0200 | [diff] [blame] | 35 | |
Henrik Boström | 0f0aa9c | 2020-06-02 13:02:36 +0200 | [diff] [blame] | 36 | class VideoSourceRestrictionsListenerForTesting |
| 37 | : public VideoSourceRestrictionsListener { |
Henrik Boström | 722fa4d | 2020-04-29 16:46:30 +0200 | [diff] [blame] | 38 | public: |
Henrik Boström | 0f0aa9c | 2020-06-02 13:02:36 +0200 | [diff] [blame] | 39 | VideoSourceRestrictionsListenerForTesting() |
Henrik Boström | 722fa4d | 2020-04-29 16:46:30 +0200 | [diff] [blame] | 40 | : restrictions_updated_count_(0), |
| 41 | restrictions_(), |
| 42 | adaptation_counters_(), |
| 43 | reason_(nullptr) {} |
Henrik Boström | 0f0aa9c | 2020-06-02 13:02:36 +0200 | [diff] [blame] | 44 | ~VideoSourceRestrictionsListenerForTesting() override {} |
Henrik Boström | 722fa4d | 2020-04-29 16:46:30 +0200 | [diff] [blame] | 45 | |
| 46 | size_t restrictions_updated_count() const { |
Evan Shrubsole | ce971b0 | 2020-06-12 16:00:03 +0200 | [diff] [blame] | 47 | RTC_DCHECK_RUN_ON(&sequence_checker_); |
Henrik Boström | 722fa4d | 2020-04-29 16:46:30 +0200 | [diff] [blame] | 48 | return restrictions_updated_count_; |
| 49 | } |
Henrik Boström | 39ab1b5 | 2020-06-03 09:21:34 +0200 | [diff] [blame] | 50 | VideoSourceRestrictions restrictions() const { |
Evan Shrubsole | ce971b0 | 2020-06-12 16:00:03 +0200 | [diff] [blame] | 51 | RTC_DCHECK_RUN_ON(&sequence_checker_); |
Henrik Boström | 39ab1b5 | 2020-06-03 09:21:34 +0200 | [diff] [blame] | 52 | return restrictions_; |
| 53 | } |
| 54 | VideoAdaptationCounters adaptation_counters() const { |
Evan Shrubsole | ce971b0 | 2020-06-12 16:00:03 +0200 | [diff] [blame] | 55 | RTC_DCHECK_RUN_ON(&sequence_checker_); |
Henrik Boström | 722fa4d | 2020-04-29 16:46:30 +0200 | [diff] [blame] | 56 | return adaptation_counters_; |
| 57 | } |
Henrik Boström | 39ab1b5 | 2020-06-03 09:21:34 +0200 | [diff] [blame] | 58 | rtc::scoped_refptr<Resource> reason() const { |
Evan Shrubsole | ce971b0 | 2020-06-12 16:00:03 +0200 | [diff] [blame] | 59 | RTC_DCHECK_RUN_ON(&sequence_checker_); |
Henrik Boström | 39ab1b5 | 2020-06-03 09:21:34 +0200 | [diff] [blame] | 60 | return reason_; |
| 61 | } |
Henrik Boström | 722fa4d | 2020-04-29 16:46:30 +0200 | [diff] [blame] | 62 | |
Henrik Boström | 0f0aa9c | 2020-06-02 13:02:36 +0200 | [diff] [blame] | 63 | // VideoSourceRestrictionsListener implementation. |
Henrik Boström | 722fa4d | 2020-04-29 16:46:30 +0200 | [diff] [blame] | 64 | void OnVideoSourceRestrictionsUpdated( |
| 65 | VideoSourceRestrictions restrictions, |
| 66 | const VideoAdaptationCounters& adaptation_counters, |
Evan Shrubsole | ec0af26 | 2020-07-01 11:47:46 +0200 | [diff] [blame] | 67 | rtc::scoped_refptr<Resource> reason, |
| 68 | const VideoSourceRestrictions& unfiltered_restrictions) override { |
Evan Shrubsole | ce971b0 | 2020-06-12 16:00:03 +0200 | [diff] [blame] | 69 | RTC_DCHECK_RUN_ON(&sequence_checker_); |
Henrik Boström | 722fa4d | 2020-04-29 16:46:30 +0200 | [diff] [blame] | 70 | ++restrictions_updated_count_; |
| 71 | restrictions_ = restrictions; |
| 72 | adaptation_counters_ = adaptation_counters; |
| 73 | reason_ = reason; |
| 74 | } |
| 75 | |
| 76 | private: |
Evan Shrubsole | ce971b0 | 2020-06-12 16:00:03 +0200 | [diff] [blame] | 77 | 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öm | 722fa4d | 2020-04-29 16:46:30 +0200 | [diff] [blame] | 83 | }; |
| 84 | |
| 85 | class ResourceAdaptationProcessorTest : public ::testing::Test { |
| 86 | public: |
| 87 | ResourceAdaptationProcessorTest() |
Evan Shrubsole | 4d75d9c | 2020-06-03 14:09:09 +0200 | [diff] [blame] | 88 | : frame_rate_provider_(), |
Henrik Boström | 722fa4d | 2020-04-29 16:46:30 +0200 | [diff] [blame] | 89 | input_state_provider_(&frame_rate_provider_), |
Henrik Boström | 5cc28b0 | 2020-06-01 17:59:05 +0200 | [diff] [blame] | 90 | resource_(FakeResource::Create("FakeResource")), |
| 91 | other_resource_(FakeResource::Create("OtherFakeResource")), |
Evan Shrubsole | 34b1a42 | 2020-07-02 14:42:09 +0200 | [diff] [blame] | 92 | video_stream_adapter_( |
Evan Shrubsole | d73d421 | 2020-08-17 11:10:45 +0200 | [diff] [blame] | 93 | std::make_unique<VideoStreamAdapter>(&input_state_provider_, |
Jonas Oreland | c7f691a | 2022-03-09 15:12:07 +0100 | [diff] [blame] | 94 | &frame_rate_provider_, |
| 95 | field_trials_)), |
Henrik Boström | 381d109 | 2020-05-12 18:49:07 +0200 | [diff] [blame] | 96 | processor_(std::make_unique<ResourceAdaptationProcessor>( |
Evan Shrubsole | ec0af26 | 2020-07-01 11:47:46 +0200 | [diff] [blame] | 97 | video_stream_adapter_.get())) { |
Evan Shrubsole | ec0af26 | 2020-07-01 11:47:46 +0200 | [diff] [blame] | 98 | video_stream_adapter_->AddRestrictionsListener(&restrictions_listener_); |
Evan Shrubsole | 4d75d9c | 2020-06-03 14:09:09 +0200 | [diff] [blame] | 99 | processor_->AddResource(resource_); |
| 100 | processor_->AddResource(other_resource_); |
Henrik Boström | 722fa4d | 2020-04-29 16:46:30 +0200 | [diff] [blame] | 101 | } |
| 102 | ~ResourceAdaptationProcessorTest() override { |
Evan Shrubsole | 4d75d9c | 2020-06-03 14:09:09 +0200 | [diff] [blame] | 103 | if (processor_) { |
| 104 | DestroyProcessor(); |
| 105 | } |
Henrik Boström | 722fa4d | 2020-04-29 16:46:30 +0200 | [diff] [blame] | 106 | } |
| 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öm | 39ab1b5 | 2020-06-03 09:21:34 +0200 | [diff] [blame] | 122 | void DestroyProcessor() { |
Evan Shrubsole | ce971b0 | 2020-06-12 16:00:03 +0200 | [diff] [blame] | 123 | if (resource_) { |
| 124 | processor_->RemoveResource(resource_); |
| 125 | } |
| 126 | if (other_resource_) { |
| 127 | processor_->RemoveResource(other_resource_); |
| 128 | } |
Evan Shrubsole | ec0af26 | 2020-07-01 11:47:46 +0200 | [diff] [blame] | 129 | video_stream_adapter_->RemoveRestrictionsListener(&restrictions_listener_); |
Henrik Boström | 39ab1b5 | 2020-06-03 09:21:34 +0200 | [diff] [blame] | 130 | processor_.reset(); |
| 131 | } |
| 132 | |
Evan Shrubsole | ce971b0 | 2020-06-12 16:00:03 +0200 | [diff] [blame] | 133 | static void WaitUntilTaskQueueIdle() { |
| 134 | ASSERT_TRUE(rtc::Thread::Current()->ProcessMessages(0)); |
| 135 | } |
| 136 | |
Henrik Boström | 722fa4d | 2020-04-29 16:46:30 +0200 | [diff] [blame] | 137 | protected: |
Jonas Oreland | c7f691a | 2022-03-09 15:12:07 +0100 | [diff] [blame] | 138 | webrtc::test::ScopedKeyValueConfig field_trials_; |
Henrik Boström | 722fa4d | 2020-04-29 16:46:30 +0200 | [diff] [blame] | 139 | FakeFrameRateProvider frame_rate_provider_; |
| 140 | VideoStreamInputStateProvider input_state_provider_; |
Henrik Boström | c55516d | 2020-05-11 16:29:22 +0200 | [diff] [blame] | 141 | rtc::scoped_refptr<FakeResource> resource_; |
| 142 | rtc::scoped_refptr<FakeResource> other_resource_; |
Evan Shrubsole | ec0af26 | 2020-07-01 11:47:46 +0200 | [diff] [blame] | 143 | std::unique_ptr<VideoStreamAdapter> video_stream_adapter_; |
Henrik Boström | 381d109 | 2020-05-12 18:49:07 +0200 | [diff] [blame] | 144 | std::unique_ptr<ResourceAdaptationProcessor> processor_; |
Henrik Boström | 0f0aa9c | 2020-06-02 13:02:36 +0200 | [diff] [blame] | 145 | VideoSourceRestrictionsListenerForTesting restrictions_listener_; |
Henrik Boström | 722fa4d | 2020-04-29 16:46:30 +0200 | [diff] [blame] | 146 | }; |
| 147 | |
| 148 | } // namespace |
| 149 | |
| 150 | TEST_F(ResourceAdaptationProcessorTest, DisabledByDefault) { |
Evan Shrubsole | 4d75d9c | 2020-06-03 14:09:09 +0200 | [diff] [blame] | 151 | SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize); |
Evan Shrubsole | 4d75d9c | 2020-06-03 14:09:09 +0200 | [diff] [blame] | 152 | // Adaptation does not happen when disabled. |
| 153 | resource_->SetUsageState(ResourceUsageState::kOveruse); |
| 154 | EXPECT_EQ(0u, restrictions_listener_.restrictions_updated_count()); |
Henrik Boström | 722fa4d | 2020-04-29 16:46:30 +0200 | [diff] [blame] | 155 | } |
| 156 | |
| 157 | TEST_F(ResourceAdaptationProcessorTest, InsufficientInput) { |
Evan Shrubsole | 3444a49 | 2020-07-07 09:04:34 +0200 | [diff] [blame] | 158 | video_stream_adapter_->SetDegradationPreference( |
Evan Shrubsole | 4d75d9c | 2020-06-03 14:09:09 +0200 | [diff] [blame] | 159 | DegradationPreference::MAINTAIN_FRAMERATE); |
Evan Shrubsole | 4d75d9c | 2020-06-03 14:09:09 +0200 | [diff] [blame] | 160 | // 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öm | 722fa4d | 2020-04-29 16:46:30 +0200 | [diff] [blame] | 170 | } |
| 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. |
| 176 | TEST_F(ResourceAdaptationProcessorTest, |
| 177 | OveruseTriggersRestrictingResolutionInMaintainFrameRate) { |
Evan Shrubsole | 3444a49 | 2020-07-07 09:04:34 +0200 | [diff] [blame] | 178 | video_stream_adapter_->SetDegradationPreference( |
Evan Shrubsole | 4d75d9c | 2020-06-03 14:09:09 +0200 | [diff] [blame] | 179 | DegradationPreference::MAINTAIN_FRAMERATE); |
Evan Shrubsole | 4d75d9c | 2020-06-03 14:09:09 +0200 | [diff] [blame] | 180 | 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öm | 722fa4d | 2020-04-29 16:46:30 +0200 | [diff] [blame] | 185 | } |
| 186 | |
| 187 | TEST_F(ResourceAdaptationProcessorTest, |
| 188 | OveruseTriggersRestrictingFrameRateInMaintainResolution) { |
Evan Shrubsole | 3444a49 | 2020-07-07 09:04:34 +0200 | [diff] [blame] | 189 | video_stream_adapter_->SetDegradationPreference( |
Evan Shrubsole | 4d75d9c | 2020-06-03 14:09:09 +0200 | [diff] [blame] | 190 | DegradationPreference::MAINTAIN_RESOLUTION); |
Evan Shrubsole | 4d75d9c | 2020-06-03 14:09:09 +0200 | [diff] [blame] | 191 | 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öm | 722fa4d | 2020-04-29 16:46:30 +0200 | [diff] [blame] | 196 | } |
| 197 | |
| 198 | TEST_F(ResourceAdaptationProcessorTest, |
| 199 | OveruseTriggersRestrictingFrameRateAndResolutionInBalanced) { |
Evan Shrubsole | 3444a49 | 2020-07-07 09:04:34 +0200 | [diff] [blame] | 200 | video_stream_adapter_->SetDegradationPreference( |
| 201 | DegradationPreference::BALANCED); |
Evan Shrubsole | 4d75d9c | 2020-06-03 14:09:09 +0200 | [diff] [blame] | 202 | 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öm | 722fa4d | 2020-04-29 16:46:30 +0200 | [diff] [blame] | 216 | } |
| 217 | |
| 218 | TEST_F(ResourceAdaptationProcessorTest, AwaitingPreviousAdaptation) { |
Evan Shrubsole | 3444a49 | 2020-07-07 09:04:34 +0200 | [diff] [blame] | 219 | video_stream_adapter_->SetDegradationPreference( |
Evan Shrubsole | 4d75d9c | 2020-06-03 14:09:09 +0200 | [diff] [blame] | 220 | DegradationPreference::MAINTAIN_FRAMERATE); |
Evan Shrubsole | 4d75d9c | 2020-06-03 14:09:09 +0200 | [diff] [blame] | 221 | 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öm | 722fa4d | 2020-04-29 16:46:30 +0200 | [diff] [blame] | 228 | } |
| 229 | |
| 230 | TEST_F(ResourceAdaptationProcessorTest, CannotAdaptUpWhenUnrestricted) { |
Evan Shrubsole | 3444a49 | 2020-07-07 09:04:34 +0200 | [diff] [blame] | 231 | video_stream_adapter_->SetDegradationPreference( |
Evan Shrubsole | 4d75d9c | 2020-06-03 14:09:09 +0200 | [diff] [blame] | 232 | DegradationPreference::MAINTAIN_FRAMERATE); |
Evan Shrubsole | 4d75d9c | 2020-06-03 14:09:09 +0200 | [diff] [blame] | 233 | SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize); |
| 234 | resource_->SetUsageState(ResourceUsageState::kUnderuse); |
| 235 | EXPECT_EQ(0u, restrictions_listener_.restrictions_updated_count()); |
Henrik Boström | 722fa4d | 2020-04-29 16:46:30 +0200 | [diff] [blame] | 236 | } |
| 237 | |
| 238 | TEST_F(ResourceAdaptationProcessorTest, UnderuseTakesUsBackToUnrestricted) { |
Evan Shrubsole | 3444a49 | 2020-07-07 09:04:34 +0200 | [diff] [blame] | 239 | video_stream_adapter_->SetDegradationPreference( |
Evan Shrubsole | 4d75d9c | 2020-06-03 14:09:09 +0200 | [diff] [blame] | 240 | DegradationPreference::MAINTAIN_FRAMERATE); |
Evan Shrubsole | 4d75d9c | 2020-06-03 14:09:09 +0200 | [diff] [blame] | 241 | 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öm | 722fa4d | 2020-04-29 16:46:30 +0200 | [diff] [blame] | 248 | } |
| 249 | |
Evan Shrubsole | 0dcb470 | 2020-05-07 13:45:14 +0200 | [diff] [blame] | 250 | TEST_F(ResourceAdaptationProcessorTest, |
| 251 | ResourcesCanNotAdaptUpIfNeverAdaptedDown) { |
Evan Shrubsole | 3444a49 | 2020-07-07 09:04:34 +0200 | [diff] [blame] | 252 | video_stream_adapter_->SetDegradationPreference( |
Evan Shrubsole | 4d75d9c | 2020-06-03 14:09:09 +0200 | [diff] [blame] | 253 | DegradationPreference::MAINTAIN_FRAMERATE); |
Evan Shrubsole | 4d75d9c | 2020-06-03 14:09:09 +0200 | [diff] [blame] | 254 | SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize); |
| 255 | resource_->SetUsageState(ResourceUsageState::kOveruse); |
| 256 | EXPECT_EQ(1u, restrictions_listener_.restrictions_updated_count()); |
| 257 | RestrictSource(restrictions_listener_.restrictions()); |
Evan Shrubsole | 0dcb470 | 2020-05-07 13:45:14 +0200 | [diff] [blame] | 258 | |
Evan Shrubsole | 4d75d9c | 2020-06-03 14:09:09 +0200 | [diff] [blame] | 259 | // Other resource signals under-use |
| 260 | other_resource_->SetUsageState(ResourceUsageState::kUnderuse); |
| 261 | EXPECT_EQ(1u, restrictions_listener_.restrictions_updated_count()); |
Evan Shrubsole | 0dcb470 | 2020-05-07 13:45:14 +0200 | [diff] [blame] | 262 | } |
| 263 | |
| 264 | TEST_F(ResourceAdaptationProcessorTest, |
| 265 | ResourcesCanNotAdaptUpIfNotAdaptedDownAfterReset) { |
Evan Shrubsole | 3444a49 | 2020-07-07 09:04:34 +0200 | [diff] [blame] | 266 | video_stream_adapter_->SetDegradationPreference( |
Evan Shrubsole | 4d75d9c | 2020-06-03 14:09:09 +0200 | [diff] [blame] | 267 | DegradationPreference::MAINTAIN_FRAMERATE); |
Evan Shrubsole | 4d75d9c | 2020-06-03 14:09:09 +0200 | [diff] [blame] | 268 | SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize); |
| 269 | resource_->SetUsageState(ResourceUsageState::kOveruse); |
| 270 | EXPECT_EQ(1u, restrictions_listener_.restrictions_updated_count()); |
Evan Shrubsole | 0dcb470 | 2020-05-07 13:45:14 +0200 | [diff] [blame] | 271 | |
Evan Shrubsole | ec0af26 | 2020-07-01 11:47:46 +0200 | [diff] [blame] | 272 | video_stream_adapter_->ClearRestrictions(); |
Evan Shrubsole | 4d75d9c | 2020-06-03 14:09:09 +0200 | [diff] [blame] | 273 | 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 Shrubsole | 0dcb470 | 2020-05-07 13:45:14 +0200 | [diff] [blame] | 277 | |
Evan Shrubsole | 4d75d9c | 2020-06-03 14:09:09 +0200 | [diff] [blame] | 278 | // 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 Shrubsole | 0dcb470 | 2020-05-07 13:45:14 +0200 | [diff] [blame] | 282 | } |
| 283 | |
Evan Shrubsole | 6446903 | 2020-06-11 10:45:29 +0200 | [diff] [blame] | 284 | TEST_F(ResourceAdaptationProcessorTest, OnlyMostLimitedResourceMayAdaptUp) { |
Evan Shrubsole | 3444a49 | 2020-07-07 09:04:34 +0200 | [diff] [blame] | 285 | video_stream_adapter_->SetDegradationPreference( |
Evan Shrubsole | 6446903 | 2020-06-11 10:45:29 +0200 | [diff] [blame] | 286 | DegradationPreference::MAINTAIN_FRAMERATE); |
Evan Shrubsole | 6446903 | 2020-06-11 10:45:29 +0200 | [diff] [blame] | 287 | 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 Titov | ea24027 | 2021-07-26 12:40:21 +0200 | [diff] [blame] | 295 | // `other_resource_` is most limited, resource_ can't adapt up. |
Evan Shrubsole | 6446903 | 2020-06-11 10:45:29 +0200 | [diff] [blame] | 296 | 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 Titov | ea24027 | 2021-07-26 12:40:21 +0200 | [diff] [blame] | 303 | // `resource_` and `other_resource_` are now most limited, so both must |
Evan Shrubsole | 6446903 | 2020-06-11 10:45:29 +0200 | [diff] [blame] | 304 | // 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 Shrubsole | 0dcb470 | 2020-05-07 13:45:14 +0200 | [diff] [blame] | 313 | TEST_F(ResourceAdaptationProcessorTest, |
| 314 | MultipleResourcesCanTriggerMultipleAdaptations) { |
Evan Shrubsole | 3444a49 | 2020-07-07 09:04:34 +0200 | [diff] [blame] | 315 | video_stream_adapter_->SetDegradationPreference( |
Evan Shrubsole | 4d75d9c | 2020-06-03 14:09:09 +0200 | [diff] [blame] | 316 | DegradationPreference::MAINTAIN_FRAMERATE); |
Evan Shrubsole | 4d75d9c | 2020-06-03 14:09:09 +0200 | [diff] [blame] | 317 | 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 Shrubsole | 0dcb470 | 2020-05-07 13:45:14 +0200 | [diff] [blame] | 327 | |
Evan Shrubsole | 6446903 | 2020-06-11 10:45:29 +0200 | [diff] [blame] | 328 | // resource_ is not most limited so can't adapt from underuse. |
Evan Shrubsole | 4d75d9c | 2020-06-03 14:09:09 +0200 | [diff] [blame] | 329 | resource_->SetUsageState(ResourceUsageState::kUnderuse); |
Evan Shrubsole | 6446903 | 2020-06-11 10:45:29 +0200 | [diff] [blame] | 330 | EXPECT_EQ(3, restrictions_listener_.adaptation_counters().Total()); |
| 331 | RestrictSource(restrictions_listener_.restrictions()); |
| 332 | other_resource_->SetUsageState(ResourceUsageState::kUnderuse); |
Evan Shrubsole | 4d75d9c | 2020-06-03 14:09:09 +0200 | [diff] [blame] | 333 | EXPECT_EQ(2, restrictions_listener_.adaptation_counters().Total()); |
| 334 | RestrictSource(restrictions_listener_.restrictions()); |
Evan Shrubsole | 6446903 | 2020-06-11 10:45:29 +0200 | [diff] [blame] | 335 | // resource_ is still not most limited so can't adapt from underuse. |
Evan Shrubsole | 4d75d9c | 2020-06-03 14:09:09 +0200 | [diff] [blame] | 336 | resource_->SetUsageState(ResourceUsageState::kUnderuse); |
| 337 | EXPECT_EQ(2, restrictions_listener_.adaptation_counters().Total()); |
| 338 | RestrictSource(restrictions_listener_.restrictions()); |
Evan Shrubsole | 0dcb470 | 2020-05-07 13:45:14 +0200 | [diff] [blame] | 339 | |
Evan Shrubsole | 6446903 | 2020-06-11 10:45:29 +0200 | [diff] [blame] | 340 | // 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 Shrubsole | 4d75d9c | 2020-06-03 14:09:09 +0200 | [diff] [blame] | 346 | other_resource_->SetUsageState(ResourceUsageState::kUnderuse); |
Evan Shrubsole | 6446903 | 2020-06-11 10:45:29 +0200 | [diff] [blame] | 347 | 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 Shrubsole | 4d75d9c | 2020-06-03 14:09:09 +0200 | [diff] [blame] | 365 | 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 Shrubsole | 6446903 | 2020-06-11 10:45:29 +0200 | [diff] [blame] | 369 | } |
| 370 | |
| 371 | TEST_F(ResourceAdaptationProcessorTest, |
| 372 | MostLimitedResourceAdaptationWorksAfterChangingDegradataionPreference) { |
Evan Shrubsole | 3444a49 | 2020-07-07 09:04:34 +0200 | [diff] [blame] | 373 | video_stream_adapter_->SetDegradationPreference( |
Evan Shrubsole | 6446903 | 2020-06-11 10:45:29 +0200 | [diff] [blame] | 374 | DegradationPreference::MAINTAIN_FRAMERATE); |
Evan Shrubsole | 6446903 | 2020-06-11 10:45:29 +0200 | [diff] [blame] | 375 | SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize); |
| 376 | // Adapt down until we can't anymore. |
| 377 | resource_->SetUsageState(ResourceUsageState::kOveruse); |
Evan Shrubsole | 4d75d9c | 2020-06-03 14:09:09 +0200 | [diff] [blame] | 378 | RestrictSource(restrictions_listener_.restrictions()); |
Evan Shrubsole | 6446903 | 2020-06-11 10:45:29 +0200 | [diff] [blame] | 379 | 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 Shrubsole | 3444a49 | 2020-07-07 09:04:34 +0200 | [diff] [blame] | 389 | video_stream_adapter_->SetDegradationPreference( |
Evan Shrubsole | 6446903 | 2020-06-11 10:45:29 +0200 | [diff] [blame] | 390 | 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 Shrubsole | 0dcb470 | 2020-05-07 13:45:14 +0200 | [diff] [blame] | 402 | } |
| 403 | |
Ilya Nikolaevskiy | 8e321cd | 2020-05-11 15:33:23 +0200 | [diff] [blame] | 404 | TEST_F(ResourceAdaptationProcessorTest, |
| 405 | AdaptsDownWhenOtherResourceIsAlwaysUnderused) { |
Evan Shrubsole | 3444a49 | 2020-07-07 09:04:34 +0200 | [diff] [blame] | 406 | video_stream_adapter_->SetDegradationPreference( |
Evan Shrubsole | 4d75d9c | 2020-06-03 14:09:09 +0200 | [diff] [blame] | 407 | DegradationPreference::MAINTAIN_FRAMERATE); |
Evan Shrubsole | 4d75d9c | 2020-06-03 14:09:09 +0200 | [diff] [blame] | 408 | 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 Nikolaevskiy | 8e321cd | 2020-05-11 15:33:23 +0200 | [diff] [blame] | 412 | |
Evan Shrubsole | 4d75d9c | 2020-06-03 14:09:09 +0200 | [diff] [blame] | 413 | 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 Nikolaevskiy | 8e321cd | 2020-05-11 15:33:23 +0200 | [diff] [blame] | 417 | |
Evan Shrubsole | 4d75d9c | 2020-06-03 14:09:09 +0200 | [diff] [blame] | 418 | 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 Nikolaevskiy | 8e321cd | 2020-05-11 15:33:23 +0200 | [diff] [blame] | 423 | } |
| 424 | |
Henrik Boström | 39ab1b5 | 2020-06-03 09:21:34 +0200 | [diff] [blame] | 425 | TEST_F(ResourceAdaptationProcessorTest, |
| 426 | TriggerOveruseNotOnAdaptationTaskQueue) { |
Evan Shrubsole | 3444a49 | 2020-07-07 09:04:34 +0200 | [diff] [blame] | 427 | video_stream_adapter_->SetDegradationPreference( |
Evan Shrubsole | 4d75d9c | 2020-06-03 14:09:09 +0200 | [diff] [blame] | 428 | DegradationPreference::MAINTAIN_FRAMERATE); |
Evan Shrubsole | 4d75d9c | 2020-06-03 14:09:09 +0200 | [diff] [blame] | 429 | 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öm | 39ab1b5 | 2020-06-03 09:21:34 +0200 | [diff] [blame] | 435 | EXPECT_EQ_WAIT(1u, restrictions_listener_.restrictions_updated_count(), |
| 436 | kDefaultTimeoutMs); |
| 437 | } |
| 438 | |
| 439 | TEST_F(ResourceAdaptationProcessorTest, |
| 440 | DestroyProcessorWhileResourceListenerDelegateHasTaskInFlight) { |
Evan Shrubsole | 3444a49 | 2020-07-07 09:04:34 +0200 | [diff] [blame] | 441 | video_stream_adapter_->SetDegradationPreference( |
Evan Shrubsole | 4d75d9c | 2020-06-03 14:09:09 +0200 | [diff] [blame] | 442 | DegradationPreference::MAINTAIN_FRAMERATE); |
Evan Shrubsole | 4d75d9c | 2020-06-03 14:09:09 +0200 | [diff] [blame] | 443 | SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize); |
| 444 | |
Artem Titov | ea24027 | 2021-07-26 12:40:21 +0200 | [diff] [blame] | 445 | // Wait for `resource_` to signal oversue first so we know that the delegate |
Evan Shrubsole | 4d75d9c | 2020-06-03 14:09:09 +0200 | [diff] [blame] | 446 | // 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öm | 39ab1b5 | 2020-06-03 09:21:34 +0200 | [diff] [blame] | 458 | // 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 Shrubsole | ce971b0 | 2020-06-12 16:00:03 +0200 | [diff] [blame] | 463 | TEST_F(ResourceAdaptationProcessorTest, |
| 464 | ResourceOveruseIgnoredWhenSignalledDuringRemoval) { |
Evan Shrubsole | 3444a49 | 2020-07-07 09:04:34 +0200 | [diff] [blame] | 465 | video_stream_adapter_->SetDegradationPreference( |
Evan Shrubsole | ce971b0 | 2020-06-12 16:00:03 +0200 | [diff] [blame] | 466 | DegradationPreference::MAINTAIN_FRAMERATE); |
| 467 | SetInputStates(true, kDefaultFrameRate, kDefaultFrameSize); |
| 468 | |
| 469 | rtc::Event overuse_event; |
| 470 | TaskQueueForTest resource_task_queue("ResourceTaskQueue"); |
Artem Titov | ea24027 | 2021-07-26 12:40:21 +0200 | [diff] [blame] | 471 | // Queues task for `resource_` overuse while `processor_` is still listening. |
Evan Shrubsole | ce971b0 | 2020-06-12 16:00:03 +0200 | [diff] [blame] | 472 | resource_task_queue.PostTask(ToQueuedTask([&]() { |
| 473 | resource_->SetUsageState(ResourceUsageState::kOveruse); |
| 474 | overuse_event.Set(); |
| 475 | })); |
| 476 | EXPECT_TRUE(overuse_event.Wait(kDefaultTimeoutMs)); |
Artem Titov | ea24027 | 2021-07-26 12:40:21 +0200 | [diff] [blame] | 477 | // Once we know the overuse task is queued, remove `resource_` so that |
| 478 | // `processor_` is not listening to it. |
Evan Shrubsole | ce971b0 | 2020-06-12 16:00:03 +0200 | [diff] [blame] | 479 | processor_->RemoveResource(resource_); |
| 480 | |
Artem Titov | ea24027 | 2021-07-26 12:40:21 +0200 | [diff] [blame] | 481 | // Runs the queued task so `processor_` gets signalled kOveruse from |
| 482 | // `resource_` even though `processor_` was not listening. |
Evan Shrubsole | ce971b0 | 2020-06-12 16:00:03 +0200 | [diff] [blame] | 483 | WaitUntilTaskQueueIdle(); |
| 484 | |
Artem Titov | ea24027 | 2021-07-26 12:40:21 +0200 | [diff] [blame] | 485 | // No restrictions should change even though `resource_` signaled `kOveruse`. |
Evan Shrubsole | ce971b0 | 2020-06-12 16:00:03 +0200 | [diff] [blame] | 486 | EXPECT_EQ(0u, restrictions_listener_.restrictions_updated_count()); |
| 487 | |
Artem Titov | ea24027 | 2021-07-26 12:40:21 +0200 | [diff] [blame] | 488 | // Delete `resource_` for cleanup. |
Evan Shrubsole | ce971b0 | 2020-06-12 16:00:03 +0200 | [diff] [blame] | 489 | resource_ = nullptr; |
| 490 | } |
| 491 | |
| 492 | TEST_F(ResourceAdaptationProcessorTest, |
| 493 | RemovingOnlyAdaptedResourceResetsAdaptation) { |
Evan Shrubsole | 3444a49 | 2020-07-07 09:04:34 +0200 | [diff] [blame] | 494 | video_stream_adapter_->SetDegradationPreference( |
Evan Shrubsole | ce971b0 | 2020-06-12 16:00:03 +0200 | [diff] [blame] | 495 | 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 Titov | ea24027 | 2021-07-26 12:40:21 +0200 | [diff] [blame] | 505 | // Delete `resource_` for cleanup. |
Evan Shrubsole | ce971b0 | 2020-06-12 16:00:03 +0200 | [diff] [blame] | 506 | resource_ = nullptr; |
| 507 | } |
| 508 | |
| 509 | TEST_F(ResourceAdaptationProcessorTest, |
| 510 | RemovingMostLimitedResourceSetsAdaptationToNextLimitedLevel) { |
Evan Shrubsole | 3444a49 | 2020-07-07 09:04:34 +0200 | [diff] [blame] | 511 | video_stream_adapter_->SetDegradationPreference( |
| 512 | DegradationPreference::BALANCED); |
Evan Shrubsole | ce971b0 | 2020-06-12 16:00:03 +0200 | [diff] [blame] | 513 | 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 Titov | ea24027 | 2021-07-26 12:40:21 +0200 | [diff] [blame] | 527 | // Removing most limited `resource_` should revert us back to |
Evan Shrubsole | ce971b0 | 2020-06-12 16:00:03 +0200 | [diff] [blame] | 528 | 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 Titov | ea24027 | 2021-07-26 12:40:21 +0200 | [diff] [blame] | 534 | // Delete `resource_` for cleanup. |
Evan Shrubsole | ce971b0 | 2020-06-12 16:00:03 +0200 | [diff] [blame] | 535 | resource_ = nullptr; |
| 536 | } |
| 537 | |
| 538 | TEST_F(ResourceAdaptationProcessorTest, |
| 539 | RemovingMostLimitedResourceSetsAdaptationIfInputStateUnchanged) { |
Evan Shrubsole | 3444a49 | 2020-07-07 09:04:34 +0200 | [diff] [blame] | 540 | video_stream_adapter_->SetDegradationPreference( |
Evan Shrubsole | ce971b0 | 2020-06-12 16:00:03 +0200 | [diff] [blame] | 541 | 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 Titov | ea24027 | 2021-07-26 12:40:21 +0200 | [diff] [blame] | 561 | // Removing most limited `resource_` should revert us back to, even though we |
| 562 | // did not call RestrictSource() after `resource_` was overused. Normally |
Evan Shrubsole | ce971b0 | 2020-06-12 16:00:03 +0200 | [diff] [blame] | 563 | // 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 Titov | ea24027 | 2021-07-26 12:40:21 +0200 | [diff] [blame] | 571 | // Delete `resource_` for cleanup. |
Evan Shrubsole | ce971b0 | 2020-06-12 16:00:03 +0200 | [diff] [blame] | 572 | resource_ = nullptr; |
| 573 | } |
| 574 | |
| 575 | TEST_F(ResourceAdaptationProcessorTest, |
| 576 | RemovingResourceNotMostLimitedHasNoEffectOnLimitations) { |
Evan Shrubsole | 3444a49 | 2020-07-07 09:04:34 +0200 | [diff] [blame] | 577 | video_stream_adapter_->SetDegradationPreference( |
| 578 | DegradationPreference::BALANCED); |
Evan Shrubsole | ce971b0 | 2020-06-12 16:00:03 +0200 | [diff] [blame] | 579 | 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 Titov | ea24027 | 2021-07-26 12:40:21 +0200 | [diff] [blame] | 593 | // Removing most limited `resource_` should revert us back to |
Evan Shrubsole | ce971b0 | 2020-06-12 16:00:03 +0200 | [diff] [blame] | 594 | processor_->RemoveResource(other_resource_); |
| 595 | EXPECT_EQ(current_restrictions, restrictions_listener_.restrictions()); |
| 596 | EXPECT_EQ(current_counters, restrictions_listener_.adaptation_counters()); |
| 597 | |
Artem Titov | ea24027 | 2021-07-26 12:40:21 +0200 | [diff] [blame] | 598 | // Delete `other_resource_` for cleanup. |
Evan Shrubsole | ce971b0 | 2020-06-12 16:00:03 +0200 | [diff] [blame] | 599 | other_resource_ = nullptr; |
| 600 | } |
| 601 | |
| 602 | TEST_F(ResourceAdaptationProcessorTest, |
| 603 | RemovingMostLimitedResourceAfterSwitchingDegradationPreferences) { |
Evan Shrubsole | 3444a49 | 2020-07-07 09:04:34 +0200 | [diff] [blame] | 604 | video_stream_adapter_->SetDegradationPreference( |
Evan Shrubsole | ce971b0 | 2020-06-12 16:00:03 +0200 | [diff] [blame] | 605 | 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 Shrubsole | 3444a49 | 2020-07-07 09:04:34 +0200 | [diff] [blame] | 616 | video_stream_adapter_->SetDegradationPreference( |
Evan Shrubsole | ce971b0 | 2020-06-12 16:00:03 +0200 | [diff] [blame] | 617 | DegradationPreference::MAINTAIN_RESOLUTION); |
| 618 | resource_->SetUsageState(ResourceUsageState::kOveruse); |
| 619 | RestrictSource(restrictions_listener_.restrictions()); |
| 620 | EXPECT_EQ(2, restrictions_listener_.adaptation_counters().Total()); |
| 621 | |
Artem Titov | ea24027 | 2021-07-26 12:40:21 +0200 | [diff] [blame] | 622 | // Revert to `other_resource_` when removing `resource_` even though the |
Evan Shrubsole | ce971b0 | 2020-06-12 16:00:03 +0200 | [diff] [blame] | 623 | // 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 Shrubsole | 3444a49 | 2020-07-07 09:04:34 +0200 | [diff] [blame] | 630 | video_stream_adapter_->SetDegradationPreference( |
Evan Shrubsole | ce971b0 | 2020-06-12 16:00:03 +0200 | [diff] [blame] | 631 | DegradationPreference::MAINTAIN_FRAMERATE); |
| 632 | EXPECT_EQ(next_limited_restrictions, restrictions_listener_.restrictions()); |
| 633 | |
Artem Titov | ea24027 | 2021-07-26 12:40:21 +0200 | [diff] [blame] | 634 | // Delete `resource_` for cleanup. |
Evan Shrubsole | ce971b0 | 2020-06-12 16:00:03 +0200 | [diff] [blame] | 635 | resource_ = nullptr; |
| 636 | } |
| 637 | |
| 638 | TEST_F(ResourceAdaptationProcessorTest, |
| 639 | RemovingMostLimitedResourceSetsNextLimitationsInDisabled) { |
Evan Shrubsole | 3444a49 | 2020-07-07 09:04:34 +0200 | [diff] [blame] | 640 | video_stream_adapter_->SetDegradationPreference( |
Evan Shrubsole | ce971b0 | 2020-06-12 16:00:03 +0200 | [diff] [blame] | 641 | 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 Shrubsole | 3444a49 | 2020-07-07 09:04:34 +0200 | [diff] [blame] | 655 | video_stream_adapter_->SetDegradationPreference( |
| 656 | DegradationPreference::DISABLED); |
Evan Shrubsole | ce971b0 | 2020-06-12 16:00:03 +0200 | [diff] [blame] | 657 | |
Artem Titov | ea24027 | 2021-07-26 12:40:21 +0200 | [diff] [blame] | 658 | // Revert to `other_resource_` when removing `resource_` even though the |
Evan Shrubsole | ce971b0 | 2020-06-12 16:00:03 +0200 | [diff] [blame] | 659 | // 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 Shrubsole | 3444a49 | 2020-07-07 09:04:34 +0200 | [diff] [blame] | 664 | video_stream_adapter_->SetDegradationPreference( |
Evan Shrubsole | ce971b0 | 2020-06-12 16:00:03 +0200 | [diff] [blame] | 665 | 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 Titov | ea24027 | 2021-07-26 12:40:21 +0200 | [diff] [blame] | 670 | // Delete `resource_` for cleanup. |
Evan Shrubsole | ce971b0 | 2020-06-12 16:00:03 +0200 | [diff] [blame] | 671 | resource_ = nullptr; |
| 672 | } |
| 673 | |
| 674 | TEST_F(ResourceAdaptationProcessorTest, |
| 675 | RemovedResourceSignalsIgnoredByProcessor) { |
Evan Shrubsole | 3444a49 | 2020-07-07 09:04:34 +0200 | [diff] [blame] | 676 | video_stream_adapter_->SetDegradationPreference( |
Evan Shrubsole | ce971b0 | 2020-06-12 16:00:03 +0200 | [diff] [blame] | 677 | 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 Titov | ea24027 | 2021-07-26 12:40:21 +0200 | [diff] [blame] | 684 | // Delete `resource_` for cleanup. |
Evan Shrubsole | ce971b0 | 2020-06-12 16:00:03 +0200 | [diff] [blame] | 685 | resource_ = nullptr; |
| 686 | } |
| 687 | |
| 688 | TEST_F(ResourceAdaptationProcessorTest, |
| 689 | RemovingResourceWhenMultipleMostLimtedHasNoEffect) { |
Evan Shrubsole | 3444a49 | 2020-07-07 09:04:34 +0200 | [diff] [blame] | 690 | video_stream_adapter_->SetDegradationPreference( |
Evan Shrubsole | ce971b0 | 2020-06-12 16:00:03 +0200 | [diff] [blame] | 691 | 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 Titov | ea24027 | 2021-07-26 12:40:21 +0200 | [diff] [blame] | 697 | // Adapt `resource_` up and then down so that both resource's are most |
Evan Shrubsole | ce971b0 | 2020-06-12 16:00:03 +0200 | [diff] [blame] | 698 | // 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 Titov | ea24027 | 2021-07-26 12:40:21 +0200 | [diff] [blame] | 705 | // Removing `resource_` has no effect since both `resource_` and |
| 706 | // `other_resource_` are most limited. |
Evan Shrubsole | ce971b0 | 2020-06-12 16:00:03 +0200 | [diff] [blame] | 707 | processor_->RemoveResource(resource_); |
| 708 | EXPECT_EQ(1, restrictions_listener_.adaptation_counters().Total()); |
| 709 | |
Artem Titov | ea24027 | 2021-07-26 12:40:21 +0200 | [diff] [blame] | 710 | // Delete `resource_` for cleanup. |
Evan Shrubsole | ce971b0 | 2020-06-12 16:00:03 +0200 | [diff] [blame] | 711 | resource_ = nullptr; |
| 712 | } |
| 713 | |
Evan Shrubsole | bd4a718 | 2020-08-14 10:08:54 +0200 | [diff] [blame] | 714 | TEST_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 Titov | ea24027 | 2021-07-26 12:40:21 +0200 | [diff] [blame] | 732 | // Now both `resource_` and `other_resource_` are most limited. Underuse of |
| 733 | // `resource_` will not adapt up. |
Evan Shrubsole | bd4a718 | 2020-08-14 10:08:54 +0200 | [diff] [blame] | 734 | resource_->SetUsageState(ResourceUsageState::kUnderuse); |
| 735 | EXPECT_EQ(last_update_count, |
| 736 | restrictions_listener_.restrictions_updated_count()); |
| 737 | } |
| 738 | |
Henrik Boström | 722fa4d | 2020-04-29 16:46:30 +0200 | [diff] [blame] | 739 | } // namespace webrtc |