mirror of
https://github.com/nyanmisaka/mpp.git
synced 2025-10-05 17:16:50 +08:00
[h264e]: implement SEI writting
Change-Id: I7e4960983fd20e924752b143dc368af4ebc44eb5 Signed-off-by: Lin Kesheng <lks@rock-chips.com>
This commit is contained in:
@@ -733,56 +733,66 @@ MPP_RET h264e_set_pps(H264eHalContext *ctx, H264ePps *pps, H264eSps *sps)
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
void h264e_sei_pack2str(char *str, H264eHalContext *ctx)
|
||||
void h264e_sei_pack2str(char *str, H264eHalContext *ctx, RcSyntax *rc_syn)
|
||||
{
|
||||
MppEncCfgSet *cfg = ctx->cfg;
|
||||
MppEncH264Cfg *codec = &cfg->codec.h264;
|
||||
MppEncPrepCfg *prep = &cfg->prep;
|
||||
MppEncRcCfg *rc = &cfg->rc;
|
||||
H264eHwCfg *hw_cfg = &ctx->hw_cfg;
|
||||
RK_U32 prep_change = prep->change & MPP_ENC_PREP_CFG_CHANGE_INPUT;
|
||||
RK_U32 codec_change = prep->change;
|
||||
RK_U32 rc_change = rc->change;
|
||||
RK_S32 len = H264E_SEI_BUF_SIZE - H264E_UUID_LENGTH;
|
||||
|
||||
if (prep->change || codec->change || rc->change)
|
||||
H264E_HAL_SPRINT(str, "frm %d: ", ctx->frame_cnt);
|
||||
if (prep_change || codec_change || rc_change)
|
||||
H264E_HAL_SPRINT(str, len, "frm %d cfg: ", ctx->frame_cnt);
|
||||
|
||||
/* prep cfg */
|
||||
if (prep->change) {
|
||||
RK_U32 change = prep->change;
|
||||
|
||||
H264E_HAL_SPRINT(str, "[prep] ");
|
||||
if (change & MPP_ENC_PREP_CFG_CHANGE_INPUT) {
|
||||
H264E_HAL_SPRINT(str, "w=%d ", prep->width);
|
||||
H264E_HAL_SPRINT(str, "h=%d ", prep->height);
|
||||
H264E_HAL_SPRINT(str, "fmt=%d ", prep->format);
|
||||
H264E_HAL_SPRINT(str, "h_std=%d ", prep->hor_stride);
|
||||
H264E_HAL_SPRINT(str, "v_std=%d ", prep->ver_stride);
|
||||
if (prep_change) {
|
||||
H264E_HAL_SPRINT(str, len, "[prep] ");
|
||||
if (prep_change & MPP_ENC_PREP_CFG_CHANGE_INPUT) {
|
||||
H264E_HAL_SPRINT(str, len, "w=%d ", prep->width);
|
||||
H264E_HAL_SPRINT(str, len, "h=%d ", prep->height);
|
||||
H264E_HAL_SPRINT(str, len, "fmt=%d ", prep->format);
|
||||
H264E_HAL_SPRINT(str, len, "h_strd=%d ", prep->hor_stride);
|
||||
H264E_HAL_SPRINT(str, len, "v_strd=%d ", prep->ver_stride);
|
||||
}
|
||||
}
|
||||
|
||||
/* codec cfg */
|
||||
if (codec->change) {
|
||||
H264E_HAL_SPRINT(str, "[codec] ");
|
||||
H264E_HAL_SPRINT(str, "profile=%d ", codec->profile);
|
||||
H264E_HAL_SPRINT(str, "level=%d ", codec->level);
|
||||
H264E_HAL_SPRINT(str, "b_cabac=%d ", codec->entropy_coding_mode);
|
||||
H264E_HAL_SPRINT(str, "cabac_idc=%d ", codec->cabac_init_idc);
|
||||
H264E_HAL_SPRINT(str, "t8x8=%d ", codec->transform8x8_mode);
|
||||
H264E_HAL_SPRINT(str, "constrain_intra=%d ", codec->constrained_intra_pred_mode);
|
||||
H264E_HAL_SPRINT(str, "dblk=%d:%d:%d ", codec->deblock_disable,
|
||||
if (codec_change) {
|
||||
H264E_HAL_SPRINT(str, len, "[codec] ");
|
||||
H264E_HAL_SPRINT(str, len, "profile=%d ", codec->profile);
|
||||
H264E_HAL_SPRINT(str, len, "level=%d ", codec->level);
|
||||
H264E_HAL_SPRINT(str, len, "b_cabac=%d ", codec->entropy_coding_mode);
|
||||
H264E_HAL_SPRINT(str, len, "cabac_idc=%d ", codec->cabac_init_idc);
|
||||
H264E_HAL_SPRINT(str, len, "t8x8=%d ", codec->transform8x8_mode);
|
||||
H264E_HAL_SPRINT(str, len, "constrain_intra=%d ", codec->constrained_intra_pred_mode);
|
||||
H264E_HAL_SPRINT(str, len, "dblk=%d:%d:%d ", codec->deblock_disable,
|
||||
codec->deblock_offset_alpha, codec->deblock_offset_beta);
|
||||
H264E_HAL_SPRINT(str, "cbcr_qp_offset=%d:%d ", codec->chroma_cb_qp_offset,
|
||||
H264E_HAL_SPRINT(str, len, "cbcr_qp_offset=%d:%d ", codec->chroma_cb_qp_offset,
|
||||
codec->chroma_cr_qp_offset);
|
||||
H264E_HAL_SPRINT(str, "qp_max=%d ", codec->qp_max);
|
||||
H264E_HAL_SPRINT(str, "qp_min=%d ", codec->qp_min);
|
||||
H264E_HAL_SPRINT(str, "qp_max_step=%d ", codec->qp_max_step);
|
||||
H264E_HAL_SPRINT(str, len, "qp_max=%d ", codec->qp_max);
|
||||
H264E_HAL_SPRINT(str, len, "qp_min=%d ", codec->qp_min);
|
||||
H264E_HAL_SPRINT(str, len, "qp_max_step=%d ", codec->qp_max_step);
|
||||
}
|
||||
|
||||
/* rc cfg */
|
||||
if (rc->change) {
|
||||
H264E_HAL_SPRINT(str, "[rc] ");
|
||||
H264E_HAL_SPRINT(str, "rc_mode=%d ", rc->rc_mode);
|
||||
H264E_HAL_SPRINT(str, "quality=%d ", rc->quality);
|
||||
H264E_HAL_SPRINT(str, "bps=%d:%d:%d ", rc->bps_target, rc->bps_min, rc->bps_max);
|
||||
H264E_HAL_SPRINT(str, "fps_in=%d:%d:%d ", rc->fps_in_num, rc->fps_in_denorm, rc->fps_in_flex);
|
||||
H264E_HAL_SPRINT(str, "fps_out=%d:%d:%d ", rc->fps_out_num, rc->fps_out_denorm, rc->fps_out_flex);
|
||||
H264E_HAL_SPRINT(str, "gop=%d ", rc->gop);
|
||||
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);
|
||||
}
|
||||
|
||||
if (rc_syn) {
|
||||
H264E_HAL_SPRINT(str, len, "[frm %d] ", ctx->frame_cnt);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -112,9 +112,13 @@ extern RK_U32 h264e_hal_log_mode;
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define H264E_HAL_SPRINT(s, ...) \
|
||||
#define H264E_HAL_SPRINT(s, len, ...) \
|
||||
do { \
|
||||
s += sprintf(s, ## __VA_ARGS__); \
|
||||
if (len > 0) { \
|
||||
RK_S32 n = snprintf(s, len, ## __VA_ARGS__); \
|
||||
s += n; \
|
||||
len -= n; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define H264E_UUID_LENGTH 16
|
||||
@@ -442,6 +446,6 @@ const RK_U8 h264e_zigzag_scan4[2][16];
|
||||
const RK_U8 h264e_zigzag_scan8[2][64];
|
||||
void h264e_rkv_set_format(H264eHwCfg *hw_cfg, MppEncPrepCfg *prep_cfg);
|
||||
void h264e_vpu_set_format(H264eHwCfg *hw_cfg, MppEncPrepCfg *prep_cfg);
|
||||
void h264e_sei_pack2str(char *str, H264eHalContext *ctx);
|
||||
void h264e_sei_pack2str(char *str, H264eHalContext *ctx, RcSyntax *rc_syn);
|
||||
|
||||
#endif
|
||||
|
@@ -1644,14 +1644,13 @@ static MPP_RET h264e_rkv_sei_write(H264eRkvStream *s, RK_U8 *payload, RK_S32 pay
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
MPP_RET h264e_rkv_sei_encode(H264eHalContext *ctx)
|
||||
MPP_RET h264e_rkv_sei_encode(H264eHalContext *ctx, RcSyntax *rc_syn)
|
||||
{
|
||||
H264eRkvExtraInfo *info = (H264eRkvExtraInfo *)ctx->extra_info;
|
||||
char *str = (char *)info->sei_buf;
|
||||
RK_S32 str_len = 0;
|
||||
|
||||
h264e_sei_pack2str(str + H264E_UUID_LENGTH, ctx);
|
||||
|
||||
h264e_sei_pack2str(str + H264E_UUID_LENGTH, ctx, rc_syn);
|
||||
str_len = strlen(str) + 1;
|
||||
if (str_len > H264E_SEI_BUF_SIZE) {
|
||||
h264e_hal_err("SEI actual string length %d exceed malloced size %d", str_len, H264E_SEI_BUF_SIZE);
|
||||
@@ -1660,7 +1659,6 @@ MPP_RET h264e_rkv_sei_encode(H264eHalContext *ctx)
|
||||
h264e_rkv_sei_write(&info->stream, (RK_U8 *)str, str_len, H264E_SEI_USER_DATA_UNREGISTERED);
|
||||
}
|
||||
|
||||
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
@@ -1965,13 +1963,6 @@ static MPP_RET h264e_rkv_set_extra_info(H264eHalContext *ctx)
|
||||
h264e_rkv_pps_write(pps, sps, &info->stream);
|
||||
h264e_rkv_nal_end(info);
|
||||
|
||||
if (ctx->sei_mode == MPP_ENC_SEI_MODE_ONE_SEQ || ctx->sei_mode == MPP_ENC_SEI_MODE_ONE_FRAME) {
|
||||
info->sei_change_flg |= H264E_SEI_CHG_SPSPPS;
|
||||
h264e_rkv_nal_start(info, H264E_NAL_SEI, H264E_NAL_PRIORITY_DISPOSABLE);
|
||||
h264e_rkv_sei_encode(ctx);
|
||||
h264e_rkv_nal_end(info);
|
||||
}
|
||||
|
||||
h264e_rkv_encapsulate_nals(info);
|
||||
|
||||
h264e_hal_leave();
|
||||
@@ -2500,6 +2491,10 @@ static MPP_RET h264e_rkv_update_hw_cfg(H264eHalContext *ctx, HalEncTask *task, H
|
||||
hw_cfg->hor_stride = prep->hor_stride;
|
||||
hw_cfg->ver_stride = prep->ver_stride;
|
||||
|
||||
// for smaller resolution, SEI may have a bad influence on RC
|
||||
if (hw_cfg->width * hw_cfg->height < 640 * 480)
|
||||
ctx->sei_mode = MPP_ENC_SEI_MODE_DISABLE;
|
||||
|
||||
h264e_rkv_set_format(hw_cfg, prep);
|
||||
}
|
||||
|
||||
@@ -2538,8 +2533,6 @@ static MPP_RET h264e_rkv_update_hw_cfg(H264eHalContext *ctx, HalEncTask *task, H
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
prep->change = 0;
|
||||
}
|
||||
|
||||
if (codec->change) {
|
||||
@@ -2553,8 +2546,6 @@ static MPP_RET h264e_rkv_update_hw_cfg(H264eHalContext *ctx, HalEncTask *task, H
|
||||
hw_cfg->qp = codec->qp_init;
|
||||
|
||||
hw_cfg->qp_prev = hw_cfg->qp;
|
||||
|
||||
codec->change = 0;
|
||||
}
|
||||
|
||||
/* init qp calculate, if outside doesn't set init qp.
|
||||
@@ -2705,6 +2696,7 @@ MPP_RET hal_h264e_rkv_gen_regs(void *hal, HalTaskInfo *task)
|
||||
H264ePps *pps = &extra_info->pps;
|
||||
HalEncTask *enc_task = &task->enc;
|
||||
H264eHwCfg *hw_cfg = &ctx->hw_cfg;
|
||||
RcSyntax *rc_syn = (RcSyntax *)enc_task->syntax.data;
|
||||
|
||||
RK_S32 pic_width_align16 = 0;
|
||||
RK_S32 pic_height_align16 = 0;
|
||||
@@ -2731,12 +2723,13 @@ MPP_RET hal_h264e_rkv_gen_regs(void *hal, HalTaskInfo *task)
|
||||
|
||||
h264e_hal_dbg(H264E_DBG_SIMPLE, "frame %d | type %d | start gen regs", ctx->frame_cnt, syn->frame_type);
|
||||
|
||||
if (ctx->sei_mode == MPP_ENC_SEI_MODE_ONE_FRAME && extra_info->sei_change_flg) {
|
||||
if (ctx->sei_mode != MPP_ENC_SEI_MODE_DISABLE) {
|
||||
extra_info->nal_num = 0;
|
||||
h264e_rkv_stream_reset(&extra_info->stream);
|
||||
h264e_rkv_nal_start(extra_info, H264E_NAL_SEI, H264E_NAL_PRIORITY_DISPOSABLE);
|
||||
h264e_rkv_sei_encode(ctx);
|
||||
h264e_rkv_sei_encode(ctx, rc_syn);
|
||||
h264e_rkv_nal_end(extra_info);
|
||||
rc_syn->bit_target -= extra_info->nal[0].i_payload; // take off SEI size
|
||||
}
|
||||
|
||||
if (ctx->frame_cnt == 0) {
|
||||
@@ -2952,7 +2945,7 @@ MPP_RET hal_h264e_rkv_gen_regs(void *hal, HalTaskInfo *task)
|
||||
else if (pic_width_align16 <= 4096)
|
||||
regs->swreg45.cach_l2_tag = 0x3;
|
||||
|
||||
h264e_rkv_set_rc_regs(ctx, regs, syn, (RcSyntax *)enc_task->syntax.data);
|
||||
h264e_rkv_set_rc_regs(ctx, regs, syn, rc_syn);
|
||||
|
||||
regs->swreg56.rect_size = (sps->i_profile_idc == H264_PROFILE_BASELINE && sps->i_level_idc <= 30);
|
||||
regs->swreg56.inter_4x4 = 1;
|
||||
@@ -3127,10 +3120,12 @@ MPP_RET hal_h264e_rkv_start(void *hal, HalTaskInfo *task)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static MPP_RET h264e_rkv_set_feedback(h264e_feedback *fb, H264eRkvIoctlOutput *out)
|
||||
static MPP_RET h264e_rkv_set_feedback(H264eHalContext *ctx, H264eRkvIoctlOutput *out, HalEncTask *enc_task)
|
||||
{
|
||||
RK_U32 k = 0;
|
||||
H264eRkvIoctlOutputElem *elem = NULL;
|
||||
H264eRkvExtraInfo *extra_info = (H264eRkvExtraInfo *)ctx->extra_info;
|
||||
h264e_feedback *fb = &ctx->feedback;
|
||||
|
||||
h264e_hal_enter();
|
||||
for (k = 0; k < out->frame_num; k++) {
|
||||
@@ -3180,6 +3175,13 @@ static MPP_RET h264e_rkv_set_feedback(h264e_feedback *fb, H264eRkvIoctlOutput *o
|
||||
fb->hw_status = elem->hw_status;
|
||||
}
|
||||
|
||||
if (ctx->sei_mode != MPP_ENC_SEI_MODE_DISABLE) {
|
||||
H264eRkvNal *nal = &extra_info->nal[0];
|
||||
mpp_buffer_write(enc_task->output, fb->out_strm_size,
|
||||
nal->p_payload, nal->i_payload);
|
||||
fb->out_strm_size += nal->i_payload;
|
||||
}
|
||||
|
||||
h264e_hal_leave();
|
||||
|
||||
return MPP_OK;
|
||||
@@ -3249,8 +3251,10 @@ MPP_RET hal_h264e_rkv_wait(void *hal, HalTaskInfo *task)
|
||||
IOInterruptCB int_cb = ctx->int_cb;
|
||||
h264e_feedback *fb = &ctx->feedback;
|
||||
HalEncTask *enc_task = &task->enc;
|
||||
MppEncPrepCfg *prep = &ctx->cfg->prep;
|
||||
MppEncRcCfg *rcfg = &ctx->cfg->rc;
|
||||
MppEncCfgSet *cfg = ctx->cfg;
|
||||
MppEncPrepCfg *prep = &cfg->prep;
|
||||
MppEncRcCfg *rc = &cfg->rc;
|
||||
MppEncH264Cfg *codec = &cfg->codec.h264;
|
||||
H264eHwCfg *hw_cfg = &ctx->hw_cfg;
|
||||
RK_S32 num_mb = MPP_ALIGN(prep->width, 16) * MPP_ALIGN(prep->height, 16) / 16 / 16;
|
||||
/* for dumping ratecontrol message */
|
||||
@@ -3308,14 +3312,14 @@ MPP_RET hal_h264e_rkv_wait(void *hal, HalTaskInfo *task)
|
||||
(void)cmd;
|
||||
#endif
|
||||
|
||||
h264e_rkv_set_feedback(fb, reg_out);
|
||||
h264e_rkv_set_feedback(ctx, reg_out, enc_task);
|
||||
|
||||
/* we need re-encode */
|
||||
if (ctx->frame_cnt == 1) {
|
||||
h264e_rkv_resend(ctx, 0);
|
||||
|
||||
h264e_rkv_set_feedback(fb, reg_out);
|
||||
} else if ((RK_S32)ctx->frame_cnt < rcfg->fps_out_num / rcfg->fps_out_denorm &&
|
||||
h264e_rkv_set_feedback(ctx, reg_out, enc_task);
|
||||
} else if ((RK_S32)ctx->frame_cnt < rc->fps_out_num / rc->fps_out_denorm &&
|
||||
rc_syn->type == INTER_P_FRAME &&
|
||||
rc_syn->bit_target > fb->out_strm_size * 8 * 1.5) {
|
||||
/* re-encode frame if it meets all the conditions below:
|
||||
@@ -3332,7 +3336,7 @@ MPP_RET hal_h264e_rkv_wait(void *hal, HalTaskInfo *task)
|
||||
fb->qp_sum = new_qp * num_mb;
|
||||
|
||||
h264e_rkv_resend(ctx, 1);
|
||||
h264e_rkv_set_feedback(fb, reg_out);
|
||||
h264e_rkv_set_feedback(ctx, reg_out, enc_task);
|
||||
}
|
||||
|
||||
task->enc.length = fb->out_strm_size;
|
||||
@@ -3398,6 +3402,11 @@ MPP_RET hal_h264e_rkv_wait(void *hal, HalTaskInfo *task)
|
||||
h264e_rkv_dump_mpp_reg_out(ctx);
|
||||
h264e_rkv_dump_mpp_feedback(ctx);
|
||||
h264e_rkv_dump_mpp_strm_out(ctx, enc_task->output);
|
||||
|
||||
codec->change = 0;
|
||||
prep->change = 0;
|
||||
rc->change = 0;
|
||||
|
||||
h264e_hal_leave();
|
||||
|
||||
return MPP_OK;
|
||||
|
@@ -573,7 +573,7 @@ static MPP_RET h264e_vpu_sei_encode(H264eHalContext *ctx)
|
||||
char *str = (char *)info->sei_buf;
|
||||
RK_S32 str_len = 0;
|
||||
|
||||
h264e_sei_pack2str(str + H264E_UUID_LENGTH, ctx);
|
||||
h264e_sei_pack2str(str + H264E_UUID_LENGTH, ctx, NULL);
|
||||
|
||||
str_len = strlen(str) + 1;
|
||||
if (str_len > H264E_SEI_BUF_SIZE) {
|
||||
|
@@ -645,7 +645,7 @@ MPP_RET test_mpp_setup(MpiEncTestData *p)
|
||||
}
|
||||
|
||||
/* optional */
|
||||
p->sei_mode = MPP_ENC_SEI_MODE_ONE_SEQ;
|
||||
p->sei_mode = MPP_ENC_SEI_MODE_ONE_FRAME;
|
||||
ret = mpi->control(ctx, MPP_ENC_SET_SEI_CFG, &p->sei_mode);
|
||||
if (ret) {
|
||||
mpp_err("mpi control enc set sei cfg failed ret %d\n", ret);
|
||||
|
Reference in New Issue
Block a user