blob: 40e35ecc772fef8130d067fa38922a0eb0304004 [file] [log] [blame]
Henrik Boströmefbec9a2020-03-06 10:41:25 +01001/*
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ömb0f2e0c2020-03-06 13:32:03 +010016#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ömefbec9a2020-03-06 10:41:25 +010020#include "call/adaptation/video_source_restrictions.h"
Henrik Boströmb0f2e0c2020-03-06 13:32:03 +010021#include "modules/video_coding/utility/quality_scaler.h"
22#include "rtc_base/experiments/balanced_degradation_settings.h"
Henrik Boströmefbec9a2020-03-06 10:41:25 +010023#include "video/adaptation/adaptation_counters.h"
24
25namespace 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.
33class VideoStreamAdapter {
34 public:
Henrik Boströmb0f2e0c2020-03-06 13:32:03 +010035 enum class SetDegradationPreferenceResult {
36 kRestrictionsNotCleared,
37 kRestrictionsCleared,
38 };
Henrik Boströmefbec9a2020-03-06 10:41:25 +010039
Henrik Boströmb0f2e0c2020-03-06 13:32:03 +010040 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ömefbec9a2020-03-06 10:41:25 +010070
71 VideoStreamAdapter();
72 ~VideoStreamAdapter();
73
Henrik Boströmefbec9a2020-03-06 10:41:25 +010074 VideoSourceRestrictions source_restrictions() const;
75 const AdaptationCounters& adaptation_counters() const;
Henrik Boströmb0f2e0c2020-03-06 13:32:03 +010076 // 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ömefbec9a2020-03-06 10:41:25 +010081 void ClearRestrictions();
82
Henrik Boströmb0f2e0c2020-03-06 13:32:03 +010083 // 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ömefbec9a2020-03-06 10:41:25 +0100119
120 private:
121 class VideoSourceRestrictor;
122
Henrik Boströmb0f2e0c2020-03-06 13:32:03 +0100123 // 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ömefbec9a2020-03-06 10:41:25 +0100141 const std::unique_ptr<VideoSourceRestrictor> source_restrictor_;
Henrik Boströmb0f2e0c2020-03-06 13:32:03 +0100142 // 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ömefbec9a2020-03-06 10:41:25 +0100157};
158
159} // namespace webrtc
160
161#endif // VIDEO_ADAPTATION_VIDEO_STREAM_ADAPTER_H_