[h265d]: Fix error on multi-frame packet decoding

When need_split flag is disabled decoder can only receive input packet
as one frame. But if user send two frames in one packet decoder will
loss a valid frame and finally lead to memory leak.

This patch treat this case as an error and bypass later hardware
proccsing. Althrough this process will lead to frame skip it still
brings in more stability.

Change-Id: Ibe566c847e0c7e259d14913ac210171edcfc903b
Signed-off-by: Herman Chen <herman.chen@rock-chips.com>
This commit is contained in:
Herman Chen
2018-11-26 21:07:05 +08:00
parent 1babbc9cc2
commit 4a6fd29168
3 changed files with 33 additions and 7 deletions

View File

@@ -1179,9 +1179,13 @@ static RK_S32 mpp_hevc_output_frame(void *ctx, int flush)
static RK_S32 hevc_frame_start(HEVCContext *s)
{
int ret;
if (s->ref) {
mpp_log_f("found two frame in one packet do nothing!\n");
return 0;
}
s->is_decoded = 0;
s->first_nal_type = s->nal_unit_type;
s->miss_ref_flag = 0;
@@ -1773,10 +1777,11 @@ MPP_RET h265d_parse(void *ctx, HalDecTask *task)
ret = parser_nal_units(s);
if (ret < 0) {
if (ret == MPP_ERR_STREAM) {
mpp_log("current stream is no right skip it");
mpp_log("current stream is no right skip it %p\n", s->ref);
ret = 0;
}
return ret;
// return ret;
task->flags.parse_err = 1;
}
h265d_dbg(H265D_DBG_GLOBAL, "decode poc = %d", s->poc);
if (s->ref) {
@@ -1784,7 +1789,6 @@ MPP_RET h265d_parse(void *ctx, HalDecTask *task)
s->task->syntax.data = s->hal_pic_private;
s->task->syntax.number = 1;
s->task->valid = 1;
}
if (s->eos) {
h265d_flush(ctx);

View File

@@ -1331,6 +1331,12 @@ MPP_RET hal_h265d_gen_regs(void *hal, HalTaskInfo *syn)
RK_S32 valid_ref = -1;
MppBuffer framebuf = NULL;
if (syn->dec.flags.parse_err ||
syn->dec.flags.ref_err) {
h265h_dbg(H265H_DBG_TASK_ERR, "%s found task error\n", __FUNCTION__);
return MPP_OK;
}
h265d_dxva2_picture_context_t *dxva_cxt =
(h265d_dxva2_picture_context_t *)syn->dec.syntax.data;
h265d_reg_context_t *reg_cxt = ( h265d_reg_context_t *)hal;
@@ -1493,6 +1499,13 @@ MPP_RET hal_h265d_start(void *hal, HalTaskInfo *task)
RK_S32 index = task->dec.reg_index;
RK_S32 i;
if (task->dec.flags.parse_err ||
task->dec.flags.ref_err) {
h265h_dbg(H265H_DBG_TASK_ERR, "%s found task error\n", __FUNCTION__);
return MPP_OK;
}
if (reg_cxt->fast_mode) {
p = (RK_U8*)reg_cxt->g_buf[index].hw_regs;
hw_regs = ( H265d_REGS_t *)reg_cxt->g_buf[index].hw_regs;
@@ -1532,6 +1545,12 @@ MPP_RET hal_h265d_wait(void *hal, HalTaskInfo *task)
H265d_REGS_t *hw_regs = NULL;
RK_S32 i;
if (task->dec.flags.parse_err ||
task->dec.flags.ref_err) {
h265h_dbg(H265H_DBG_TASK_ERR, "%s found task error\n", __FUNCTION__);
goto ERR_PROC;
}
if (reg_cxt->fast_mode) {
hw_regs = ( H265d_REGS_t *)reg_cxt->g_buf[index].hw_regs;
} else {
@@ -1541,8 +1560,11 @@ MPP_RET hal_h265d_wait(void *hal, HalTaskInfo *task)
p = (RK_U8*)hw_regs;
ret = mpp_device_wait_reg(reg_cxt->dev_ctx, (RK_U32*)hw_regs, RKVDEC_HEVC_REGISTERS);
if (hw_regs->sw_interrupt.sw_dec_error_sta
|| hw_regs->sw_interrupt.sw_dec_empty_sta) {
ERR_PROC:
if (task->dec.flags.parse_err ||
task->dec.flags.ref_err ||
hw_regs->sw_interrupt.sw_dec_error_sta ||
hw_regs->sw_interrupt.sw_dec_empty_sta) {
if (!reg_cxt->fast_mode) {
if (reg_cxt->int_cb.callBack)
reg_cxt->int_cb.callBack(reg_cxt->int_cb.opaque, &task->dec);
@@ -1554,7 +1576,6 @@ MPP_RET hal_h265d_wait(void *hal, HalTaskInfo *task)
reg_cxt->fast_mode_err_found = 1;
mpp_frame_set_errinfo(mframe, 1);
}
}
} else {
if (reg_cxt->fast_mode && reg_cxt->fast_mode_err_found) {

View File

@@ -35,6 +35,7 @@
#define H265H_DBG_PPS (0x00000004)
#define H265H_DBG_REG (0x00000008)
#define H265H_DBG_FAST_ERR (0x00000010)
#define H265H_DBG_TASK_ERR (0x00000020)
#define HEVC_DECODER_REG_NUM (48)
#define RKVDEC_REG_PERF_CYCLE_INDEX (64)