mirror of
https://github.com/nyanmisaka/mpp.git
synced 2025-10-06 01:26:49 +08:00
[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:
@@ -37,58 +37,6 @@
|
|||||||
|
|
||||||
static RK_U32 mpp_rc_debug = 0;
|
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)
|
MPP_RET mpp_data_init(MppData **data, RK_S32 size)
|
||||||
{
|
{
|
||||||
if (NULL == data || size <= 0) {
|
if (NULL == data || size <= 0) {
|
||||||
|
@@ -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;
|
regs->swreg54.rc_qp_mod = 2; //sw_quality_flag;
|
||||||
if (syn->frame_type == H264E_RKV_FRAME_I) {
|
if (syn->frame_type == H264E_RKV_FRAME_I) {
|
||||||
regs->swreg54.rc_fact0 = 16; //sw_quality_factor_0;
|
regs->swreg54.rc_fact0 = 8; //sw_quality_factor_0;
|
||||||
regs->swreg54.rc_fact1 = 0; //sw_quality_factor_1;
|
regs->swreg54.rc_fact1 = 8; //sw_quality_factor_1;
|
||||||
} else {
|
} else {
|
||||||
regs->swreg54.rc_fact0 = 0; //sw_quality_factor_0;
|
regs->swreg54.rc_fact0 = 0; //sw_quality_factor_0;
|
||||||
regs->swreg54.rc_fact1 = 16; //sw_quality_factor_1;
|
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;
|
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)
|
if (NULL == ctx->intra_qs)
|
||||||
mpp_linreg_init(&ctx->intra_qs, MPP_MIN(rc->gop, 10), 2);
|
mpp_linreg_init(&ctx->intra_qs, MPP_MIN(rc->gop, 10), 2);
|
||||||
if (NULL == ctx->inter_qs)
|
if (NULL == ctx->inter_qs)
|
||||||
|
@@ -181,6 +181,8 @@ static __inline RK_U32 mpp_is_32bit()
|
|||||||
return ((sizeof(void *) == 4) ? (1) : (0));
|
return ((sizeof(void *) == 4) ? (1) : (0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RK_S32 axb_div_c(RK_S32 a, RK_S32 b, RK_S32 c);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@@ -55,3 +55,54 @@ RK_S32 mpp_log2_16bit(RK_U32 v)
|
|||||||
return n;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user