1 /*
2  *  Copyright (c) 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 MODULES_VIDEO_CODING_CODECS_AV1_SCALABLE_VIDEO_CONTROLLER_H_
11 #define MODULES_VIDEO_CODING_CODECS_AV1_SCALABLE_VIDEO_CONTROLLER_H_
12 
13 #include <vector>
14 
15 #include "absl/container/inlined_vector.h"
16 #include "absl/types/optional.h"
17 #include "api/transport/rtp/dependency_descriptor.h"
18 #include "api/video/video_bitrate_allocation.h"
19 #include "common_video/generic_frame_descriptor/generic_frame_info.h"
20 
21 namespace webrtc {
22 
23 // Controls how video should be encoded to be scalable. Outputs results as
24 // buffer usage configuration for encoder and enough details to communicate the
25 // scalability structure via dependency descriptor rtp header extension.
26 class ScalableVideoController {
27  public:
28   struct StreamLayersConfig {
29     int num_spatial_layers = 1;
30     int num_temporal_layers = 1;
31     // Spatial layers scaling. Frames with spatial_id = i expected to be encoded
32     // with original_resolution * scaling_factor_num[i] / scaling_factor_den[i].
33     int scaling_factor_num[DependencyDescriptor::kMaxSpatialIds] = {1, 1, 1, 1};
34     int scaling_factor_den[DependencyDescriptor::kMaxSpatialIds] = {1, 1, 1, 1};
35   };
36   class LayerFrameConfig {
37    public:
38     // Builders/setters.
39     LayerFrameConfig& Id(int value);
40     LayerFrameConfig& Keyframe();
41     LayerFrameConfig& S(int value);
42     LayerFrameConfig& T(int value);
43     LayerFrameConfig& Reference(int buffer_id);
44     LayerFrameConfig& Update(int buffer_id);
45     LayerFrameConfig& ReferenceAndUpdate(int buffer_id);
46 
47     // Getters.
Id()48     int Id() const { return id_; }
IsKeyframe()49     bool IsKeyframe() const { return is_keyframe_; }
SpatialId()50     int SpatialId() const { return spatial_id_; }
TemporalId()51     int TemporalId() const { return temporal_id_; }
Buffers()52     const absl::InlinedVector<CodecBufferUsage, kMaxEncoderBuffers>& Buffers()
53         const {
54       return buffers_;
55     }
56 
57    private:
58     // Id to match configuration returned by NextFrameConfig with
59     // (possibly modified) configuration passed back via OnEncoderDone.
60     // The meaning of the id is an implementation detail of
61     // the ScalableVideoController.
62     int id_ = 0;
63 
64     // Indication frame should be encoded as a key frame. In particular when
65     // `is_keyframe=true` property `CodecBufferUsage::referenced` should be
66     // ignored and treated as false.
67     bool is_keyframe_ = false;
68 
69     int spatial_id_ = 0;
70     int temporal_id_ = 0;
71     // Describes how encoder which buffers encoder allowed to reference and
72     // which buffers encoder should update.
73     absl::InlinedVector<CodecBufferUsage, kMaxEncoderBuffers> buffers_;
74   };
75 
76   virtual ~ScalableVideoController() = default;
77 
78   // Returns video structure description for encoder to configure itself.
79   virtual StreamLayersConfig StreamConfig() const = 0;
80 
81   // Returns video structure description in format compatible with
82   // dependency descriptor rtp header extension.
83   virtual FrameDependencyStructure DependencyStructure() const = 0;
84 
85   // Notifies Controller with updated bitrates per layer. In particular notifies
86   // when certain layers should be disabled.
87   // Controller shouldn't produce LayerFrameConfig for disabled layers.
88   // TODO(bugs.webrtc.org/11404): Make pure virtual when implemented by all
89   // structures.
OnRatesUpdated(const VideoBitrateAllocation & bitrates)90   virtual void OnRatesUpdated(const VideoBitrateAllocation& bitrates) {}
91 
92   // When `restart` is true, first `LayerFrameConfig` should have `is_keyframe`
93   // set to true.
94   // Returned vector shouldn't be empty.
95   virtual std::vector<LayerFrameConfig> NextFrameConfig(bool restart) = 0;
96 
97   // Returns configuration to pass to EncoderCallback.
98   virtual absl::optional<GenericFrameInfo> OnEncodeDone(
99       LayerFrameConfig config) = 0;
100 };
101 
102 // Below are implementation details.
103 inline ScalableVideoController::LayerFrameConfig&
Id(int value)104 ScalableVideoController::LayerFrameConfig::Id(int value) {
105   id_ = value;
106   return *this;
107 }
108 inline ScalableVideoController::LayerFrameConfig&
Keyframe()109 ScalableVideoController::LayerFrameConfig::Keyframe() {
110   is_keyframe_ = true;
111   return *this;
112 }
113 inline ScalableVideoController::LayerFrameConfig&
S(int value)114 ScalableVideoController::LayerFrameConfig::S(int value) {
115   spatial_id_ = value;
116   return *this;
117 }
118 inline ScalableVideoController::LayerFrameConfig&
T(int value)119 ScalableVideoController::LayerFrameConfig::T(int value) {
120   temporal_id_ = value;
121   return *this;
122 }
123 inline ScalableVideoController::LayerFrameConfig&
Reference(int buffer_id)124 ScalableVideoController::LayerFrameConfig::Reference(int buffer_id) {
125   buffers_.emplace_back(buffer_id, /*referenced=*/true, /*updated=*/false);
126   return *this;
127 }
128 inline ScalableVideoController::LayerFrameConfig&
Update(int buffer_id)129 ScalableVideoController::LayerFrameConfig::Update(int buffer_id) {
130   buffers_.emplace_back(buffer_id, /*referenced=*/false, /*updated=*/true);
131   return *this;
132 }
133 inline ScalableVideoController::LayerFrameConfig&
ReferenceAndUpdate(int buffer_id)134 ScalableVideoController::LayerFrameConfig::ReferenceAndUpdate(int buffer_id) {
135   buffers_.emplace_back(buffer_id, /*referenced=*/true, /*updated=*/true);
136   return *this;
137 }
138 
139 }  // namespace webrtc
140 
141 #endif  // MODULES_VIDEO_CODING_CODECS_AV1_SCALABLE_VIDEO_CONTROLLER_H_
142