mirror of
https://github.com/nyanmisaka/mpp.git
synced 2025-10-18 15:10:39 +08:00
[avs2d]: Fix buffer leak issue
When decoding S picture, reference list with be force to set to only one left. Slot flag should be cleared for the already marked buffers at reference list. But decoded picture may not be correct if following AVS2 specification. So for S picture, keep those reference frames found by doi_of_ref and replace the content of the first reference frame with scene ref only. Change-Id: I9f84fdd55acfc9cf9d65deb065ccf97c36de1321 Signed-off-by: Johnson Ding <johnson.ding@rock-chips.com>
This commit is contained in:
@@ -323,9 +323,17 @@ static MPP_RET dpb_remove_frame(Avs2dCtx_t *p_dec, Avs2dFrame_t *p)
|
||||
MppFrame frame = p->frame;
|
||||
|
||||
avs2d_dbg_dpb("In.");
|
||||
|
||||
if (p->picture_type == GB_PICTURE || p->invisible) {
|
||||
MppBuffer buffer = NULL;
|
||||
mpp_buf_slot_get_prop(p_dec->frame_slots, p->slot_idx, SLOT_BUFFER, &buffer);
|
||||
mpp_buffer_put(buffer);
|
||||
}
|
||||
|
||||
mpp_buf_slot_clr_flag(p_dec->frame_slots, p->slot_idx, SLOT_CODEC_USE);
|
||||
avs2d_dbg_dpb("dpb remove frame slot_idx %d, doi %d poi %d, dpb used %d",
|
||||
p->slot_idx, p->doi, p->poi, mgr->used_size);
|
||||
|
||||
memset(p, 0, sizeof(Avs2dFrame_t));
|
||||
p->frame = frame;
|
||||
p->slot_idx = NO_VAL;
|
||||
@@ -467,7 +475,7 @@ static Avs2dFrame_t *dpb_alloc_frame(Avs2dCtx_t *p_dec, HalDecTask *task)
|
||||
frm->intra_frame_flag = (frm->scene_frame_flag || frm->picture_type == I_PICTURE);
|
||||
frm->refered_by_scene = frm->scene_frame_flag;
|
||||
frm->refered_by_others = (frm->picture_type != GB_PICTURE && mgr->cur_rps.refered_by_others);
|
||||
avs2d_dbg_dpb("frame picture type ref by others %d\n", frm->refered_by_others);
|
||||
avs2d_dbg_dpb("frame picture type %d, ref by others %d\n", frm->picture_type, frm->refered_by_others);
|
||||
if (vsh->chroma_format == CHROMA_420 && vsh->bit_depth == 8) {
|
||||
mpp_frame_set_fmt(mframe, MPP_FMT_YUV420SP);
|
||||
} else if (vsh->chroma_format == CHROMA_420 && vsh->bit_depth == 10) {
|
||||
@@ -677,10 +685,10 @@ static MPP_RET dpb_set_frame_refs(Avs2dCtx_t *p_dec, Avs2dFrameMgr_t *mgr, HalDe
|
||||
if (!mgr->scene_ref) {
|
||||
error_flag = 1;
|
||||
} else if (mgr->scene_ref != mgr->refs[0] || mgr->num_of_ref > 1) {
|
||||
AVS2D_DBG(AVS2D_DBG_ERROR, "Error reference frame(doi %lld ~ %lld) for S.\n",
|
||||
AVS2D_DBG(AVS2D_DBG_ERROR, "Error reference frame(doi %ld ~ %ld) for S.\n",
|
||||
mgr->scene_ref->doi, mgr->refs[0] ? mgr->refs[0]->doi : -1);
|
||||
mgr->num_of_ref = 1;
|
||||
replace_ref_flag = 1;
|
||||
p_dec->syntax.refp.scene_ref_replace_pos = 0;
|
||||
}
|
||||
} else if ((p_cur->picture_type == P_PICTURE || p_cur->picture_type == F_PICTURE) &&
|
||||
p_dec->ph.background_reference_flag) {
|
||||
@@ -689,6 +697,7 @@ static MPP_RET dpb_set_frame_refs(Avs2dCtx_t *p_dec, Avs2dFrameMgr_t *mgr, HalDe
|
||||
error_flag = 1;
|
||||
} else {
|
||||
replace_ref_flag = 1;
|
||||
p_dec->syntax.refp.scene_ref_replace_pos = mgr->num_of_ref - 1;
|
||||
}
|
||||
} else if (p_cur->picture_type == B_PICTURE &&
|
||||
(mgr->num_of_ref != 2 || (mgr->refs[0] && mgr->refs[0]->poi <= p_cur->poi) ||
|
||||
@@ -724,10 +733,8 @@ MPP_RET avs2d_dpb_insert(Avs2dCtx_t *p_dec, HalDecTask *task)
|
||||
|
||||
AVS2D_PARSE_TRACE("In.");
|
||||
|
||||
if (p_dec->ph.picture_type != GB_PICTURE) {
|
||||
//!< output frame from dpb
|
||||
dpb_scan_output_frame(p_dec);
|
||||
}
|
||||
//!< output frame from dpb
|
||||
dpb_scan_output_frame(p_dec);
|
||||
|
||||
compute_frame_order_index(p_dec);
|
||||
|
||||
|
@@ -591,6 +591,7 @@ static MPP_RET parse_picture_header_intra(Avs2dCtx_t *p_dec)
|
||||
BitReadCtx_t *bitctx = &p_dec->bitctx;
|
||||
Avs2dSeqHeader_t *vsh = &p_dec->vsh;
|
||||
Avs2dPicHeader_t *ph = &p_dec->ph;
|
||||
RK_U32 last_pic_out_delay = ph->picture_output_delay;
|
||||
|
||||
AVS2D_PARSE_TRACE("In.");
|
||||
memset(ph, 0, sizeof(Avs2dPicHeader_t));
|
||||
@@ -627,7 +628,7 @@ static MPP_RET parse_picture_header_intra(Avs2dCtx_t *p_dec)
|
||||
AVS2D_PARSE_TRACE("temporal_id %d\n", ph->temporal_id);
|
||||
}
|
||||
|
||||
if (vsh->low_delay == 0 && (!ph->background_picture_flag || ph->background_picture_output_flag)) {
|
||||
if (vsh->low_delay == 0 && !(ph->background_picture_flag && !ph->background_picture_output_flag)) {
|
||||
READ_UE(bitctx, &ph->picture_output_delay);
|
||||
AVS2D_PARSE_TRACE("picture_output_delay %d\n", ph->picture_output_delay);
|
||||
if (ph->picture_output_delay >= 64) {
|
||||
@@ -636,7 +637,7 @@ static MPP_RET parse_picture_header_intra(Avs2dCtx_t *p_dec)
|
||||
goto __FAILED;
|
||||
}
|
||||
} else {
|
||||
ph->picture_output_delay = 0;
|
||||
ph->picture_output_delay = last_pic_out_delay;
|
||||
}
|
||||
|
||||
READ_ONEBIT(bitctx, &predict);
|
||||
@@ -737,6 +738,7 @@ static MPP_RET parse_picture_header_inter(Avs2dCtx_t *p_dec)
|
||||
|
||||
if (vsh->low_delay == 0) {
|
||||
READ_UE(bitctx, &ph->picture_output_delay);
|
||||
AVS2D_PARSE_TRACE("picture_output_delay %d\n", ph->picture_output_delay);
|
||||
if (ph->picture_output_delay >= 64) {
|
||||
ret = MPP_NOK;
|
||||
mpp_err_f("invalid picture output delay(%d) intra.\n", ph->picture_output_delay);
|
||||
|
@@ -57,6 +57,7 @@ typedef struct _DXVA_RefParams_AVS2 {
|
||||
RK_S32 ref_poc_list[32];
|
||||
RK_S32 scene_ref_slot_idx;
|
||||
RK_S32 scene_ref_enable;
|
||||
RK_S32 scene_ref_replace_pos;
|
||||
} RefParams_Avs2d, *LP_RefParams_Avs2d;
|
||||
|
||||
typedef struct _DXVA_AlfParams_AVS2 {
|
||||
|
@@ -427,14 +427,15 @@ static MPP_RET fill_registers(Avs2dHalCtx_t *p_hal, Vdpu34xAvs2dRegSet *p_regs,
|
||||
if (p_hal->syntax.refp.scene_ref_enable && p_hal->syntax.refp.scene_ref_slot_idx >= 0) {
|
||||
MppFrame scene_ref = NULL;
|
||||
RK_S32 slot_idx = p_hal->syntax.refp.scene_ref_slot_idx;
|
||||
RK_S32 replace_idx = p_hal->syntax.refp.scene_ref_replace_pos;
|
||||
|
||||
mpp_buf_slot_get_prop(p_hal->frame_slots, slot_idx, SLOT_FRAME_PTR, &scene_ref);
|
||||
|
||||
if (scene_ref) {
|
||||
p_regs->avs2d_addr.ref_base[refp->ref_pic_num - 1] = get_frame_fd(p_hal, slot_idx);
|
||||
p_regs->avs2d_addr.ref_base[replace_idx] = get_frame_fd(p_hal, slot_idx);
|
||||
mv_buf = hal_bufs_get_buf(p_hal->cmv_bufs, slot_idx);
|
||||
p_regs->avs2d_addr.colmv_base[refp->ref_pic_num - 1] = mpp_buffer_get_fd(mv_buf->buf[0]);
|
||||
p_regs->avs2d_param.reg67_098_ref_poc[refp->ref_pic_num - 1] = mpp_frame_get_poc(scene_ref);
|
||||
p_regs->avs2d_addr.colmv_base[replace_idx] = mpp_buffer_get_fd(mv_buf->buf[0]);
|
||||
p_regs->avs2d_param.reg67_098_ref_poc[replace_idx] = mpp_frame_get_poc(scene_ref);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -429,15 +429,16 @@ static MPP_RET fill_registers(Avs2dHalCtx_t *p_hal, Vdpu382Avs2dRegSet *p_regs,
|
||||
|
||||
if (p_hal->syntax.refp.scene_ref_enable && p_hal->syntax.refp.scene_ref_slot_idx >= 0) {
|
||||
MppFrame scene_ref = NULL;
|
||||
RK_S32 replace_idx = p_hal->syntax.refp.scene_ref_replace_pos;
|
||||
RK_S32 slot_idx = p_hal->syntax.refp.scene_ref_slot_idx;
|
||||
|
||||
mpp_buf_slot_get_prop(p_hal->frame_slots, slot_idx, SLOT_FRAME_PTR, &scene_ref);
|
||||
|
||||
if (scene_ref) {
|
||||
p_regs->avs2d_addr.ref_base[refp->ref_pic_num - 1] = get_frame_fd(p_hal, slot_idx);
|
||||
p_regs->avs2d_addr.ref_base[replace_idx] = get_frame_fd(p_hal, slot_idx);
|
||||
mv_buf = hal_bufs_get_buf(p_hal->cmv_bufs, slot_idx);
|
||||
p_regs->avs2d_addr.colmv_base[refp->ref_pic_num - 1] = mpp_buffer_get_fd(mv_buf->buf[0]);
|
||||
p_regs->avs2d_param.reg67_098_ref_poc[refp->ref_pic_num - 1] = mpp_frame_get_poc(scene_ref);
|
||||
p_regs->avs2d_addr.colmv_base[replace_idx] = mpp_buffer_get_fd(mv_buf->buf[0]);
|
||||
p_regs->avs2d_param.reg67_098_ref_poc[replace_idx] = mpp_frame_get_poc(scene_ref);
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user