Henrik Boström | efbec9a | 2020-03-06 10:41:25 +0100 | [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 VIDEO_ADAPTATION_VIDEO_STREAM_ADAPTER_H_ |
| 12 | #define VIDEO_ADAPTATION_VIDEO_STREAM_ADAPTER_H_ |
| 13 | |
| 14 | #include <memory> |
| 15 | |
Henrik Boström | b0f2e0c | 2020-03-06 13:32:03 +0100 | [diff] [blame^] | 16 | #include "absl/types/optional.h" |
| 17 | #include "api/rtp_parameters.h" |
| 18 | #include "api/video/video_stream_encoder_observer.h" |
| 19 | #include "call/adaptation/encoder_settings.h" |
Henrik Boström | efbec9a | 2020-03-06 10:41:25 +0100 | [diff] [blame] | 20 | #include "call/adaptation/video_source_restrictions.h" |
Henrik Boström | b0f2e0c | 2020-03-06 13:32:03 +0100 | [diff] [blame^] | 21 | #include "modules/video_coding/utility/quality_scaler.h" |
| 22 | #include "rtc_base/experiments/balanced_degradation_settings.h" |
Henrik Boström | efbec9a | 2020-03-06 10:41:25 +0100 | [diff] [blame] | 23 | #include "video/adaptation/adaptation_counters.h" |
| 24 | |
| 25 | namespace webrtc { |
| 26 | |
| 27 | // Owns the VideoSourceRestriction for a single stream and is responsible for |
| 28 | // adapting it up or down when told to do so. This class serves the following |
| 29 | // purposes: |
| 30 | // 1. Keep track of a stream's restrictions. |
| 31 | // 2. Provide valid ways to adapt up or down the stream's restrictions. |
| 32 | // 3. Modify the stream's restrictions in one of the valid ways. |
| 33 | class VideoStreamAdapter { |
| 34 | public: |
Henrik Boström | b0f2e0c | 2020-03-06 13:32:03 +0100 | [diff] [blame^] | 35 | enum class SetDegradationPreferenceResult { |
| 36 | kRestrictionsNotCleared, |
| 37 | kRestrictionsCleared, |
| 38 | }; |
Henrik Boström | efbec9a | 2020-03-06 10:41:25 +0100 | [diff] [blame] | 39 | |
Henrik Boström | b0f2e0c | 2020-03-06 13:32:03 +0100 | [diff] [blame^] | 40 | enum class VideoInputMode { |
| 41 | kNoVideo, |
| 42 | kNormalVideo, |
| 43 | kScreenshareVideo, |
| 44 | }; |
| 45 | |
| 46 | enum class AdaptationAction { |
| 47 | kIncreaseResolution, |
| 48 | kDecreaseResolution, |
| 49 | kIncreaseFrameRate, |
| 50 | kDecreaseFrameRate, |
| 51 | }; |
| 52 | |
| 53 | // Describes an adaptation step: increasing or decreasing resolution or frame |
| 54 | // rate to a given value. |
| 55 | // TODO(https://crbug.com/webrtc/11393): Make these private implementation |
| 56 | // details, and expose something that allows you to inspect the |
| 57 | // VideoSourceRestrictions instead. The adaptation steps could be expressed as |
| 58 | // a graph, for instance. |
| 59 | struct AdaptationTarget { |
| 60 | AdaptationTarget(AdaptationAction action, int value); |
| 61 | // Which action the VideoSourceRestrictor needs to take. |
| 62 | const AdaptationAction action; |
| 63 | // Target pixel count or frame rate depending on |action|. |
| 64 | const int value; |
| 65 | |
| 66 | // Allow this struct to be instantiated as an optional, even though it's in |
| 67 | // a private namespace. |
| 68 | friend class absl::optional<AdaptationTarget>; |
| 69 | }; |
Henrik Boström | efbec9a | 2020-03-06 10:41:25 +0100 | [diff] [blame] | 70 | |
| 71 | VideoStreamAdapter(); |
| 72 | ~VideoStreamAdapter(); |
| 73 | |
Henrik Boström | efbec9a | 2020-03-06 10:41:25 +0100 | [diff] [blame] | 74 | VideoSourceRestrictions source_restrictions() const; |
| 75 | const AdaptationCounters& adaptation_counters() const; |
Henrik Boström | b0f2e0c | 2020-03-06 13:32:03 +0100 | [diff] [blame^] | 76 | // TODO(hbos): Can we get rid of any external dependencies on |
| 77 | // BalancedDegradationPreference? How the adaptor generates possible next |
| 78 | // steps for adaptation should be an implementation detail. Can the relevant |
| 79 | // information be inferred from GetAdaptUpTarget()/GetAdaptDownTarget()? |
| 80 | const BalancedDegradationSettings& balanced_settings() const; |
Henrik Boström | efbec9a | 2020-03-06 10:41:25 +0100 | [diff] [blame] | 81 | void ClearRestrictions(); |
| 82 | |
Henrik Boström | b0f2e0c | 2020-03-06 13:32:03 +0100 | [diff] [blame^] | 83 | // TODO(hbos): Setting the degradation preference should not clear |
| 84 | // restrictions! This is not defined in the spec and is unexpected, there is a |
| 85 | // tiny risk that people would discover and rely on this behavior. |
| 86 | SetDegradationPreferenceResult SetDegradationPreference( |
| 87 | DegradationPreference degradation_preference); |
| 88 | // TODO(hbos): This is only used in one place externally by |
| 89 | // OveruseFrameDetectorResourceAdaptationModule - can we get rid of that |
| 90 | // usage? This is exposing an implementation detail. |
| 91 | DegradationPreference EffectiveDegradationPreference( |
| 92 | VideoInputMode input_mode) const; |
| 93 | |
| 94 | // Returns a target that we are guaranteed to be able to adapt to, or null if |
| 95 | // adaptation is not desired or not possible. |
| 96 | absl::optional<AdaptationTarget> GetAdaptUpTarget( |
| 97 | const absl::optional<EncoderSettings>& encoder_settings, |
| 98 | absl::optional<uint32_t> encoder_target_bitrate_bps, |
| 99 | VideoInputMode input_mode, |
| 100 | int input_pixels, |
| 101 | int input_fps, |
| 102 | AdaptationObserverInterface::AdaptReason reason) const; |
| 103 | // TODO(https://crbug.com/webrtc/11393): Remove the dependency on |
| 104 | // |encoder_stats_observer| - simply checking which adaptation target is |
| 105 | // available should not have side-effects. |
| 106 | absl::optional<AdaptationTarget> GetAdaptDownTarget( |
| 107 | const absl::optional<EncoderSettings>& encoder_settings, |
| 108 | VideoInputMode input_mode, |
| 109 | int input_pixels, |
| 110 | int input_fps, |
| 111 | int min_pixels_per_frame, |
| 112 | VideoStreamEncoderObserver* encoder_stats_observer) const; |
| 113 | // Applies the |target| to |source_restrictor_|. |
| 114 | void ApplyAdaptationTarget(const AdaptationTarget& target, |
| 115 | VideoInputMode input_mode, |
| 116 | int input_pixels, |
| 117 | int input_fps, |
| 118 | int min_pixels_per_frame); |
Henrik Boström | efbec9a | 2020-03-06 10:41:25 +0100 | [diff] [blame] | 119 | |
| 120 | private: |
| 121 | class VideoSourceRestrictor; |
| 122 | |
Henrik Boström | b0f2e0c | 2020-03-06 13:32:03 +0100 | [diff] [blame^] | 123 | // The input frame rate and resolution at the time of an adaptation in the |
| 124 | // direction described by |mode_| (up or down). |
| 125 | // TODO(https://crbug.com/webrtc/11393): Can this be renamed? Can this be |
| 126 | // merged with AdaptationTarget? |
| 127 | struct AdaptationRequest { |
| 128 | // The pixel count produced by the source at the time of the adaptation. |
| 129 | int input_pixel_count_; |
| 130 | // Framerate received from the source at the time of the adaptation. |
| 131 | int framerate_fps_; |
| 132 | // Indicates if request was to adapt up or down. |
| 133 | enum class Mode { kAdaptUp, kAdaptDown } mode_; |
| 134 | |
| 135 | // This is a static method rather than an anonymous namespace function due |
| 136 | // to namespace visiblity. |
| 137 | static Mode GetModeFromAdaptationAction(AdaptationAction action); |
| 138 | }; |
| 139 | |
| 140 | // Owner and modifier of the VideoSourceRestriction of this stream adaptor. |
Henrik Boström | efbec9a | 2020-03-06 10:41:25 +0100 | [diff] [blame] | 141 | const std::unique_ptr<VideoSourceRestrictor> source_restrictor_; |
Henrik Boström | b0f2e0c | 2020-03-06 13:32:03 +0100 | [diff] [blame^] | 142 | // Decides the next adaptation target in DegradationPreference::BALANCED. |
| 143 | const BalancedDegradationSettings balanced_settings_; |
| 144 | // When deciding the next target up or down, different strategies are used |
| 145 | // depending on the DegradationPreference. |
| 146 | // https://w3c.github.io/mst-content-hint/#dom-rtcdegradationpreference |
| 147 | DegradationPreference degradation_preference_; |
| 148 | |
| 149 | // The input frame rate, resolution and adaptation direction of the last |
| 150 | // ApplyAdaptationTarget(). Used to avoid adapting twice if a recent |
| 151 | // adaptation has not had an effect on the input frame rate or resolution yet. |
| 152 | // TODO(hbos): Can we implement a more general "cooldown" mechanism of |
| 153 | // resources intead? If we already have adapted it seems like we should wait |
| 154 | // a while before adapting again, so that we are not acting on usage |
| 155 | // measurements that are made obsolete/unreliable by an "ongoing" adaptation. |
| 156 | absl::optional<AdaptationRequest> last_adaptation_request_; |
Henrik Boström | efbec9a | 2020-03-06 10:41:25 +0100 | [diff] [blame] | 157 | }; |
| 158 | |
| 159 | } // namespace webrtc |
| 160 | |
| 161 | #endif // VIDEO_ADAPTATION_VIDEO_STREAM_ADAPTER_H_ |