diff --git a/inc/mpp_rc_api.h b/inc/mpp_rc_api.h index 30b9eed2..c717d1ca 100644 --- a/inc/mpp_rc_api.h +++ b/inc/mpp_rc_api.h @@ -170,6 +170,7 @@ typedef struct RcImplApi_t { MPP_RET (*deinit)(void *ctx); MPP_RET (*check_drop)(void *ctx, EncRcTask *task); + MPP_RET (*check_reenc)(void *ctx, EncRcTask *task); /* * frm_start - frame level rate control frm_start. diff --git a/mpp/codec/inc/rc.h b/mpp/codec/inc/rc.h index d9261da3..a1957cc0 100644 --- a/mpp/codec/inc/rc.h +++ b/mpp/codec/inc/rc.h @@ -70,6 +70,8 @@ MPP_RET rc_update_usr_cfg(RcCtx ctx, RcCfg *cfg); /* Frame rate convertion */ MPP_RET rc_frm_check_drop(RcCtx ctx, EncRcTask *task); +/* Frame reenc check */ +MPP_RET rc_frm_check_reenc(RcCtx ctx, EncRcTask *task); /* Frame level rate and quality control */ MPP_RET rc_frm_start(RcCtx ctx, EncRcTask *task); diff --git a/mpp/codec/rc/rc.cpp b/mpp/codec/rc/rc.cpp index 79af4e5b..faf691cd 100644 --- a/mpp/codec/rc/rc.cpp +++ b/mpp/codec/rc/rc.cpp @@ -173,6 +173,17 @@ MPP_RET rc_frm_check_drop(RcCtx ctx, EncRcTask *task) return ret; } +MPP_RET rc_frm_check_reenc(RcCtx ctx, EncRcTask *task) +{ + MppRcImpl *p = (MppRcImpl *)ctx; + const RcImplApi *api = p->api; + + if (!api || !api->check_reenc || !p->ctx || !task) + return MPP_OK; + + return api->check_reenc(p->ctx, task); +} + MPP_RET rc_frm_start(RcCtx ctx, EncRcTask *task) { MppRcImpl *p = (MppRcImpl *)ctx; diff --git a/mpp/codec/rc/rc_model_v2.c b/mpp/codec/rc/rc_model_v2.c index d20dd857..9fc2e6df 100644 --- a/mpp/codec/rc/rc_model_v2.c +++ b/mpp/codec/rc/rc_model_v2.c @@ -1320,47 +1320,58 @@ MPP_RET rc_model_v2_hal_end(void *ctx, EncRcTask *task) return MPP_OK; } -MPP_RET rc_model_v2_end(void *ctx, EncRcTask *task) +MPP_RET rc_model_v2_check_reenc(void *ctx, EncRcTask *task) { RcModelV2Ctx *p = (RcModelV2Ctx *)ctx; EncRcTaskInfo *cfg = (EncRcTaskInfo *)&task->info; EncFrmStatus *frm = &task->frm; + frm->reencode = 0; + + if ((p->usr_cfg.mode == RC_FIXQP) || + (task->force.force_flag & ENC_RC_FORCE_QP)) + return MPP_OK; + + if (check_re_enc(p, cfg)) { + if (p->usr_cfg.mode == RC_CBR) { + reenc_calc_cbr_ratio(p, cfg); + } else { + reenc_calc_vbr_ratio(p, cfg); + } + + if (p->next_ratio != 0 && cfg->quality_target < cfg->quality_max) { + p->reenc_cnt++; + frm->reencode = 1; + } + } + + return MPP_OK; +} + +MPP_RET rc_model_v2_end(void *ctx, EncRcTask *task) +{ + RcModelV2Ctx *p = (RcModelV2Ctx *)ctx; + EncRcTaskInfo *cfg = (EncRcTaskInfo *)&task->info; + rc_dbg_func("enter ctx %p cfg %p\n", ctx, cfg); + rc_dbg_rc("bits_mode_update real_bit %d", cfg->bit_real); if (p->usr_cfg.mode == RC_FIXQP) goto DONE; - if (!(task->force.force_flag & ENC_RC_FORCE_QP)) { - if (check_re_enc(p, cfg)) { - if (p->usr_cfg.mode == RC_CBR) { - reenc_calc_cbr_ratio(p, cfg); - } else { - reenc_calc_vbr_ratio(p, cfg); - } + p->last_inst_bps = p->ins_bps; + p->first_frm_flg = 0; - if (p->next_ratio != 0 && cfg->quality_target < cfg->quality_max) { - p->reenc_cnt++; - frm->reencode = 1; - } - } + bits_model_update(p, cfg->bit_real, cfg->madi); + + if (p->usr_cfg.mode == RC_AVBR) { + moving_judge_update(p, cfg); + bit_statics_update(p, cfg->bit_real); } - - if (!frm->reencode) { - rc_dbg_rc("bits_mode_update real_bit %d", cfg->bit_real); - p->last_inst_bps = p->ins_bps; - p->first_frm_flg = 0; - bits_model_update(p, cfg->bit_real, cfg->madi); - if (p->usr_cfg.mode == RC_AVBR) { - moving_judge_update(p, cfg); - bit_statics_update(p, cfg->bit_real); - } - p->last_frame_type = p->frame_type; - p->pre_mean_qp = cfg->quality_real; - p->scale_qp = p->cur_scale_qp; - p->prev_md_prop = 0; - } - + p->last_frame_type = p->frame_type; + p->pre_mean_qp = cfg->quality_real; + p->scale_qp = p->cur_scale_qp; + p->prev_md_prop = 0; p->pre_target_bits = cfg->bit_target; p->pre_real_bits = cfg->bit_real; @@ -1376,6 +1387,7 @@ const RcImplApi default_h264e = { rc_model_v2_init, rc_model_v2_deinit, NULL, + rc_model_v2_check_reenc, rc_model_v2_start, rc_model_v2_end, rc_model_v2_hal_start, @@ -1389,6 +1401,7 @@ const RcImplApi default_h265e = { rc_model_v2_init, rc_model_v2_deinit, NULL, + rc_model_v2_check_reenc, rc_model_v2_start, rc_model_v2_end, rc_model_v2_hal_start, @@ -1402,6 +1415,7 @@ const RcImplApi default_jpege = { rc_model_v2_init, rc_model_v2_deinit, NULL, + rc_model_v2_check_reenc, rc_model_v2_start, rc_model_v2_end, rc_model_v2_hal_start, @@ -1546,6 +1560,7 @@ const RcImplApi default_vp8e = { rc_model_v2_init, rc_model_v2_deinit, NULL, + rc_model_v2_check_reenc, rc_model_v2_start, rc_model_v2_end, rc_model_v2_vp8_hal_start, diff --git a/mpp/codec/rc/rc_model_v2_smt.c b/mpp/codec/rc/rc_model_v2_smt.c index f095fc7e..340aa075 100644 --- a/mpp/codec/rc/rc_model_v2_smt.c +++ b/mpp/codec/rc/rc_model_v2_smt.c @@ -986,7 +986,7 @@ MPP_RET rc_model_v2_smt_start(void *ctx, EncRcTask *task) return MPP_OK; } -MPP_RET rc_model_v2_smt_end(void *ctx, EncRcTask *task) +MPP_RET rc_model_v2_smt_check_reenc(void *ctx, EncRcTask *task) { RcModelV2SmtCtx *p = (RcModelV2SmtCtx *)ctx; EncRcTaskInfo *cfg = (EncRcTaskInfo *)&task->info; @@ -999,56 +999,67 @@ MPP_RET rc_model_v2_smt_end(void *ctx, EncRcTask *task) } else { reenc_calc_vbr_ratio_smt(p, cfg); } - } else { - MppFrame frame = task->frame; - RK_S32 width = mpp_frame_get_width(frame); - RK_S32 height = mpp_frame_get_height(frame); - RK_S32 bit_real = cfg->bit_real; - RK_S32 madi = cfg->madi; - RK_S32 cu64_num = (MPP_ALIGN(width, 64) / 64 * MPP_ALIGN(height, 64) / 64) ; - RK_U64 sse_dat = cfg->madp * cu64_num; - RK_U32 qp_sum; - double avg_qp = 0.0; - RK_S32 avg_sse = 1; - - if (p->codec_type == 1) - qp_sum = cfg->quality_real / 64; // 265 - else - qp_sum = cfg->quality_real / 16; // 264 - - avg_qp = qp_sum; - avg_sse = (RK_S32)sqrt((double)(sse_dat)); - p->qp_preavg = (RK_S32)(avg_qp + 0.5); - if (p->frame_type == INTER_P_FRAME) { - if (madi >= MAD_THDI) { - avg_qp = p->qp_out; - } - } - - if (p->frame_type == INTER_P_FRAME || p->gop_mode == MPP_GOP_ALL_INTRA) { - mpp_data_update(p->qp_p, avg_qp); - mpp_data_update(p->sse_p, avg_sse); - } else { - p->intra_preqp = p->qp_out; - p->intra_presse = avg_sse; - p->intra_premadi = madi; - p->intra_prerealbit = bit_real; - } - - p->st_madi = cfg->madi; - rc_dbg_rc("bits_mode_update real_bit %d", bit_real); - bits_model_update_smt(p, bit_real); - p->pre_target_bits = cfg->bit_target; - p->pre_real_bits = bit_real; - p->qp_prev_out = p->qp_out; - p->last_inst_bps = p->ins_bps; - p->last_frame_type = p->frame_type; } rc_dbg_func("leave %p\n", ctx); return MPP_OK; } +MPP_RET rc_model_v2_smt_end(void *ctx, EncRcTask *task) +{ + RcModelV2SmtCtx *p = (RcModelV2SmtCtx *)ctx; + EncRcTaskInfo *cfg = (EncRcTaskInfo *)&task->info; + + rc_dbg_func("enter ctx %p cfg %p\n", ctx, cfg); + + MppFrame frame = task->frame; + RK_S32 width = mpp_frame_get_width(frame); + RK_S32 height = mpp_frame_get_height(frame); + RK_S32 bit_real = cfg->bit_real; + RK_S32 madi = cfg->madi; + RK_S32 cu64_num = (MPP_ALIGN(width, 64) / 64 * MPP_ALIGN(height, 64) / 64) ; + RK_U64 sse_dat = cfg->madp * cu64_num; + RK_U32 qp_sum; + double avg_qp = 0.0; + RK_S32 avg_sse = 1; + + if (p->codec_type == 1) + qp_sum = cfg->quality_real / 64; // 265 + else + qp_sum = cfg->quality_real / 16; // 264 + + avg_qp = qp_sum; + avg_sse = (RK_S32)sqrt((double)(sse_dat)); + p->qp_preavg = (RK_S32)(avg_qp + 0.5); + if (p->frame_type == INTER_P_FRAME) { + if (madi >= MAD_THDI) { + avg_qp = p->qp_out; + } + } + + if (p->frame_type == INTER_P_FRAME || p->gop_mode == MPP_GOP_ALL_INTRA) { + mpp_data_update(p->qp_p, avg_qp); + mpp_data_update(p->sse_p, avg_sse); + } else { + p->intra_preqp = p->qp_out; + p->intra_presse = avg_sse; + p->intra_premadi = madi; + p->intra_prerealbit = bit_real; + } + + p->st_madi = cfg->madi; + rc_dbg_rc("bits_mode_update real_bit %d", bit_real); + bits_model_update_smt(p, bit_real); + p->pre_target_bits = cfg->bit_target; + p->pre_real_bits = bit_real; + p->qp_prev_out = p->qp_out; + p->last_inst_bps = p->ins_bps; + p->last_frame_type = p->frame_type; + + rc_dbg_func("leave %p\n", ctx); + return MPP_OK; +} + MPP_RET rc_model_v2_smt_hal_start(void *ctx, EncRcTask *task) { @@ -1071,6 +1082,7 @@ const RcImplApi smt_h264e = { rc_model_v2_smt_h264_init, rc_model_v2_smt_deinit, NULL, + rc_model_v2_smt_check_reenc, rc_model_v2_smt_start, rc_model_v2_smt_end, rc_model_v2_smt_hal_start, @@ -1084,6 +1096,7 @@ const RcImplApi smt_h265e = { rc_model_v2_smt_h265_init, rc_model_v2_smt_deinit, NULL, + rc_model_v2_smt_check_reenc, rc_model_v2_smt_start, rc_model_v2_smt_end, rc_model_v2_smt_hal_start, diff --git a/mpp/codec/rc/test/rc_api_test.c b/mpp/codec/rc/test/rc_api_test.c index a4d3a00b..218006eb 100644 --- a/mpp/codec/rc/test/rc_api_test.c +++ b/mpp/codec/rc/test/rc_api_test.c @@ -34,6 +34,7 @@ const RcImplApi test_h264_api = { NULL, NULL, NULL, + NULL, }; const RcImplApi test_h265_api = { @@ -47,6 +48,7 @@ const RcImplApi test_h265_api = { NULL, NULL, NULL, + NULL, }; int main()