From 38d51610f1572aa7e31fab6fe140d176f235a039 Mon Sep 17 00:00:00 2001 From: Ding Wei Date: Tue, 3 Apr 2018 19:12:15 +0800 Subject: [PATCH] [vp9d]: add errorinfo marking 1. dicard stream when has not got keyframe. 2. when frame is not intra, check the errinfo flag for refs. 3. when hard return is not ready, mark errinfo. 4. when reset setting, discard the frame remainng. Change-Id: Idd03a8476e76875176475167ca5890e247f75ee3 Signed-off-by: Ding Wei --- mpp/codec/dec/vp9/vp9d_api.c | 2 +- mpp/codec/dec/vp9/vp9d_parser.c | 20 ++++++++++++++++++-- mpp/codec/dec/vp9/vp9d_parser.h | 3 ++- mpp/hal/rkdec/vp9d/hal_vp9d_api.c | 9 ++++++--- 4 files changed, 27 insertions(+), 7 deletions(-) diff --git a/mpp/codec/dec/vp9/vp9d_api.c b/mpp/codec/dec/vp9/vp9d_api.c index e549e34c..68cadaee 100644 --- a/mpp/codec/dec/vp9/vp9d_api.c +++ b/mpp/codec/dec/vp9/vp9d_api.c @@ -174,7 +174,7 @@ MPP_RET vp9d_prepare(void *ctx, MppPacket pkt, HalDecTask *task) consumed = vp9d_split_frame(ps, &out_data, &out_size, buf, length); pos += consumed; mpp_packet_set_pos(pkt, pos); - + vp9d_dbg(VP9D_DBG_STRMIN, "pkt_len=%d, pts=%lld\n", length, pts); vp9d_get_frame_stream(vp9_ctx, out_data, out_size); if (out_size > 0) { task->input_packet = vp9_ctx->pkt; diff --git a/mpp/codec/dec/vp9/vp9d_parser.c b/mpp/codec/dec/vp9/vp9d_parser.c index 1dbfb9de..11dbe2b6 100644 --- a/mpp/codec/dec/vp9/vp9d_parser.c +++ b/mpp/codec/dec/vp9/vp9d_parser.c @@ -395,6 +395,7 @@ static RK_S32 vp9_alloc_frame(Vp9CodecContext *ctx, VP9Frame *frame) mpp_frame_set_hor_stride(frame->f, ctx->width); mpp_frame_set_ver_stride(frame->f, ctx->height); mpp_frame_set_errinfo(frame->f, 0); + mpp_frame_set_discard(frame->f, 0); mpp_frame_set_pts(frame->f, s->pts); #if 0 mpp_frame_set_fmt(frame->frame, s->h265dctx->pix_fmt); @@ -684,6 +685,13 @@ static RK_S32 decode_parser_header(Vp9CodecContext *ctx, s->errorres = mpp_get_bit1(&s->gb); vp9d_dbg(VP9D_DBG_HEADER, "error_resilient_mode %d", s->errorres); s->use_last_frame_mvs = !s->errorres && !last_invisible; + s->got_keyframes += s->keyframe ? 1 : 0; + vp9d_dbg(VP9D_DBG_HEADER, "keyframe=%d, intraonly=%d, got_keyframes=%d\n", + s->keyframe, s->intraonly, s->got_keyframes); + if (!s->got_keyframes) { + mpp_err_f("have not got keyframe.\n"); + return MPP_ERR_STREAM; + } if (s->keyframe) { if (mpp_get_bits(&s->gb, 24) != VP9_SYNCCODE) { // synccode mpp_err("Invalid sync code\n"); @@ -1619,20 +1627,25 @@ RK_S32 vp9_parser_frame(Vp9CodecContext *ctx, HalDecTask *task) vp9d_parser2_syntax(ctx); - task->syntax.data = (void*)&ctx->pic_params; task->syntax.number = 1; task->valid = 1; task->output = s->frames[CUR_FRAME].slot_index; task->input_packet = ctx->pkt; + for (i = 0; i < 3; i++) { if (s->refs[s->refidx[i]].slot_index < 0x7f) { + MppFrame mframe = NULL; mpp_buf_slot_set_flag(s->slots, s->refs[s->refidx[i]].slot_index, SLOT_HAL_INPUT); task->refer[i] = s->refs[s->refidx[i]].slot_index; + mpp_buf_slot_get_prop(s->slots, task->refer[i], SLOT_FRAME_PTR, &mframe); + if (mframe) + task->flags.had_error |= mpp_frame_get_errinfo(mframe); } else { task->refer[i] = -1; } } + vp9d_dbg(VP9D_DBG_REF, "ref_errinfo=%d\n", task->flags.had_error); if (s->eos) { task->flags.eos = 1; } @@ -1641,7 +1654,8 @@ RK_S32 vp9_parser_frame(Vp9CodecContext *ctx, HalDecTask *task) mpp_buf_slot_set_flag(s->slots, s->frames[CUR_FRAME].slot_index, SLOT_QUEUE_USE); mpp_buf_slot_enqueue(s->slots, s->frames[CUR_FRAME].slot_index, QUEUE_DISPLAY); } - vp9d_dbg(VP9D_DBG_REF, "s->refreshrefmask = %d s->frames[CUR_FRAME] = %d", s->refreshrefmask, s->frames[CUR_FRAME].slot_index); + vp9d_dbg(VP9D_DBG_REF, "s->refreshrefmask = %d s->frames[CUR_FRAME] = %d", + s->refreshrefmask, s->frames[CUR_FRAME].slot_index); for (i = 0; i < 3; i++) { if (s->refs[s->refidx[i]].ref != NULL) { vp9d_dbg(VP9D_DBG_REF, "ref buf select %d", s->refs[s->refidx[i]].slot_index); @@ -1672,6 +1686,8 @@ MPP_RET vp9d_paser_reset(Vp9CodecContext *ctx) VP9Context *s = ctx->priv_data; SplitContext_t *ps = (SplitContext_t *)ctx->priv_data2; VP9ParseContext *pc = (VP9ParseContext *)ps->priv_data; + + s->got_keyframes = 0; for (i = 0; i < 3; i++) { if (s->frames[i].ref) { vp9_unref_frame(s, &s->frames[i]); diff --git a/mpp/codec/dec/vp9/vp9d_parser.h b/mpp/codec/dec/vp9/vp9d_parser.h index 85a12202..7702e418 100644 --- a/mpp/codec/dec/vp9/vp9d_parser.h +++ b/mpp/codec/dec/vp9/vp9d_parser.h @@ -34,6 +34,7 @@ extern RK_U32 vp9d_debug; #define VP9D_DBG_HEADER (0x00000002) #define VP9D_DBG_REF (0x00000004) #define VP9D_DBG_PORBE (0x00000008) +#define VP9D_DBG_STRMIN (0x00000010) @@ -139,7 +140,7 @@ typedef struct VP9Context { RK_U8 varcompref[2]; VP9Frame frames[3]; VP9Frame refs[8]; - + RK_U32 got_keyframes; struct { RK_U8 level; diff --git a/mpp/hal/rkdec/vp9d/hal_vp9d_api.c b/mpp/hal/rkdec/vp9d/hal_vp9d_api.c index 9ad31b70..e2933377 100644 --- a/mpp/hal/rkdec/vp9d/hal_vp9d_api.c +++ b/mpp/hal/rkdec/vp9d/hal_vp9d_api.c @@ -868,11 +868,8 @@ MPP_RET hal_vp9d_wait(void *hal, HalTaskInfo *task) RK_U32 i; VP9_REGS *hw_regs = (VP9_REGS*)reg_cxt->hw_regs; RK_U8* p = (RK_U8*)hw_regs; - MppBuffer framebuf = NULL; - mpp_buf_slot_get_prop(reg_cxt->slots, task->dec.output, SLOT_BUFFER, &framebuf); ret = mpp_device_wait_reg(reg_cxt->vpu_socket, (RK_U32*)hw_regs, sizeof(VP9_REGS) / 4); - for (i = 0; i < sizeof(VP9_REGS) / 4; i++) { if (i == 1) { vp9h_dbg(VP9H_DBG_REG, "RK_VP9_DEC: regs[%02d]=%08X\n", i, *((RK_U32*)p)); @@ -881,6 +878,12 @@ MPP_RET hal_vp9d_wait(void *hal, HalTaskInfo *task) p += 4; } + if (task->dec.flags.had_error || !hw_regs->swreg1_int.sw_dec_rdy_sta) { + MppFrame mframe = NULL; + mpp_buf_slot_get_prop(reg_cxt->slots, task->dec.output, SLOT_FRAME_PTR, &mframe); + mpp_frame_set_errinfo(mframe, 1); + } + reg_cxt->ls_info.abs_delta_last = pic_param->stVP9Segments.abs_delta; for (i = 0 ; i < 4; i ++) { reg_cxt->ls_info.last_ref_deltas[i] = pic_param->ref_deltas[i];