[rc]: add init qp estimation

if outside doesn't set init qp value, mpp will estimate one init qp
according to resolution and bitrate.

Change-Id: If5415f6a3bfa3f2981ffd4eb044614bf9b035d2f
Signed-off-by: Jung Zhao <jung.zhao@rock-chips.com>
This commit is contained in:
Jung Zhao
2017-01-16 16:27:11 +08:00
committed by Herman Chen
parent cab7420bd7
commit 038a3bd665
4 changed files with 89 additions and 54 deletions

View File

@@ -37,58 +37,6 @@
static RK_U32 mpp_rc_debug = 0;
static RK_S32 axb_div_c(RK_S32 a, RK_S32 b, RK_S32 c)
{
RK_U32 left = 32;
RK_U32 right = 0;
RK_U32 shift;
RK_S32 sign = 1;
RK_S32 tmp;
if (a == 0 || b == 0)
return 0;
else if ((a * b / b) == a && c != 0)
return (a * b / c);
if (a < 0) {
sign = -1;
a = -a;
}
if (b < 0) {
sign *= -1;
b = -b;
}
if (c < 0) {
sign *= -1;
c = -c;
}
if (c == 0)
return 0x7FFFFFFF * sign;
if (b > a) {
tmp = b;
b = a;
a = tmp;
}
for (--left; (((RK_U32)a << left) >> left) != (RK_U32)a; --left)
;
left--;
while (((RK_U32)b >> right) > (RK_U32)c)
right++;
if (right > left) {
return 0x7FFFFFFF * sign;
} else {
shift = left - right;
return (RK_S32)((((RK_U32)a << shift) /
(RK_U32)c * (RK_U32)b) >> shift) * sign;
}
}
MPP_RET mpp_data_init(MppData **data, RK_S32 size)
{
if (NULL == data || size <= 0) {

View File

@@ -2385,8 +2385,8 @@ MPP_RET hal_h264e_rkv_set_rc_regs(h264e_hal_context *ctx, h264e_rkv_reg_set *reg
regs->swreg54.rc_qp_mod = 2; //sw_quality_flag;
if (syn->frame_type == H264E_RKV_FRAME_I) {
regs->swreg54.rc_fact0 = 16; //sw_quality_factor_0;
regs->swreg54.rc_fact1 = 0; //sw_quality_factor_1;
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;
@@ -2742,6 +2742,40 @@ static MPP_RET hal_h264e_rkv_update_hw_cfg(h264e_hal_context *ctx, HalEncTask *t
codec->change = 0;
}
/* init qp calculate, if outside doesn't set init qp.
* mpp will use bpp to estimates one.
*/
if (hw_cfg->pic_init_qp <= 0) {
RK_S32 qp_tbl[2][9] = {
{27, 44, 72, 119, 192, 314, 453, 653, 0x7FFFFFFF},
{49, 45, 41, 37, 33, 29, 25, 21, 17}};
RK_S32 pels = ctx->cfg->prep.width * ctx->cfg->prep.height;
RK_S32 bits_per_pic = axb_div_c(rc->bps_target,
rc->fps_out_denorm,
rc->fps_out_num);
if (pels) {
RK_S32 upscale = 8000;
if (bits_per_pic > 1000000)
hw_cfg->pic_init_qp = codec->qp_min;
else {
RK_S32 j = -1;
pels >>= 8;
bits_per_pic >>= 5;
bits_per_pic *= pels + 250;
bits_per_pic /= 350 + (3 * pels) / 4;
bits_per_pic = axb_div_c(bits_per_pic, upscale, pels << 6);
while (qp_tbl[0][++j] < bits_per_pic);
hw_cfg->pic_init_qp = qp_tbl[1][j];
hw_cfg->qp_prev = hw_cfg->pic_init_qp;
}
}
}
if (NULL == ctx->intra_qs)
mpp_linreg_init(&ctx->intra_qs, MPP_MIN(rc->gop, 10), 2);
if (NULL == ctx->inter_qs)

View File

@@ -181,6 +181,8 @@ static __inline RK_U32 mpp_is_32bit()
return ((sizeof(void *) == 4) ? (1) : (0));
}
RK_S32 axb_div_c(RK_S32 a, RK_S32 b, RK_S32 c);
#ifdef __cplusplus
}
#endif

View File

@@ -55,3 +55,54 @@ RK_S32 mpp_log2_16bit(RK_U32 v)
return n;
}
RK_S32 axb_div_c(RK_S32 a, RK_S32 b, RK_S32 c)
{
RK_U32 left = 32;
RK_U32 right = 0;
RK_U32 shift;
RK_S32 sign = 1;
RK_S32 tmp;
if (a == 0 || b == 0)
return 0;
else if ((a * b / b) == a && c != 0)
return (a * b / c);
if (a < 0) {
sign = -1;
a = -a;
}
if (b < 0) {
sign *= -1;
b = -b;
}
if (c < 0) {
sign *= -1;
c = -c;
}
if (c == 0)
return 0x7FFFFFFF * sign;
if (b > a) {
tmp = b;
b = a;
a = tmp;
}
for (--left; (((RK_U32)a << left) >> left) != (RK_U32)a; --left)
;
left--;
while (((RK_U32)b >> right) > (RK_U32)c)
right++;
if (right > left) {
return 0x7FFFFFFF * sign;
} else {
shift = left - right;
return (RK_S32)((((RK_U32)a << shift) /
(RK_U32)c * (RK_U32)b) >> shift) * sign;
}
}