| /* | |
| * Copyright (c) 2021, Alliance for Open Media. All rights reserved. | |
| * | |
| * This source code is subject to the terms of the BSD 2 Clause License and | |
| * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License | |
| * was not distributed with this source code in the LICENSE file, you can | |
| * obtain it at www.aomedia.org/license/software. If the Alliance for Open | |
| * Media Patent License 1.0 was not distributed with this source code in the | |
| * PATENTS file, you can obtain it at www.aomedia.org/license/patent. | |
| */ | |
| #ifndef AOM_AV1_RATECTRL_RTC_H_ | |
| #define AOM_AV1_RATECTRL_RTC_H_ | |
| #ifdef __cplusplus | |
| #include <cstddef> | |
| #include <cstdint> | |
| #include <memory> | |
| #else | |
| #include <stdbool.h> | |
| #include <stddef.h> | |
| #include <stdint.h> | |
| #endif // __cplusplus | |
| struct AV1_COMP; | |
| typedef struct AomAV1LoopfilterLevel { | |
| int filter_level[2]; | |
| int filter_level_u; | |
| int filter_level_v; | |
| } AomAV1LoopfilterLevel; | |
| typedef struct AomAV1CdefInfo { | |
| int cdef_strength_y; | |
| int cdef_strength_uv; | |
| int damping; | |
| } AomAV1CdefInfo; | |
| typedef struct AomAV1SegmentationData { | |
| const uint8_t *segmentation_map; | |
| size_t segmentation_map_size; | |
| const int *delta_q; | |
| size_t delta_q_size; | |
| } AomAV1SegmentationData; | |
| typedef enum AomFrameType { kAomKeyFrame, kAomInterFrame } AomFrameType; | |
| typedef struct AomAV1FrameParamsRTC { | |
| AomFrameType frame_type; | |
| int spatial_layer_id; | |
| int temporal_layer_id; | |
| } AomAV1FrameParamsRTC; | |
| typedef enum AomFrameDropDecision { | |
| kAomFrameDropDecisionOk, // Frame is encoded. | |
| kAomFrameDropDecisionDrop, // Frame is dropped. | |
| } AomFrameDropDecision; | |
| // These constants come from AV1 spec. | |
| enum { | |
| kAomAV1MaxLayers = 32, | |
| kAomAV1MaxTemporalLayers = 8, | |
| kAomAV1MaxSpatialLayers = 4, | |
| }; | |
| typedef struct AomAV1RateControlRtcConfig { | |
| #ifdef __cplusplus | |
| AomAV1RateControlRtcConfig(); | |
| #endif | |
| int width; | |
| int height; | |
| // Flag indicating if the content is screen or not. | |
| bool is_screen; | |
| // 0-63 | |
| int max_quantizer; | |
| int min_quantizer; | |
| int64_t target_bandwidth; | |
| int64_t buf_initial_sz; | |
| int64_t buf_optimal_sz; | |
| int64_t buf_sz; | |
| int undershoot_pct; | |
| int overshoot_pct; | |
| int max_intra_bitrate_pct; | |
| int max_inter_bitrate_pct; | |
| int frame_drop_thresh; | |
| int max_consec_drop_ms; | |
| double framerate; | |
| int layer_target_bitrate[kAomAV1MaxLayers]; | |
| int ts_rate_decimator[kAomAV1MaxTemporalLayers]; | |
| int aq_mode; | |
| // Number of spatial layers | |
| int ss_number_layers; | |
| // Number of temporal layers | |
| int ts_number_layers; | |
| int max_quantizers[kAomAV1MaxLayers]; | |
| int min_quantizers[kAomAV1MaxLayers]; | |
| int scaling_factor_num[kAomAV1MaxSpatialLayers]; | |
| int scaling_factor_den[kAomAV1MaxSpatialLayers]; | |
| // Bit-depth (8, 10, or 12). | |
| int bit_depth; | |
| } AomAV1RateControlRtcConfig; | |
| struct AomAV1RateControlRTC; | |
| typedef struct AomAV1RateControlRTC AomAV1RateControlRTC; | |
| #ifdef __cplusplus | |
| namespace aom { | |
| using AV1LoopfilterLevel = AomAV1LoopfilterLevel; | |
| using AV1CdefInfo = AomAV1CdefInfo; | |
| using AV1SegmentationData = AomAV1SegmentationData; | |
| using AV1FrameParamsRTC = AomAV1FrameParamsRTC; | |
| using AV1RateControlRtcConfig = AomAV1RateControlRtcConfig; | |
| using FrameType = AomFrameType; | |
| constexpr FrameType kKeyFrame = kAomKeyFrame; | |
| constexpr FrameType kInterFrame = kAomInterFrame; | |
| using FrameDropDecision = AomFrameDropDecision; | |
| constexpr FrameDropDecision kFrameDropDecisionOk = kAomFrameDropDecisionOk; | |
| constexpr FrameDropDecision kFrameDropDecisionDrop = kAomFrameDropDecisionDrop; | |
| class AV1RateControlRTC { | |
| public: | |
| static std::unique_ptr<AV1RateControlRTC> Create( | |
| const AV1RateControlRtcConfig &cfg); | |
| ~AV1RateControlRTC(); | |
| bool UpdateRateControl(const AV1RateControlRtcConfig &rc_cfg); | |
| // GetQP() needs to be called after ComputeQP() to get the latest QP | |
| int GetQP() const; | |
| // GetLoopfilterLevel() needs to be called after ComputeQP() | |
| AV1LoopfilterLevel GetLoopfilterLevel() const; | |
| // GetCdefInfo() needs to be called after ComputeQP() | |
| AV1CdefInfo GetCdefInfo() const; | |
| // Returns the segmentation map used for cyclic refresh, based on 4x4 blocks. | |
| bool GetSegmentationData(AV1SegmentationData *segmentation_data) const; | |
| // ComputeQP returns the QP if the frame is not dropped (kOk return), | |
| // otherwise it returns kDrop and subsequent GetQP and PostEncodeUpdate | |
| // are not to be called (av1_rc_postencode_update_drop_frame is already | |
| // called via ComputeQP if drop is decided). | |
| FrameDropDecision ComputeQP(const AV1FrameParamsRTC &frame_params); | |
| // Feedback to rate control with the size of current encoded frame | |
| void PostEncodeUpdate(uint64_t encoded_frame_size); | |
| private: | |
| AV1RateControlRTC() = default; | |
| bool InitRateControl(const AV1RateControlRtcConfig &cfg); | |
| AV1_COMP *cpi_; | |
| int initial_width_; | |
| int initial_height_; | |
| bool rc_is_valid_ = false; | |
| }; | |
| } // namespace aom | |
| #endif // __cplusplus | |
| #ifdef __cplusplus | |
| extern "C" { | |
| #endif | |
| AomAV1RateControlRTC *av1_ratecontrol_rtc_create( | |
| const AomAV1RateControlRtcConfig *rc_cfg); | |
| void av1_ratecontrol_rtc_destroy(AomAV1RateControlRTC *controller); | |
| bool av1_ratecontrol_rtc_update(AomAV1RateControlRTC *controller, | |
| const AomAV1RateControlRtcConfig *rc_cfg); | |
| int av1_ratecontrol_rtc_get_qp(const AomAV1RateControlRTC *controller); | |
| AomAV1LoopfilterLevel av1_ratecontrol_rtc_get_loop_filter_level( | |
| const AomAV1RateControlRTC *controller); | |
| AomFrameDropDecision av1_ratecontrol_rtc_compute_qp( | |
| AomAV1RateControlRTC *controller, const AomAV1FrameParamsRTC *frame_params); | |
| void av1_ratecontrol_rtc_post_encode_update(AomAV1RateControlRTC *controller, | |
| uint64_t encoded_frame_size); | |
| bool av1_ratecontrol_rtc_get_segmentation( | |
| const AomAV1RateControlRTC *controller, | |
| AomAV1SegmentationData *segmentation_data); | |
| AomAV1CdefInfo av1_ratecontrol_rtc_get_cdef_info( | |
| const AomAV1RateControlRTC *controller); | |
| void av1_ratecontrol_rtc_init_ratecontrol_config( | |
| AomAV1RateControlRtcConfig *config); | |
| #ifdef __cplusplus | |
| } // extern "C" | |
| #endif | |
| #endif // AOM_AV1_RATECTRL_RTC_H_ |