Henrik Boström | b08882b | 2020-01-07 10:11:17 +0100 | [diff] [blame] | 1 | /* |
| 2 | * Copyright 2019 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 VIDEO_OVERUSE_FRAME_DETECTOR_RESOURCE_ADAPTATION_MODULE_H_ |
| 12 | #define VIDEO_OVERUSE_FRAME_DETECTOR_RESOURCE_ADAPTATION_MODULE_H_ |
| 13 | |
| 14 | #include <map> |
| 15 | #include <memory> |
| 16 | #include <string> |
| 17 | #include <utility> |
| 18 | #include <vector> |
| 19 | |
| 20 | #include "absl/types/optional.h" |
| 21 | #include "api/rtp_parameters.h" |
| 22 | #include "api/video/video_frame.h" |
Henrik Boström | b08882b | 2020-01-07 10:11:17 +0100 | [diff] [blame] | 23 | #include "api/video/video_source_interface.h" |
| 24 | #include "api/video/video_stream_encoder_observer.h" |
Henrik Boström | 4bab2fc | 2020-01-21 11:18:06 +0100 | [diff] [blame] | 25 | #include "api/video_codecs/video_codec.h" |
Henrik Boström | b08882b | 2020-01-07 10:11:17 +0100 | [diff] [blame] | 26 | #include "api/video_codecs/video_encoder.h" |
| 27 | #include "api/video_codecs/video_encoder_config.h" |
Henrik Boström | 48258ac | 2020-02-06 12:49:57 +0100 | [diff] [blame] | 28 | #include "call/adaptation/resource.h" |
Henrik Boström | 382cc6d | 2020-01-07 10:15:04 +0100 | [diff] [blame] | 29 | #include "call/adaptation/resource_adaptation_module_interface.h" |
Henrik Boström | b08882b | 2020-01-07 10:11:17 +0100 | [diff] [blame] | 30 | #include "rtc_base/experiments/balanced_degradation_settings.h" |
Evan Shrubsole | e331a12 | 2020-02-05 13:30:33 +0100 | [diff] [blame] | 31 | #include "rtc_base/experiments/quality_rampup_experiment.h" |
Evan Shrubsole | 7c3a1fc | 2020-02-04 16:26:38 +0100 | [diff] [blame] | 32 | #include "rtc_base/experiments/quality_scaler_settings.h" |
Evan Shrubsole | 33be9df | 2020-03-05 18:39:32 +0100 | [diff] [blame] | 33 | #include "rtc_base/strings/string_builder.h" |
Evan Shrubsole | 7c3a1fc | 2020-02-04 16:26:38 +0100 | [diff] [blame] | 34 | #include "system_wrappers/include/clock.h" |
Henrik Boström | efbec9a | 2020-03-06 10:41:25 +0100 | [diff] [blame] | 35 | #include "video/adaptation/adaptation_counters.h" |
| 36 | #include "video/adaptation/video_stream_adapter.h" |
Henrik Boström | 0653485 | 2020-02-06 14:27:00 +0100 | [diff] [blame] | 37 | #include "video/encode_usage_resource.h" |
Henrik Boström | b08882b | 2020-01-07 10:11:17 +0100 | [diff] [blame] | 38 | #include "video/overuse_frame_detector.h" |
Henrik Boström | 0653485 | 2020-02-06 14:27:00 +0100 | [diff] [blame] | 39 | #include "video/quality_scaler_resource.h" |
Henrik Boström | b08882b | 2020-01-07 10:11:17 +0100 | [diff] [blame] | 40 | |
| 41 | namespace webrtc { |
| 42 | |
Henrik Boström | 382cc6d | 2020-01-07 10:15:04 +0100 | [diff] [blame] | 43 | class VideoStreamEncoder; |
| 44 | |
Henrik Boström | b08882b | 2020-01-07 10:11:17 +0100 | [diff] [blame] | 45 | // This class is used by the VideoStreamEncoder and is responsible for adapting |
| 46 | // resolution up or down based on encode usage percent. It keeps track of video |
| 47 | // source settings, adaptation counters and may get influenced by |
| 48 | // VideoStreamEncoder's quality scaler through AdaptUp() and AdaptDown() calls. |
Henrik Boström | 07b17df | 2020-01-15 11:42:12 +0100 | [diff] [blame] | 49 | // |
| 50 | // This class is single-threaded. The caller is responsible for ensuring safe |
| 51 | // usage. |
Henrik Boström | b08882b | 2020-01-07 10:11:17 +0100 | [diff] [blame] | 52 | // TODO(hbos): Add unittests specific to this class, it is currently only tested |
| 53 | // indirectly in video_stream_encoder_unittest.cc and other tests exercising |
| 54 | // VideoStreamEncoder. |
Henrik Boström | efbec9a | 2020-03-06 10:41:25 +0100 | [diff] [blame] | 55 | // TODO(https://crbug.com/webrtc/11222): Rename this class to something more |
| 56 | // appropriate and move it to the video/adaptation/ subdirectory. |
Henrik Boström | b08882b | 2020-01-07 10:11:17 +0100 | [diff] [blame] | 57 | class OveruseFrameDetectorResourceAdaptationModule |
Henrik Boström | 48258ac | 2020-02-06 12:49:57 +0100 | [diff] [blame] | 58 | : public ResourceAdaptationModuleInterface, |
| 59 | public ResourceListener { |
Henrik Boström | b08882b | 2020-01-07 10:11:17 +0100 | [diff] [blame] | 60 | public: |
Henrik Boström | 07b17df | 2020-01-15 11:42:12 +0100 | [diff] [blame] | 61 | // The module can be constructed on any sequence, but must be initialized and |
| 62 | // used on a single sequence, e.g. the encoder queue. |
Henrik Boström | b08882b | 2020-01-07 10:11:17 +0100 | [diff] [blame] | 63 | OveruseFrameDetectorResourceAdaptationModule( |
Evan Shrubsole | 7c3a1fc | 2020-02-04 16:26:38 +0100 | [diff] [blame] | 64 | Clock* clock, |
Henrik Boström | ad515a2 | 2020-01-27 13:38:05 +0100 | [diff] [blame] | 65 | bool experiment_cpu_load_estimator, |
Henrik Boström | b08882b | 2020-01-07 10:11:17 +0100 | [diff] [blame] | 66 | std::unique_ptr<OveruseFrameDetector> overuse_detector, |
Henrik Boström | d238200 | 2020-01-10 15:44:01 +0100 | [diff] [blame] | 67 | VideoStreamEncoderObserver* encoder_stats_observer, |
| 68 | ResourceAdaptationModuleListener* adaptation_listener); |
Henrik Boström | b08882b | 2020-01-07 10:11:17 +0100 | [diff] [blame] | 69 | ~OveruseFrameDetectorResourceAdaptationModule() override; |
| 70 | |
Henrik Boström | b08882b | 2020-01-07 10:11:17 +0100 | [diff] [blame] | 71 | DegradationPreference degradation_preference() const { |
Henrik Boström | b08882b | 2020-01-07 10:11:17 +0100 | [diff] [blame] | 72 | return degradation_preference_; |
| 73 | } |
| 74 | |
Henrik Boström | 382cc6d | 2020-01-07 10:15:04 +0100 | [diff] [blame] | 75 | // ResourceAdaptationModuleInterface implementation. |
Henrik Boström | a3d4252 | 2020-01-16 13:55:29 +0100 | [diff] [blame] | 76 | void StartResourceAdaptation( |
Henrik Boström | d238200 | 2020-01-10 15:44:01 +0100 | [diff] [blame] | 77 | ResourceAdaptationModuleListener* adaptation_listener) override; |
Henrik Boström | a3d4252 | 2020-01-16 13:55:29 +0100 | [diff] [blame] | 78 | void StopResourceAdaptation() override; |
Evan Shrubsole | aa6fbc1 | 2020-02-25 16:26:01 +0100 | [diff] [blame] | 79 | // Uses a default AdaptReason of kCpu. |
| 80 | void AddResource(Resource* resource) override; |
| 81 | void AddResource(Resource* resource, |
| 82 | AdaptationObserverInterface::AdaptReason reason); |
Henrik Boström | a3d4252 | 2020-01-16 13:55:29 +0100 | [diff] [blame] | 83 | void SetHasInputVideo(bool has_input_video) override; |
| 84 | void SetDegradationPreference( |
| 85 | DegradationPreference degradation_preference) override; |
Henrik Boström | 4bab2fc | 2020-01-21 11:18:06 +0100 | [diff] [blame] | 86 | void SetEncoderSettings(EncoderSettings encoder_settings) override; |
Evan Shrubsole | 7c3a1fc | 2020-02-04 16:26:38 +0100 | [diff] [blame] | 87 | void SetStartBitrate(DataRate start_bitrate) override; |
| 88 | void SetTargetBitrate(DataRate target_bitrate) override; |
Evan Shrubsole | e331a12 | 2020-02-05 13:30:33 +0100 | [diff] [blame] | 89 | void SetEncoderRates( |
| 90 | const VideoEncoder::RateControlParameters& encoder_rates) override; |
Henrik Boström | 382cc6d | 2020-01-07 10:15:04 +0100 | [diff] [blame] | 91 | |
Henrik Boström | d4578ae | 2020-01-22 16:16:04 +0100 | [diff] [blame] | 92 | void OnFrame(const VideoFrame& frame) override; |
| 93 | void OnFrameDroppedDueToSize() override; |
Mirko Bonadei | 2e161c4 | 2020-02-20 08:45:01 +0000 | [diff] [blame] | 94 | void OnMaybeEncodeFrame() override; |
Henrik Boström | d4578ae | 2020-01-22 16:16:04 +0100 | [diff] [blame] | 95 | void OnEncodeStarted(const VideoFrame& cropped_frame, |
| 96 | int64_t time_when_first_seen_us) override; |
Evan Shrubsole | bfe3ef8 | 2020-01-30 14:29:35 +0100 | [diff] [blame] | 97 | void OnEncodeCompleted(const EncodedImage& encoded_image, |
Henrik Boström | d4578ae | 2020-01-22 16:16:04 +0100 | [diff] [blame] | 98 | int64_t time_sent_in_us, |
Henrik Boström | d4578ae | 2020-01-22 16:16:04 +0100 | [diff] [blame] | 99 | absl::optional<int> encode_duration_us) override; |
Evan Shrubsole | c809e8b | 2020-01-31 15:36:35 +0100 | [diff] [blame] | 100 | void OnFrameDropped(EncodedImageCallback::DropReason reason) override; |
Evan Shrubsole | e331a12 | 2020-02-05 13:30:33 +0100 | [diff] [blame] | 101 | |
Henrik Boström | 7875c99 | 2020-02-06 10:35:00 +0100 | [diff] [blame] | 102 | // TODO(hbos): Is dropping initial frames really just a special case of "don't |
| 103 | // encode frames right now"? Can this be part of VideoSourceRestrictions, |
| 104 | // which handles the output of the rest of the encoder settings? This is |
| 105 | // something we'll need to support for "disable video due to overuse", not |
| 106 | // initial frames. |
Evan Shrubsole | f2be3ef | 2020-02-03 10:43:31 +0100 | [diff] [blame] | 107 | bool DropInitialFrames() const; |
Henrik Boström | b08882b | 2020-01-07 10:11:17 +0100 | [diff] [blame] | 108 | |
Evan Shrubsole | c81798b | 2020-02-03 15:46:08 +0100 | [diff] [blame] | 109 | // TODO(eshr): This can be made private if we configure on |
| 110 | // SetDegredationPreference and SetEncoderSettings. |
| 111 | // (https://crbug.com/webrtc/11338) |
| 112 | void ConfigureQualityScaler(const VideoEncoder::EncoderInfo& encoder_info); |
Henrik Boström | b08882b | 2020-01-07 10:11:17 +0100 | [diff] [blame] | 113 | |
Henrik Boström | 48258ac | 2020-02-06 12:49:57 +0100 | [diff] [blame] | 114 | // ResourceUsageListener implementation. |
| 115 | ResourceListenerResponse OnResourceUsageStateMeasured( |
| 116 | const Resource& resource) override; |
| 117 | |
Evan Shrubsole | 33be9df | 2020-03-05 18:39:32 +0100 | [diff] [blame] | 118 | // For reasons of adaptation and statistics, we not only count the total |
| 119 | // number of adaptations, but we also count the number of adaptations per |
| 120 | // reason. |
| 121 | // This method takes the new total number of adaptations and allocates that to |
| 122 | // the "active" count - number of adaptations for the current reason. |
| 123 | // The "other" count is the number of adaptations for the other reason. |
| 124 | // This must be called for each adaptation step made. |
| 125 | static void OnAdaptationCountChanged( |
| 126 | const AdaptationCounters& adaptation_count, |
| 127 | AdaptationCounters* active_count, |
| 128 | AdaptationCounters* other_active); |
| 129 | |
Henrik Boström | b08882b | 2020-01-07 10:11:17 +0100 | [diff] [blame] | 130 | private: |
Henrik Boström | 8cfecac | 2020-02-07 11:29:14 +0100 | [diff] [blame] | 131 | class InitialFrameDropper; |
Henrik Boström | b08882b | 2020-01-07 10:11:17 +0100 | [diff] [blame] | 132 | |
Evan Shrubsole | aa6fbc1 | 2020-02-25 16:26:01 +0100 | [diff] [blame] | 133 | enum class State { kStopped, kStarted }; |
| 134 | |
Henrik Boström | 6038383 | 2020-02-28 09:03:53 +0100 | [diff] [blame] | 135 | // Returns a target that we are guaranteed to be able to adapt to, or null if |
| 136 | // adaptation is not desired or not possible. |
Henrik Boström | b0f2e0c | 2020-03-06 13:32:03 +0100 | [diff] [blame^] | 137 | absl::optional<VideoStreamAdapter::AdaptationTarget> GetAdaptUpTarget( |
Henrik Boström | 6038383 | 2020-02-28 09:03:53 +0100 | [diff] [blame] | 138 | int input_pixels, |
| 139 | int input_fps, |
| 140 | AdaptationObserverInterface::AdaptReason reason) const; |
Henrik Boström | b0f2e0c | 2020-03-06 13:32:03 +0100 | [diff] [blame^] | 141 | absl::optional<VideoStreamAdapter::AdaptationTarget> GetAdaptDownTarget( |
Henrik Boström | 6038383 | 2020-02-28 09:03:53 +0100 | [diff] [blame] | 142 | int input_pixels, |
| 143 | int input_fps, |
Evan Shrubsole | 33be9df | 2020-03-05 18:39:32 +0100 | [diff] [blame] | 144 | int min_pixels_per_frame) const; |
Henrik Boström | 6038383 | 2020-02-28 09:03:53 +0100 | [diff] [blame] | 145 | // Applies the |target| to |source_restrictor_|. |
Henrik Boström | b0f2e0c | 2020-03-06 13:32:03 +0100 | [diff] [blame^] | 146 | void ApplyAdaptationTarget(const VideoStreamAdapter::AdaptationTarget& target, |
| 147 | int input_pixels, |
| 148 | int input_fps, |
| 149 | int min_pixels_per_frame); |
Henrik Boström | 6038383 | 2020-02-28 09:03:53 +0100 | [diff] [blame] | 150 | |
| 151 | // Performs the adaptation by getting the next target, applying it and |
| 152 | // informing listeners of the new VideoSourceRestriction and adapt counters. |
Henrik Boström | 48258ac | 2020-02-06 12:49:57 +0100 | [diff] [blame] | 153 | void OnResourceUnderuse(AdaptationObserverInterface::AdaptReason reason); |
| 154 | ResourceListenerResponse OnResourceOveruse( |
| 155 | AdaptationObserverInterface::AdaptReason reason); |
| 156 | |
Henrik Boström | ad515a2 | 2020-01-27 13:38:05 +0100 | [diff] [blame] | 157 | CpuOveruseOptions GetCpuOveruseOptions() const; |
Henrik Boström | d4578ae | 2020-01-22 16:16:04 +0100 | [diff] [blame] | 158 | int LastInputFrameSizeOrDefault() const; |
Henrik Boström | 6038383 | 2020-02-28 09:03:53 +0100 | [diff] [blame] | 159 | int MinPixelsPerFrame() const; |
Evan Shrubsole | c81798b | 2020-02-03 15:46:08 +0100 | [diff] [blame] | 160 | VideoStreamEncoderObserver::AdaptationSteps GetActiveCounts( |
Henrik Boström | 7875c99 | 2020-02-06 10:35:00 +0100 | [diff] [blame] | 161 | AdaptationObserverInterface::AdaptReason reason); |
Henrik Boström | b0f2e0c | 2020-03-06 13:32:03 +0100 | [diff] [blame^] | 162 | VideoStreamAdapter::VideoInputMode GetVideoInputMode() const; |
Henrik Boström | 4bab2fc | 2020-01-21 11:18:06 +0100 | [diff] [blame] | 163 | |
Henrik Boström | 8234b92 | 2020-01-13 17:26:50 +0100 | [diff] [blame] | 164 | // Makes |video_source_restrictions_| up-to-date and informs the |
| 165 | // |adaptation_listener_| if restrictions are changed, allowing the listener |
| 166 | // to reconfigure the source accordingly. |
Henrik Boström | 07b17df | 2020-01-15 11:42:12 +0100 | [diff] [blame] | 167 | void MaybeUpdateVideoSourceRestrictions(); |
Henrik Boström | 7875c99 | 2020-02-06 10:35:00 +0100 | [diff] [blame] | 168 | // Calculates an up-to-date value of the target frame rate and informs the |
| 169 | // |encode_usage_resource_| of the new value. |
Henrik Boström | fae6f0e | 2020-01-20 11:16:50 +0100 | [diff] [blame] | 170 | void MaybeUpdateTargetFrameRate(); |
Henrik Boström | 8234b92 | 2020-01-13 17:26:50 +0100 | [diff] [blame] | 171 | |
Evan Shrubsole | c81798b | 2020-02-03 15:46:08 +0100 | [diff] [blame] | 172 | // Use nullopt to disable quality scaling. |
| 173 | void UpdateQualityScalerSettings( |
| 174 | absl::optional<VideoEncoder::QpThresholds> qp_thresholds); |
| 175 | |
Henrik Boström | 7875c99 | 2020-02-06 10:35:00 +0100 | [diff] [blame] | 176 | void UpdateAdaptationStats(AdaptationObserverInterface::AdaptReason reason); |
Henrik Boström | b08882b | 2020-01-07 10:11:17 +0100 | [diff] [blame] | 177 | |
Evan Shrubsole | e331a12 | 2020-02-05 13:30:33 +0100 | [diff] [blame] | 178 | // Checks to see if we should execute the quality rampup experiment. The |
| 179 | // experiment resets all video restrictions at the start of the call in the |
| 180 | // case the bandwidth estimate is high enough. |
| 181 | // TODO(https://crbug.com/webrtc/11222) Move experiment details into an inner |
| 182 | // class. |
| 183 | void MaybePerformQualityRampupExperiment(); |
| 184 | void ResetVideoSourceRestrictions(); |
| 185 | |
Evan Shrubsole | 33be9df | 2020-03-05 18:39:32 +0100 | [diff] [blame] | 186 | std::string ActiveCountsToString() const; |
| 187 | |
Henrik Boström | 8234b92 | 2020-01-13 17:26:50 +0100 | [diff] [blame] | 188 | ResourceAdaptationModuleListener* const adaptation_listener_; |
Evan Shrubsole | 7c3a1fc | 2020-02-04 16:26:38 +0100 | [diff] [blame] | 189 | Clock* clock_; |
Evan Shrubsole | aa6fbc1 | 2020-02-25 16:26:01 +0100 | [diff] [blame] | 190 | State state_; |
Henrik Boström | ad515a2 | 2020-01-27 13:38:05 +0100 | [diff] [blame] | 191 | const bool experiment_cpu_load_estimator_; |
Henrik Boström | 8234b92 | 2020-01-13 17:26:50 +0100 | [diff] [blame] | 192 | // The restrictions that |adaptation_listener_| is informed of. |
Henrik Boström | 07b17df | 2020-01-15 11:42:12 +0100 | [diff] [blame] | 193 | VideoSourceRestrictions video_source_restrictions_; |
Henrik Boström | a3d4252 | 2020-01-16 13:55:29 +0100 | [diff] [blame] | 194 | bool has_input_video_; |
Henrik Boström | b0f2e0c | 2020-03-06 13:32:03 +0100 | [diff] [blame^] | 195 | // TODO(https://crbug.com/webrtc/11393): DegradationPreference has mostly |
| 196 | // moved to VideoStreamAdapter. Move it entirely and delete it from this |
| 197 | // class. If the responsibility of generating next steps for adaptations is |
| 198 | // owned by the adapter, this class has no buisness relying on implementation |
| 199 | // details of the adapter. |
Henrik Boström | 07b17df | 2020-01-15 11:42:12 +0100 | [diff] [blame] | 200 | DegradationPreference degradation_preference_; |
Henrik Boström | ce0ea49 | 2020-01-13 11:27:18 +0100 | [diff] [blame] | 201 | // Keeps track of source restrictions that this adaptation module outputs. |
Henrik Boström | efbec9a | 2020-03-06 10:41:25 +0100 | [diff] [blame] | 202 | const std::unique_ptr<VideoStreamAdapter> stream_adapter_; |
Henrik Boström | 7875c99 | 2020-02-06 10:35:00 +0100 | [diff] [blame] | 203 | const std::unique_ptr<EncodeUsageResource> encode_usage_resource_; |
| 204 | const std::unique_ptr<QualityScalerResource> quality_scaler_resource_; |
Henrik Boström | 8cfecac | 2020-02-07 11:29:14 +0100 | [diff] [blame] | 205 | const std::unique_ptr<InitialFrameDropper> initial_frame_dropper_; |
Henrik Boström | 7875c99 | 2020-02-06 10:35:00 +0100 | [diff] [blame] | 206 | const bool quality_scaling_experiment_enabled_; |
Henrik Boström | d4578ae | 2020-01-22 16:16:04 +0100 | [diff] [blame] | 207 | absl::optional<int> last_input_frame_size_; |
Henrik Boström | fae6f0e | 2020-01-20 11:16:50 +0100 | [diff] [blame] | 208 | absl::optional<double> target_frame_rate_; |
Evan Shrubsole | 7c3a1fc | 2020-02-04 16:26:38 +0100 | [diff] [blame] | 209 | // This is the last non-zero target bitrate for the encoder. |
| 210 | absl::optional<uint32_t> encoder_target_bitrate_bps_; |
Evan Shrubsole | e331a12 | 2020-02-05 13:30:33 +0100 | [diff] [blame] | 211 | absl::optional<VideoEncoder::RateControlParameters> encoder_rates_; |
Evan Shrubsole | e331a12 | 2020-02-05 13:30:33 +0100 | [diff] [blame] | 212 | bool quality_rampup_done_; |
| 213 | QualityRampupExperiment quality_rampup_experiment_; |
Henrik Boström | 4bab2fc | 2020-01-21 11:18:06 +0100 | [diff] [blame] | 214 | absl::optional<EncoderSettings> encoder_settings_; |
Henrik Boström | 07b17df | 2020-01-15 11:42:12 +0100 | [diff] [blame] | 215 | VideoStreamEncoderObserver* const encoder_stats_observer_; |
Evan Shrubsole | aa6fbc1 | 2020-02-25 16:26:01 +0100 | [diff] [blame] | 216 | |
| 217 | // Ties a resource to a reason for statistical reporting. This AdaptReason is |
| 218 | // also used by this module to make decisions about how to adapt up/down. |
| 219 | struct ResourceAndReason { |
| 220 | ResourceAndReason(Resource* resource, |
| 221 | AdaptationObserverInterface::AdaptReason reason) |
| 222 | : resource(resource), reason(reason) {} |
| 223 | virtual ~ResourceAndReason() = default; |
| 224 | |
| 225 | Resource* const resource; |
| 226 | const AdaptationObserverInterface::AdaptReason reason; |
| 227 | }; |
| 228 | std::vector<ResourceAndReason> resources_; |
Evan Shrubsole | 33be9df | 2020-03-05 18:39:32 +0100 | [diff] [blame] | 229 | // One AdaptationCounter for each reason, tracking the number of times we have |
| 230 | // adapted for each reason. The sum of active_counts_ MUST always equal the |
| 231 | // total adaptation provided by the VideoSourceRestrictions. |
| 232 | // TODO(https://crbug.com/webrtc/11392): Move all active count logic to |
| 233 | // encoder_stats_observer_; Counters used for deciding if the video resolution |
| 234 | // or framerate is currently restricted, and if so, why, on a per degradation |
| 235 | // preference basis. |
| 236 | std::array<AdaptationCounters, AdaptationObserverInterface::kScaleReasonSize> |
| 237 | active_counts_; |
Henrik Boström | b08882b | 2020-01-07 10:11:17 +0100 | [diff] [blame] | 238 | }; |
| 239 | |
| 240 | } // namespace webrtc |
| 241 | |
| 242 | #endif // VIDEO_OVERUSE_FRAME_DETECTOR_RESOURCE_ADAPTATION_MODULE_H_ |