| // 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" |
| |
| 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 { |
| // Frame size. |
| int width; |
| int height; |
| // Quantizer parameter,the range is 0-63. |
| int max_quantizer; |
| int min_quantizer; |
| // Target_bandwidth is in kbps. |
| int64_t target_bandwidth; |
| // Frame rate. |
| double framerate; |
| // 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; |
| // Number of temporal layers. |
| int ts_number_layers; |
| // 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]; |
| }; |
| |
| // FrameParams is used for passing frame params. |
| struct FrameParams { |
| enum class FrameType { kKeyFrame, kInterFrame }; |
| FrameType frame_type; |
| int spatial_layer_id; |
| int temporal_layer_id; |
| }; |
| |
| 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_ |