mirror of
https://github.com/nyanmisaka/mpp.git
synced 2025-10-16 22:21:11 +08:00
[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:

committed by
Herman Chen

parent
3d9aec512f
commit
09e626dc05
@@ -150,11 +150,13 @@ typedef struct MppRateControl_s {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* intra - intra frame bits record
|
* intra - intra frame bits record
|
||||||
|
* inter - inter frame bits record
|
||||||
* pid_intra - intra frame bits record
|
* pid_intra - intra frame bits record
|
||||||
* pid_inter - inter frame bits record
|
* pid_inter - inter frame bits record
|
||||||
* pid_gop - serial frame bits record
|
* pid_gop - serial frame bits record
|
||||||
*/
|
*/
|
||||||
MppData *intra;
|
MppData *intra;
|
||||||
|
MppData *inter;
|
||||||
MppData *gop_bits;
|
MppData *gop_bits;
|
||||||
MppData *intra_percent;
|
MppData *intra_percent;
|
||||||
MppPIDCtx pid_intra;
|
MppPIDCtx pid_intra;
|
||||||
|
@@ -106,6 +106,7 @@ RK_S32 mpp_data_avg(MppData *p, RK_S32 len, RK_S32 num, RK_S32 denorm)
|
|||||||
sum += p->val[pos];
|
sum += p->val[pos];
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
/* This case is not used so far, but may be useful in the future */
|
||||||
mpp_assert(num > denorm);
|
mpp_assert(num > denorm);
|
||||||
RK_S32 acc_num = num;
|
RK_S32 acc_num = num;
|
||||||
RK_S32 acc_denorm = denorm;
|
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;
|
pos = p->len - 1;
|
||||||
|
|
||||||
sum += p->val[pos] * acc_num / acc_denorm;
|
sum += p->val[pos] * acc_num / acc_denorm;
|
||||||
acc_num += num;
|
acc_num *= num;
|
||||||
acc_denorm += denorm;
|
acc_denorm *= denorm;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return DIV(sum, len);
|
return DIV(sum, len);
|
||||||
@@ -212,6 +213,11 @@ MPP_RET mpp_rc_deinit(MppRateControl *ctx)
|
|||||||
ctx->intra = NULL;
|
ctx->intra = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ctx->inter) {
|
||||||
|
mpp_data_deinit(ctx->inter);
|
||||||
|
ctx->inter = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (ctx->gop_bits) {
|
if (ctx->gop_bits) {
|
||||||
mpp_data_deinit(ctx->gop_bits);
|
mpp_data_deinit(ctx->gop_bits);
|
||||||
ctx->gop_bits = NULL;
|
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_deinit(ctx->intra);
|
||||||
mpp_data_init(&ctx->intra, gop);
|
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)
|
if (ctx->gop_bits)
|
||||||
mpp_data_deinit(ctx->gop_bits);
|
mpp_data_deinit(ctx->gop_bits);
|
||||||
mpp_data_init(&ctx->gop_bits, gop);
|
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) {
|
if (ctx->acc_intra_count) {
|
||||||
intra_percent = mpp_data_avg(ctx->intra_percent, 1, 1, 1) / 100.0;
|
intra_percent = mpp_data_avg(ctx->intra_percent, 1, 1, 1) / 100.0;
|
||||||
ctx->last_intra_percent = intra_percent;
|
ctx->last_intra_percent = intra_percent;
|
||||||
}
|
|
||||||
|
|
||||||
if (ctx->acc_intra_count) {
|
ctx->bits_target = (ctx->fps_out * ctx->bits_per_pic + diff_bit)
|
||||||
ctx->bits_target = (ctx->fps_out * ctx->bits_per_pic + diff_bit) * intra_percent;
|
* intra_percent;
|
||||||
} else
|
} else {
|
||||||
ctx->bits_target = ctx->bits_per_intra - mpp_pid_calc(&ctx->pid_intra);
|
ctx->bits_target = ctx->bits_per_intra
|
||||||
|
- mpp_pid_calc(&ctx->pid_intra);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (ctx->pre_frmtype == INTRA_FRAME) {
|
if (ctx->pre_frmtype == INTRA_FRAME) {
|
||||||
RK_S32 diff_bit = mpp_pid_calc(&ctx->pid_fps);
|
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;
|
} 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;
|
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, bits, ctx->bits_per_inter);
|
||||||
ctx->acc_inter_count++;
|
ctx->acc_inter_count++;
|
||||||
ctx->acc_inter_bits_in_fps += bits;
|
ctx->acc_inter_bits_in_fps += bits;
|
||||||
|
mpp_data_update(ctx->inter, bits);
|
||||||
mpp_data_update(ctx->gop_bits, bits);
|
mpp_data_update(ctx->gop_bits, bits);
|
||||||
mpp_pid_update(&ctx->pid_inter, bits - ctx->bits_target);
|
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;
|
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;
|
ctx->pre_frmtype = ctx->cur_frmtype;
|
||||||
|
|
||||||
return MPP_OK;
|
return MPP_OK;
|
||||||
|
@@ -782,9 +782,6 @@ void h264e_sei_pack2str(char *str, H264eHalContext *ctx, RcSyntax *rc_syn)
|
|||||||
/* rc cfg */
|
/* rc cfg */
|
||||||
if (rc_change) {
|
if (rc_change) {
|
||||||
H264E_HAL_SPRINT(str, len, "[rc] ");
|
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_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, "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);
|
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) {
|
if (rc_syn) {
|
||||||
H264E_HAL_SPRINT(str, len, "[frm %d] ", ctx->frame_cnt);
|
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, "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);
|
H264E_HAL_SPRINT(str, len, "qp=%d:%d:%d ", hw_cfg->qp, hw_cfg->qp_min, hw_cfg->qp_max);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user