mirror of
https://github.com/nyanmisaka/mpp.git
synced 2025-10-14 21:25:42 +08:00
[h264_dpb]: add fast play once
fast once can be controlled by cmake cmd: -DENABLE_FASTPLAY_ONCE=ON Change-Id: Id0073ef8356acec700030b98b417d4f6999bf894 Signed-off-by: Hongjin Li <vic.hong@rock-chips.com>
This commit is contained in:
@@ -265,7 +265,11 @@ void mpp_dec_cfg_set_default(MppDecCfgSet *cfg)
|
||||
cfg->base.coding = MPP_VIDEO_CodingUnused;
|
||||
cfg->base.hw_type = -1;
|
||||
cfg->base.fast_parse = 1;
|
||||
cfg->base.enable_fast_play = 1;
|
||||
#ifdef ENABLE_FASTPLAY_ONCE
|
||||
cfg->base.enable_fast_play = MPP_ENABLE_FAST_PLAY_ONCE;
|
||||
#else
|
||||
cfg->base.enable_fast_play = MPP_ENABLE_FAST_PLAY;
|
||||
#endif
|
||||
}
|
||||
|
||||
MPP_RET mpp_dec_cfg_init(MppDecCfg *cfg)
|
||||
|
@@ -344,6 +344,8 @@ MPP_RET h264d_init(void *decoder, ParserCfg *init)
|
||||
FUN_CHECK(ret = init_vid_ctx(p_Dec->p_Vid));
|
||||
FUN_CHECK(ret = init_dec_ctx(p_Dec));
|
||||
p_Dec->immediate_out = p_Dec->cfg->base.fast_out;
|
||||
p_Dec->p_Vid->dpb_fast_out = p_Dec->cfg->base.enable_fast_play;
|
||||
p_Dec->p_Vid->dpb_first_fast_played = 0;
|
||||
__RETURN:
|
||||
return ret = MPP_OK;
|
||||
__FAILED:
|
||||
@@ -439,6 +441,8 @@ MPP_RET h264d_reset(void *decoder)
|
||||
p_Dec->dxva_ctx->strm_offset = 0;
|
||||
p_Dec->dxva_ctx->slice_count = 0;
|
||||
p_Dec->last_frame_slot_idx = -1;
|
||||
p_Dec->p_Vid->dpb_fast_out = p_Dec->cfg->base.enable_fast_play;
|
||||
p_Dec->p_Vid->dpb_first_fast_played = 0;
|
||||
|
||||
__RETURN:
|
||||
return ret = MPP_OK;
|
||||
@@ -480,9 +484,16 @@ __FAILED:
|
||||
*/
|
||||
MPP_RET h264d_control(void *decoder, MpiCmd cmd_type, void *param)
|
||||
{
|
||||
(void) decoder;
|
||||
(void) cmd_type;
|
||||
(void) param;
|
||||
H264_DecCtx_t *p_Dec = (H264_DecCtx_t *)decoder;
|
||||
|
||||
switch (cmd_type) {
|
||||
case MPP_DEC_SET_ENABLE_FAST_PLAY:
|
||||
p_Dec->p_Vid->dpb_fast_out = (param) ? (*((RK_U32 *)param)) : (1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
|
@@ -867,7 +867,7 @@ static void write_picture(H264_StorePic_t *p, H264dVideoCtx_t *p_Vid)
|
||||
if (p_err->used_ref_flag && p_err->first_iframe_is_output) {
|
||||
mpp_frame_set_errinfo(mframe, MPP_FRAME_ERR_UNKNOW);
|
||||
} else {
|
||||
if (p_Vid->p_Dec->cfg->base.enable_fast_play)
|
||||
if (p_Vid->dpb_fast_out)
|
||||
mpp_frame_set_discard(mframe, MPP_FRAME_ERR_UNKNOW);
|
||||
}
|
||||
}
|
||||
@@ -1302,6 +1302,63 @@ __FAILED:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static MPP_RET output_dpb_normal(H264_DpbBuf_t *p_Dpb)
|
||||
{
|
||||
MPP_RET ret = MPP_NOK;
|
||||
RK_S32 min_poc = 0;
|
||||
RK_S32 min_pos = 0;
|
||||
RK_S32 poc_inc = 0;
|
||||
|
||||
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 {
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (!remove_unused_frame_from_dpb(p_Dpb));
|
||||
|
||||
return MPP_OK;
|
||||
__FAILED:
|
||||
return ret;
|
||||
}
|
||||
static MPP_RET output_dpb_fastplay(H264_DpbBuf_t *p_Dpb, H264_FrameStore_t *fs, RK_U32 is_i_frm)
|
||||
{
|
||||
MPP_RET ret = MPP_NOK;
|
||||
|
||||
if ((p_Dpb->p_Vid->dpb_fast_out && is_i_frm)) {
|
||||
FUN_CHECK(ret = write_stored_frame(p_Dpb->p_Vid, p_Dpb, fs));
|
||||
} else
|
||||
output_dpb_normal(p_Dpb);
|
||||
|
||||
return MPP_OK;
|
||||
__FAILED:
|
||||
return ret;
|
||||
}
|
||||
static MPP_RET output_dpb_fastplay_once(H264_DpbBuf_t *p_Dpb, H264_FrameStore_t *fs, RK_U32 is_i_frm)
|
||||
{
|
||||
MPP_RET ret = MPP_NOK;
|
||||
|
||||
if (p_Dpb->p_Vid->dpb_fast_out && is_i_frm && !p_Dpb->p_Vid->dpb_first_fast_played) {
|
||||
FUN_CHECK(ret = write_stored_frame(p_Dpb->p_Vid, p_Dpb, fs));
|
||||
p_Dpb->p_Vid->dpb_first_fast_played = 1;
|
||||
} else {
|
||||
// disable fast play once in the second gop
|
||||
if (p_Dpb->p_Vid->dpb_fast_out && is_i_frm && p_Dpb->p_Vid->dpb_first_fast_played) {
|
||||
p_Dpb->p_Vid->dpb_fast_out = MPP_DISABLE_FAST_PLAY;
|
||||
}
|
||||
output_dpb_normal(p_Dpb);
|
||||
}
|
||||
|
||||
return MPP_OK;
|
||||
__FAILED:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static MPP_RET scan_dpb_output(H264_DpbBuf_t *p_Dpb, H264_StorePic_t *p)
|
||||
{
|
||||
MPP_RET ret = MPP_NOK;
|
||||
@@ -1309,28 +1366,24 @@ static MPP_RET scan_dpb_output(H264_DpbBuf_t *p_Dpb, H264_StorePic_t *p)
|
||||
|
||||
if (fs->is_used == 3) {
|
||||
H264dErrCtx_t *p_err = &p_Dpb->p_Vid->p_Dec->errctx;
|
||||
RK_S32 min_poc = 0;
|
||||
RK_S32 min_pos = 0;
|
||||
RK_S32 poc_inc = 0;
|
||||
RK_U32 is_i_frm = p_err->i_slice_no < 2 && p_Dpb->last_output_poc == INT_MIN;
|
||||
|
||||
if (p_Dpb->p_Vid->p_Dec->cfg->base.fast_out ||
|
||||
(p_Dpb->p_Vid->p_Dec->cfg->base.enable_fast_play &&
|
||||
p_err->i_slice_no < 2 && p_Dpb->last_output_poc == INT_MIN)) {
|
||||
if (p_Dpb->p_Vid->p_Dec->cfg->base.fast_out)
|
||||
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) {
|
||||
H264D_WARNNING("write_stored_frame, line %d", __LINE__);
|
||||
FUN_CHECK(ret = write_stored_frame(p_Dpb->p_Vid, p_Dpb, p_Dpb->fs[min_pos]));
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
else {
|
||||
switch (p_Dpb->p_Vid->p_Dec->cfg->base.enable_fast_play) {
|
||||
case MPP_DISABLE_FAST_PLAY:
|
||||
FUN_CHECK(ret = output_dpb_normal(p_Dpb));
|
||||
break;
|
||||
case MPP_ENABLE_FAST_PLAY:
|
||||
FUN_CHECK(ret = output_dpb_fastplay(p_Dpb, fs, is_i_frm));
|
||||
break;
|
||||
case MPP_ENABLE_FAST_PLAY_ONCE:
|
||||
FUN_CHECK(ret = output_dpb_fastplay_once(p_Dpb, fs, is_i_frm));
|
||||
break;
|
||||
default:
|
||||
H264D_ERR("unsupport output mode");
|
||||
}
|
||||
while (!remove_unused_frame_from_dpb(p_Dpb));
|
||||
}
|
||||
|
||||
if (is_i_frm)
|
||||
|
@@ -1045,6 +1045,9 @@ typedef struct h264d_video_ctx_t {
|
||||
MppMemPool pic_st;
|
||||
//!< spspps data update
|
||||
RK_U32 spspps_update;
|
||||
|
||||
RK_U32 dpb_fast_out;
|
||||
RK_U32 dpb_first_fast_played;
|
||||
} H264dVideoCtx_t;
|
||||
|
||||
typedef struct h264d_mem_t {
|
||||
|
@@ -37,6 +37,10 @@ if( ENABLE_H264D )
|
||||
set(HAL_H264D hal_h264d)
|
||||
add_definitions(-DHAVE_H264D)
|
||||
endif()
|
||||
option(ENABLE_FASTPLAY_ONCE "Enable h.264 decoder fast play once" OFF)
|
||||
if( ENABLE_FASTPLAY_ONCE )
|
||||
add_definitions(-DENABLE_FASTPLAY_ONCE)
|
||||
endif()
|
||||
|
||||
# H.265 decoder
|
||||
option(ENABLE_H265D "Enable h.265 decoder" ON)
|
||||
|
@@ -50,6 +50,13 @@ typedef enum MppVprocMode_e {
|
||||
MPP_VPROC_MODE_ALL = (0xFFFFFFFF),
|
||||
} MppVprocMode;
|
||||
|
||||
typedef enum FastPlayMode_e {
|
||||
MPP_DISABLE_FAST_PLAY,
|
||||
MPP_ENABLE_FAST_PLAY,
|
||||
// first gop fast play when poc include negative value, otherwise enable fast play all time
|
||||
MPP_ENABLE_FAST_PLAY_ONCE,
|
||||
} FastPlayMode;
|
||||
|
||||
typedef struct MppDecBaseCfg_t {
|
||||
RK_U64 change;
|
||||
|
||||
|
Reference in New Issue
Block a user