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