From 5380307bccbfd6e7b5b8d6acd06d451355fb592f Mon Sep 17 00:00:00 2001 From: "sayon.chen" Date: Mon, 6 Jan 2020 16:15:01 +0800 Subject: [PATCH] [rkv_h265e]: Move rc qp calc from api to hal Change-Id: I8d64c97d3be4828feabb10fbe9077ac9a125b229 Signed-off-by: sayon.chen --- mpp/codec/enc/h265/h265e_api_v2.c | 74 +------- mpp/codec/enc/h265/h265e_codec.h | 34 +--- mpp/codec/enc/h265/h265e_syntax.c | 70 +------- mpp/common/h265e_syntax_new.h | 45 +++-- mpp/hal/rkenc/h265e/hal_h265e_rkv.c | 220 ++++++++++++++++++------ mpp/hal/rkenc/h265e/hal_h265e_rkv_ctx.h | 7 + 6 files changed, 208 insertions(+), 242 deletions(-) diff --git a/mpp/codec/enc/h265/h265e_api_v2.c b/mpp/codec/enc/h265/h265e_api_v2.c index 0e5c871e..f77a5610 100644 --- a/mpp/codec/enc/h265/h265e_api_v2.c +++ b/mpp/codec/enc/h265/h265e_api_v2.c @@ -31,28 +31,6 @@ extern RK_U32 h265e_debug; -static RK_U32 mb_num[12] = { - 0x0, 0xc8, 0x2bc, 0x4b0, - 0x7d0, 0xfa0, 0x1f40, 0x3e80, - 0x4e20, 0x4e20, 0x4e20, 0x4e20, -}; - -static RK_U32 tab_bit[12] = { - 0xEC4, 0xDF2, 0xC4E, 0xB7C, 0xAAA, 0xEC4, 0x834, 0x690, 0x834, 0x834, 0x834, 0x834, -}; - -static RK_U8 qp_table[96] = { - 0xF, 0xF, 0xF, 0xF, 0xF, 0x10, 0x12, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x19, 0x1A, 0x1B, 0x1C, 0x1C, 0x1D, 0x1D, 0x1E, 0x1E, - 0x1E, 0x1F, 0x1F, 0x20, 0x20, 0x21, 0x21, 0x21, 0x22, 0x22, 0x22, - 0x22, 0x23, 0x23, 0x23, 0x24, 0x24, 0x24, 0x24, 0x24, 0x25, 0x25, - 0x25, 0x25, 0x26, 0x26, 0x26, 0x26, 0x26, 0x27, 0x27, 0x27, 0x27, - 0x27, 0x27, 0x28, 0x28, 0x28, 0x28, 0x29, 0x29, 0x29, 0x29, 0x29, - 0x29, 0x29, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2B, - 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2C, 0x2C, 0x2C, 0x2C, - 0x2C, 0x2C, 0x2C, 0x2C, 0x2D, 0x2D, 0x2D, 0x2D, -}; - static MPP_RET h265e_init(void *ctx, EncImplCfg *ctrlCfg) { H265eCtx *p = (H265eCtx *)ctx; @@ -94,6 +72,7 @@ static MPP_RET h265e_init(void *ctx, EncImplCfg *ctrlCfg) h265->max_i_qp = 51; h265->min_i_qp = 10; h265->ip_qp_delta = 3; + h265->raw_dealt_qp = 2; h265->max_delta_qp = 10; h265->const_intra_pred = 0; h265->gop_delta_qp = 0; @@ -394,21 +373,6 @@ static MPP_RET h265e_proc_dpb(void *ctx, HalEncTask *task) return MPP_OK; } -static RK_S32 cal_first_i_start_qp(RK_S32 target_bit, RK_U32 total_mb) -{ - RK_S32 cnt = 0, index, i; - - for (i = 0; i < 11; i++) { - if (mb_num[i] > total_mb) - break; - cnt++; - } - index = (total_mb * tab_bit[cnt] - 300) / target_bit; // - index = mpp_clip(index, 4, 95); - - return qp_table[index]; -} - static MPP_RET h265e_proc_rc(void *ctx, HalEncTask *task) { (void)task; @@ -425,39 +389,6 @@ static MPP_RET h265e_proc_rc(void *ctx, HalEncTask *task) rc_frm_start(p->rc_ctx, &frms->rc_cfg, &frms->status); - if (frms->seq_idx == 0 && frms->status.is_intra) { - if (h265->qp_init == -1) { - frms->start_qp = cal_first_i_start_qp(frms->rc_cfg.bit_target, frms->mb_per_frame << 4); - frms->cur_scale_qp = (frms->start_qp + h265->ip_qp_delta) << 6; - } else { - - frms->start_qp = h265->qp_init; - frms->cur_scale_qp = (frms->start_qp + h265->ip_qp_delta) << 6; - } - - frms->pre_i_qp = frms->cur_scale_qp >> 6; - frms->pre_p_qp = frms->cur_scale_qp >> 6; - frms->frame_type = INTRA_FRAME; - } else { - RK_S32 qp_scale = frms->cur_scale_qp + frms->rc_cfg.next_ratio; - RK_S32 start_qp = 0; - - if (frms->status.is_intra) { - frms->frame_type = INTRA_FRAME; - qp_scale = mpp_clip(qp_scale, (h265->min_i_qp << 6), (h265->max_i_qp << 6)); - start_qp = ((frms->pre_i_qp + ((qp_scale + frms->rc_cfg.next_i_ratio) >> 6)) >> 1); - - start_qp = mpp_clip(start_qp, h265->min_i_qp, h265->max_i_qp); - frms->pre_i_qp = start_qp; - frms->start_qp = start_qp; - frms->cur_scale_qp = qp_scale; - } else { - frms->frame_type = INTER_P_FRAME; - qp_scale = mpp_clip(qp_scale, (h265->min_qp << 6), (h265->max_qp << 6)); - frms->cur_scale_qp = qp_scale; - frms->start_qp = qp_scale >> 6; - } - } p->frms.status.reencode = 0; h265e_dbg_func("leave\n"); @@ -523,10 +454,7 @@ static MPP_RET h265e_update_rc(void *ctx, HalEncTask *task) if (rc_hal_cfg->need_reenc) { p->frms.status.reencode = 1; - } else { - p->frms.last_frame_type = p->frms.frame_type; } - h265e_dbg_func("leave\n"); return MPP_OK; } diff --git a/mpp/codec/enc/h265/h265e_codec.h b/mpp/codec/enc/h265/h265e_codec.h index b742b1bc..aeffc6d6 100644 --- a/mpp/codec/enc/h265/h265e_codec.h +++ b/mpp/codec/enc/h265/h265e_codec.h @@ -22,10 +22,10 @@ #include "mpp_rc.h" #include "h265e_syntax.h" +#include "h265e_syntax_new.h" #include "h265e_dpb.h" #include "enc_impl_api.h" #include "rc_api.h" -#include "rc.h" #define H265E_DBG_FUNCTION (0x00000001) #define H265E_DBG_INPUT (0x00000010) @@ -55,36 +55,6 @@ extern RK_U32 h265e_debug; #define h265e_dbg_dpb(fmt, ...) h265e_dbg(H265E_DBG_DPB, fmt, ## __VA_ARGS__) #define h265e_dbg_slice(fmt, ...) h265e_dbg(H265E_DBG_SLICE, fmt, ## __VA_ARGS__) -/* - * Split reference frame configure to two parts - * The first part is slice depended info like poc / frame_num, and frame - * type and flags. - * The other part is gop structure depended info like gop index, ref_status - * and ref_frm_index. This part is inited from dpb gop hierarchy info. - */ -typedef struct H265eFrmInfo_s { - RK_S32 seq_idx; - - RK_S32 curr_idx; - RK_S32 refr_idx; - - // current frame rate control and dpb status info - RK_S32 mb_per_frame; - RK_S32 mb_raw; - RK_S32 mb_wid; - RK_S32 frame_type; - RK_S32 last_frame_type; - RK_S32 cur_scale_qp; - RK_S32 pre_i_qp; - RK_S32 pre_p_qp; - RK_S32 start_qp; - - RcHalCfg rc_cfg; - EncFrmStatus status; - - RK_S32 usage[MAX_REFS + 1]; -} H265eFrmInfo; - typedef struct H265eCtx_t { MppEncCfgSet *cfg; MppEncCfgSet *set; @@ -107,7 +77,7 @@ typedef struct H265eCtx_t { void *extra_info; void *param_buf; MppPacket packeted_param; - H265eSyntax syntax; + H265eSyntax_new syntax; H265eFeedback feedback; struct list_head rc_list; } H265eCtx; diff --git a/mpp/codec/enc/h265/h265e_syntax.c b/mpp/codec/enc/h265/h265e_syntax.c index 2a16843f..46462397 100644 --- a/mpp/codec/enc/h265/h265e_syntax.c +++ b/mpp/codec/enc/h265/h265e_syntax.c @@ -340,74 +340,10 @@ RK_S32 fill_ref_parameters(const H265eCtx *h, H265eSlicParams *sp) } -RK_S32 fill_rc_parameters(H265eCtx *h, RcParams *rp) +RK_S32 fill_frm_info(H265eCtx *h, H265eFrmInfo *syn_frms) { H265eFrmInfo *frms = &h->frms; - MppEncRcCfg *rc = &h->cfg->rc; - RcHalCfg *rc_cfg = &frms->rc_cfg; - MppEncCodecCfg *codec = &h->cfg->codec; - MppEncH265Cfg *h265 = &codec->h265; - RK_U32 i; - RK_U32 ctu_target_bits_mul_16 = (rc_cfg->bit_target << 4) / frms->mb_per_frame; - RK_U32 ctu_target_bits; - RK_S32 negative_bits_thd, positive_bits_thd; - memset(rp, 0, sizeof(RcParams)); - if (ctu_target_bits_mul_16 >= 0x100000) { - ctu_target_bits_mul_16 = 0x50000; - } - - ctu_target_bits = (ctu_target_bits_mul_16 * frms->mb_wid) >> 4; - negative_bits_thd = 0 - ctu_target_bits / 4; - positive_bits_thd = ctu_target_bits / 4; - - if (rc->rc_mode == MPP_ENC_RC_MODE_FIXQP) { - rp->pic_qp = h265->qp_init; - rp->rc_max_qp = h265->qp_init; - rp->rc_min_qp = h265->qp_init; - return 0; - } - - rp->rc_en = 1; - rp->rc_qp_range = 2; - - rp->pic_qp = frms->start_qp; - - if (frms->status.is_intra) { - rp->rc_max_qp = h265->max_i_qp; - rp->rc_min_qp = h265->min_i_qp; - } else { - rp->rc_max_qp = h265->max_qp; - rp->rc_min_qp = h265->min_qp; - } - rp->frame_type = frms->status.is_intra ? 2 : 0; - rp->rc_ctu_num = frms->mb_wid; - - rp->ctu_ebits = ctu_target_bits_mul_16; - rp->bits_thd[0] = negative_bits_thd; - rp->bits_thd[1] = positive_bits_thd; - rp->bits_thd[2] = positive_bits_thd; - - rp->bits_thd[3] = positive_bits_thd; - rp->bits_thd[4] = positive_bits_thd; - rp->bits_thd[5] = positive_bits_thd; - rp->bits_thd[6] = positive_bits_thd; - rp->bits_thd[7] = positive_bits_thd; - rp->bits_thd[8] = positive_bits_thd; - - rp->qp_adjust[0] = -1; - rp->qp_adjust[1] = 0; - rp->qp_adjust[2] = 0; - rp->qp_adjust[3] = 0; - rp->qp_adjust[4] = 0; - rp->qp_adjust[5] = 0; - rp->qp_adjust[6] = 0; - rp->qp_adjust[7] = 0; - rp->qp_adjust[8] = 1; - for ( i = 0; i < 8; i++) { - rp->qpmax_area[i] = h265->qpmax_map[i]; - rp->qpmin_area[i] = h265->qpmin_map[i]; - } - rp->qpmap_mode = h265->qpmap_mode; + memcpy(syn_frms, frms, sizeof(*frms)); return 0; } @@ -418,7 +354,7 @@ RK_S32 h265e_syntax_fill(void *ctx) fill_picture_parameters(h, &syn->pp); fill_slice_parameters(h, &syn->sp); fill_ref_parameters(h, &syn->sp); - fill_rc_parameters(h, &syn->rp); + fill_frm_info(h, &syn->frms); syn->ud.plt_data = NULL; if (h->plt_flag) { syn->ud.plt_data = (void*)&h->cfg->osd_plt; diff --git a/mpp/common/h265e_syntax_new.h b/mpp/common/h265e_syntax_new.h index 8946b0d3..37d8f83b 100644 --- a/mpp/common/h265e_syntax_new.h +++ b/mpp/common/h265e_syntax_new.h @@ -17,6 +17,8 @@ #ifndef __H265E_SYNTAX_NEW_H__ #define __H265E_SYNTAX_NEW_H__ #include "mpp_rc.h" +#include "h265_syntax.h" +#include "rc.h" typedef struct H265PicEntry_t { RK_U8 bPicEntry[3]; @@ -188,24 +190,31 @@ typedef struct H265eSlicParams_t { RK_U32 sli_splt_byte; RK_U32 tot_poc_num; } H265eSlicParams; +/* + * Split reference frame configure to two parts + * The first part is slice depended info like poc / frame_num, and frame + * type and flags. + * The other part is gop structure depended info like gop index, ref_status + * and ref_frm_index. This part is inited from dpb gop hierarchy info. + */ -typedef struct RcParams_t { - RK_U8 rc_en; - RK_U8 pic_qp; - RK_U8 frame_type; - RK_U8 coding_type; - RK_U8 rc_qp_range; - RK_U8 rc_max_qp; - RK_U8 rc_min_qp; - RK_U16 rc_ctu_num; - RK_U32 ctu_ebits; - RK_S32 bits_thd[9]; - RK_S8 qp_adjust[9]; - RK_U8 qpmax_area[8]; - RK_U8 qpmin_area[8]; - RK_U8 qpmap_mode; - RK_U32 bit_target; -} RcParams; +typedef struct H265eFrmInfo_s { + RK_S32 seq_idx; + + RK_S32 curr_idx; + RK_S32 refr_idx; + + // current frame rate control and dpb status info + RK_S32 mb_per_frame; + RK_S32 mb_raw; + RK_S32 mb_wid; + RK_S32 frame_type; + RK_S32 last_frame_type; + + RcHalCfg rc_cfg; + EncFrmStatus status; + RK_S32 usage[MAX_REFS + 1]; +} H265eFrmInfo; typedef struct UserDatas_t { void *plt_data; @@ -215,8 +224,8 @@ typedef struct H265eSyntax_new_t { RK_S32 idr_request; H265ePicParams pp; H265eSlicParams sp; - RcParams rp; UserDatas ud; + H265eFrmInfo frms; } H265eSyntax_new; #ifdef __cplusplus diff --git a/mpp/hal/rkenc/h265e/hal_h265e_rkv.c b/mpp/hal/rkenc/h265e/hal_h265e_rkv.c index 19f01505..c1f2e04e 100644 --- a/mpp/hal/rkenc/h265e/hal_h265e_rkv.c +++ b/mpp/hal/rkenc/h265e/hal_h265e_rkv.c @@ -128,6 +128,43 @@ RK_U32 lamd_modb_qp[52] = { 0x00700000, 0x00890000, 0x00b00000, 0x00e00000 }; +static RK_U32 mb_num[12] = { + 0x0, 0xc8, 0x2bc, 0x4b0, + 0x7d0, 0xfa0, 0x1f40, 0x3e80, + 0x4e20, 0x4e20, 0x4e20, 0x4e20, +}; + +static RK_U32 tab_bit[12] = { + 0xEC4, 0xDF2, 0xC4E, 0xB7C, 0xAAA, 0xEC4, 0x834, 0x690, 0x834, 0x834, 0x834, 0x834, +}; + +static RK_U8 qp_table[96] = { + 0xF, 0xF, 0xF, 0xF, 0xF, 0x10, 0x12, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x19, 0x1A, 0x1B, 0x1C, 0x1C, 0x1D, 0x1D, 0x1E, 0x1E, + 0x1E, 0x1F, 0x1F, 0x20, 0x20, 0x21, 0x21, 0x21, 0x22, 0x22, 0x22, + 0x22, 0x23, 0x23, 0x23, 0x24, 0x24, 0x24, 0x24, 0x24, 0x25, 0x25, + 0x25, 0x25, 0x26, 0x26, 0x26, 0x26, 0x26, 0x27, 0x27, 0x27, 0x27, + 0x27, 0x27, 0x28, 0x28, 0x28, 0x28, 0x29, 0x29, 0x29, 0x29, 0x29, + 0x29, 0x29, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2B, + 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2C, 0x2C, 0x2C, 0x2C, + 0x2C, 0x2C, 0x2C, 0x2C, 0x2D, 0x2D, 0x2D, 0x2D, +}; + +static RK_S32 cal_first_i_start_qp(RK_S32 target_bit, RK_U32 total_mb) +{ + RK_S32 cnt = 0, index, i; + + for (i = 0; i < 11; i++) { + if (mb_num[i] > total_mb) + break; + cnt++; + } + index = (total_mb * tab_bit[cnt] - 300) / target_bit; // + index = mpp_clip(index, 4, 95); + + return qp_table[index]; +} + static MPP_RET h265e_rkv_free_buffers(H265eRkvHalContext *ctx) { @@ -358,8 +395,8 @@ MPP_RET hal_h265e_rkv_init(void *hal, MppEncHalCfg *cfg) ctx->ioctl_output = mpp_calloc(H265eRkvIoctlOutput, 1); ctx->regs = mpp_calloc(H265eRkvRegSet, RKVE_LINKTABLE_FRAME_NUM); ctx->l2_regs = mpp_calloc(H265eRkvL2RegSet, RKVE_LINKTABLE_FRAME_NUM); - ctx->rc_hal_cfg = mpp_calloc(H265eRkvL2RegSet, RKVE_LINKTABLE_FRAME_NUM); - ctx->buffers = mpp_calloc(RcHalCfg, RKVE_LINKTABLE_FRAME_NUM); + ctx->rc_hal_cfg = mpp_calloc(RcHalCfg, RKVE_LINKTABLE_FRAME_NUM); + ctx->buffers = mpp_calloc(h265e_hal_rkv_buffers, RKVE_LINKTABLE_FRAME_NUM); ctx->set = cfg->set; ctx->cfg = cfg->cfg; @@ -607,56 +644,125 @@ h265e_rkv_set_roi_regs(H265eRkvHalContext *ctx, H265eRkvRegSet *regs) return MPP_OK; } -static MPP_RET h265e_rkv_set_rc_regs(H265eRkvRegSet *regs, H265eSyntax_new *syn) +static MPP_RET h265e_rkv_set_rc_regs(H265eRkvHalContext *ctx, H265eRkvRegSet *regs, H265eSyntax_new *syn) { - regs->enc_pic.pic_qp = syn->rp.pic_qp; - regs->rc_cfg.rc_en = syn->rp.rc_en; - regs->synt_sli1.sli_qp = syn->rp.pic_qp; + H265eFrmInfo *frms = &syn->frms; + MppEncCfgSet *cfg = ctx->cfg; + MppEncRcCfg *rc = &cfg->rc; + RcHalCfg *rc_cfg = &frms->rc_cfg; + MppEncCodecCfg *codec = &cfg->codec; + MppEncH265Cfg *h265 = &codec->h265; + RK_U32 ctu_target_bits_mul_16 = (rc_cfg->bit_target << 4) / frms->mb_per_frame; + RK_U32 ctu_target_bits; + RK_S32 negative_bits_thd, positive_bits_thd; - regs->rc_cfg.rc_ctu_num = syn->rp.rc_ctu_num; - regs->rc_qp.rc_qp_range = syn->rp.rc_qp_range; - regs->rc_qp.rc_max_qp = syn->rp.rc_max_qp; - regs->rc_qp.rc_min_qp = syn->rp.rc_min_qp; - regs->rc_tgt.ctu_ebits = syn->rp.ctu_ebits; + if (frms->seq_idx == 0 && frms->status.is_intra) { + if (h265->qp_init == -1) { + ctx->start_qp = cal_first_i_start_qp(frms->rc_cfg.bit_target, frms->mb_per_frame << 4); + ctx->cur_scale_qp = (ctx->start_qp + h265->ip_qp_delta) << 6; + } else { - regs->rc_erp0.bits_thd0 = syn->rp.bits_thd[0]; - regs->rc_erp1.bits_thd1 = syn->rp.bits_thd[1]; - regs->rc_erp2.bits_thd2 = syn->rp.bits_thd[2]; - regs->rc_erp3.bits_thd3 = syn->rp.bits_thd[3]; - regs->rc_erp4.bits_thd4 = syn->rp.bits_thd[4]; - regs->rc_erp5.bits_thd5 = syn->rp.bits_thd[5]; - regs->rc_erp6.bits_thd6 = syn->rp.bits_thd[6]; - regs->rc_erp7.bits_thd7 = syn->rp.bits_thd[7]; - regs->rc_erp8.bits_thd8 = syn->rp.bits_thd[8]; + ctx->start_qp = h265->qp_init; + ctx->cur_scale_qp = (ctx->start_qp + h265->ip_qp_delta) << 6; + } - regs->rc_adj0.qp_adjust0 = syn->rp.qp_adjust[0]; - regs->rc_adj0.qp_adjust1 = syn->rp.qp_adjust[1]; - regs->rc_adj0.qp_adjust2 = syn->rp.qp_adjust[2]; - regs->rc_adj0.qp_adjust3 = syn->rp.qp_adjust[3]; - regs->rc_adj0.qp_adjust4 = syn->rp.qp_adjust[4]; - regs->rc_adj1.qp_adjust5 = syn->rp.qp_adjust[5]; - regs->rc_adj1.qp_adjust6 = syn->rp.qp_adjust[6]; - regs->rc_adj1.qp_adjust7 = syn->rp.qp_adjust[7]; - regs->rc_adj1.qp_adjust8 = syn->rp.qp_adjust[8]; + ctx->pre_i_qp = ctx->cur_scale_qp >> 6; + ctx->pre_p_qp = ctx->cur_scale_qp >> 6; + } else { + RK_S32 qp_scale = ctx->cur_scale_qp + frms->rc_cfg.next_ratio; + RK_S32 start_qp = 0; - regs->qpmap0.qpmin_area0 = syn->rp.qpmin_area[1]; - regs->qpmap0.qpmax_area0 = syn->rp.qpmax_area[1]; - regs->qpmap0.qpmin_area1 = syn->rp.qpmin_area[1]; - regs->qpmap0.qpmax_area1 = syn->rp.qpmax_area[2]; - regs->qpmap0.qpmin_area2 = syn->rp.qpmin_area[2]; - regs->qpmap1.qpmax_area2 = syn->rp.qpmax_area[2]; - regs->qpmap1.qpmin_area3 = syn->rp.qpmin_area[3]; - regs->qpmap1.qpmax_area3 = syn->rp.qpmax_area[3]; - regs->qpmap1.qpmin_area4 = syn->rp.qpmin_area[4]; - regs->qpmap1.qpmax_area4 = syn->rp.qpmax_area[4]; - regs->qpmap2.qpmin_area5 = syn->rp.qpmin_area[5]; - regs->qpmap2.qpmax_area5 = syn->rp.qpmax_area[5]; - regs->qpmap2.qpmin_area6 = syn->rp.qpmin_area[6]; - regs->qpmap2.qpmax_area6 = syn->rp.qpmax_area[6]; - regs->qpmap2.qpmin_area7 = syn->rp.qpmin_area[7]; - regs->qpmap3.qpmax_area7 = syn->rp.qpmax_area[7]; - regs->qpmap3.qpmap_mode = syn->rp.qpmap_mode; + if (frms->status.is_intra) { + qp_scale = mpp_clip(qp_scale, (h265->min_i_qp << 6), (h265->max_i_qp << 6)); + start_qp = ((ctx->pre_i_qp + ((qp_scale + frms->rc_cfg.next_i_ratio) >> 6)) >> 1); + start_qp = mpp_clip(start_qp, h265->min_i_qp, h265->max_i_qp); + ctx->pre_i_qp = start_qp; + ctx->start_qp = start_qp; + ctx->cur_scale_qp = qp_scale; + } else { + qp_scale = mpp_clip(qp_scale, (h265->min_qp << 6), (h265->max_qp << 6)); + ctx->cur_scale_qp = qp_scale; + ctx->start_qp = qp_scale >> 6; + } + } + if (rc->rc_mode == MPP_ENC_RC_MODE_FIXQP) { + regs->enc_pic.pic_qp = h265->qp_init; + regs->synt_sli1.sli_qp = h265->qp_init; + + regs->rc_qp.rc_max_qp = h265->qp_init; + regs->rc_qp.rc_min_qp = h265->qp_init; + } else { + RK_S32 rc_max_qp, rc_min_qp; + if (ctu_target_bits_mul_16 >= 0x100000) { + ctu_target_bits_mul_16 = 0x50000; + } + ctu_target_bits = (ctu_target_bits_mul_16 * frms->mb_wid) >> 4; + negative_bits_thd = 0 - ctu_target_bits / 4; + positive_bits_thd = ctu_target_bits / 4; + + if (frms->status.is_intra) { + rc_max_qp = h265->max_i_qp; + rc_min_qp = h265->min_i_qp; + } else { + rc_max_qp = h265->max_qp; + rc_min_qp = h265->min_qp; + } + mpp_log("ctx->start_qp = %d", ctx->start_qp); + regs->enc_pic.pic_qp = ctx->start_qp; + regs->rc_cfg.rc_en = 1; + regs->synt_sli1.sli_qp = ctx->start_qp; + + regs->rc_cfg.rc_ctu_num = frms->mb_wid; + regs->rc_qp.rc_qp_range = h265->raw_dealt_qp; + regs->rc_qp.rc_max_qp = rc_max_qp; + regs->rc_qp.rc_min_qp = rc_min_qp; + regs->rc_tgt.ctu_ebits = ctu_target_bits_mul_16; + + regs->rc_erp0.bits_thd0 = negative_bits_thd; + regs->rc_erp1.bits_thd1 = positive_bits_thd; + regs->rc_erp2.bits_thd2 = positive_bits_thd; + regs->rc_erp3.bits_thd3 = positive_bits_thd; + regs->rc_erp4.bits_thd4 = positive_bits_thd; + regs->rc_erp5.bits_thd5 = positive_bits_thd; + regs->rc_erp6.bits_thd6 = positive_bits_thd; + regs->rc_erp7.bits_thd7 = positive_bits_thd; + regs->rc_erp8.bits_thd8 = positive_bits_thd; + + regs->rc_adj0.qp_adjust0 = -1; + regs->rc_adj0.qp_adjust1 = 0; + regs->rc_adj0.qp_adjust2 = 0; + regs->rc_adj0.qp_adjust3 = 0; + regs->rc_adj0.qp_adjust4 = 0; + regs->rc_adj1.qp_adjust5 = 0; + regs->rc_adj1.qp_adjust6 = 0; + regs->rc_adj1.qp_adjust7 = 0; + regs->rc_adj1.qp_adjust8 = 1; + + regs->qpmap0.qpmin_area0 = h265->qpmin_map[0]; + regs->qpmap0.qpmax_area0 = h265->qpmax_map[0]; + regs->qpmap0.qpmin_area1 = h265->qpmin_map[1]; + regs->qpmap0.qpmax_area1 = h265->qpmax_map[1]; + regs->qpmap0.qpmin_area2 = h265->qpmin_map[2]; + regs->qpmap1.qpmax_area2 = h265->qpmax_map[2]; + regs->qpmap1.qpmin_area3 = h265->qpmin_map[3]; + regs->qpmap1.qpmax_area3 = h265->qpmax_map[3]; + regs->qpmap1.qpmin_area4 = h265->qpmin_map[4]; + regs->qpmap1.qpmax_area4 = h265->qpmax_map[4]; + regs->qpmap2.qpmin_area5 = h265->qpmin_map[5]; + regs->qpmap2.qpmax_area5 = h265->qpmax_map[5]; + regs->qpmap2.qpmin_area6 = h265->qpmin_map[6]; + regs->qpmap2.qpmax_area6 = h265->qpmax_map[6]; + regs->qpmap2.qpmin_area7 = h265->qpmin_map[7]; + regs->qpmap3.qpmax_area7 = h265->qpmax_map[7]; + regs->qpmap3.qpmap_mode = h265->qpmap_mode; + } + if (ctx->frame_type == INTRA_FRAME) { + regs->enc_pic.rdo_wgt_sel = 0; + } else { + regs->enc_pic.rdo_wgt_sel = 1; + } + regs->dtrns_cfg.cime_dspw_orsd = (ctx->frame_type == INTER_P_FRAME); return MPP_OK; } @@ -808,7 +914,7 @@ MPP_RET hal_h265e_rkv_gen_regs(void *hal, HalEncTask *task) fbc_header_len = (pic_wd64 * pic_h64) << 6; h265e_hal_dbg(H265E_DBG_SIMPLE, "frame %d | type %d | start gen regs", - ctx->frame_cnt, syn->rp.frame_type); + ctx->frame_cnt, ctx->frame_type); if (ctx->enc_mode == 2 || ctx->enc_mode == 3) { //link table mode RK_U32 idx = ctx->frame_cnt_gen_ready; @@ -859,7 +965,7 @@ MPP_RET hal_h265e_rkv_gen_regs(void *hal, HalEncTask *task) regs->enc_pic.node_int = 0; regs->enc_pic.log2_ctu_num = ceil(log2((double)pic_wd64 * pic_h64)); - if (syn->rp.frame_type == INTRA_FRAME) { + if (ctx->frame_type == INTRA_FRAME) { regs->enc_pic.rdo_wgt_sel = 0; } else { regs->enc_pic.rdo_wgt_sel = 1; @@ -868,7 +974,7 @@ MPP_RET hal_h265e_rkv_gen_regs(void *hal, HalEncTask *task) regs->enc_wdg.vs_load_thd = 0; regs->enc_wdg.rfp_load_thd = 0; - regs->dtrns_cfg.cime_dspw_orsd = (syn->rp.frame_type == INTER_P_FRAME); + regs->dtrns_cfg.cime_dspw_orsd = (ctx->frame_type == INTER_P_FRAME); regs->dtrns_map.src_bus_ordr = 0x0; regs->dtrns_map.cmvw_bus_ordr = 0x0; @@ -1044,10 +1150,10 @@ MPP_RET hal_h265e_rkv_gen_regs(void *hal, HalEncTask *task) RK_U32 i_nal_type = 0; /* TODO: extend syn->frame_coding_type definition */ - if (syn->rp.frame_type == INTRA_FRAME) { + if (ctx->frame_type == INTRA_FRAME) { /* reset ref pictures */ i_nal_type = NAL_IDR_W_RADL; - } else if (syn->rp.frame_type == INTER_P_FRAME ) { + } else if (ctx->frame_type == INTER_P_FRAME ) { i_nal_type = NAL_TRAIL_R; } else { i_nal_type = NAL_TRAIL_R; @@ -1055,7 +1161,9 @@ MPP_RET hal_h265e_rkv_gen_regs(void *hal, HalEncTask *task) regs->synt_nal.nal_unit_type = i_nal_type; } h265e_rkv_set_pp_regs(regs, &ctx->cfg->prep); - h265e_rkv_set_rc_regs(regs, syn); + + h265e_rkv_set_rc_regs(ctx, regs, syn); + h265e_rkv_set_slice_regs(syn, regs); h265e_rkv_set_ref_regs(syn, regs); @@ -1321,6 +1429,8 @@ MPP_RET hal_h265e_rkv_get_task(void *hal, HalEncTask *task) H265eSyntax_new *syn = (H265eSyntax_new *)task->syntax.data; MppFrame frame = task->frame; MppMeta meta = mpp_frame_get_meta(frame); + H265eFrmInfo *frms = &syn->frms; + h265e_hal_enter(); if ((!ctx->alloc_flg)) { if (MPP_OK != h265e_rkv_allocate_buffers(ctx, syn)) { @@ -1332,6 +1442,12 @@ MPP_RET hal_h265e_rkv_get_task(void *hal, HalEncTask *task) ctx->alloc_flg = 1; } + if (frms->status.is_intra) { + ctx->frame_type = INTRA_FRAME; + } else { + ctx->frame_type = INTER_P_FRAME; + } + ctx->roi_data = NULL; ctx->osd_data = NULL; mpp_meta_get_ptr(meta, KEY_ROI_DATA, (void**)&ctx->roi_data); diff --git a/mpp/hal/rkenc/h265e/hal_h265e_rkv_ctx.h b/mpp/hal/rkenc/h265e/hal_h265e_rkv_ctx.h index 2a36baca..3f49fea3 100644 --- a/mpp/hal/rkenc/h265e/hal_h265e_rkv_ctx.h +++ b/mpp/hal/rkenc/h265e/hal_h265e_rkv_ctx.h @@ -59,6 +59,13 @@ typedef struct H265eRkvHalContext_t { RK_U32 frame_cnt_send_ready; RK_U32 num_frames_to_send; + /*qp decision*/ + RK_S32 cur_scale_qp; + RK_S32 pre_i_qp; + RK_S32 pre_p_qp; + RK_S32 start_qp; + RK_S32 frame_type; + /* @frame_cnt starts from ZERO */ RK_U32 frame_cnt; RK_S32 osd_plt_type;