/* * 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 #include #include #else #include #include #include #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]; } 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 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_; }; } // 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_