From 3582a78e3460ec3a20fdb8dc78efb3b71e586b92 Mon Sep 17 00:00:00 2001 From: Lin Kesheng Date: Fri, 6 Jan 2017 18:10:42 +0800 Subject: [PATCH] [hal_h264e_rkv]: implement mb rc configuration 1. add H264eRcCtx to control mb rc 2. define H264eRkvMbRcCfg to list cfgs on each level 3. merge from trunk 4. implement checpoint error_bits and delta_qp according the relativeness between qp and bits 5. correct qp_adjust 6. merge from trunk 7. correct traget_bit_error 8. VBR: adjust qp_min/qp_max according to quality configuration Change-Id: I25eefc992c6e68842a675fd04286d0564bd5d2c2 Signed-off-by: Lin Kesheng --- mpp/codec/mpp_rc.cpp | 4 +- mpp/common/h264e_syntax.h | 1 - mpp/hal/common/h264/hal_h264e_com.c | 4 +- mpp/hal/common/h264/hal_h264e_com.h | 53 +++++++++ mpp/hal/rkenc/h264e/hal_h264e_rkv.c | 175 ++++++++++++++++++++-------- mpp/hal/rkenc/h264e/hal_h264e_rkv.h | 18 +++ test/mpi_rc_test.c | 49 ++++---- 7 files changed, 226 insertions(+), 78 deletions(-) diff --git a/mpp/codec/mpp_rc.cpp b/mpp/codec/mpp_rc.cpp index 56f5536f..76057580 100644 --- a/mpp/codec/mpp_rc.cpp +++ b/mpp/codec/mpp_rc.cpp @@ -385,7 +385,7 @@ MPP_RET mpp_rc_bits_allocation(MppRateControl *ctx, RcSyntax *rc_syn) if (ctx->acc_intra_count) { intra_percent = ctx->acc_intra_bits * 1.0 / - (ctx->acc_intra_bits + ctx->acc_inter_bits); + (ctx->acc_intra_bits + ctx->acc_inter_bits); ctx->last_intra_percent = intra_percent; } @@ -403,7 +403,7 @@ MPP_RET mpp_rc_bits_allocation(MppRateControl *ctx, RcSyntax *rc_syn) RK_S32 bits_prev_intra = mpp_data_avg(ctx->intra, 1, 1, 1); ctx->bits_per_inter = (ctx->bps_target - bits_prev_intra + diff_bit * (1 - ctx->last_intra_percent)) / - (ctx->window_len - 1); + (ctx->window_len - 1); mpp_rc_dbg_rc("RC: rc ctx %p bits pic %d win %d intra %d inter %d\n", ctx, ctx->bits_per_pic, ctx->window_len, diff --git a/mpp/common/h264e_syntax.h b/mpp/common/h264e_syntax.h index e8b5c59c..56c3241e 100644 --- a/mpp/common/h264e_syntax.h +++ b/mpp/common/h264e_syntax.h @@ -95,7 +95,6 @@ typedef struct H264eHwCfg_t { RK_S32 link_table_en; RK_S32 keyframe_max_interval; - RK_S32 mb_rc_mode; //0: disable mbrc, 1:slice/frame rc, 2:MB rc. RK_S32 roi_en; RK_S32 osd_mode; //0: disable osd, 1:palette type 0(congfigurable mode), 2:palette type 1(fixed mode). RK_S32 preproc_en; diff --git a/mpp/hal/common/h264/hal_h264e_com.c b/mpp/hal/common/h264/hal_h264e_com.c index f42bdaa7..e1704b08 100644 --- a/mpp/hal/common/h264/hal_h264e_com.c +++ b/mpp/hal/common/h264/hal_h264e_com.c @@ -697,12 +697,12 @@ MPP_RET hal_h264e_set_pps(h264e_hal_context *ctx, h264e_hal_pps *pps, h264e_hal_ if (sps->i_profile_idc < H264_PROFILE_HIGH) { if (pps->b_transform_8x8_mode) { pps->b_transform_8x8_mode = 0; - mpp_log_f("wanrning: for profile %d b_transform_8x8_mode should be 0", + mpp_log_f("warning: for profile %d b_transform_8x8_mode should be 0", sps->i_profile_idc); } if (pps->i_second_chroma_qp_index_offset) { pps->i_second_chroma_qp_index_offset = 0; - mpp_log_f("wanrning: for profile %d i_second_chroma_qp_index_offset should be 0", + mpp_log_f("warning: for profile %d i_second_chroma_qp_index_offset should be 0", sps->i_profile_idc); } } diff --git a/mpp/hal/common/h264/hal_h264e_com.h b/mpp/hal/common/h264/hal_h264e_com.h index fc3cfbc2..ffe0ebcb 100644 --- a/mpp/hal/common/h264/hal_h264e_com.h +++ b/mpp/hal/common/h264/hal_h264e_com.h @@ -117,6 +117,12 @@ extern RK_U32 h264e_hal_log_mode; mpp_log(fmt, ## __VA_ARGS__);\ } while (0) +#define h264e_hal_log_rc(fmt, ...) \ + do {\ + if (h264e_hal_log_mode & H264E_HAL_LOG_RC)\ + mpp_log(fmt, ## __VA_ARGS__);\ + } while (0) + #define H264E_HAL_MIN(a,b) ( (a)<(b) ? (a) : (b) ) #define H264E_HAL_MAX(a,b) ( (a)>(b) ? (a) : (b) ) #define H264E_HAL_MIN3(a,b,c) H264E_HAL_MIN((a),H264E_HAL_MIN((b),(c))) @@ -191,6 +197,20 @@ extern RK_U32 h264e_hal_log_mode; #define H264E_CSP2_VFLIP 0x1000 /* the csp is vertically flipped */ #define H264E_CSP2_HIGH_DEPTH 0x2000 /* the csp has a depth of 16 bits per pixel component */ +#define H264E_MB_RC_ONLY_QUALITY 1 +#define H264E_MB_RC_MORE_QUALITY 2 +#define H264E_MB_RC_BALANCE 3 +#define H264E_MB_RC_MORE_BITRATE 4 +#define H264E_MB_RC_ONLY_BITRATE 5 +#define H264E_MB_RC_M_NUM 5 + +#define H264E_MB_RC_Q_WORST 1 +#define H264E_MB_RC_Q_WORSE 2 +#define H264E_MB_RC_Q_MEDIUM 3 +#define H264E_MB_RC_Q_BETTER 4 +#define H264E_MB_RC_Q_BEST 5 +#define H264E_MB_RC_Q_NUM 5 + typedef enum h264e_rkv_csp_t { H264E_RKV_CSP_BGRA8888, // 0 H264E_RKV_CSP_BGR888, // 1 @@ -421,6 +441,38 @@ typedef struct h264e_hal_param_t { h264e_hal_ref_param ref; } h264e_hal_param; +typedef struct H264eMbRcCtx_t { + /* + * rc_mode - rate control mode + * Mpp balances quality and bit rate by the mode index + * Mpp provide 5 level of balance mode of quality and bit rate + * 1 - only quality mode: only quality parameter takes effect + * 2 - more quality mode: quality parameter takes more effect + * 3 - balance mode : balance quality and bitrate 50 to 50 + * 4 - more bitrate mode: bitrate parameter takes more effect + * 5 - only bitrate mode: only bitrate parameter takes effect + */ + RK_U32 mode; + + /* + * quality - quality parameter + * mpp does not give the direct parameter in different protocol. + * mpp provide total 5 quality level 1 ~ 5 + * 0 - auto + * 1 - worst + * 2 - worse + * 3 - medium + * 4 - better + * 5 - best + */ + RK_U32 quality; + + RK_U32 num_positive_class; /*range: 1~9, deafult: 4 */ + + RK_S32 last_frame_target_qp; + RK_S32 last_frame_real_qp; +} H264eMbRcCtx; + typedef struct h264e_hal_context_t { MppHalApi api; RK_S32 vpu_fd; @@ -457,6 +509,7 @@ typedef struct h264e_hal_context_t { MppLinReg *inter_qs; MppLinReg *intra_qs; MppData *qp_p; + H264eMbRcCtx mb_rc; } h264e_hal_context; MPP_RET hal_h264e_set_sps(h264e_hal_context *ctx, h264e_hal_sps *sps); diff --git a/mpp/hal/rkenc/h264e/hal_h264e_rkv.c b/mpp/hal/rkenc/h264e/hal_h264e_rkv.c index 2c387b7f..10fee156 100644 --- a/mpp/hal/rkenc/h264e/hal_h264e_rkv.c +++ b/mpp/hal/rkenc/h264e/hal_h264e_rkv.c @@ -223,6 +223,24 @@ static RK_U32 reg_idx2addr_map[132] = { }; #endif +static H264eRkvMbRcMcfg mb_rc_m_cfg[H264E_MB_RC_M_NUM] = { + /* aq_prop, aq_strength, mb_num, qp_range, error_bits_div, num_positive_class, filter_strength */ + {16, 1, 0, 1, 0, 0, 1}, // mode = 1 + {8, 1, 1, 2, 8, 4, 0}, // mode = 2 + {4, 1, 1, 4, 8, 4, 0}, // mode = 3 + {2, 1, 1, 8, 8, 4, 0}, // mode = 4 + {0, 1, 1, 12, 8, 4, 0}, // mode = 5 +}; + +static H264eRkvMbRcQcfg mb_rc_q_cfg[H264E_MB_RC_Q_NUM] = { + /* qp_min, qp_max */ + {31, 51}, // quality = 1 + {28, 46}, // quality = 2 + {24, 42}, // quality = 3 + {20, 39}, // quality = 4 + {16, 35}, // quality = 5 +}; + static MPP_RET hal_h264e_rkv_close_dump_files(void *dump_files) { h264e_hal_rkv_dump_files *files = (h264e_hal_rkv_dump_files *)dump_files; @@ -2241,8 +2259,31 @@ MPP_RET hal_h264e_rkv_set_ioctl_extra_info(h264e_rkv_ioctl_extra_info *extra_inf return MPP_OK; } -MPP_RET hal_h264e_rkv_set_rc_regs(h264e_hal_context *ctx, h264e_rkv_reg_set *regs, H264eHwCfg *syn, - RcSyntax *rc_syn, h264e_hal_rkv_coveragetest_cfg *test) +static void hal_h264e_rkv_set_mb_rc(h264e_hal_context *ctx) +{ + RK_U32 m = 0; + RK_U32 q = 0; + MppEncCfgSet *cfg = ctx->cfg; + MppEncRcCfg *rc = &cfg->rc; + H264eHwCfg *hw = &ctx->hw_cfg; + H264eMbRcCtx *mb_rc = &ctx->mb_rc; + + m = rc->rc_mode; + q = rc->quality; + + /* for intra frame, pay more attention to quality */ + if (hw->frame_type == H264E_RKV_FRAME_I) + m--; + m = H264E_HAL_CLIP3(m, 1, 5); + + mb_rc->mode = m; + mb_rc->quality = q; + h264e_hal_log_rc("mode %d quality %d", mb_rc->mode, mb_rc->quality); +} + + +static MPP_RET hal_h264e_rkv_set_rc_regs(h264e_hal_context *ctx, h264e_rkv_reg_set *regs, H264eHwCfg *syn, + RcSyntax *rc_syn, h264e_hal_rkv_coveragetest_cfg *test) { if (test && test->mbrc) { RK_U32 num_mbs_oneframe = (syn->width + 15) / 16 * ((syn->height + 15) / 16); @@ -2293,55 +2334,75 @@ MPP_RET hal_h264e_rkv_set_rc_regs(h264e_hal_context *ctx, h264e_rkv_reg_set *reg RK_U32 num_mbs_oneframe = (syn->width + 15) / 16 * ((syn->height + 15) / 16); RK_U32 mb_target_size_mul_16 = (rc_syn->bit_target << 4) / num_mbs_oneframe; RK_U32 mb_target_size = mb_target_size_mul_16 >> 4; - RK_U32 aq_strength = 2; - RK_U32 rc_ctu_num = (syn->width + 15) / 16; + H264eMbRcCtx *mb_rc = &ctx->mb_rc; + H264eRkvMbRcMcfg m_cfg; + + hal_h264e_rkv_set_mb_rc(ctx); + m_cfg = mb_rc_m_cfg[mb_rc->mode - 1]; + + syn->qp_min = MPP_MIN(syn->qp, syn->qp_min); + syn->qp_max = MPP_MAX(syn->qp, syn->qp_max); regs->swreg10.pic_qp = syn->qp;//syn->swreg10.pic_qp; //if CQP, pic_qp=qp constant. - regs->swreg46.rc_en = syn->mb_rc_mode >= 1 ? 1 : 0; //0: disable mb rc - regs->swreg46.rc_mode = syn->mb_rc_mode == 2 ? 1 : 0; //0:frame/slice rc; 1:mbrc - if (rc_syn->type == INTRA_FRAME) - regs->swreg54.rc_qp_range = 2; - else - regs->swreg54.rc_qp_range = 4; - regs->swreg54.rc_max_qp = syn->qp_max; - regs->swreg54.rc_min_qp = syn->qp_min; - if (regs->swreg46.rc_mode) { //mb rc mode open - regs->swreg46.aqmode_en = 1; - regs->swreg46.aq_strg = (RK_U32)(aq_strength * 1.0397 * 256); - regs->swreg46.Reserved = 0x0; - regs->swreg46.rc_ctu_num = rc_ctu_num; + regs->swreg46.rc_en = 1; //0: disable mb rc + regs->swreg46.rc_mode = m_cfg.aq_prop < 16; //0:frame/slice rc; 1:mbrc - regs->swreg47.bits_error0 = (mb_target_size * rc_ctu_num / 8) * -4; - regs->swreg47.bits_error1 = (mb_target_size * rc_ctu_num / 8) * -3; - regs->swreg48.bits_error2 = (mb_target_size * rc_ctu_num / 8) * -2; - regs->swreg48.bits_error3 = (mb_target_size * rc_ctu_num / 8) * -1; - regs->swreg49.bits_error4 = (mb_target_size * rc_ctu_num / 8) * 1; - regs->swreg49.bits_error5 = (mb_target_size * rc_ctu_num / 8) * 2; - regs->swreg50.bits_error6 = (mb_target_size * rc_ctu_num / 8) * 3; - regs->swreg50.bits_error7 = (mb_target_size * rc_ctu_num / 8) * 4; - regs->swreg51.bits_error8 = (mb_target_size * rc_ctu_num / 8) * 5; + regs->swreg46.aqmode_en = m_cfg.aq_prop && m_cfg.aq_strength; + regs->swreg46.aq_strg = (RK_U32)(m_cfg.aq_strength * 1.0397 * 256); + regs->swreg54.rc_qp_mod = 2; //sw_quality_flag; + regs->swreg54.rc_fact0 = m_cfg.aq_prop; + regs->swreg54.rc_fact1 = 16 - m_cfg.aq_prop; + regs->swreg54.rc_max_qp = syn->qp_max; + regs->swreg54.rc_min_qp = syn->qp_min; - regs->swreg52.qp_adjust0 = -4; - regs->swreg52.qp_adjust1 = -3; - regs->swreg52.qp_adjust2 = -2; - regs->swreg52.qp_adjust3 = -1; - regs->swreg52.qp_adjust4 = 0; - regs->swreg52.qp_adjust5 = 1; - regs->swreg53.qp_adjust6 = 2; - regs->swreg53.qp_adjust7 = 3; - regs->swreg53.qp_adjust8 = 4; - - regs->swreg54.rc_qp_mod = 2; //sw_quality_flag; - if (syn->frame_type == H264E_RKV_FRAME_I) { - regs->swreg54.rc_fact0 = 8; //sw_quality_factor_0; - regs->swreg54.rc_fact1 = 8; //sw_quality_factor_1; - } else { - regs->swreg54.rc_fact0 = 0; //sw_quality_factor_0; - regs->swreg54.rc_fact1 = 16; //sw_quality_factor_1; - } - - regs->swreg55.ctu_ebits = mb_target_size_mul_16; + if (regs->swreg46.aqmode_en) { + regs->swreg54.rc_max_qp = (RK_U32)MPP_MIN(syn->qp_max, (RK_S32)(syn->qp + m_cfg.qp_range)); + regs->swreg54.rc_min_qp = (RK_U32)MPP_MAX(syn->qp_min, (RK_S32)(syn->qp - m_cfg.qp_range)); + if (regs->swreg54.rc_max_qp < regs->swreg54.rc_min_qp) + MPP_SWAP(RK_U32, regs->swreg54.rc_max_qp, regs->swreg54.rc_min_qp); } + + if (regs->swreg46.rc_mode) { //checkpoint rc open + RK_S32 shift = m_cfg.num_positive_class - 4; + RK_U32 target = mb_target_size * m_cfg.mb_num; + + regs->swreg54.rc_qp_range = m_cfg.qp_range; + regs->swreg46.rc_ctu_num = m_cfg.mb_num; + regs->swreg55.ctu_ebits = mb_target_size_mul_16; + + regs->swreg47.bits_error0 = (RK_S32)((pow(0.88, 4) - 1) * (double)target); + regs->swreg47.bits_error1 = (RK_S32)((pow(0.88, 3) - 1) * (double)target); + regs->swreg48.bits_error2 = (RK_S32)((pow(0.88, 2) - 1) * (double)target); + regs->swreg48.bits_error3 = (RK_S32)((pow(0.88, 1) - 1) * (double)target); + regs->swreg49.bits_error4 = (RK_S32)((pow(1.12, 1) - 1) * (double)target); + regs->swreg49.bits_error5 = (RK_S32)((pow(1.12, 2) - 1) * (double)target); + regs->swreg50.bits_error6 = (RK_S32)((pow(1.12, 3) - 1) * (double)target); + regs->swreg50.bits_error7 = (RK_S32)((pow(1.12, 4) - 1) * (double)target); + regs->swreg51.bits_error8 = (RK_S32)((pow(1.12, 5) - 1) * (double)target); + + regs->swreg52.qp_adjust0 = -4 + shift; + regs->swreg52.qp_adjust1 = -3 + shift; + regs->swreg52.qp_adjust2 = -2 + shift; + regs->swreg52.qp_adjust3 = -1 + shift; + regs->swreg52.qp_adjust4 = 0 + shift; + regs->swreg52.qp_adjust5 = 1 + shift; + regs->swreg53.qp_adjust6 = 2 + shift; + regs->swreg53.qp_adjust7 = 3 + shift; + regs->swreg53.qp_adjust8 = 4 + shift; + + } + regs->swreg62.sli_beta_ofst = m_cfg.filter_strength; + regs->swreg62.sli_alph_ofst = m_cfg.filter_strength; + + h264e_hal_log_rc("rc_en %d rc_mode %d level %d qp %d qp_min %d qp_max %d", + regs->swreg46.rc_en, regs->swreg46.rc_mode, mb_rc->mode, + regs->swreg10.pic_qp, regs->swreg54.rc_min_qp, regs->swreg54.rc_max_qp); + + h264e_hal_log_rc("aq_prop %d aq_strength %d mb_num %d qp_range %d error_bits_div %d num_pos_class %d", + m_cfg.aq_prop, m_cfg.aq_strength, m_cfg.mb_num, m_cfg.qp_range, m_cfg.error_bits_div, + m_cfg.num_positive_class); + h264e_hal_log_rc("target qp %d frame_bits %d", syn->qp, rc_syn->bit_target); + (void)ctx; } @@ -2596,6 +2657,7 @@ static RK_S32 hal_h264e_rkv_find_best_qp(MppLinReg *ctx, MppEncH264Cfg *codec, R } else break; } while (qp <= qp_max && qp >= qp_min); + qp_best = mpp_clip(qp_best, qp_min, qp_max); } return qp_best; @@ -2727,8 +2789,6 @@ static MPP_RET hal_h264e_rkv_update_hw_cfg(h264e_hal_context *ctx, HalEncTask *t h264e_hal_log_detail("RC: qp calc ctx %p qp [%d %d] prev %d target bit %d\n", ctx->inter_qs, codec->qp_min, codec->qp_max, hw_cfg->qp_prev, rc_syn->bit_target); - if (rc->rc_mode >= 4) //bitrate parameter takes more effect - hw_cfg->mb_rc_mode = 2; { RK_S32 prev_frame_type = hw_cfg->frame_type; @@ -3135,8 +3195,6 @@ MPP_RET hal_h264e_rkv_gen_regs(void *hal, HalTaskInfo *task) regs->swreg62.rodr_pic_idx = dpb_ctx->ref_pic_list_order[0][0].idc; //syn->swreg62.rodr_pic_idx; regs->swreg62.ref_list0_rodr = dpb_ctx->b_ref_pic_list_reordering[0]; //syn->swreg62.ref_list0_rodr; - regs->swreg62.sli_beta_ofst = 0; //syn->slice_beta_offset; - regs->swreg62.sli_alph_ofst = 0; //syn->slice_alpha_offset; regs->swreg62.dis_dblk_idc = 0; //syn->disable_deblocking_filter_idc; regs->swreg62.rodr_pic_num = dpb_ctx->ref_pic_list_order[0][0].arg; //syn->swreg62.rodr_pic_num; @@ -3313,6 +3371,7 @@ static MPP_RET hal_h264e_rkv_set_feedback(h264e_feedback *fb, h264e_rkv_ioctl_ou { RK_U32 k = 0; h264e_rkv_ioctl_output_elem *elem = NULL; + h264e_hal_debug_enter(); for (k = 0; k < out->frame_num; k++) { elem = &out->elem[k]; @@ -3360,6 +3419,7 @@ static MPP_RET hal_h264e_rkv_set_feedback(h264e_feedback *fb, h264e_rkv_ioctl_ou } h264e_hal_debug_leave(); + return MPP_OK; } @@ -3374,9 +3434,10 @@ MPP_RET hal_h264e_rkv_wait(void *hal, HalTaskInfo *task) h264e_feedback *fb = &ctx->feedback; HalEncTask *enc_task = &task->enc; MppEncPrepCfg *prep = &ctx->cfg->prep; + H264eHwCfg *hw_cfg = &ctx->hw_cfg; + H264eMbRcCtx *mb_rc = &ctx->mb_rc; RK_S32 num_mb = MPP_ALIGN(prep->width, 16) * MPP_ALIGN(prep->height, 16) / 16 / 16; /* for dumping ratecontrol message */ - H264eHwCfg *hw_cfg = &ctx->hw_cfg; RcSyntax *rc_syn = (RcSyntax *)task->enc.syntax.data; h264e_hal_debug_enter(); @@ -3472,6 +3533,11 @@ MPP_RET hal_h264e_rkv_wait(void *hal, HalTaskInfo *task) h264_q_step[avg_qp], result.bits * 256 / mb_per_pic); int_cb.callBack(int_cb.opaque, fb); + + mb_rc->last_frame_real_qp = avg_qp; + mb_rc->last_frame_target_qp = hw_cfg->qp; + + h264e_hal_log_rc("real qp %d frame_bits %d", avg_qp, result.bits); } hal_h264e_rkv_dump_mpp_reg_out(ctx); @@ -3543,6 +3609,7 @@ MPP_RET hal_h264e_rkv_control(void *hal, RK_S32 cmd_type, void *param) case MPP_ENC_SET_CODEC_CFG : { MppEncH264Cfg *src = &ctx->set->codec.h264; MppEncH264Cfg *dst = &ctx->cfg->codec.h264; + MppEncRcCfg *rc = &ctx->cfg->rc; RK_U32 change = src->change; // TODO: do codec check first @@ -3577,6 +3644,12 @@ MPP_RET hal_h264e_rkv_control(void *hal, RK_S32 cmd_type, void *param) dst->qp_max = src->qp_max; dst->qp_min = src->qp_min; dst->qp_max_step = src->qp_max_step; + /* (VBR) if focus on quality, qp range is limited more precisely */ + if (rc->rc_mode <= H264E_MB_RC_MORE_QUALITY) { + H264eRkvMbRcQcfg cfg = mb_rc_q_cfg[rc->quality - 1]; + dst->qp_min = cfg.qp_min; + dst->qp_max = cfg.qp_max; + } } if (change & MPP_ENC_H264_CFG_CHANGE_INTRA_REFRESH) { dst->intra_refresh_mode = src->intra_refresh_mode; diff --git a/mpp/hal/rkenc/h264e/hal_h264e_rkv.h b/mpp/hal/rkenc/h264e/hal_h264e_rkv.h index 5c8cd8eb..87eaf589 100644 --- a/mpp/hal/rkenc/h264e/hal_h264e_rkv.h +++ b/mpp/hal/rkenc/h264e/hal_h264e_rkv.h @@ -963,6 +963,24 @@ typedef struct h264e_rkv_ioctl_output_t { h264e_rkv_ioctl_output_elem elem[RKV_H264E_LINKTABLE_MAX_SIZE]; } h264e_rkv_ioctl_output; +/* mode cfg */ +typedef struct H264eRkvMbRcMcfg_t { + RK_U32 aq_prop; //0~16, 0:only enable aq, 16:only enable checkpoint + + RK_U32 aq_strength; //0~3 + + RK_U32 mb_num; + RK_U32 qp_range; //0~15 + RK_U32 error_bits_div; + RK_U32 num_positive_class; //0~9 + RK_U32 filter_strength; +} H264eRkvMbRcMcfg; + +/* quality cfg */ +typedef struct H264eRkvMbRcQcfg_t { + RK_U32 qp_min; + RK_U32 qp_max; +} H264eRkvMbRcQcfg; #define RK_H264E_NUM_REGS ((RK_S32)(sizeof(h264e_rkv_reg_set)/4)) diff --git a/test/mpi_rc_test.c b/test/mpi_rc_test.c index fa929fad..894dffe5 100644 --- a/test/mpi_rc_test.c +++ b/test/mpi_rc_test.c @@ -238,6 +238,7 @@ static MPP_RET gen_yuv_image(RK_U8 *buf, MppEncPrepCfg *prep_cfg, RK_U32 frame_c ret = MPP_NOK; } break; } + return ret; } @@ -306,7 +307,7 @@ static MPP_RET mpi_rc_init(MpiRcTestCtx *ctx) ret = MPP_ERR_OPEN_FILE; goto err; } - fprintf(file->fp_stat, "frame,size(byte),psnr,ssim,ins_bitrate(byte/s),avg_bitrate(byte/s)\n"); + fprintf(file->fp_stat, "frame,size(bit),psnr,ssim,ins_bitrate(bit/s),avg_bitrate(bit/s)\n"); } ctx->com_buf = mpp_malloc(RK_U8, cmd->width * cmd->height * 2); @@ -522,10 +523,10 @@ static void mpi_rc_log_stat(MpiRcTestCtx *ctx, RK_U32 frame_count, RK_U32 one_se MpiRcFile *file = &ctx->file; FILE *fp = file->fp_stat; - mpp_log("frame %3d | frame_size %6d bytes | psnr %5.2f | ssim %5.5f", + mpp_log("frame %3d | frame_size %6d bits | psnr %5.2f | ssim %5.5f", frame_count, stat->frame_size, stat->psnr_y, stat->ssim_y); if (one_second) - mpp_log("ins_bitrate %d byte/s", stat->ins_bitrate); + mpp_log("ins_bitrate %d bit/s", stat->ins_bitrate); if (fp) { fprintf(fp, "%3d,%6d,%5.2f,%5.5f,", @@ -595,7 +596,7 @@ static MPP_RET mpi_rc_codec(MpiRcTestCtx *ctx) MppEncRcCfg *rc_cfg = &cfg.rc; MppEncPrepCfg *prep_cfg = &cfg.prep; MppEncCodecCfg *codec_cfg = &cfg.codec; - RK_S32 fps = 30; + RK_S32 fps = 20; mpp_log_f("test start width %d height %d codingtype %d\n", width, height, type); ret = mpp_buffer_group_get_internal(&frm_grp, MPP_BUFFER_TYPE_ION); @@ -712,29 +713,33 @@ static MPP_RET mpi_rc_codec(MpiRcTestCtx *ctx) } rc_cfg->change = MPP_ENC_RC_CFG_CHANGE_ALL; - rc_cfg->rc_mode = 3; + rc_cfg->rc_mode = 5; rc_cfg->quality = 0; - rc_cfg->bps_target = 2000000; - rc_cfg->bps_max = 3000000; - rc_cfg->bps_min = 1000000; + rc_cfg->bps_target = 800000; + rc_cfg->bps_max = 800000; + rc_cfg->bps_min = 800000; rc_cfg->fps_in_denorm = 1; rc_cfg->fps_out_denorm = 1; rc_cfg->fps_in_num = fps; rc_cfg->fps_out_num = fps; rc_cfg->fps_in_flex = 0; rc_cfg->fps_out_flex = 0; - rc_cfg->gop = 30; + rc_cfg->gop = fps; rc_cfg->skip_cnt = 0; ret = enc_mpi->control(enc_ctx, MPP_ENC_SET_RC_CFG, rc_cfg); + if (ret) { + mpp_err("mpi control enc set rc cfg failed ret %d\n", ret); + goto MPP_TEST_OUT; + } - prep_cfg->change = MPP_ENC_PREP_CFG_CHANGE_INPUT | - MPP_ENC_PREP_CFG_CHANGE_FORMAT; - prep_cfg->width = width; - prep_cfg->height = height; - prep_cfg->hor_stride = hor_stride; - prep_cfg->ver_stride = ver_stride; - prep_cfg->format = fmt; + prep_cfg->change = MPP_ENC_PREP_CFG_CHANGE_INPUT | + MPP_ENC_PREP_CFG_CHANGE_FORMAT; + prep_cfg->width = width; + prep_cfg->height = height; + prep_cfg->hor_stride = hor_stride; + prep_cfg->ver_stride = ver_stride; + prep_cfg->format = fmt; ret = enc_mpi->control(enc_ctx, MPP_ENC_SET_PREP_CFG, prep_cfg); if (ret) { @@ -781,7 +786,7 @@ static MPP_RET mpi_rc_codec(MpiRcTestCtx *ctx) codec_cfg->h264.qp_min = 12; codec_cfg->h264.qp_max_step = 8; } - codec_cfg->h264.qp_init = 26; + codec_cfg->h264.qp_init = 0; ret = enc_mpi->control(enc_ctx, MPP_ENC_SET_CODEC_CFG, codec_cfg); if (ret) { mpp_err("mpi control enc set codec cfg failed ret %d\n", ret); @@ -910,10 +915,10 @@ static MPP_RET mpi_rc_codec(MpiRcTestCtx *ctx) if (fp_enc_out) fwrite(ptr, 1, len, fp_enc_out); - //mpp_log_f("encoded frame %d size %d\n", frame_count, len); - stream_size += len; - stream_size_1s += len; - stat->frame_size = len; + //mpp_log_f("encoded frame %d size %d bits\n", frame_count, len * 8); + stream_size += len * 8; + stream_size_1s += len * 8; + stat->frame_size = len * 8; if ((frame_count + 1) % fps == 0) { stat->ins_bitrate = stream_size_1s; stream_size_1s = 0; @@ -1016,7 +1021,7 @@ static MPP_RET mpi_rc_codec(MpiRcTestCtx *ctx) } stat->avg_bitrate = (RK_U64)stream_size * fps / frame_count; - mpp_log_f("avg_bitrate %d byte/s", stat->avg_bitrate); + mpp_log_f("avg_bitrate %d bit/s", stat->avg_bitrate); if (fp_stat) fprintf(fp_stat, "%d\n", stat->avg_bitrate);