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