Henrik Boström | 87eece9 | 2020-04-17 18:36:19 +0200 | [diff] [blame] | 1 | /* |
| 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 Shrubsole | 0dcb470 | 2020-05-07 13:45:14 +0200 | [diff] [blame] | 14 | #include <map> |
Henrik Boström | 87eece9 | 2020-04-17 18:36:19 +0200 | [diff] [blame] | 15 | #include <memory> |
Henrik Boström | f0eef12 | 2020-05-28 16:22:42 +0200 | [diff] [blame] | 16 | #include <string> |
Evan Shrubsole | 6446903 | 2020-06-11 10:45:29 +0200 | [diff] [blame] | 17 | #include <utility> |
Henrik Boström | 87eece9 | 2020-04-17 18:36:19 +0200 | [diff] [blame] | 18 | #include <vector> |
| 19 | |
| 20 | #include "absl/types/optional.h" |
Henrik Boström | e2e8c17 | 2020-06-03 09:24:06 +0200 | [diff] [blame] | 21 | #include "api/adaptation/resource.h" |
Henrik Boström | 87eece9 | 2020-04-17 18:36:19 +0200 | [diff] [blame] | 22 | #include "api/rtp_parameters.h" |
Henrik Boström | c55516d | 2020-05-11 16:29:22 +0200 | [diff] [blame] | 23 | #include "api/scoped_refptr.h" |
Henrik Boström | 39ab1b5 | 2020-06-03 09:21:34 +0200 | [diff] [blame] | 24 | #include "api/task_queue/task_queue_base.h" |
Evan Shrubsole | d7d2f27 | 2020-07-03 15:16:43 +0200 | [diff] [blame] | 25 | #include "api/video/video_adaptation_counters.h" |
Henrik Boström | 87eece9 | 2020-04-17 18:36:19 +0200 | [diff] [blame] | 26 | #include "api/video/video_frame.h" |
| 27 | #include "api/video/video_stream_encoder_observer.h" |
Henrik Boström | 87eece9 | 2020-04-17 18:36:19 +0200 | [diff] [blame] | 28 | #include "call/adaptation/resource_adaptation_processor_interface.h" |
| 29 | #include "call/adaptation/video_source_restrictions.h" |
| 30 | #include "call/adaptation/video_stream_adapter.h" |
| 31 | #include "call/adaptation/video_stream_input_state.h" |
| 32 | #include "call/adaptation/video_stream_input_state_provider.h" |
| 33 | |
| 34 | namespace webrtc { |
| 35 | |
Henrik Boström | c55516d | 2020-05-11 16:29:22 +0200 | [diff] [blame] | 36 | // The Resource Adaptation Processor is responsible for reacting to resource |
| 37 | // usage measurements (e.g. overusing or underusing CPU). When a resource is |
| 38 | // overused the Processor is responsible for performing mitigations in order to |
| 39 | // consume less resources. |
| 40 | // |
| 41 | // Today we have one Processor per VideoStreamEncoder and the Processor is only |
| 42 | // capable of restricting resolution or frame rate of the encoded stream. In the |
| 43 | // future we should have a single Processor responsible for all encoded streams, |
| 44 | // and it should be capable of reconfiguring other things than just |
| 45 | // VideoSourceRestrictions (e.g. reduce render frame rate). |
| 46 | // See Resource-Adaptation hotlist: |
| 47 | // https://bugs.chromium.org/u/590058293/hotlists/Resource-Adaptation |
| 48 | // |
| 49 | // The ResourceAdaptationProcessor is single-threaded. It may be constructed on |
| 50 | // any thread but MUST subsequently be used and destroyed on a single sequence, |
Evan Shrubsole | 517f81e | 2020-07-09 13:35:33 +0200 | [diff] [blame] | 51 | // i.e. the "resource adaptation task queue". Resources can be added and removed |
| 52 | // from any thread. |
Henrik Boström | 87eece9 | 2020-04-17 18:36:19 +0200 | [diff] [blame] | 53 | class ResourceAdaptationProcessor : public ResourceAdaptationProcessorInterface, |
Evan Shrubsole | ec0af26 | 2020-07-01 11:47:46 +0200 | [diff] [blame] | 54 | public VideoSourceRestrictionsListener, |
Evan Shrubsole | 3444a49 | 2020-07-07 09:04:34 +0200 | [diff] [blame] | 55 | public ResourceListener { |
Henrik Boström | 87eece9 | 2020-04-17 18:36:19 +0200 | [diff] [blame] | 56 | public: |
Evan Shrubsole | d73d421 | 2020-08-17 11:10:45 +0200 | [diff] [blame] | 57 | explicit ResourceAdaptationProcessor( |
Evan Shrubsole | ec0af26 | 2020-07-01 11:47:46 +0200 | [diff] [blame] | 58 | VideoStreamAdapter* video_stream_adapter); |
Henrik Boström | 87eece9 | 2020-04-17 18:36:19 +0200 | [diff] [blame] | 59 | ~ResourceAdaptationProcessor() override; |
| 60 | |
| 61 | // ResourceAdaptationProcessorInterface implementation. |
Evan Shrubsole | ec0af26 | 2020-07-01 11:47:46 +0200 | [diff] [blame] | 62 | void AddResourceLimitationsListener( |
| 63 | ResourceLimitationsListener* limitations_listener) override; |
| 64 | void RemoveResourceLimitationsListener( |
| 65 | ResourceLimitationsListener* limitations_listener) override; |
Henrik Boström | c55516d | 2020-05-11 16:29:22 +0200 | [diff] [blame] | 66 | void AddResource(rtc::scoped_refptr<Resource> resource) override; |
Henrik Boström | f4a9991 | 2020-06-11 12:07:14 +0200 | [diff] [blame] | 67 | std::vector<rtc::scoped_refptr<Resource>> GetResources() const override; |
Henrik Boström | c55516d | 2020-05-11 16:29:22 +0200 | [diff] [blame] | 68 | void RemoveResource(rtc::scoped_refptr<Resource> resource) override; |
Henrik Boström | 87eece9 | 2020-04-17 18:36:19 +0200 | [diff] [blame] | 69 | |
Henrik Boström | 87eece9 | 2020-04-17 18:36:19 +0200 | [diff] [blame] | 70 | // ResourceListener implementation. |
| 71 | // Triggers OnResourceUnderuse() or OnResourceOveruse(). |
Henrik Boström | 39ab1b5 | 2020-06-03 09:21:34 +0200 | [diff] [blame] | 72 | void OnResourceUsageStateMeasured(rtc::scoped_refptr<Resource> resource, |
| 73 | ResourceUsageState usage_state) override; |
Henrik Boström | 87eece9 | 2020-04-17 18:36:19 +0200 | [diff] [blame] | 74 | |
Evan Shrubsole | ec0af26 | 2020-07-01 11:47:46 +0200 | [diff] [blame] | 75 | // VideoSourceRestrictionsListener implementation. |
| 76 | void OnVideoSourceRestrictionsUpdated( |
| 77 | VideoSourceRestrictions restrictions, |
| 78 | const VideoAdaptationCounters& adaptation_counters, |
| 79 | rtc::scoped_refptr<Resource> reason, |
| 80 | const VideoSourceRestrictions& unfiltered_restrictions) override; |
| 81 | |
Henrik Boström | 87eece9 | 2020-04-17 18:36:19 +0200 | [diff] [blame] | 82 | private: |
Henrik Boström | 39ab1b5 | 2020-06-03 09:21:34 +0200 | [diff] [blame] | 83 | // If resource usage measurements happens off the adaptation task queue, this |
| 84 | // class takes care of posting the measurement for the processor to handle it |
| 85 | // on the adaptation task queue. |
| 86 | class ResourceListenerDelegate : public rtc::RefCountInterface, |
| 87 | public ResourceListener { |
| 88 | public: |
| 89 | explicit ResourceListenerDelegate(ResourceAdaptationProcessor* processor); |
| 90 | |
Henrik Boström | 39ab1b5 | 2020-06-03 09:21:34 +0200 | [diff] [blame] | 91 | void OnProcessorDestroyed(); |
| 92 | |
| 93 | // ResourceListener implementation. |
| 94 | void OnResourceUsageStateMeasured(rtc::scoped_refptr<Resource> resource, |
| 95 | ResourceUsageState usage_state) override; |
| 96 | |
| 97 | private: |
Evan Shrubsole | 8572841 | 2020-08-25 13:12:12 +0200 | [diff] [blame] | 98 | TaskQueueBase* task_queue_; |
| 99 | ResourceAdaptationProcessor* processor_ RTC_GUARDED_BY(task_queue_); |
Henrik Boström | 39ab1b5 | 2020-06-03 09:21:34 +0200 | [diff] [blame] | 100 | }; |
| 101 | |
Henrik Boström | f0eef12 | 2020-05-28 16:22:42 +0200 | [diff] [blame] | 102 | enum class MitigationResult { |
Evan Shrubsole | 6446903 | 2020-06-11 10:45:29 +0200 | [diff] [blame] | 103 | kNotMostLimitedResource, |
| 104 | kSharedMostLimitedResource, |
Henrik Boström | f0eef12 | 2020-05-28 16:22:42 +0200 | [diff] [blame] | 105 | kRejectedByAdapter, |
Henrik Boström | f0eef12 | 2020-05-28 16:22:42 +0200 | [diff] [blame] | 106 | kAdaptationApplied, |
| 107 | }; |
| 108 | |
| 109 | struct MitigationResultAndLogMessage { |
| 110 | MitigationResultAndLogMessage(); |
| 111 | MitigationResultAndLogMessage(MitigationResult result, std::string message); |
| 112 | MitigationResult result; |
| 113 | std::string message; |
| 114 | }; |
| 115 | |
Henrik Boström | 87eece9 | 2020-04-17 18:36:19 +0200 | [diff] [blame] | 116 | // Performs the adaptation by getting the next target, applying it and |
| 117 | // informing listeners of the new VideoSourceRestriction and adaptation |
| 118 | // counters. |
Henrik Boström | f0eef12 | 2020-05-28 16:22:42 +0200 | [diff] [blame] | 119 | MitigationResultAndLogMessage OnResourceUnderuse( |
| 120 | rtc::scoped_refptr<Resource> reason_resource); |
| 121 | MitigationResultAndLogMessage OnResourceOveruse( |
| 122 | rtc::scoped_refptr<Resource> reason_resource); |
Henrik Boström | 87eece9 | 2020-04-17 18:36:19 +0200 | [diff] [blame] | 123 | |
Evan Shrubsole | d7d2f27 | 2020-07-03 15:16:43 +0200 | [diff] [blame] | 124 | void UpdateResourceLimitations(rtc::scoped_refptr<Resource> reason_resource, |
| 125 | const VideoSourceRestrictions& restrictions, |
| 126 | const VideoAdaptationCounters& counters) |
Evan Shrubsole | 8572841 | 2020-08-25 13:12:12 +0200 | [diff] [blame] | 127 | RTC_RUN_ON(task_queue_); |
Evan Shrubsole | 6446903 | 2020-06-11 10:45:29 +0200 | [diff] [blame] | 128 | |
Artem Titov | ea24027 | 2021-07-26 12:40:21 +0200 | [diff] [blame] | 129 | // Searches `adaptation_limits_by_resources_` for each resource with the |
Evan Shrubsole | 6446903 | 2020-06-11 10:45:29 +0200 | [diff] [blame] | 130 | // highest total adaptation counts. Adaptation up may only occur if the |
| 131 | // resource performing the adaptation is the only most limited resource. This |
| 132 | // function returns the list of all most limited resources as well as the |
| 133 | // corresponding adaptation of that resource. |
Evan Shrubsole | ce971b0 | 2020-06-12 16:00:03 +0200 | [diff] [blame] | 134 | std::pair<std::vector<rtc::scoped_refptr<Resource>>, |
| 135 | VideoStreamAdapter::RestrictionsWithCounters> |
Evan Shrubsole | 8572841 | 2020-08-25 13:12:12 +0200 | [diff] [blame] | 136 | FindMostLimitedResources() const RTC_RUN_ON(task_queue_); |
Henrik Boström | 87eece9 | 2020-04-17 18:36:19 +0200 | [diff] [blame] | 137 | |
Evan Shrubsole | 517f81e | 2020-07-09 13:35:33 +0200 | [diff] [blame] | 138 | void RemoveLimitationsImposedByResource( |
| 139 | rtc::scoped_refptr<Resource> resource); |
Evan Shrubsole | ce971b0 | 2020-06-12 16:00:03 +0200 | [diff] [blame] | 140 | |
Evan Shrubsole | 8572841 | 2020-08-25 13:12:12 +0200 | [diff] [blame] | 141 | TaskQueueBase* task_queue_; |
Henrik Boström | 39ab1b5 | 2020-06-03 09:21:34 +0200 | [diff] [blame] | 142 | rtc::scoped_refptr<ResourceListenerDelegate> resource_listener_delegate_; |
Henrik Boström | 87eece9 | 2020-04-17 18:36:19 +0200 | [diff] [blame] | 143 | // Input and output. |
Evan Shrubsole | 517f81e | 2020-07-09 13:35:33 +0200 | [diff] [blame] | 144 | mutable Mutex resources_lock_; |
Henrik Boström | c55516d | 2020-05-11 16:29:22 +0200 | [diff] [blame] | 145 | std::vector<rtc::scoped_refptr<Resource>> resources_ |
Evan Shrubsole | 517f81e | 2020-07-09 13:35:33 +0200 | [diff] [blame] | 146 | RTC_GUARDED_BY(resources_lock_); |
| 147 | std::vector<ResourceLimitationsListener*> resource_limitations_listeners_ |
Evan Shrubsole | 8572841 | 2020-08-25 13:12:12 +0200 | [diff] [blame] | 148 | RTC_GUARDED_BY(task_queue_); |
Henrik Boström | c55516d | 2020-05-11 16:29:22 +0200 | [diff] [blame] | 149 | // Purely used for statistics, does not ensure mapped resources stay alive. |
Evan Shrubsole | ce971b0 | 2020-06-12 16:00:03 +0200 | [diff] [blame] | 150 | std::map<rtc::scoped_refptr<Resource>, |
| 151 | VideoStreamAdapter::RestrictionsWithCounters> |
Evan Shrubsole | 8572841 | 2020-08-25 13:12:12 +0200 | [diff] [blame] | 152 | adaptation_limits_by_resources_ RTC_GUARDED_BY(task_queue_); |
Henrik Boström | 87eece9 | 2020-04-17 18:36:19 +0200 | [diff] [blame] | 153 | // Responsible for generating and applying possible adaptations. |
Evan Shrubsole | 8572841 | 2020-08-25 13:12:12 +0200 | [diff] [blame] | 154 | VideoStreamAdapter* const stream_adapter_ RTC_GUARDED_BY(task_queue_); |
Henrik Boström | c55516d | 2020-05-11 16:29:22 +0200 | [diff] [blame] | 155 | VideoSourceRestrictions last_reported_source_restrictions_ |
Evan Shrubsole | 8572841 | 2020-08-25 13:12:12 +0200 | [diff] [blame] | 156 | RTC_GUARDED_BY(task_queue_); |
Henrik Boström | f0eef12 | 2020-05-28 16:22:42 +0200 | [diff] [blame] | 157 | // Keeps track of previous mitigation results per resource since the last |
| 158 | // successful adaptation. Used to avoid RTC_LOG spam. |
| 159 | std::map<Resource*, MitigationResult> previous_mitigation_results_ |
Evan Shrubsole | 8572841 | 2020-08-25 13:12:12 +0200 | [diff] [blame] | 160 | RTC_GUARDED_BY(task_queue_); |
Henrik Boström | 87eece9 | 2020-04-17 18:36:19 +0200 | [diff] [blame] | 161 | }; |
| 162 | |
| 163 | } // namespace webrtc |
| 164 | |
| 165 | #endif // CALL_ADAPTATION_RESOURCE_ADAPTATION_PROCESSOR_H_ |