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