video_stream_adapter.h 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  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. #ifndef CALL_ADAPTATION_VIDEO_STREAM_ADAPTER_H_
  11. #define CALL_ADAPTATION_VIDEO_STREAM_ADAPTER_H_
  12. #include <memory>
  13. #include "absl/types/optional.h"
  14. #include "api/adaptation/resource.h"
  15. #include "api/rtp_parameters.h"
  16. #include "api/video/video_adaptation_counters.h"
  17. #include "call/adaptation/video_source_restrictions.h"
  18. #include "call/adaptation/video_stream_input_state.h"
  19. #include "modules/video_coding/utility/quality_scaler.h"
  20. #include "rtc_base/experiments/balanced_degradation_settings.h"
  21. namespace webrtc {
  22. class VideoStreamAdapter;
  23. extern const int kMinFrameRateFps;
  24. VideoSourceRestrictions FilterRestrictionsByDegradationPreference(
  25. VideoSourceRestrictions source_restrictions,
  26. DegradationPreference degradation_preference);
  27. VideoAdaptationCounters FilterVideoAdaptationCountersByDegradationPreference(
  28. VideoAdaptationCounters counters,
  29. DegradationPreference degradation_preference);
  30. int GetHigherResolutionThan(int pixel_count);
  31. // Represents one step that the VideoStreamAdapter can take when adapting the
  32. // VideoSourceRestrictions up or down. Or, if adaptation is not valid, provides
  33. // a Status code indicating the reason for not adapting.
  34. class Adaptation final {
  35. public:
  36. enum class Status {
  37. // Applying this adaptation will have an effect. All other Status codes
  38. // indicate that adaptation is not possible and why.
  39. kValid,
  40. // Cannot adapt. The minimum or maximum adaptation has already been reached.
  41. // There are no more steps to take.
  42. kLimitReached,
  43. // Cannot adapt. The resolution or frame rate requested by a recent
  44. // adaptation has not yet been reflected in the input resolution or frame
  45. // rate; adaptation is refused to avoid "double-adapting".
  46. kAwaitingPreviousAdaptation,
  47. };
  48. static const char* StatusToString(Status status);
  49. // The status of this Adaptation. To find out how this Adaptation affects
  50. // VideoSourceRestrictions, see VideoStreamAdapter::PeekNextRestrictions().
  51. Status status() const;
  52. // Used for stats reporting.
  53. bool min_pixel_limit_reached() const;
  54. private:
  55. // The adapter needs to know about step type and step target in order to
  56. // construct and perform an Adaptation, which is a detail we do not want to
  57. // expose to the public interface.
  58. friend class VideoStreamAdapter;
  59. enum class StepType {
  60. kIncreaseResolution,
  61. kDecreaseResolution,
  62. kIncreaseFrameRate,
  63. kDecreaseFrameRate,
  64. kForce
  65. };
  66. struct Step {
  67. Step(StepType type, int target);
  68. // StepType is kForce
  69. Step(VideoSourceRestrictions restrictions,
  70. VideoAdaptationCounters counters);
  71. const StepType type;
  72. // Pixel or frame rate depending on |type|.
  73. // Only set when |type| is not kForce.
  74. const absl::optional<int> target;
  75. // Only set when |type| is kForce.
  76. const absl::optional<VideoSourceRestrictions> restrictions;
  77. // Only set when |type| is kForce.
  78. const absl::optional<VideoAdaptationCounters> counters;
  79. };
  80. // Constructs with a valid adaptation Step. Status is kValid.
  81. Adaptation(int validation_id, Step step);
  82. Adaptation(int validation_id, Step step, bool min_pixel_limit_reached);
  83. // Constructor when adaptation is not valid. Status MUST NOT be kValid.
  84. Adaptation(int validation_id, Status invalid_status);
  85. Adaptation(int validation_id,
  86. Status invalid_status,
  87. bool min_pixel_limit_reached);
  88. const Step& step() const; // Only callable if |status_| is kValid.
  89. // An Adaptation can become invalidated if the state of VideoStreamAdapter is
  90. // modified before the Adaptation is applied. To guard against this, this ID
  91. // has to match VideoStreamAdapter::adaptation_validation_id_ when applied.
  92. const int validation_id_;
  93. const Status status_;
  94. const absl::optional<Step> step_; // Only present if |status_| is kValid.
  95. const bool min_pixel_limit_reached_;
  96. };
  97. // Owns the VideoSourceRestriction for a single stream and is responsible for
  98. // adapting it up or down when told to do so. This class serves the following
  99. // purposes:
  100. // 1. Keep track of a stream's restrictions.
  101. // 2. Provide valid ways to adapt up or down the stream's restrictions.
  102. // 3. Modify the stream's restrictions in one of the valid ways.
  103. class VideoStreamAdapter {
  104. public:
  105. VideoStreamAdapter();
  106. ~VideoStreamAdapter();
  107. VideoSourceRestrictions source_restrictions() const;
  108. const VideoAdaptationCounters& adaptation_counters() const;
  109. void ClearRestrictions();
  110. // TODO(hbos): Setting the degradation preference should not clear
  111. // restrictions! This is not defined in the spec and is unexpected, there is a
  112. // tiny risk that people would discover and rely on this behavior.
  113. void SetDegradationPreference(DegradationPreference degradation_preference);
  114. // The adaptaiton logic depends on these inputs.
  115. void SetInput(VideoStreamInputState input_state);
  116. // Returns an adaptation that we are guaranteed to be able to apply, or a
  117. // status code indicating the reason why we cannot adapt.
  118. Adaptation GetAdaptationUp() const;
  119. Adaptation GetAdaptationDown() const;
  120. Adaptation GetAdaptationTo(const VideoAdaptationCounters& counters,
  121. const VideoSourceRestrictions& restrictions) const;
  122. struct RestrictionsWithCounters {
  123. VideoSourceRestrictions restrictions;
  124. VideoAdaptationCounters adaptation_counters;
  125. };
  126. // Returns the restrictions that result from applying the adaptation, without
  127. // actually applying it. If the adaptation is not valid, current restrictions
  128. // are returned.
  129. RestrictionsWithCounters PeekNextRestrictions(
  130. const Adaptation& adaptation) const;
  131. // Updates source_restrictions() based according to the Adaptation.
  132. void ApplyAdaptation(const Adaptation& adaptation);
  133. private:
  134. class VideoSourceRestrictor;
  135. // The input frame rate and resolution at the time of an adaptation in the
  136. // direction described by |mode_| (up or down).
  137. // TODO(https://crbug.com/webrtc/11393): Can this be renamed? Can this be
  138. // merged with AdaptationTarget?
  139. struct AdaptationRequest {
  140. // The pixel count produced by the source at the time of the adaptation.
  141. int input_pixel_count_;
  142. // Framerate received from the source at the time of the adaptation.
  143. int framerate_fps_;
  144. // Degradation preference for the request.
  145. Adaptation::StepType step_type_;
  146. };
  147. // Owner and modifier of the VideoSourceRestriction of this stream adaptor.
  148. const std::unique_ptr<VideoSourceRestrictor> source_restrictor_;
  149. // Decides the next adaptation target in DegradationPreference::BALANCED.
  150. const BalancedDegradationSettings balanced_settings_;
  151. // To guard against applying adaptations that have become invalidated, an
  152. // Adaptation that is applied has to have a matching validation ID.
  153. int adaptation_validation_id_;
  154. // When deciding the next target up or down, different strategies are used
  155. // depending on the DegradationPreference.
  156. // https://w3c.github.io/mst-content-hint/#dom-rtcdegradationpreference
  157. DegradationPreference degradation_preference_;
  158. VideoStreamInputState input_state_;
  159. // The input frame rate, resolution and adaptation direction of the last
  160. // ApplyAdaptationTarget(). Used to avoid adapting twice if a recent
  161. // adaptation has not had an effect on the input frame rate or resolution yet.
  162. // TODO(hbos): Can we implement a more general "cooldown" mechanism of
  163. // resources intead? If we already have adapted it seems like we should wait
  164. // a while before adapting again, so that we are not acting on usage
  165. // measurements that are made obsolete/unreliable by an "ongoing" adaptation.
  166. absl::optional<AdaptationRequest> last_adaptation_request_;
  167. };
  168. } // namespace webrtc
  169. #endif // CALL_ADAPTATION_VIDEO_STREAM_ADAPTER_H_