diff --git a/inc/rk_mpi_cmd.h b/inc/rk_mpi_cmd.h index 42741903..195595d3 100644 --- a/inc/rk_mpi_cmd.h +++ b/inc/rk_mpi_cmd.h @@ -100,6 +100,7 @@ typedef enum { MPP_DEC_SET_DISABLE_ERROR, /* When set it will disable sw/hw error (H.264 / H.265) */ MPP_DEC_SET_IMMEDIATE_OUT, MPP_DEC_SET_ENABLE_DEINTERLACE, /* MPP enable deinterlace by default. Vpuapi can disable it */ + MPP_DEC_SET_DISABLE_FAST_PLAY, /* disable idr output immediately */ MPP_DEC_CMD_QUERY = CMD_MODULE_CODEC | CMD_CTX_ID_DEC | CMD_DEC_QUERY, /* query decoder runtime information for decode stage */ diff --git a/mpp/base/mpp_dec_cfg.cpp b/mpp/base/mpp_dec_cfg.cpp index f76bdfcf..8e0466cd 100644 --- a/mpp/base/mpp_dec_cfg.cpp +++ b/mpp/base/mpp_dec_cfg.cpp @@ -162,6 +162,7 @@ static const char *dec_cfg_func_names[] = { ENTRY(base, sort_pts, U32, RK_U32, MPP_DEC_CFG_CHANGE_SORT_PTS, base, sort_pts) \ ENTRY(base, disable_error, U32, RK_U32, MPP_DEC_CFG_CHANGE_DISABLE_ERROR, base, disable_error) \ ENTRY(base, enable_vproc, U32, RK_U32, MPP_DEC_CFG_CHANGE_ENABLE_VPROC, base, enable_vproc) \ + ENTRY(base, disable_fast_play, U32, RK_U32, MPP_DEC_CFG_CHANGE_DISABLE_FAST_PLAY, base, disable_fast_play) \ ENTRY(cb, pkt_rdy_cb, PTR, MppExtCbFunc, MPP_DEC_CB_CFG_CHANGE_PKT_RDY, cb, pkt_rdy_cb) \ ENTRY(cb, pkt_rdy_ctx, PTR, MppExtCbCtx, MPP_DEC_CB_CFG_CHANGE_PKT_RDY, cb, pkt_rdy_ctx) \ ENTRY(cb, pkt_rdy_cmd, S32, RK_S32, MPP_DEC_CB_CFG_CHANGE_PKT_RDY, cb, pkt_rdy_cmd) \ diff --git a/mpp/codec/dec/h264/h264d_dpb.c b/mpp/codec/dec/h264/h264d_dpb.c index 2e40aa47..c44ed2b6 100644 --- a/mpp/codec/dec/h264/h264d_dpb.c +++ b/mpp/codec/dec/h264/h264d_dpb.c @@ -873,7 +873,8 @@ static void write_picture(H264_StorePic_t *p, H264dVideoCtx_t *p_Vid) } } //!< discard less than first i frame poc - if ((p_err->i_slice_no < 2) && (p->poc < p_err->first_iframe_poc)) { + if ((p_err->i_slice_no < 2) && (p->poc < p_err->first_iframe_poc) && + (!p_Vid->p_Dec->cfg->base.disable_fast_play)) { if (p_err->used_ref_flag) { mpp_frame_set_errinfo(mframe, MPP_FRAME_ERR_UNKNOW); } else { @@ -1254,20 +1255,22 @@ static MPP_RET scan_dpb_output(H264_DpbBuf_t *p_Dpb, H264_StorePic_t *p) H264_FrameStore_t *fs = p_Dpb->fs[p_Dpb->used_size - 1]; if (fs->is_used == 3) { - RK_S32 min_poc = 0, min_pos = 0; - RK_S32 poc_inc = fs->poc - p_Dpb->last_output_poc; H264dErrCtx_t *p_err = &p_Dpb->p_Vid->p_Dec->errctx; - - if ((p_Dpb->last_output_poc > INT_MIN) && abs(poc_inc) & 0x1) { - p_Dpb->poc_interval = 1; - } + RK_S32 min_poc = 0; + RK_S32 min_pos = 0; + RK_S32 poc_inc = 0; if (p_Dpb->p_Vid->p_Dec->cfg->base.fast_out || - (p_err->i_slice_no < 2 && p_Dpb->last_output_poc == INT_MIN)) { + (!p_Dpb->p_Vid->p_Dec->cfg->base.disable_fast_play && + p_err->i_slice_no < 2 && p_Dpb->last_output_poc == INT_MIN)) { FUN_CHECK(ret = write_stored_frame(p_Dpb->p_Vid, p_Dpb, fs)); } else { while ((p_Dpb->last_output_poc > INT_MIN) && (get_smallest_poc(p_Dpb, &min_poc, &min_pos))) { + poc_inc = min_poc - p_Dpb->last_output_poc; + if ((p_Dpb->last_output_poc > INT_MIN) && abs(poc_inc) & 0x1) { + p_Dpb->poc_interval = 1; + } if ((min_poc - p_Dpb->last_output_poc) <= p_Dpb->poc_interval) { FUN_CHECK(ret = write_stored_frame(p_Dpb->p_Vid, p_Dpb, p_Dpb->fs[min_pos])); } else { diff --git a/mpp/codec/mpp_dec.cpp b/mpp/codec/mpp_dec.cpp index 104d577e..2d02dc30 100644 --- a/mpp/codec/mpp_dec.cpp +++ b/mpp/codec/mpp_dec.cpp @@ -438,7 +438,8 @@ MPP_RET mpp_dec_proc_cfg(MppDecImpl *dec, MpiCmd cmd, void *param) case MPP_DEC_SET_IMMEDIATE_OUT : case MPP_DEC_SET_OUTPUT_FORMAT : case MPP_DEC_SET_DISABLE_ERROR : - case MPP_DEC_SET_ENABLE_DEINTERLACE : { + case MPP_DEC_SET_ENABLE_DEINTERLACE : + case MPP_DEC_SET_DISABLE_FAST_PLAY : { ret = mpp_dec_set_cfg_by_cmd(&dec->cfg, cmd, param); dec->cfg.base.change = 0; } break; @@ -1614,6 +1615,9 @@ MPP_RET mpp_dec_set_cfg(MppDecCfgSet *dst, MppDecCfgSet *src) if (change & MPP_DEC_CFG_CHANGE_ENABLE_VPROC) dst_base->enable_vproc = src_base->enable_vproc; + if (change & MPP_DEC_CFG_CHANGE_DISABLE_FAST_PLAY) + dst_base->disable_fast_play = src_base->disable_fast_play; + dst_base->change = change; src_base->change = 0; } @@ -2098,6 +2102,11 @@ MPP_RET mpp_dec_set_cfg_by_cmd(MppDecCfgSet *set, MpiCmd cmd, void *param) cfg->change |= MPP_DEC_CFG_CHANGE_ENABLE_VPROC; dec_dbg_func("enable dec_vproc %d\n", cfg->enable_vproc); } break; + case MPP_DEC_SET_DISABLE_FAST_PLAY : { + cfg->disable_fast_play = (param) ? (*((RK_U32 *)param)) : (0); + cfg->change |= MPP_DEC_CFG_CHANGE_DISABLE_FAST_PLAY; + dec_dbg_func("disable idr immediately output %d\n", cfg->disable_fast_play); + } break; default : { mpp_err_f("unsupported cfg update cmd %x\n", cmd); ret = MPP_NOK; diff --git a/mpp/inc/mpp_dec_cfg.h b/mpp/inc/mpp_dec_cfg.h index 26750705..e2ae26d0 100644 --- a/mpp/inc/mpp_dec_cfg.h +++ b/mpp/inc/mpp_dec_cfg.h @@ -34,6 +34,7 @@ typedef enum MppDecCfgChange_e { MPP_DEC_CFG_CHANGE_SORT_PTS = (1 << 13), MPP_DEC_CFG_CHANGE_DISABLE_ERROR = (1 << 14), MPP_DEC_CFG_CHANGE_ENABLE_VPROC = (1 << 15), + MPP_DEC_CFG_CHANGE_DISABLE_FAST_PLAY = (1 << 16), MPP_DEC_CFG_CHANGE_ALL = (0xFFFFFFFF), } MppDecCfgChange; @@ -54,6 +55,7 @@ typedef struct MppDecBaseCfg_t { RK_U32 sort_pts; RK_U32 disable_error; RK_U32 enable_vproc; + RK_U32 disable_fast_play; } MppDecBaseCfg; typedef enum MppDecCbCfgChange_e { diff --git a/mpp/mpp.cpp b/mpp/mpp.cpp index b30b53d9..d38378f8 100644 --- a/mpp/mpp.cpp +++ b/mpp/mpp.cpp @@ -1066,7 +1066,8 @@ MPP_RET Mpp::control_dec(MpiCmd cmd, MppParam param) case MPP_DEC_SET_PARSER_FAST_MODE : case MPP_DEC_SET_IMMEDIATE_OUT : case MPP_DEC_SET_DISABLE_ERROR : - case MPP_DEC_SET_ENABLE_DEINTERLACE : { + case MPP_DEC_SET_ENABLE_DEINTERLACE : + case MPP_DEC_SET_DISABLE_FAST_PLAY : { /* * These control may be set before mpp_init * When this case happen record the config and wait for decoder init