blob: ca2fec08c3f6d336778fe57e902a0ccace49294b [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"
Evan Shrubsoled7d2f272020-07-03 15:16:43 +020025#include "api/video/video_adaptation_counters.h"
Henrik Boström87eece92020-04-17 18:36:19 +020026#include "api/video/video_frame.h"
27#include "api/video/video_stream_encoder_observer.h"
Henrik Boström87eece92020-04-17 18:36:19 +020028#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
34namespace webrtc {
35
Henrik Boströmc55516d2020-05-11 16:29:22 +020036// 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 Shrubsole517f81e2020-07-09 13:35:33 +020051// i.e. the "resource adaptation task queue". Resources can be added and removed
52// from any thread.
Henrik Boström87eece92020-04-17 18:36:19 +020053class ResourceAdaptationProcessor : public ResourceAdaptationProcessorInterface,
Evan Shrubsoleec0af262020-07-01 11:47:46 +020054 public VideoSourceRestrictionsListener,
Evan Shrubsole3444a492020-07-07 09:04:34 +020055 public ResourceListener {
Henrik Boström87eece92020-04-17 18:36:19 +020056 public:
Evan Shrubsoled73d4212020-08-17 11:10:45 +020057 explicit ResourceAdaptationProcessor(
Evan Shrubsoleec0af262020-07-01 11:47:46 +020058 VideoStreamAdapter* video_stream_adapter);
Henrik Boström87eece92020-04-17 18:36:19 +020059 ~ResourceAdaptationProcessor() override;
60
61 // ResourceAdaptationProcessorInterface implementation.
Evan Shrubsoleec0af262020-07-01 11:47:46 +020062 void AddResourceLimitationsListener(
63 ResourceLimitationsListener* limitations_listener) override;
64 void RemoveResourceLimitationsListener(
65 ResourceLimitationsListener* limitations_listener) override;
Henrik Boströmc55516d2020-05-11 16:29:22 +020066 void AddResource(rtc::scoped_refptr<Resource> resource) override;
Henrik Boströmf4a99912020-06-11 12:07:14 +020067 std::vector<rtc::scoped_refptr<Resource>> GetResources() const override;
Henrik Boströmc55516d2020-05-11 16:29:22 +020068 void RemoveResource(rtc::scoped_refptr<Resource> resource) override;
Henrik Boström87eece92020-04-17 18:36:19 +020069
Henrik Boström87eece92020-04-17 18:36:19 +020070 // ResourceListener implementation.
71 // Triggers OnResourceUnderuse() or OnResourceOveruse().
Henrik Boström39ab1b52020-06-03 09:21:34 +020072 void OnResourceUsageStateMeasured(rtc::scoped_refptr<Resource> resource,
73 ResourceUsageState usage_state) override;
Henrik Boström87eece92020-04-17 18:36:19 +020074
Evan Shrubsoleec0af262020-07-01 11:47:46 +020075 // 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öm87eece92020-04-17 18:36:19 +020082 private:
Henrik Boström39ab1b52020-06-03 09:21:34 +020083 // 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öm39ab1b52020-06-03 09:21:34 +020091 void OnProcessorDestroyed();
92
93 // ResourceListener implementation.
94 void OnResourceUsageStateMeasured(rtc::scoped_refptr<Resource> resource,
95 ResourceUsageState usage_state) override;
96
97 private:
Evan Shrubsole85728412020-08-25 13:12:12 +020098 TaskQueueBase* task_queue_;
99 ResourceAdaptationProcessor* processor_ RTC_GUARDED_BY(task_queue_);
Henrik Boström39ab1b52020-06-03 09:21:34 +0200100 };
101
Henrik Boströmf0eef122020-05-28 16:22:42 +0200102 enum class MitigationResult {
Evan Shrubsole64469032020-06-11 10:45:29 +0200103 kNotMostLimitedResource,
104 kSharedMostLimitedResource,
Henrik Boströmf0eef122020-05-28 16:22:42 +0200105 kRejectedByAdapter,
Henrik Boströmf0eef122020-05-28 16:22:42 +0200106 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öm87eece92020-04-17 18:36:19 +0200116 // Performs the adaptation by getting the next target, applying it and
117 // informing listeners of the new VideoSourceRestriction and adaptation
118 // counters.
Henrik Boströmf0eef122020-05-28 16:22:42 +0200119 MitigationResultAndLogMessage OnResourceUnderuse(
120 rtc::scoped_refptr<Resource> reason_resource);
121 MitigationResultAndLogMessage OnResourceOveruse(
122 rtc::scoped_refptr<Resource> reason_resource);
Henrik Boström87eece92020-04-17 18:36:19 +0200123
Evan Shrubsoled7d2f272020-07-03 15:16:43 +0200124 void UpdateResourceLimitations(rtc::scoped_refptr<Resource> reason_resource,
125 const VideoSourceRestrictions& restrictions,
126 const VideoAdaptationCounters& counters)
Evan Shrubsole85728412020-08-25 13:12:12 +0200127 RTC_RUN_ON(task_queue_);
Evan Shrubsole64469032020-06-11 10:45:29 +0200128
Artem Titovea240272021-07-26 12:40:21 +0200129 // Searches `adaptation_limits_by_resources_` for each resource with the
Evan Shrubsole64469032020-06-11 10:45:29 +0200130 // 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 Shrubsolece971b02020-06-12 16:00:03 +0200134 std::pair<std::vector<rtc::scoped_refptr<Resource>>,
135 VideoStreamAdapter::RestrictionsWithCounters>
Evan Shrubsole85728412020-08-25 13:12:12 +0200136 FindMostLimitedResources() const RTC_RUN_ON(task_queue_);
Henrik Boström87eece92020-04-17 18:36:19 +0200137
Evan Shrubsole517f81e2020-07-09 13:35:33 +0200138 void RemoveLimitationsImposedByResource(
139 rtc::scoped_refptr<Resource> resource);
Evan Shrubsolece971b02020-06-12 16:00:03 +0200140
Evan Shrubsole85728412020-08-25 13:12:12 +0200141 TaskQueueBase* task_queue_;
Henrik Boström39ab1b52020-06-03 09:21:34 +0200142 rtc::scoped_refptr<ResourceListenerDelegate> resource_listener_delegate_;
Henrik Boström87eece92020-04-17 18:36:19 +0200143 // Input and output.
Evan Shrubsole517f81e2020-07-09 13:35:33 +0200144 mutable Mutex resources_lock_;
Henrik Boströmc55516d2020-05-11 16:29:22 +0200145 std::vector<rtc::scoped_refptr<Resource>> resources_
Evan Shrubsole517f81e2020-07-09 13:35:33 +0200146 RTC_GUARDED_BY(resources_lock_);
147 std::vector<ResourceLimitationsListener*> resource_limitations_listeners_
Evan Shrubsole85728412020-08-25 13:12:12 +0200148 RTC_GUARDED_BY(task_queue_);
Henrik Boströmc55516d2020-05-11 16:29:22 +0200149 // Purely used for statistics, does not ensure mapped resources stay alive.
Evan Shrubsolece971b02020-06-12 16:00:03 +0200150 std::map<rtc::scoped_refptr<Resource>,
151 VideoStreamAdapter::RestrictionsWithCounters>
Evan Shrubsole85728412020-08-25 13:12:12 +0200152 adaptation_limits_by_resources_ RTC_GUARDED_BY(task_queue_);
Henrik Boström87eece92020-04-17 18:36:19 +0200153 // Responsible for generating and applying possible adaptations.
Evan Shrubsole85728412020-08-25 13:12:12 +0200154 VideoStreamAdapter* const stream_adapter_ RTC_GUARDED_BY(task_queue_);
Henrik Boströmc55516d2020-05-11 16:29:22 +0200155 VideoSourceRestrictions last_reported_source_restrictions_
Evan Shrubsole85728412020-08-25 13:12:12 +0200156 RTC_GUARDED_BY(task_queue_);
Henrik Boströmf0eef122020-05-28 16:22:42 +0200157 // 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 Shrubsole85728412020-08-25 13:12:12 +0200160 RTC_GUARDED_BY(task_queue_);
Henrik Boström87eece92020-04-17 18:36:19 +0200161};
162
163} // namespace webrtc
164
165#endif // CALL_ADAPTATION_RESOURCE_ADAPTATION_PROCESSOR_H_