diff --git a/inc/rk_mpi_cmd.h b/inc/rk_mpi_cmd.h index f702cfe0..941cdcc6 100644 --- a/inc/rk_mpi_cmd.h +++ b/inc/rk_mpi_cmd.h @@ -52,6 +52,22 @@ typedef enum MppEncSeiMode_t { MPP_ENC_SEI_MODE_ONE_FRAME /* one frame may have one SEI, if SEI info has changed */ } MppEncSeiMode; +typedef enum MppEncRcMode_t { + MPP_ENC_RC_MODE_VBR, + MPP_ENC_RC_MODE_CBR, + MPP_ENC_RC_MODE_BUTT +} MppEncRcMode; + +typedef enum MppEncRcQuality_t { + MPP_ENC_RC_QUALITY_WORST, + MPP_ENC_RC_QUALITY_WORSE, + MPP_ENC_RC_QUALITY_MEDIUM, + MPP_ENC_RC_QUALITY_BETTER, + MPP_ENC_RC_QUALITY_BEST, + MPP_ENC_RC_QUALITY_CQP, + MPP_ENC_RC_QUALITY_BUTT +} MppEncRcQuality; + typedef enum { MPP_OSAL_CMD_BASE = CMD_MODULE_OSAL, MPP_OSAL_CMD_END, @@ -256,28 +272,36 @@ typedef struct MppEncRcCfg_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 + * + * mpp provide two rate control mode: + * + * Constant Bit Rate (CBR) mode + * - paramter 'bps*' define target bps + * - paramter quality and qp will not take effect + * + * Variable Bit Rate (VBR) mode + * - paramter 'quality' define 5 quality levels + * - paramter 'bps*' is used as reference but not strict condition + * - special Constant QP (CQP) mode is under VBR mode + * CQP mode will work with qp in CodecCfg. But only use for test + * + * default: CBR */ - RK_S32 rc_mode; + MppEncRcMode rc_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 + * quality - quality parameter, only takes effect in VBR mode + * + * Mpp does not give the direct parameter in different protocol. + * + * Mpp provide total 5 quality level: + * Worst - worse - Medium - better - best + * + * extra CQP level means special constant-qp (CQP) mode + * + * default value: Medium */ - RK_S32 quality; + MppEncRcQuality quality; /* * bit rate parameters diff --git a/mpp/codec/enc/h264/src/h264e_api.c b/mpp/codec/enc/h264/src/h264e_api.c index 6c321999..0c0a2a77 100644 --- a/mpp/codec/enc/h264/src/h264e_api.c +++ b/mpp/codec/enc/h264/src/h264e_api.c @@ -93,7 +93,8 @@ MPP_RET h264e_init(void *ctx, ControllerCfg *ctrl_cfg) * gop 60 */ rc_cfg->change = 0; - rc_cfg->rc_mode = 3; + rc_cfg->rc_mode = MPP_ENC_RC_MODE_CBR; + rc_cfg->quality = MPP_ENC_RC_QUALITY_MEDIUM; rc_cfg->bps_target = 2000 * 1000; rc_cfg->bps_max = rc_cfg->bps_target * 5 / 4; rc_cfg->bps_min = rc_cfg->bps_target * 3 / 4; diff --git a/mpp/hal/common/h264/hal_h264e_com.h b/mpp/hal/common/h264/hal_h264e_com.h index 7b72e70d..cdc87321 100644 --- a/mpp/hal/common/h264/hal_h264e_com.h +++ b/mpp/hal/common/h264/hal_h264e_com.h @@ -197,20 +197,13 @@ 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_ONLY_QUALITY 0 +#define H264E_MB_RC_MORE_QUALITY 1 +#define H264E_MB_RC_BALANCE 2 +#define H264E_MB_RC_MORE_BITRATE 3 +#define H264E_MB_RC_ONLY_BITRATE 4 #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 @@ -446,31 +439,25 @@ 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 + * 0 - only quality mode: only quality parameter takes effect + * 1 - more quality mode: quality parameter takes more effect + * 2 - balance mode : balance quality and bitrate 50 to 50 + * 3 - more bitrate mode: bitrate parameter takes more effect + * 4 - only bitrate mode: only bitrate parameter takes effect */ - RK_U32 mode; + RK_S32 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 + * mpp provide total 5 quality level 0 ~ 4 + * 0 - worst + * 1 - worse + * 2 - medium + * 3 - better + * 4 - 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; + RK_S32 quality; } H264eMbRcCtx; typedef struct h264e_hal_context_t { diff --git a/mpp/hal/rkenc/h264e/hal_h264e_rkv.c b/mpp/hal/rkenc/h264e/hal_h264e_rkv.c index bc634ce6..fde63453 100644 --- a/mpp/hal/rkenc/h264e/hal_h264e_rkv.c +++ b/mpp/hal/rkenc/h264e/hal_h264e_rkv.c @@ -51,7 +51,7 @@ double QP2Qstep( double qp_avg ) RK_S32 QP = qp_avg * 4.0; Qstep = 0.625 * pow(1.0293, QP % 24); - for(i = 0; i < (QP / 24); i++) + for (i = 0; i < (QP / 24); i++) Qstep *= 2; return Qstep * 4; @@ -227,21 +227,22 @@ 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, 4, 8, 4, 0}, // mode = 4 - {0, 1, 1, 2, 8, 4, 0}, // mode = 5 + /* aq_prop, aq_strength, mb_num, qp_range */ + {16, 1, 0, 1}, // mode = 0 + {8, 1, 1, 2}, // mode = 1 + {4, 1, 1, 4}, // mode = 2 + {2, 1, 1, 4}, // mode = 3 + {0, 1, 1, 2}, // mode = 4 }; -static H264eRkvMbRcQcfg mb_rc_q_cfg[H264E_MB_RC_Q_NUM] = { +static H264eRkvMbRcQcfg mb_rc_q_cfg[MPP_ENC_RC_QUALITY_BUTT] = { /* qp_min, qp_max */ - {31, 51}, // quality = 1 - {28, 46}, // quality = 2 - {24, 42}, // quality = 3 - {20, 39}, // quality = 4 - {16, 35}, // quality = 5 + {31, 51}, // worst + {28, 46}, // worse + {24, 42}, // medium + {20, 39}, // better + {16, 35}, // best + {0, 0}, // cqp }; static MPP_RET hal_h264e_rkv_close_dump_files(void *dump_files) @@ -2269,24 +2270,34 @@ MPP_RET hal_h264e_rkv_set_ioctl_extra_info(h264e_rkv_ioctl_extra_info *extra_inf static void hal_h264e_rkv_set_mb_rc(h264e_hal_context *ctx) { - RK_U32 m = 0; - RK_U32 q = 0; + RK_S32 m = 0; + RK_S32 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; + if (rc->rc_mode == MPP_ENC_RC_MODE_VBR) { + m = H264E_MB_RC_ONLY_QUALITY; + q = rc->quality; + if (q != MPP_ENC_RC_QUALITY_CQP) { + /* better quality for intra frame */ + if (hw->frame_type == H264E_RKV_FRAME_I) + q++; + q = H264E_HAL_CLIP3(q, MPP_ENC_RC_QUALITY_WORST, MPP_ENC_RC_QUALITY_BEST); + } + } else { // CBR + m = H264E_MB_RC_ONLY_BITRATE; + if (hw->frame_type == H264E_RKV_FRAME_I) + m--; + m = H264E_HAL_CLIP3(m, H264E_MB_RC_ONLY_QUALITY, H264E_MB_RC_ONLY_BITRATE); + q = -1; + } - /* 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); + h264e_hal_log_rc("mbrc mode %d quality %d", mb_rc->mode, mb_rc->quality); } @@ -2342,14 +2353,24 @@ static MPP_RET hal_h264e_rkv_set_rc_regs(h264e_hal_context *ctx, h264e_rkv_reg_s 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; + MppEncRcCfg *rc = &ctx->cfg->rc; 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]; + m_cfg = mb_rc_m_cfg[mb_rc->mode]; - syn->qp_min = MPP_MIN(syn->qp, syn->qp_min); - syn->qp_max = MPP_MAX(syn->qp, syn->qp_max); + /* (VBR) if focus on quality, qp range is limited more precisely */ + if (rc->rc_mode == MPP_ENC_RC_MODE_VBR) { + if (rc->quality == MPP_ENC_RC_QUALITY_CQP) { + syn->qp_min = syn->qp; + syn->qp_max = syn->qp; + } else { + H264eRkvMbRcQcfg q_cfg = mb_rc_q_cfg[mb_rc->quality]; + syn->qp_min = q_cfg.qp_min; + syn->qp_max = q_cfg.qp_max; + } + } regs->swreg10.pic_qp = syn->qp;//syn->swreg10.pic_qp; //if CQP, pic_qp=qp constant. regs->swreg46.rc_en = 1; //0: disable mb rc @@ -2371,7 +2392,6 @@ static MPP_RET hal_h264e_rkv_set_rc_regs(h264e_hal_context *ctx, h264e_rkv_reg_s } 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; @@ -2388,27 +2408,26 @@ static MPP_RET hal_h264e_rkv_set_rc_regs(h264e_hal_context *ctx, h264e_rkv_reg_s 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->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->swreg62.sli_beta_ofst = m_cfg.filter_strength; - regs->swreg62.sli_alph_ofst = m_cfg.filter_strength; + regs->swreg62.sli_beta_ofst = 0; + regs->swreg62.sli_alph_ofst = 0; 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("aq_prop %d aq_strength %d mb_num %d qp_range %d", + m_cfg.aq_prop, m_cfg.aq_strength, m_cfg.mb_num, m_cfg.qp_range); h264e_hal_log_rc("target qp %d frame_bits %d", syn->qp, rc_syn->bit_target); (void)ctx; @@ -2803,37 +2822,39 @@ static MPP_RET hal_h264e_rkv_update_hw_cfg(h264e_hal_context *ctx, HalEncTask *t { RK_S32 prev_frame_type = hw_cfg->frame_type; + RK_S32 is_cqp = rc->rc_mode == MPP_ENC_RC_MODE_VBR && rc->quality == MPP_ENC_RC_QUALITY_CQP; if (rc_syn->type == INTRA_FRAME) { hw_cfg->frame_type = H264E_RKV_FRAME_I; hw_cfg->coding_type = RKVENC_CODING_TYPE_IDR; hw_cfg->frame_num = 0; - if (ctx->frame_cnt == 0) - hw_cfg->qp = hw_cfg->qp_prev; - else - hw_cfg->qp = mpp_data_avg(ctx->qp_p, -1, 1, 1) - 3; + if (!is_cqp) { + if (ctx->frame_cnt > 0) + hw_cfg->qp = mpp_data_avg(ctx->qp_p, -1, 1, 1) - 3; - /* - * Previous frame is inter then intra frame can not - * have a big qp step between these two frames - */ - if (prev_frame_type == H264E_RKV_FRAME_P) - hw_cfg->qp = mpp_clip(hw_cfg->qp, hw_cfg->qp_prev - 2, hw_cfg->qp_prev + 2); + /* + * Previous frame is inter then intra frame can not + * have a big qp step between these two frames + */ + if (prev_frame_type == H264E_RKV_FRAME_P) + hw_cfg->qp = mpp_clip(hw_cfg->qp, hw_cfg->qp_prev - 2, hw_cfg->qp_prev + 2); + } } else { hw_cfg->frame_type = H264E_RKV_FRAME_P; hw_cfg->coding_type = RKVENC_CODING_TYPE_P; - RK_S32 sse = mpp_data_avg(ctx->sse_p, 1, 1, 1) + 1; + if (!is_cqp) { + RK_S32 sse = mpp_data_avg(ctx->sse_p, 1, 1, 1) + 1; + hw_cfg->qp = hal_h264e_rkv_find_best_qp(ctx->inter_qs, codec, hw_cfg->qp_prev, rc_syn->bit_target * 256 / sse); - hw_cfg->qp = hal_h264e_rkv_find_best_qp(ctx->inter_qs, codec, hw_cfg->qp_prev, rc_syn->bit_target * 256 / sse); - - /* - * Previous frame is intra then inter frame can not - * have a big qp step between these two frames - */ - if (prev_frame_type == H264E_RKV_FRAME_I) - hw_cfg->qp = mpp_clip(hw_cfg->qp, hw_cfg->qp_prev - 4, hw_cfg->qp_prev + 4); + /* + * Previous frame is intra then inter frame can not + * have a big qp step between these two frames + */ + if (prev_frame_type == H264E_RKV_FRAME_I) + hw_cfg->qp = mpp_clip(hw_cfg->qp, hw_cfg->qp_prev - 4, hw_cfg->qp_prev + 4); + } } } @@ -3390,7 +3411,7 @@ static MPP_RET hal_h264e_rkv_set_feedback(h264e_feedback *fb, h264e_rkv_ioctl_ou fb->qp_sum = elem->swreg71.qp_sum; fb->out_strm_size = elem->swreg69.bs_lgth; fb->sse_sum = elem->swreg70.sse_l32 + - ((RK_S64)(elem->swreg71.sse_h8 & 0xff) << 32); + ((RK_S64)(elem->swreg71.sse_h8 & 0xff) << 32); fb->hw_status = 0; h264e_hal_log_detail("hw_status: 0x%08x", elem->hw_status); @@ -3440,7 +3461,7 @@ static MPP_RET hal_h264e_rkv_set_feedback(h264e_feedback *fb, h264e_rkv_ioctl_ou /* this function must be called after first VPUClientWaitResult, * since it depend on h264e_feedback structure, and this structure will * be filled after VPUClientWaitResult called - */ + */ static MPP_RET hal_h264e_rkv_resend(h264e_hal_context *ctx, RK_S32 mb_rc) { unsigned int k = 0; @@ -3457,7 +3478,7 @@ static MPP_RET hal_h264e_rkv_resend(h264e_hal_context *ctx, RK_S32 mb_rc) reg_list->swreg10.pic_qp = fb->qp_sum / num_mb;//syn->swreg10.pic_qp; //if CQP, pic_qp=qp constant. reg_list->swreg46.rc_en = mb_rc; //0: disable mb rc reg_list->swreg46.rc_mode = mb_rc ? 1 : 0; //0:frame/slice rc; 1:mbrc - reg_list->swreg46.aqmode_en = mb_rc; + reg_list->swreg46.aqmode_en = mb_rc; for (k = 0; k < ioctl_info->frame_num; k++) memcpy(&ioctl_info->reg_info[k].regs, @@ -3502,7 +3523,6 @@ MPP_RET hal_h264e_rkv_wait(void *hal, HalTaskInfo *task) 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 */ RcSyntax *rc_syn = (RcSyntax *)task->enc.syntax.data; @@ -3598,7 +3618,7 @@ MPP_RET hal_h264e_rkv_wait(void *hal, HalTaskInfo *task) /* dump rc message */ h264e_hal_log_rc("target bits %d real bits %d " - "target qp %d real qp %d\n", + "target qp %d real qp %0.2f\n", rc_syn->bit_target, result.bits, hw_cfg->qp, avg_qp); if (h264e_hal_log_mode & H264E_HAL_LOG_DUMP_RC) { @@ -3623,11 +3643,7 @@ MPP_RET hal_h264e_rkv_wait(void *hal, HalTaskInfo *task) } 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); + h264e_hal_log_rc("real qp %0.2f frame_bits %d", avg_qp, result.bits); } hal_h264e_rkv_dump_mpp_reg_out(ctx); @@ -3699,7 +3715,6 @@ 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 @@ -3734,12 +3749,6 @@ 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 87eaf589..a57066a3 100644 --- a/mpp/hal/rkenc/h264e/hal_h264e_rkv.h +++ b/mpp/hal/rkenc/h264e/hal_h264e_rkv.h @@ -971,9 +971,6 @@ typedef struct H264eRkvMbRcMcfg_t { 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 */ diff --git a/mpp/legacy/vpu_api_legacy.cpp b/mpp/legacy/vpu_api_legacy.cpp index b110cf50..6ec7d4e2 100755 --- a/mpp/legacy/vpu_api_legacy.cpp +++ b/mpp/legacy/vpu_api_legacy.cpp @@ -138,7 +138,7 @@ static MPP_RET vpu_api_set_enc_cfg(MppCtx mpp_ctx, MppApi *mpi, mpp_log("setup encoder rate control config:\n"); mpp_log("width %4d height %4d format %d\n", width, height, fmt); - mpp_log("rc_mode %s qp %d bps %d\n", (rc_mode) ? ("VBR") : ("CQP"), qp, bps); + mpp_log("rc_mode %s qp %d bps %d\n", (rc_mode) ? ("CBR") : ("CQP"), qp, bps); mpp_log("fps in %d fps out %d gop %d\n", fps_in, fps_out, gop); mpp_log("setup encoder stream feature config:\n"); mpp_log("profile %d level %d cabac %d\n", profile, level, cabac_en); @@ -161,29 +161,22 @@ static MPP_RET vpu_api_set_enc_cfg(MppCtx mpp_ctx, MppApi *mpi, } rc_cfg->change = MPP_ENC_RC_CFG_CHANGE_ALL; - /* auto quality */ - rc_cfg->quality = 0; if (rc_mode == 0) { - /* 0 - constant QP */ - /* constant QP does not have bps */ - rc_cfg->rc_mode = 1; + /* 0 - constant qp mode: fixed qp */ + rc_cfg->rc_mode = MPP_ENC_RC_MODE_VBR; + rc_cfg->quality = MPP_ENC_RC_QUALITY_CQP; rc_cfg->bps_target = -1; rc_cfg->bps_max = -1; rc_cfg->bps_min = -1; } else if (rc_mode == 1) { - /* 1 - constant bitrate */ - /* constant bitrate has very small bps range of 1/16 bps */ - rc_cfg->rc_mode = 5; + /* 1 - constant bitrate: small bps range */ + rc_cfg->rc_mode = MPP_ENC_RC_MODE_CBR; + rc_cfg->quality = MPP_ENC_RC_QUALITY_MEDIUM; rc_cfg->bps_target = bps; rc_cfg->bps_max = bps * 17 / 16; rc_cfg->bps_min = bps * 15 / 16; - } else if (rc_mode == 2) { - /* 2 - variable bitrate */ - /* variable bitrate has large bps range */ - rc_cfg->rc_mode = 3; - rc_cfg->bps_target = bps; - rc_cfg->bps_max = bps * 17 / 16; - rc_cfg->bps_min = bps * 1 / 16; + } else { + mpp_err("invalid vpu rc mode %d\n", rc_mode); } /* fix input / output frame rate */ @@ -216,21 +209,17 @@ static MPP_RET vpu_api_set_enc_cfg(MppCtx mpp_ctx, MppApi *mpi, if (rc_mode == 0) { /* constant QP mode qp is fixed */ + codec_cfg->h264.qp_init = qp; codec_cfg->h264.qp_max = qp; codec_cfg->h264.qp_min = qp; codec_cfg->h264.qp_max_step = 0; - } else if (rc_mode == 1) { + } else { /* constant bitrate do not limit qp range */ + codec_cfg->h264.qp_init = 0; codec_cfg->h264.qp_max = 48; codec_cfg->h264.qp_min = 4; - codec_cfg->h264.qp_max_step = 51; - } else if (rc_mode == 2) { - /* variable bitrate has qp min limit */ - codec_cfg->h264.qp_max = 48; - codec_cfg->h264.qp_min = qp; - codec_cfg->h264.qp_max_step = 8; + codec_cfg->h264.qp_max_step = 16; } - codec_cfg->h264.qp_init = 26; } break; case MPP_VIDEO_CodingMJPEG : { codec_cfg->jpeg.change = MPP_ENC_JPEG_CFG_CHANGE_QP; @@ -1324,7 +1313,7 @@ RK_S32 VpuApiLegacy::control(VpuCodecContext *ctx, VPU_API_CMD cmd, void *param) switch (cmd) { case VPU_API_ENC_SETCFG : { MppCodingType coding = (MppCodingType)ctx->videoCoding; - + memcpy(&enc_cfg, param, sizeof(enc_cfg)); return vpu_api_set_enc_cfg(mpp_ctx, mpi, coding, format, &enc_cfg); } break; diff --git a/test/mpi_enc_test.c b/test/mpi_enc_test.c index db9a024d..c4ac0b69 100644 --- a/test/mpi_enc_test.c +++ b/test/mpi_enc_test.c @@ -534,45 +534,26 @@ MPP_RET test_mpp_setup(MpiEncTestData *p) } rc_cfg->change = MPP_ENC_RC_CFG_CHANGE_ALL; - /* - * 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 - */ - rc_cfg->rc_mode = 1; - /* - * 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 - */ - rc_cfg->quality = 0; + rc_cfg->rc_mode = MPP_ENC_RC_MODE_CBR; + rc_cfg->quality = MPP_ENC_RC_QUALITY_MEDIUM; - if (rc_cfg->rc_mode == 1) { - /* constant QP does not have bps */ - rc_cfg->bps_target = -1; - rc_cfg->bps_max = -1; - rc_cfg->bps_min = -1; - } else if (rc_cfg->rc_mode == 5) { + if (rc_cfg->rc_mode == MPP_ENC_RC_MODE_CBR) { /* constant bitrate has very small bps range of 1/16 bps */ rc_cfg->bps_target = p->bps; rc_cfg->bps_max = p->bps * 17 / 16; rc_cfg->bps_min = p->bps * 15 / 16; - } else if (rc_cfg->rc_mode == 3) { - /* variable bitrate has large bps range */ - rc_cfg->bps_target = p->bps; - rc_cfg->bps_max = p->bps * 17 / 16; - rc_cfg->bps_min = p->bps * 1 / 16; + } else if (rc_cfg->rc_mode == MPP_ENC_RC_MODE_VBR) { + if (rc_cfg->quality == MPP_ENC_RC_QUALITY_CQP) { + /* constant QP does not have bps */ + rc_cfg->bps_target = -1; + rc_cfg->bps_max = -1; + rc_cfg->bps_min = -1; + } else { + /* variable bitrate has large bps range */ + rc_cfg->bps_target = p->bps; + rc_cfg->bps_max = p->bps * 17 / 16; + rc_cfg->bps_min = p->bps * 1 / 16; + } } /* fix input / output frame rate */ @@ -619,22 +600,25 @@ MPP_RET test_mpp_setup(MpiEncTestData *p) codec_cfg->h264.entropy_coding_mode = 1; codec_cfg->h264.cabac_init_idc = 0; - if (rc_cfg->rc_mode == 1) { - /* constant QP mode qp is fixed */ - p->qp_max = p->qp_init; - p->qp_min = p->qp_init; - p->qp_step = 0; - } else if (rc_cfg->rc_mode == 5) { + if (rc_cfg->rc_mode == MPP_ENC_RC_MODE_CBR) { /* constant bitrate do not limit qp range */ p->qp_max = 48; p->qp_min = 4; p->qp_step = 16; - } else if (rc_cfg->rc_mode == 3) { - /* variable bitrate has qp min limit */ - p->qp_max = 40; - p->qp_min = 12; - p->qp_step = 8; + } else if (rc_cfg->rc_mode == MPP_ENC_RC_MODE_VBR) { + if (rc_cfg->quality == MPP_ENC_RC_QUALITY_CQP) { + /* constant QP mode qp is fixed */ + p->qp_max = p->qp_init; + p->qp_min = p->qp_init; + p->qp_step = 0; + } else { + /* variable bitrate has qp min limit */ + p->qp_max = 40; + p->qp_min = 12; + p->qp_step = 8; + } } + codec_cfg->h264.qp_max = p->qp_max; codec_cfg->h264.qp_min = p->qp_min; codec_cfg->h264.qp_max_step = p->qp_step; diff --git a/test/mpi_rc_test.c b/test/mpi_rc_test.c index 894dffe5..c8a92916 100644 --- a/test/mpi_rc_test.c +++ b/test/mpi_rc_test.c @@ -713,8 +713,8 @@ static MPP_RET mpi_rc_codec(MpiRcTestCtx *ctx) } rc_cfg->change = MPP_ENC_RC_CFG_CHANGE_ALL; - rc_cfg->rc_mode = 5; - rc_cfg->quality = 0; + rc_cfg->rc_mode = MPP_ENC_RC_MODE_CBR; + rc_cfg->quality = MPP_ENC_RC_QUALITY_MEDIUM; rc_cfg->bps_target = 800000; rc_cfg->bps_max = 800000; rc_cfg->bps_min = 800000; @@ -770,23 +770,26 @@ static MPP_RET mpi_rc_codec(MpiRcTestCtx *ctx) codec_cfg->h264.entropy_coding_mode = 1; codec_cfg->h264.cabac_init_idc = 0; - if (rc_cfg->rc_mode == 1) { - /* constant QP mode qp is fixed */ - codec_cfg->h264.qp_max = 26; - codec_cfg->h264.qp_min = 26; - codec_cfg->h264.qp_max_step = 0; - } else if (rc_cfg->rc_mode == 5) { + codec_cfg->h264.qp_init = 0; + if (rc_cfg->rc_mode == MPP_ENC_RC_MODE_CBR) { /* constant bitrate do not limit qp range */ codec_cfg->h264.qp_max = 48; codec_cfg->h264.qp_min = 4; codec_cfg->h264.qp_max_step = 16; - } else if (rc_cfg->rc_mode == 3) { - /* variable bitrate has qp min limit */ - codec_cfg->h264.qp_max = 40; - codec_cfg->h264.qp_min = 12; - codec_cfg->h264.qp_max_step = 8; + } else if (rc_cfg->rc_mode == MPP_ENC_RC_MODE_VBR) { + if (rc_cfg->quality == MPP_ENC_RC_QUALITY_CQP) { + /* constant QP mode qp is fixed */ + codec_cfg->h264.qp_init = 26; + codec_cfg->h264.qp_max = 26; + codec_cfg->h264.qp_min = 26; + codec_cfg->h264.qp_max_step = 0; + } else { + /* variable bitrate has qp min limit */ + codec_cfg->h264.qp_max = 40; + codec_cfg->h264.qp_min = 12; + codec_cfg->h264.qp_max_step = 8; + } } - 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); @@ -1081,8 +1084,8 @@ MPP_TEST_OUT: MPP_FREE(dec_in_buf); if (MPP_OK == ret) - mpp_log("test success total frame %d bps %lld\n", - frame_count, (RK_U64)((stream_size * 8 * fps) / frame_count)); + mpp_log("test success total frame %d bps %d\n", + frame_count, stat->avg_bitrate); else mpp_err_f("failed ret %d\n", ret);