[h264e]: fix mosaic bug

If target bit is zero, it will exist mosaic in the encoded
picture. In this case, half of the average bit rate of
previous P frames is assigned to target bit.

Change-Id: I990e80ae04affb0a6bed2e6f456c77657f31a221
Signed-off-by: timkingh.huang <timkingh.huang@rock-chips.com>
This commit is contained in:
timkingh.huang
2017-04-25 17:28:54 +08:00
committed by Herman Chen
parent 3d9aec512f
commit 09e626dc05
3 changed files with 40 additions and 20 deletions

View File

@@ -150,11 +150,13 @@ typedef struct MppRateControl_s {
/*
* intra - intra frame bits record
* inter - inter frame bits record
* pid_intra - intra frame bits record
* pid_inter - inter frame bits record
* pid_gop - serial frame bits record
*/
MppData *intra;
MppData *inter;
MppData *gop_bits;
MppData *intra_percent;
MppPIDCtx pid_intra;

View File

@@ -106,6 +106,7 @@ RK_S32 mpp_data_avg(MppData *p, RK_S32 len, RK_S32 num, RK_S32 denorm)
sum += p->val[pos];
}
} else {
/* This case is not used so far, but may be useful in the future */
mpp_assert(num > denorm);
RK_S32 acc_num = num;
RK_S32 acc_denorm = denorm;
@@ -119,8 +120,8 @@ RK_S32 mpp_data_avg(MppData *p, RK_S32 len, RK_S32 num, RK_S32 denorm)
pos = p->len - 1;
sum += p->val[pos] * acc_num / acc_denorm;
acc_num += num;
acc_denorm += denorm;
acc_num *= num;
acc_denorm *= denorm;
}
}
return DIV(sum, len);
@@ -212,6 +213,11 @@ MPP_RET mpp_rc_deinit(MppRateControl *ctx)
ctx->intra = NULL;
}
if (ctx->inter) {
mpp_data_deinit(ctx->inter);
ctx->inter = NULL;
}
if (ctx->gop_bits) {
mpp_data_deinit(ctx->gop_bits);
ctx->gop_bits = NULL;
@@ -276,6 +282,10 @@ MPP_RET mpp_rc_update_user_cfg(MppRateControl *ctx, MppEncRcCfg *cfg, RK_S32 for
mpp_data_deinit(ctx->intra);
mpp_data_init(&ctx->intra, gop);
if (ctx->inter)
mpp_data_deinit(ctx->inter);
mpp_data_init(&ctx->inter, ctx->fps_out); /* need test */
if (ctx->gop_bits)
mpp_data_deinit(ctx->gop_bits);
mpp_data_init(&ctx->gop_bits, gop);
@@ -408,12 +418,13 @@ MPP_RET mpp_rc_bits_allocation(MppRateControl *ctx, RcSyntax *rc_syn)
if (ctx->acc_intra_count) {
intra_percent = mpp_data_avg(ctx->intra_percent, 1, 1, 1) / 100.0;
ctx->last_intra_percent = intra_percent;
}
if (ctx->acc_intra_count) {
ctx->bits_target = (ctx->fps_out * ctx->bits_per_pic + diff_bit) * intra_percent;
} else
ctx->bits_target = ctx->bits_per_intra - mpp_pid_calc(&ctx->pid_intra);
ctx->bits_target = (ctx->fps_out * ctx->bits_per_pic + diff_bit)
* intra_percent;
} else {
ctx->bits_target = ctx->bits_per_intra
- mpp_pid_calc(&ctx->pid_intra);
}
} else {
if (ctx->pre_frmtype == INTRA_FRAME) {
RK_S32 diff_bit = mpp_pid_calc(&ctx->pid_fps);
@@ -447,7 +458,22 @@ MPP_RET mpp_rc_bits_allocation(MppRateControl *ctx, RcSyntax *rc_syn)
} break;
}
ctx->bits_target = ctx->bits_target > 0 ? ctx->bits_target : 0;
/* If target bit is zero, it will exist mosaic in the encoded picture.
* In this case, half of the average bit rate of previous P frames is
* assigned to target bit.
*/
if (ctx->bits_target <= 0) {
if (ctx->cur_frmtype == INTRA_FRAME) {
mpp_rc_dbg_rc("unbelievable case: intra frame target bits is zero!\n");
} else {
mpp_rc_dbg_rc("inter frame target bits is zero!"
"intra frame %d, inter frame %d, total_cnt %d\n",
ctx->acc_intra_count, ctx->acc_inter_count,
ctx->acc_total_count);
ctx->bits_target = mpp_data_avg(ctx->inter, -1, 1, 1) / 2;
mpp_rc_dbg_rc("after adjustment, target bits %d\n", ctx->bits_target);
}
}
rc_syn->bit_target = ctx->bits_target;
@@ -485,6 +511,7 @@ MPP_RET mpp_rc_update_hw_result(MppRateControl *ctx, RcHalResult *result)
ctx, bits, ctx->bits_per_inter);
ctx->acc_inter_count++;
ctx->acc_inter_bits_in_fps += bits;
mpp_data_update(ctx->inter, bits);
mpp_data_update(ctx->gop_bits, bits);
mpp_pid_update(&ctx->pid_inter, bits - ctx->bits_target);
}
@@ -503,15 +530,6 @@ MPP_RET mpp_rc_update_hw_result(MppRateControl *ctx, RcHalResult *result)
ctx->last_fps_bits = 0;
}
switch (ctx->gop_mode) {
case MPP_GOP_ALL_INTER : {
} break;
case MPP_GOP_ALL_INTRA : {
} break;
default : {
} break;
}
ctx->pre_frmtype = ctx->cur_frmtype;
return MPP_OK;

View File

@@ -782,9 +782,6 @@ void h264e_sei_pack2str(char *str, H264eHalContext *ctx, RcSyntax *rc_syn)
/* rc cfg */
if (rc_change) {
H264E_HAL_SPRINT(str, len, "[rc] ");
H264E_HAL_SPRINT(str, len, "rc_mode=%d ", rc->rc_mode);
H264E_HAL_SPRINT(str, len, "quality=%d ", rc->quality);
H264E_HAL_SPRINT(str, len, "bps=%d:%d:%d ", rc->bps_target, rc->bps_min, rc->bps_max);
H264E_HAL_SPRINT(str, len, "fps_in=%d:%d:%d ", rc->fps_in_num, rc->fps_in_denorm, rc->fps_in_flex);
H264E_HAL_SPRINT(str, len, "fps_out=%d:%d:%d ", rc->fps_out_num, rc->fps_out_denorm, rc->fps_out_flex);
H264E_HAL_SPRINT(str, len, "gop=%d ", rc->gop);
@@ -792,6 +789,9 @@ void h264e_sei_pack2str(char *str, H264eHalContext *ctx, RcSyntax *rc_syn)
if (rc_syn) {
H264E_HAL_SPRINT(str, len, "[frm %d] ", ctx->frame_cnt);
H264E_HAL_SPRINT(str, len, "rc_mode=%d ", rc->rc_mode);
H264E_HAL_SPRINT(str, len, "quality=%d ", rc->quality);
H264E_HAL_SPRINT(str, len, "bps=%d:%d:%d ", rc->bps_target, rc->bps_min, rc->bps_max);
H264E_HAL_SPRINT(str, len, "tgt_bit=%d:%d:%d ", rc_syn->bit_target, rc_syn->bit_min, rc_syn->bit_max);
H264E_HAL_SPRINT(str, len, "qp=%d:%d:%d ", hw_cfg->qp, hw_cfg->qp_min, hw_cfg->qp_max);
}