blob: a89d64b4129f21dc61b0e2e4dbce8b51b15adffb [file] [log] [blame]
Henrik Boström87eece92020-04-17 18:36:19 +02001/*
2 * Copyright 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ömc55516d2020-05-11 16:29:22 +020013#include <algorithm>
Henrik Boströmf0eef122020-05-28 16:22:42 +020014#include <string>
Henrik Boström87eece92020-04-17 18:36:19 +020015#include <utility>
16
17#include "absl/algorithm/container.h"
Artem Titovd15a5752021-02-10 14:31:24 +010018#include "api/sequence_checker.h"
Evan Shrubsoleec0af262020-07-01 11:47:46 +020019#include "api/video/video_adaptation_counters.h"
20#include "call/adaptation/video_stream_adapter.h"
Henrik Boströmf0eef122020-05-28 16:22:42 +020021#include "rtc_base/logging.h"
Henrik Boström39ab1b52020-06-03 09:21:34 +020022#include "rtc_base/ref_counted_object.h"
Henrik Boströmf0eef122020-05-28 16:22:42 +020023#include "rtc_base/strings/string_builder.h"
Henrik Boström39ab1b52020-06-03 09:21:34 +020024#include "rtc_base/task_utils/to_queued_task.h"
Henrik Boström87eece92020-04-17 18:36:19 +020025
26namespace webrtc {
27
Henrik Boström39ab1b52020-06-03 09:21:34 +020028ResourceAdaptationProcessor::ResourceListenerDelegate::ResourceListenerDelegate(
29 ResourceAdaptationProcessor* processor)
Tommi62b01db2022-01-25 23:41:22 +010030 : task_queue_(TaskQueueBase::Current()), processor_(processor) {
31 RTC_DCHECK(task_queue_);
Henrik Boström39ab1b52020-06-03 09:21:34 +020032}
33
34void ResourceAdaptationProcessor::ResourceListenerDelegate::
35 OnProcessorDestroyed() {
Evan Shrubsole85728412020-08-25 13:12:12 +020036 RTC_DCHECK_RUN_ON(task_queue_);
Henrik Boström39ab1b52020-06-03 09:21:34 +020037 processor_ = nullptr;
38}
39
40void ResourceAdaptationProcessor::ResourceListenerDelegate::
41 OnResourceUsageStateMeasured(rtc::scoped_refptr<Resource> resource,
42 ResourceUsageState usage_state) {
Evan Shrubsole85728412020-08-25 13:12:12 +020043 if (!task_queue_->IsCurrent()) {
44 task_queue_->PostTask(ToQueuedTask(
Henrik Boström39ab1b52020-06-03 09:21:34 +020045 [this_ref = rtc::scoped_refptr<ResourceListenerDelegate>(this),
46 resource, usage_state] {
47 this_ref->OnResourceUsageStateMeasured(resource, usage_state);
48 }));
49 return;
50 }
Evan Shrubsole85728412020-08-25 13:12:12 +020051 RTC_DCHECK_RUN_ON(task_queue_);
Henrik Boström39ab1b52020-06-03 09:21:34 +020052 if (processor_) {
53 processor_->OnResourceUsageStateMeasured(resource, usage_state);
54 }
55}
56
Henrik Boströmf0eef122020-05-28 16:22:42 +020057ResourceAdaptationProcessor::MitigationResultAndLogMessage::
58 MitigationResultAndLogMessage()
59 : result(MitigationResult::kAdaptationApplied), message() {}
60
61ResourceAdaptationProcessor::MitigationResultAndLogMessage::
62 MitigationResultAndLogMessage(MitigationResult result, std::string message)
63 : result(result), message(std::move(message)) {}
64
Henrik Boström87eece92020-04-17 18:36:19 +020065ResourceAdaptationProcessor::ResourceAdaptationProcessor(
Evan Shrubsoleec0af262020-07-01 11:47:46 +020066 VideoStreamAdapter* stream_adapter)
Tommi62b01db2022-01-25 23:41:22 +010067 : task_queue_(TaskQueueBase::Current()),
Henrik Boström39ab1b52020-06-03 09:21:34 +020068 resource_listener_delegate_(
Tomas Gunnarssonc1d58912021-04-22 19:21:43 +020069 rtc::make_ref_counted<ResourceListenerDelegate>(this)),
Henrik Boström87eece92020-04-17 18:36:19 +020070 resources_(),
Evan Shrubsoleec0af262020-07-01 11:47:46 +020071 stream_adapter_(stream_adapter),
Henrik Boström91aa7322020-04-28 12:24:33 +020072 last_reported_source_restrictions_(),
Evan Shrubsole64a60832020-08-11 09:14:46 +020073 previous_mitigation_results_() {
Tommi62b01db2022-01-25 23:41:22 +010074 RTC_DCHECK(task_queue_);
75 stream_adapter_->AddRestrictionsListener(this);
Evan Shrubsoleec0af262020-07-01 11:47:46 +020076}
Henrik Boström87eece92020-04-17 18:36:19 +020077
Henrik Boströmc55516d2020-05-11 16:29:22 +020078ResourceAdaptationProcessor::~ResourceAdaptationProcessor() {
Evan Shrubsole85728412020-08-25 13:12:12 +020079 RTC_DCHECK_RUN_ON(task_queue_);
Henrik Boströmc55516d2020-05-11 16:29:22 +020080 RTC_DCHECK(resources_.empty())
81 << "There are resource(s) attached to a ResourceAdaptationProcessor "
82 << "being destroyed.";
Evan Shrubsoleec0af262020-07-01 11:47:46 +020083 stream_adapter_->RemoveRestrictionsListener(this);
Henrik Boström39ab1b52020-06-03 09:21:34 +020084 resource_listener_delegate_->OnProcessorDestroyed();
Henrik Boströmc55516d2020-05-11 16:29:22 +020085}
86
Evan Shrubsoleec0af262020-07-01 11:47:46 +020087void ResourceAdaptationProcessor::AddResourceLimitationsListener(
88 ResourceLimitationsListener* limitations_listener) {
Evan Shrubsole85728412020-08-25 13:12:12 +020089 RTC_DCHECK_RUN_ON(task_queue_);
Evan Shrubsoleec0af262020-07-01 11:47:46 +020090 RTC_DCHECK(std::find(resource_limitations_listeners_.begin(),
91 resource_limitations_listeners_.end(),
92 limitations_listener) ==
93 resource_limitations_listeners_.end());
94 resource_limitations_listeners_.push_back(limitations_listener);
Henrik Boström87eece92020-04-17 18:36:19 +020095}
Evan Shrubsole85728412020-08-25 13:12:12 +020096
Evan Shrubsoleec0af262020-07-01 11:47:46 +020097void ResourceAdaptationProcessor::RemoveResourceLimitationsListener(
98 ResourceLimitationsListener* limitations_listener) {
Evan Shrubsole85728412020-08-25 13:12:12 +020099 RTC_DCHECK_RUN_ON(task_queue_);
Evan Shrubsoleec0af262020-07-01 11:47:46 +0200100 auto it =
101 std::find(resource_limitations_listeners_.begin(),
102 resource_limitations_listeners_.end(), limitations_listener);
103 RTC_DCHECK(it != resource_limitations_listeners_.end());
104 resource_limitations_listeners_.erase(it);
Henrik Boströmc55516d2020-05-11 16:29:22 +0200105}
106
107void ResourceAdaptationProcessor::AddResource(
108 rtc::scoped_refptr<Resource> resource) {
Evan Shrubsolece971b02020-06-12 16:00:03 +0200109 RTC_DCHECK(resource);
Evan Shrubsole517f81e2020-07-09 13:35:33 +0200110 {
111 MutexLock crit(&resources_lock_);
112 RTC_DCHECK(absl::c_find(resources_, resource) == resources_.end())
113 << "Resource \"" << resource->Name() << "\" was already registered.";
114 resources_.push_back(resource);
115 }
Niels Möllerdf209e72022-04-25 16:59:19 +0200116 resource->SetResourceListener(resource_listener_delegate_.get());
Harald Alvestrand97597c02021-11-04 12:01:23 +0000117 RTC_LOG(LS_INFO) << "Registered resource \"" << resource->Name() << "\".";
Henrik Boström87eece92020-04-17 18:36:19 +0200118}
119
Henrik Boströmf4a99912020-06-11 12:07:14 +0200120std::vector<rtc::scoped_refptr<Resource>>
121ResourceAdaptationProcessor::GetResources() const {
Evan Shrubsole517f81e2020-07-09 13:35:33 +0200122 MutexLock crit(&resources_lock_);
Henrik Boströmf4a99912020-06-11 12:07:14 +0200123 return resources_;
124}
125
Henrik Boströmc55516d2020-05-11 16:29:22 +0200126void ResourceAdaptationProcessor::RemoveResource(
127 rtc::scoped_refptr<Resource> resource) {
Evan Shrubsolece971b02020-06-12 16:00:03 +0200128 RTC_DCHECK(resource);
Harald Alvestrand97597c02021-11-04 12:01:23 +0000129 RTC_LOG(LS_INFO) << "Removing resource \"" << resource->Name() << "\".";
Evan Shrubsole517f81e2020-07-09 13:35:33 +0200130 resource->SetResourceListener(nullptr);
131 {
132 MutexLock crit(&resources_lock_);
133 auto it = absl::c_find(resources_, resource);
134 RTC_DCHECK(it != resources_.end()) << "Resource \"" << resource->Name()
135 << "\" was not a registered resource.";
136 resources_.erase(it);
137 }
138 RemoveLimitationsImposedByResource(std::move(resource));
139}
140
141void ResourceAdaptationProcessor::RemoveLimitationsImposedByResource(
142 rtc::scoped_refptr<Resource> resource) {
Evan Shrubsole85728412020-08-25 13:12:12 +0200143 if (!task_queue_->IsCurrent()) {
144 task_queue_->PostTask(ToQueuedTask(
Evan Shrubsole517f81e2020-07-09 13:35:33 +0200145 [this, resource]() { RemoveLimitationsImposedByResource(resource); }));
146 return;
147 }
Evan Shrubsole85728412020-08-25 13:12:12 +0200148 RTC_DCHECK_RUN_ON(task_queue_);
Evan Shrubsolece971b02020-06-12 16:00:03 +0200149 auto resource_adaptation_limits =
150 adaptation_limits_by_resources_.find(resource);
151 if (resource_adaptation_limits != adaptation_limits_by_resources_.end()) {
152 VideoStreamAdapter::RestrictionsWithCounters adaptation_limits =
153 resource_adaptation_limits->second;
154 adaptation_limits_by_resources_.erase(resource_adaptation_limits);
Evan Shrubsole517f81e2020-07-09 13:35:33 +0200155 if (adaptation_limits_by_resources_.empty()) {
156 // Only the resource being removed was adapted so clear restrictions.
157 stream_adapter_->ClearRestrictions();
158 return;
159 }
160
161 VideoStreamAdapter::RestrictionsWithCounters most_limited =
162 FindMostLimitedResources().second;
163
164 if (adaptation_limits.counters.Total() <= most_limited.counters.Total()) {
165 // The removed limitations were less limited than the most limited
166 // resource. Don't change the current restrictions.
167 return;
168 }
169
170 // Apply the new most limited resource as the next restrictions.
171 Adaptation adapt_to = stream_adapter_->GetAdaptationTo(
172 most_limited.counters, most_limited.restrictions);
173 RTC_DCHECK_EQ(adapt_to.status(), Adaptation::Status::kValid);
174 stream_adapter_->ApplyAdaptation(adapt_to, nullptr);
175
Harald Alvestrand97597c02021-11-04 12:01:23 +0000176 RTC_LOG(LS_INFO)
177 << "Most limited resource removed. Restoring restrictions to "
178 "next most limited restrictions: "
179 << most_limited.restrictions.ToString() << " with counters "
180 << most_limited.counters.ToString();
Evan Shrubsolece971b02020-06-12 16:00:03 +0200181 }
Henrik Boströmc55516d2020-05-11 16:29:22 +0200182}
183
Henrik Boström91aa7322020-04-28 12:24:33 +0200184void ResourceAdaptationProcessor::OnResourceUsageStateMeasured(
Henrik Boström39ab1b52020-06-03 09:21:34 +0200185 rtc::scoped_refptr<Resource> resource,
186 ResourceUsageState usage_state) {
Evan Shrubsole85728412020-08-25 13:12:12 +0200187 RTC_DCHECK_RUN_ON(task_queue_);
Evan Shrubsolece971b02020-06-12 16:00:03 +0200188 RTC_DCHECK(resource);
Artem Titovea240272021-07-26 12:40:21 +0200189 // `resource` could have been removed after signalling.
Evan Shrubsole517f81e2020-07-09 13:35:33 +0200190 {
191 MutexLock crit(&resources_lock_);
192 if (absl::c_find(resources_, resource) == resources_.end()) {
Harald Alvestrand97597c02021-11-04 12:01:23 +0000193 RTC_LOG(LS_INFO) << "Ignoring signal from removed resource \""
194 << resource->Name() << "\".";
Evan Shrubsole517f81e2020-07-09 13:35:33 +0200195 return;
196 }
Evan Shrubsolece971b02020-06-12 16:00:03 +0200197 }
Henrik Boströmf0eef122020-05-28 16:22:42 +0200198 MitigationResultAndLogMessage result_and_message;
199 switch (usage_state) {
Henrik Boström87eece92020-04-17 18:36:19 +0200200 case ResourceUsageState::kOveruse:
Henrik Boströmf0eef122020-05-28 16:22:42 +0200201 result_and_message = OnResourceOveruse(resource);
Henrik Boström91aa7322020-04-28 12:24:33 +0200202 break;
Henrik Boström87eece92020-04-17 18:36:19 +0200203 case ResourceUsageState::kUnderuse:
Henrik Boströmf0eef122020-05-28 16:22:42 +0200204 result_and_message = OnResourceUnderuse(resource);
Henrik Boström91aa7322020-04-28 12:24:33 +0200205 break;
Henrik Boström87eece92020-04-17 18:36:19 +0200206 }
Henrik Boströmf0eef122020-05-28 16:22:42 +0200207 // Maybe log the result of the operation.
208 auto it = previous_mitigation_results_.find(resource.get());
209 if (it != previous_mitigation_results_.end() &&
210 it->second == result_and_message.result) {
211 // This resource has previously reported the same result and we haven't
212 // successfully adapted since - don't log to avoid spam.
213 return;
214 }
Harald Alvestrand97597c02021-11-04 12:01:23 +0000215 RTC_LOG(LS_INFO) << "Resource \"" << resource->Name() << "\" signalled "
216 << ResourceUsageStateToString(usage_state) << ". "
217 << result_and_message.message;
Henrik Boströmf0eef122020-05-28 16:22:42 +0200218 if (result_and_message.result == MitigationResult::kAdaptationApplied) {
219 previous_mitigation_results_.clear();
220 } else {
221 previous_mitigation_results_.insert(
222 std::make_pair(resource.get(), result_and_message.result));
223 }
Henrik Boström87eece92020-04-17 18:36:19 +0200224}
225
Henrik Boströmf0eef122020-05-28 16:22:42 +0200226ResourceAdaptationProcessor::MitigationResultAndLogMessage
227ResourceAdaptationProcessor::OnResourceUnderuse(
Henrik Boströmc55516d2020-05-11 16:29:22 +0200228 rtc::scoped_refptr<Resource> reason_resource) {
Evan Shrubsole85728412020-08-25 13:12:12 +0200229 RTC_DCHECK_RUN_ON(task_queue_);
Henrik Boström87eece92020-04-17 18:36:19 +0200230 // How can this stream be adapted up?
Evan Shrubsoleb93ad752020-08-13 11:35:24 +0200231 Adaptation adaptation = stream_adapter_->GetAdaptationUp();
Henrik Boström91aa7322020-04-28 12:24:33 +0200232 if (adaptation.status() != Adaptation::Status::kValid) {
Henrik Boströmf0eef122020-05-28 16:22:42 +0200233 rtc::StringBuilder message;
234 message << "Not adapting up because VideoStreamAdapter returned "
235 << Adaptation::StatusToString(adaptation.status());
236 return MitigationResultAndLogMessage(MitigationResult::kRejectedByAdapter,
237 message.Release());
Henrik Boström91aa7322020-04-28 12:24:33 +0200238 }
Evan Shrubsole73ecede2020-07-09 13:51:39 +0200239 // Check that resource is most limited.
Evan Shrubsole64469032020-06-11 10:45:29 +0200240 std::vector<rtc::scoped_refptr<Resource>> most_limited_resources;
Evan Shrubsolece971b02020-06-12 16:00:03 +0200241 VideoStreamAdapter::RestrictionsWithCounters most_limited_restrictions;
Evan Shrubsole64469032020-06-11 10:45:29 +0200242 std::tie(most_limited_resources, most_limited_restrictions) =
243 FindMostLimitedResources();
244
Evan Shrubsole64469032020-06-11 10:45:29 +0200245 // If the most restricted resource is less limited than current restrictions
246 // then proceed with adapting up.
Evan Shrubsolece971b02020-06-12 16:00:03 +0200247 if (!most_limited_resources.empty() &&
Evan Shrubsoled7d2f272020-07-03 15:16:43 +0200248 most_limited_restrictions.counters.Total() >=
Evan Shrubsolece971b02020-06-12 16:00:03 +0200249 stream_adapter_->adaptation_counters().Total()) {
Artem Titovea240272021-07-26 12:40:21 +0200250 // If `reason_resource` is not one of the most limiting resources then abort
Evan Shrubsole64469032020-06-11 10:45:29 +0200251 // adaptation.
252 if (absl::c_find(most_limited_resources, reason_resource) ==
253 most_limited_resources.end()) {
Evan Shrubsole64469032020-06-11 10:45:29 +0200254 rtc::StringBuilder message;
255 message << "Resource \"" << reason_resource->Name()
256 << "\" was not the most limited resource.";
257 return MitigationResultAndLogMessage(
258 MitigationResult::kNotMostLimitedResource, message.Release());
259 }
260
Evan Shrubsole64469032020-06-11 10:45:29 +0200261 if (most_limited_resources.size() > 1) {
262 // If there are multiple most limited resources, all must signal underuse
263 // before the adaptation is applied.
Evan Shrubsoled7d2f272020-07-03 15:16:43 +0200264 UpdateResourceLimitations(reason_resource, adaptation.restrictions(),
265 adaptation.counters());
Evan Shrubsole64469032020-06-11 10:45:29 +0200266 rtc::StringBuilder message;
267 message << "Resource \"" << reason_resource->Name()
268 << "\" was not the only most limited resource.";
269 return MitigationResultAndLogMessage(
270 MitigationResult::kSharedMostLimitedResource, message.Release());
271 }
272 }
Henrik Boström87eece92020-04-17 18:36:19 +0200273 // Apply adaptation.
Evan Shrubsoleec0af262020-07-01 11:47:46 +0200274 stream_adapter_->ApplyAdaptation(adaptation, reason_resource);
Henrik Boströmf0eef122020-05-28 16:22:42 +0200275 rtc::StringBuilder message;
276 message << "Adapted up successfully. Unfiltered adaptations: "
277 << stream_adapter_->adaptation_counters().ToString();
278 return MitigationResultAndLogMessage(MitigationResult::kAdaptationApplied,
279 message.Release());
Henrik Boström87eece92020-04-17 18:36:19 +0200280}
281
Henrik Boströmf0eef122020-05-28 16:22:42 +0200282ResourceAdaptationProcessor::MitigationResultAndLogMessage
283ResourceAdaptationProcessor::OnResourceOveruse(
Henrik Boströmc55516d2020-05-11 16:29:22 +0200284 rtc::scoped_refptr<Resource> reason_resource) {
Evan Shrubsole85728412020-08-25 13:12:12 +0200285 RTC_DCHECK_RUN_ON(task_queue_);
Henrik Boström87eece92020-04-17 18:36:19 +0200286 // How can this stream be adapted up?
287 Adaptation adaptation = stream_adapter_->GetAdaptationDown();
Evan Shrubsolebd4a7182020-08-14 10:08:54 +0200288 if (adaptation.status() == Adaptation::Status::kLimitReached) {
289 // Add resource as most limited.
290 VideoStreamAdapter::RestrictionsWithCounters restrictions;
291 std::tie(std::ignore, restrictions) = FindMostLimitedResources();
292 UpdateResourceLimitations(reason_resource, restrictions.restrictions,
293 restrictions.counters);
294 }
Henrik Boström91aa7322020-04-28 12:24:33 +0200295 if (adaptation.status() != Adaptation::Status::kValid) {
Henrik Boströmf0eef122020-05-28 16:22:42 +0200296 rtc::StringBuilder message;
297 message << "Not adapting down because VideoStreamAdapter returned "
298 << Adaptation::StatusToString(adaptation.status());
299 return MitigationResultAndLogMessage(MitigationResult::kRejectedByAdapter,
300 message.Release());
Henrik Boström91aa7322020-04-28 12:24:33 +0200301 }
Henrik Boström87eece92020-04-17 18:36:19 +0200302 // Apply adaptation.
Evan Shrubsoled7d2f272020-07-03 15:16:43 +0200303 UpdateResourceLimitations(reason_resource, adaptation.restrictions(),
304 adaptation.counters());
Evan Shrubsoledc4d4222020-07-09 11:47:10 +0200305 stream_adapter_->ApplyAdaptation(adaptation, reason_resource);
Henrik Boströmf0eef122020-05-28 16:22:42 +0200306 rtc::StringBuilder message;
307 message << "Adapted down successfully. Unfiltered adaptations: "
308 << stream_adapter_->adaptation_counters().ToString();
309 return MitigationResultAndLogMessage(MitigationResult::kAdaptationApplied,
310 message.Release());
Henrik Boström87eece92020-04-17 18:36:19 +0200311}
312
Evan Shrubsolece971b02020-06-12 16:00:03 +0200313std::pair<std::vector<rtc::scoped_refptr<Resource>>,
314 VideoStreamAdapter::RestrictionsWithCounters>
Evan Shrubsole64469032020-06-11 10:45:29 +0200315ResourceAdaptationProcessor::FindMostLimitedResources() const {
316 std::vector<rtc::scoped_refptr<Resource>> most_limited_resources;
Evan Shrubsolece971b02020-06-12 16:00:03 +0200317 VideoStreamAdapter::RestrictionsWithCounters most_limited_restrictions{
318 VideoSourceRestrictions(), VideoAdaptationCounters()};
Evan Shrubsole0dcb4702020-05-07 13:45:14 +0200319
Evan Shrubsole64469032020-06-11 10:45:29 +0200320 for (const auto& resource_and_adaptation_limit_ :
321 adaptation_limits_by_resources_) {
Evan Shrubsolece971b02020-06-12 16:00:03 +0200322 const auto& restrictions_with_counters =
Evan Shrubsole64469032020-06-11 10:45:29 +0200323 resource_and_adaptation_limit_.second;
Evan Shrubsoled7d2f272020-07-03 15:16:43 +0200324 if (restrictions_with_counters.counters.Total() >
325 most_limited_restrictions.counters.Total()) {
Evan Shrubsolece971b02020-06-12 16:00:03 +0200326 most_limited_restrictions = restrictions_with_counters;
Evan Shrubsole64469032020-06-11 10:45:29 +0200327 most_limited_resources.clear();
328 most_limited_resources.push_back(resource_and_adaptation_limit_.first);
Evan Shrubsoled7d2f272020-07-03 15:16:43 +0200329 } else if (most_limited_restrictions.counters ==
330 restrictions_with_counters.counters) {
Evan Shrubsole64469032020-06-11 10:45:29 +0200331 most_limited_resources.push_back(resource_and_adaptation_limit_.first);
332 }
333 }
334 return std::make_pair(std::move(most_limited_resources),
335 most_limited_restrictions);
Evan Shrubsole0dcb4702020-05-07 13:45:14 +0200336}
337
Evan Shrubsole64469032020-06-11 10:45:29 +0200338void ResourceAdaptationProcessor::UpdateResourceLimitations(
339 rtc::scoped_refptr<Resource> reason_resource,
Evan Shrubsoled7d2f272020-07-03 15:16:43 +0200340 const VideoSourceRestrictions& restrictions,
341 const VideoAdaptationCounters& counters) {
Evan Shrubsoleec0af262020-07-01 11:47:46 +0200342 auto& adaptation_limits = adaptation_limits_by_resources_[reason_resource];
Evan Shrubsoled7d2f272020-07-03 15:16:43 +0200343 if (adaptation_limits.restrictions == restrictions &&
344 adaptation_limits.counters == counters) {
Evan Shrubsoleec0af262020-07-01 11:47:46 +0200345 return;
346 }
Evan Shrubsoled7d2f272020-07-03 15:16:43 +0200347 adaptation_limits = {restrictions, counters};
Evan Shrubsolece971b02020-06-12 16:00:03 +0200348
349 std::map<rtc::scoped_refptr<Resource>, VideoAdaptationCounters> limitations;
350 for (const auto& p : adaptation_limits_by_resources_) {
Evan Shrubsoled7d2f272020-07-03 15:16:43 +0200351 limitations.insert(std::make_pair(p.first, p.second.counters));
Evan Shrubsolece971b02020-06-12 16:00:03 +0200352 }
Evan Shrubsoleec0af262020-07-01 11:47:46 +0200353 for (auto limitations_listener : resource_limitations_listeners_) {
354 limitations_listener->OnResourceLimitationChanged(reason_resource,
355 limitations);
Evan Shrubsolece971b02020-06-12 16:00:03 +0200356 }
357}
358
Evan Shrubsoleec0af262020-07-01 11:47:46 +0200359void ResourceAdaptationProcessor::OnVideoSourceRestrictionsUpdated(
360 VideoSourceRestrictions restrictions,
361 const VideoAdaptationCounters& adaptation_counters,
362 rtc::scoped_refptr<Resource> reason,
363 const VideoSourceRestrictions& unfiltered_restrictions) {
Evan Shrubsole85728412020-08-25 13:12:12 +0200364 RTC_DCHECK_RUN_ON(task_queue_);
Evan Shrubsoleec0af262020-07-01 11:47:46 +0200365 if (reason) {
Evan Shrubsoled7d2f272020-07-03 15:16:43 +0200366 UpdateResourceLimitations(reason, unfiltered_restrictions,
367 adaptation_counters);
Evan Shrubsoleec0af262020-07-01 11:47:46 +0200368 } else if (adaptation_counters.Total() == 0) {
369 // Adaptations are cleared.
370 adaptation_limits_by_resources_.clear();
371 previous_mitigation_results_.clear();
372 for (auto limitations_listener : resource_limitations_listeners_) {
373 limitations_listener->OnResourceLimitationChanged(nullptr, {});
374 }
375 }
Evan Shrubsole0dcb4702020-05-07 13:45:14 +0200376}
377
Henrik Boström87eece92020-04-17 18:36:19 +0200378} // namespace webrtc