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
media / gpu / windows / video_rate_control_wrapper.h [blame]
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef MEDIA_GPU_WINDOWS_VIDEO_RATE_CONTROL_WRAPPER_H_
#define MEDIA_GPU_WINDOWS_VIDEO_RATE_CONTROL_WRAPPER_H_
#include <cstdint>
#include <memory>
#include "media/base/media_log.h"
#include "media/gpu/media_gpu_export.h"
#include "media/video/video_encode_accelerator.h"
namespace media {
// These constants come from svc and codec spec.
constexpr size_t kMaxTemporalLayers = 8;
constexpr size_t kMaxSpatialLayers = 4;
constexpr size_t kMaxLayers = kMaxTemporalLayers * kMaxSpatialLayers;
// VideoRateControlWrapper is a base class for computing
// proper quantization param for each frame.
class VideoRateControlWrapper {
public:
// RateControlConfig is a type of helper for passing configs
// to codec-specific rate controller.
struct RateControlConfig {
RateControlConfig();
~RateControlConfig();
RateControlConfig(const RateControlConfig&);
RateControlConfig& operator=(const RateControlConfig&);
// Frame size.
int width = 0;
int height = 0;
// Quantizer parameter,the range is 0-63.
int max_quantizer = 0;
int min_quantizer = 0;
// Target_bandwidth is in kbps.
int64_t target_bandwidth = 0;
// Frame rate.
double framerate = 0.0f;
// Content type, camera or display.
VideoEncodeAccelerator::Config::ContentType content_type =
VideoEncodeAccelerator::Config::ContentType::kCamera;
// Target bitrate for svc layers.
int layer_target_bitrate[kMaxLayers] = {};
// Rate decimator for temporal layers.
int ts_rate_decimator[kMaxTemporalLayers] = {};
// Number of spatial layers.
int ss_number_layers = 0;
// Number of temporal layers.
int ts_number_layers = 0;
// Quantizer parameter for svc layers.
int max_quantizers[kMaxLayers] = {};
int min_quantizers[kMaxLayers] = {};
// Scaling factor parameters for spatial layers.
int scaling_factor_num[kMaxSpatialLayers] = {};
int scaling_factor_den[kMaxSpatialLayers] = {};
// If defined, the H.264 BRC uses fixed QP difference between layers. Should
// not be defined for other SW BRCs.
std::optional<int> fixed_delta_qp;
};
// FrameParams is used for passing frame params.
struct FrameParams {
enum class FrameType { kKeyFrame, kInterFrame };
FrameType frame_type = FrameType::kKeyFrame;
int spatial_layer_id = 0;
int temporal_layer_id = 0;
unsigned int timestamp = 0;
};
virtual ~VideoRateControlWrapper() = default;
virtual void UpdateRateControl(const RateControlConfig& config) = 0;
// ComputeQP() returns qp table index and the range is up to the codec.
virtual int ComputeQP(const FrameParams& frame_params) = 0;
// GetLoopfilterLevel() is only available for VP9, others return -1.
virtual int GetLoopfilterLevel() const = 0;
// Feedback to rate control with the size of current encoded frame.
virtual void PostEncodeUpdate(uint64_t encoded_frame_size,
const FrameParams& frame_params) = 0;
};
// VideoRateControlWrapperInternal is an interface for creating
// codec-specific rate controller.
template <typename RateControlConfigType,
typename RateCtrlType,
typename FrameParamsType>
class VideoRateControlWrapperInternal : public VideoRateControlWrapper {
public:
// Creates VideoRateControlWrapper implementation.
static std::unique_ptr<VideoRateControlWrapperInternal> Create(
const RateControlConfig& config) {
auto impl = RateCtrlType::Create(ConvertControlConfig(config));
if (!impl) {
DLOG(ERROR) << "Failed creating video RateController";
return nullptr;
}
return std::make_unique<VideoRateControlWrapperInternal>(std::move(impl));
}
VideoRateControlWrapperInternal() = default;
explicit VideoRateControlWrapperInternal(std::unique_ptr<RateCtrlType> impl)
: impl_(std::move(impl)) {}
~VideoRateControlWrapperInternal() override = default;
void UpdateRateControl(const RateControlConfig& config) override {
DCHECK(impl_);
impl_->UpdateRateControl(ConvertControlConfig(config));
}
int ComputeQP(const FrameParams& frame_params) override {
DCHECK(impl_);
impl_->ComputeQP(ConvertFrameParams(frame_params));
return impl_->GetQP();
}
int GetLoopfilterLevel() const override;
void PostEncodeUpdate(uint64_t encoded_frame_size,
const FrameParams& frame_params) override;
private:
// "ConvertControlConfig" and "ConvertFrameParams" are used for passing
// parameters to impl_, which should be specialized when the template is
// instantiated.
static RateControlConfigType ConvertControlConfig(
const RateControlConfig& config);
static FrameParamsType ConvertFrameParams(const FrameParams& frame_params);
std::unique_ptr<RateCtrlType> impl_;
};
} // namespace media
#endif // MEDIA_GPU_WINDOWS_VIDEO_RATE_CONTROL_WRAPPER_H_