blob: f9dec8946e8907e0f034726eaf9041dda0b65dd5 [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#ifndef CALL_ADAPTATION_RESOURCE_ADAPTATION_PROCESSOR_H_
12#define CALL_ADAPTATION_RESOURCE_ADAPTATION_PROCESSOR_H_
13
Evan Shrubsole0dcb4702020-05-07 13:45:14 +020014#include <map>
Henrik Boström87eece92020-04-17 18:36:19 +020015#include <memory>
Henrik Boströmf0eef122020-05-28 16:22:42 +020016#include <string>
Evan Shrubsole64469032020-06-11 10:45:29 +020017#include <utility>
Henrik Boström87eece92020-04-17 18:36:19 +020018#include <vector>
19
20#include "absl/types/optional.h"
Henrik Boströme2e8c172020-06-03 09:24:06 +020021#include "api/adaptation/resource.h"
Henrik Boström87eece92020-04-17 18:36:19 +020022#include "api/rtp_parameters.h"
Henrik Boströmc55516d2020-05-11 16:29:22 +020023#include "api/scoped_refptr.h"
Henrik Boström39ab1b52020-06-03 09:21:34 +020024#include "api/task_queue/task_queue_base.h"
Henrik Boström87eece92020-04-17 18:36:19 +020025#include "api/video/video_frame.h"
26#include "api/video/video_stream_encoder_observer.h"
Henrik Boström0f0aa9c2020-06-02 13:02:36 +020027#include "call/adaptation/adaptation_constraint.h"
28#include "call/adaptation/adaptation_listener.h"
Henrik Boström87eece92020-04-17 18:36:19 +020029#include "call/adaptation/resource_adaptation_processor_interface.h"
30#include "call/adaptation/video_source_restrictions.h"
31#include "call/adaptation/video_stream_adapter.h"
32#include "call/adaptation/video_stream_input_state.h"
33#include "call/adaptation/video_stream_input_state_provider.h"
34
35namespace webrtc {
36
Henrik Boströmc55516d2020-05-11 16:29:22 +020037// The Resource Adaptation Processor is responsible for reacting to resource
38// usage measurements (e.g. overusing or underusing CPU). When a resource is
39// overused the Processor is responsible for performing mitigations in order to
40// consume less resources.
41//
42// Today we have one Processor per VideoStreamEncoder and the Processor is only
43// capable of restricting resolution or frame rate of the encoded stream. In the
44// future we should have a single Processor responsible for all encoded streams,
45// and it should be capable of reconfiguring other things than just
46// VideoSourceRestrictions (e.g. reduce render frame rate).
47// See Resource-Adaptation hotlist:
48// https://bugs.chromium.org/u/590058293/hotlists/Resource-Adaptation
49//
50// The ResourceAdaptationProcessor is single-threaded. It may be constructed on
51// any thread but MUST subsequently be used and destroyed on a single sequence,
52// i.e. the "resource adaptation task queue".
Henrik Boström87eece92020-04-17 18:36:19 +020053class ResourceAdaptationProcessor : public ResourceAdaptationProcessorInterface,
Evan Shrubsoleec0af262020-07-01 11:47:46 +020054 public VideoSourceRestrictionsListener,
Henrik Boström87eece92020-04-17 18:36:19 +020055 public ResourceListener {
56 public:
57 ResourceAdaptationProcessor(
58 VideoStreamInputStateProvider* input_state_provider,
Evan Shrubsoleec0af262020-07-01 11:47:46 +020059 VideoStreamEncoderObserver* encoder_stats_observer,
60 VideoStreamAdapter* video_stream_adapter);
Henrik Boström87eece92020-04-17 18:36:19 +020061 ~ResourceAdaptationProcessor() override;
62
Henrik Boström39ab1b52020-06-03 09:21:34 +020063 void SetResourceAdaptationQueue(
64 TaskQueueBase* resource_adaptation_queue) override;
Henrik Boströmc55516d2020-05-11 16:29:22 +020065
Henrik Boström87eece92020-04-17 18:36:19 +020066 // ResourceAdaptationProcessorInterface implementation.
67 DegradationPreference degradation_preference() const override;
68 DegradationPreference effective_degradation_preference() const override;
69
Evan Shrubsoleec0af262020-07-01 11:47:46 +020070 void AddResourceLimitationsListener(
71 ResourceLimitationsListener* limitations_listener) override;
72 void RemoveResourceLimitationsListener(
73 ResourceLimitationsListener* limitations_listener) override;
Henrik Boströmc55516d2020-05-11 16:29:22 +020074 void AddResource(rtc::scoped_refptr<Resource> resource) override;
Henrik Boströmf4a99912020-06-11 12:07:14 +020075 std::vector<rtc::scoped_refptr<Resource>> GetResources() const override;
Henrik Boströmc55516d2020-05-11 16:29:22 +020076 void RemoveResource(rtc::scoped_refptr<Resource> resource) override;
Henrik Boström0f0aa9c2020-06-02 13:02:36 +020077 void AddAdaptationConstraint(
78 AdaptationConstraint* adaptation_constraint) override;
79 void RemoveAdaptationConstraint(
80 AdaptationConstraint* adaptation_constraint) override;
81 void AddAdaptationListener(AdaptationListener* adaptation_listener) override;
82 void RemoveAdaptationListener(
83 AdaptationListener* adaptation_listener) override;
Henrik Boström87eece92020-04-17 18:36:19 +020084
85 void SetDegradationPreference(
86 DegradationPreference degradation_preference) override;
87 void SetIsScreenshare(bool is_screenshare) override;
Henrik Boström87eece92020-04-17 18:36:19 +020088
89 // ResourceListener implementation.
90 // Triggers OnResourceUnderuse() or OnResourceOveruse().
Henrik Boström39ab1b52020-06-03 09:21:34 +020091 void OnResourceUsageStateMeasured(rtc::scoped_refptr<Resource> resource,
92 ResourceUsageState usage_state) override;
Henrik Boström87eece92020-04-17 18:36:19 +020093
Evan Shrubsoleec0af262020-07-01 11:47:46 +020094 // VideoSourceRestrictionsListener implementation.
95 void OnVideoSourceRestrictionsUpdated(
96 VideoSourceRestrictions restrictions,
97 const VideoAdaptationCounters& adaptation_counters,
98 rtc::scoped_refptr<Resource> reason,
99 const VideoSourceRestrictions& unfiltered_restrictions) override;
100
Henrik Boström3745d3f2020-04-30 10:13:29 +0200101 // May trigger 1-2 adaptations. It is meant to reduce resolution but this is
102 // not guaranteed. It may adapt frame rate, which does not address the issue.
103 // TODO(hbos): Can we get rid of this?
Henrik Boström87eece92020-04-17 18:36:19 +0200104 void TriggerAdaptationDueToFrameDroppedDueToSize(
Henrik Boströmc55516d2020-05-11 16:29:22 +0200105 rtc::scoped_refptr<Resource> reason_resource) override;
Henrik Boström87eece92020-04-17 18:36:19 +0200106
107 private:
108 bool HasSufficientInputForAdaptation(
109 const VideoStreamInputState& input_state) const;
110
Henrik Boström39ab1b52020-06-03 09:21:34 +0200111 // If resource usage measurements happens off the adaptation task queue, this
112 // class takes care of posting the measurement for the processor to handle it
113 // on the adaptation task queue.
114 class ResourceListenerDelegate : public rtc::RefCountInterface,
115 public ResourceListener {
116 public:
117 explicit ResourceListenerDelegate(ResourceAdaptationProcessor* processor);
118
119 void SetResourceAdaptationQueue(TaskQueueBase* resource_adaptation_queue);
120 void OnProcessorDestroyed();
121
122 // ResourceListener implementation.
123 void OnResourceUsageStateMeasured(rtc::scoped_refptr<Resource> resource,
124 ResourceUsageState usage_state) override;
125
126 private:
127 TaskQueueBase* resource_adaptation_queue_;
128 ResourceAdaptationProcessor* processor_
129 RTC_GUARDED_BY(resource_adaptation_queue_);
130 };
131
Henrik Boströmf0eef122020-05-28 16:22:42 +0200132 enum class MitigationResult {
133 kDisabled,
134 kInsufficientInput,
Evan Shrubsole64469032020-06-11 10:45:29 +0200135 kNotMostLimitedResource,
136 kSharedMostLimitedResource,
Henrik Boströmf0eef122020-05-28 16:22:42 +0200137 kRejectedByAdapter,
Henrik Boström0f0aa9c2020-06-02 13:02:36 +0200138 kRejectedByConstraint,
Henrik Boströmf0eef122020-05-28 16:22:42 +0200139 kAdaptationApplied,
140 };
141
142 struct MitigationResultAndLogMessage {
143 MitigationResultAndLogMessage();
144 MitigationResultAndLogMessage(MitigationResult result, std::string message);
145 MitigationResult result;
146 std::string message;
147 };
148
Henrik Boström87eece92020-04-17 18:36:19 +0200149 // Performs the adaptation by getting the next target, applying it and
150 // informing listeners of the new VideoSourceRestriction and adaptation
151 // counters.
Henrik Boströmf0eef122020-05-28 16:22:42 +0200152 MitigationResultAndLogMessage OnResourceUnderuse(
153 rtc::scoped_refptr<Resource> reason_resource);
154 MitigationResultAndLogMessage OnResourceOveruse(
155 rtc::scoped_refptr<Resource> reason_resource);
Henrik Boström87eece92020-04-17 18:36:19 +0200156
157 // Needs to be invoked any time |degradation_preference_| or |is_screenshare_|
158 // changes to ensure |effective_degradation_preference_| is up-to-date.
159 void MaybeUpdateEffectiveDegradationPreference();
Evan Shrubsole64469032020-06-11 10:45:29 +0200160
161 void UpdateResourceLimitations(
162 rtc::scoped_refptr<Resource> reason_resource,
163 const VideoStreamAdapter::RestrictionsWithCounters&
164 peek_next_restrictions) RTC_RUN_ON(resource_adaptation_queue_);
165
166 // Searches |adaptation_limits_by_resources_| for each resource with the
167 // highest total adaptation counts. Adaptation up may only occur if the
168 // resource performing the adaptation is the only most limited resource. This
169 // function returns the list of all most limited resources as well as the
170 // corresponding adaptation of that resource.
Evan Shrubsolece971b02020-06-12 16:00:03 +0200171 std::pair<std::vector<rtc::scoped_refptr<Resource>>,
172 VideoStreamAdapter::RestrictionsWithCounters>
Evan Shrubsole64469032020-06-11 10:45:29 +0200173 FindMostLimitedResources() const RTC_RUN_ON(resource_adaptation_queue_);
Henrik Boström87eece92020-04-17 18:36:19 +0200174
Evan Shrubsolece971b02020-06-12 16:00:03 +0200175 void MaybeUpdateResourceLimitationsOnResourceRemoval(
176 VideoStreamAdapter::RestrictionsWithCounters removed_limitations)
177 RTC_RUN_ON(resource_adaptation_queue_);
178
Henrik Boström39ab1b52020-06-03 09:21:34 +0200179 TaskQueueBase* resource_adaptation_queue_;
180 rtc::scoped_refptr<ResourceListenerDelegate> resource_listener_delegate_;
Henrik Boström87eece92020-04-17 18:36:19 +0200181 // Input and output.
Henrik Boströmc55516d2020-05-11 16:29:22 +0200182 VideoStreamInputStateProvider* const input_state_provider_
Henrik Boström39ab1b52020-06-03 09:21:34 +0200183 RTC_GUARDED_BY(resource_adaptation_queue_);
Henrik Boströmc55516d2020-05-11 16:29:22 +0200184 VideoStreamEncoderObserver* const encoder_stats_observer_
Henrik Boström39ab1b52020-06-03 09:21:34 +0200185 RTC_GUARDED_BY(resource_adaptation_queue_);
Evan Shrubsoleec0af262020-07-01 11:47:46 +0200186 std::vector<ResourceLimitationsListener*> resource_limitations_listeners_
Henrik Boström39ab1b52020-06-03 09:21:34 +0200187 RTC_GUARDED_BY(resource_adaptation_queue_);
Henrik Boströmc55516d2020-05-11 16:29:22 +0200188 std::vector<rtc::scoped_refptr<Resource>> resources_
Henrik Boström39ab1b52020-06-03 09:21:34 +0200189 RTC_GUARDED_BY(resource_adaptation_queue_);
Henrik Boström0f0aa9c2020-06-02 13:02:36 +0200190 std::vector<AdaptationConstraint*> adaptation_constraints_
Henrik Boström39ab1b52020-06-03 09:21:34 +0200191 RTC_GUARDED_BY(resource_adaptation_queue_);
Henrik Boström0f0aa9c2020-06-02 13:02:36 +0200192 std::vector<AdaptationListener*> adaptation_listeners_
Henrik Boström39ab1b52020-06-03 09:21:34 +0200193 RTC_GUARDED_BY(resource_adaptation_queue_);
Henrik Boströmc55516d2020-05-11 16:29:22 +0200194 // Purely used for statistics, does not ensure mapped resources stay alive.
Evan Shrubsolece971b02020-06-12 16:00:03 +0200195 std::map<rtc::scoped_refptr<Resource>,
196 VideoStreamAdapter::RestrictionsWithCounters>
Evan Shrubsole64469032020-06-11 10:45:29 +0200197 adaptation_limits_by_resources_
198 RTC_GUARDED_BY(resource_adaptation_queue_);
Henrik Boström87eece92020-04-17 18:36:19 +0200199 // Adaptation strategy settings.
Henrik Boströmc55516d2020-05-11 16:29:22 +0200200 DegradationPreference degradation_preference_
Henrik Boström39ab1b52020-06-03 09:21:34 +0200201 RTC_GUARDED_BY(resource_adaptation_queue_);
Henrik Boströmc55516d2020-05-11 16:29:22 +0200202 DegradationPreference effective_degradation_preference_
Henrik Boström39ab1b52020-06-03 09:21:34 +0200203 RTC_GUARDED_BY(resource_adaptation_queue_);
204 bool is_screenshare_ RTC_GUARDED_BY(resource_adaptation_queue_);
Henrik Boström87eece92020-04-17 18:36:19 +0200205 // Responsible for generating and applying possible adaptations.
Evan Shrubsoleec0af262020-07-01 11:47:46 +0200206 VideoStreamAdapter* const stream_adapter_
Henrik Boström39ab1b52020-06-03 09:21:34 +0200207 RTC_GUARDED_BY(resource_adaptation_queue_);
Henrik Boströmc55516d2020-05-11 16:29:22 +0200208 VideoSourceRestrictions last_reported_source_restrictions_
Henrik Boström39ab1b52020-06-03 09:21:34 +0200209 RTC_GUARDED_BY(resource_adaptation_queue_);
Henrik Boströmf0eef122020-05-28 16:22:42 +0200210 // Keeps track of previous mitigation results per resource since the last
211 // successful adaptation. Used to avoid RTC_LOG spam.
212 std::map<Resource*, MitigationResult> previous_mitigation_results_
Henrik Boström39ab1b52020-06-03 09:21:34 +0200213 RTC_GUARDED_BY(resource_adaptation_queue_);
Henrik Boström91aa7322020-04-28 12:24:33 +0200214 // Prevents recursion.
215 //
216 // This is used to prevent triggering resource adaptation in the process of
217 // already handling resouce adaptation, since that could cause the same states
218 // to be modified in unexpected ways. Example:
219 //
220 // Resource::OnResourceUsageStateMeasured() ->
221 // ResourceAdaptationProcessor::OnResourceOveruse() ->
222 // Resource::OnAdaptationApplied() ->
223 // Resource::OnResourceUsageStateMeasured() ->
224 // ResourceAdaptationProcessor::OnResourceOveruse() // Boom, not allowed.
Henrik Boström39ab1b52020-06-03 09:21:34 +0200225 bool processing_in_progress_ RTC_GUARDED_BY(resource_adaptation_queue_);
Henrik Boström87eece92020-04-17 18:36:19 +0200226};
227
228} // namespace webrtc
229
230#endif // CALL_ADAPTATION_RESOURCE_ADAPTATION_PROCESSOR_H_