From c6594ae1924be6bb493ebdcae0d2cc91e8067d4b Mon Sep 17 00:00:00 2001 From: Ding Wei Date: Tue, 12 Dec 2017 15:09:54 +0800 Subject: [PATCH] [mpi_cmd]: add disable error command 1. Disable error default is not set for normal error detection. 2. On special case like drone streaming the user prefers to ignore all error and continue decoding. Then disable error flag will be set to fullfill this requirement. 3. When disable error flag is set H.264/H.265 decoding will ignore hardware error and mark all output frame as no error. Signed-off-by: Ding Wei Change-Id: I8fd619511c53ee744ae973ab3fe015565106dd37 Signed-off-by: Ding Wei --- inc/rk_mpi_cmd.h | 1 + mpp/codec/dec/h264/h264d_api.c | 13 +++++++--- mpp/codec/dec/h264/h264d_global.h | 1 + mpp/codec/dec/h265/h265d_codec.h | 2 +- mpp/codec/dec/h265/h265d_parser.c | 43 +++++++++++++++++++------------ mpp/codec/inc/mpp_dec.h | 1 + mpp/codec/mpp_dec.cpp | 7 +++++ mpp/mpp.cpp | 9 +++---- 8 files changed, 51 insertions(+), 26 deletions(-) diff --git a/inc/rk_mpi_cmd.h b/inc/rk_mpi_cmd.h index 0ac86a20..3f2c8d71 100644 --- a/inc/rk_mpi_cmd.h +++ b/inc/rk_mpi_cmd.h @@ -96,6 +96,7 @@ typedef enum { MPP_DEC_GET_VPUMEM_USED_COUNT, MPP_DEC_SET_VC1_EXTRA_DATA, MPP_DEC_SET_OUTPUT_FORMAT, + MPP_DEC_SET_DISABLE_ERROR, /* When set it will disable sw/hw error (H.264 / H.265) */ MPP_DEC_CMD_END, MPP_ENC_CMD_BASE = CMD_MODULE_CODEC | CMD_CTX_ID_ENC, diff --git a/mpp/codec/dec/h264/h264d_api.c b/mpp/codec/dec/h264/h264d_api.c index d3877547..ea9c1f81 100644 --- a/mpp/codec/dec/h264/h264d_api.c +++ b/mpp/codec/dec/h264/h264d_api.c @@ -470,11 +470,17 @@ __FAILED: MPP_RET h264d_control(void *decoder, RK_S32 cmd_type, void *param) { MPP_RET ret = MPP_ERR_UNKNOW; + H264_DecCtx_t *dec = (H264_DecCtx_t *)decoder; INP_CHECK(ret, !decoder); + switch (cmd_type) { + case MPP_DEC_SET_DISABLE_ERROR: { + dec->disable_error = *((RK_U32 *)param); + } + default : { + } break; + } - (void)cmd_type; - (void)param; __RETURN: return ret = MPP_OK; } @@ -610,7 +616,8 @@ MPP_RET h264d_parse(void *decoder, HalDecTask *in_task) in_task->syntax.number = p_Dec->dxva_ctx->syn.num; in_task->syntax.data = (void *)p_Dec->dxva_ctx->syn.buf; in_task->flags.used_for_ref = p_err->used_ref_flag; - in_task->flags.had_error = (p_err->dpb_err_flag | p_err->cur_err_flag) ? 1 : 0; + in_task->flags.had_error = (!p_Dec->disable_error + && (p_err->dpb_err_flag | p_err->cur_err_flag)) ? 1 : 0; } __RETURN: diff --git a/mpp/codec/dec/h264/h264d_global.h b/mpp/codec/dec/h264/h264d_global.h index 48f4a58d..1510457a 100644 --- a/mpp/codec/dec/h264/h264d_global.h +++ b/mpp/codec/dec/h264/h264d_global.h @@ -1147,6 +1147,7 @@ typedef struct h264_dec_ctx_t { RK_U32 task_eos; HalDecTask *in_task; RK_S32 last_frame_slot_idx; + RK_U32 disable_error; struct h264_err_ctx_t errctx; } H264_DecCtx_t; diff --git a/mpp/codec/dec/h265/h265d_codec.h b/mpp/codec/dec/h265/h265d_codec.h index 84d7ae91..107dd196 100644 --- a/mpp/codec/dec/h265/h265d_codec.h +++ b/mpp/codec/dec/h265/h265d_codec.h @@ -159,7 +159,7 @@ typedef struct H265dContext { void *compare_info; RK_U32 need_split; - + RK_U32 disable_error; } H265dContext_t; #ifdef __cplusplus extern "C" { diff --git a/mpp/codec/dec/h265/h265d_parser.c b/mpp/codec/dec/h265/h265d_parser.c index 58a21e42..9580ed51 100755 --- a/mpp/codec/dec/h265/h265d_parser.c +++ b/mpp/codec/dec/h265/h265d_parser.c @@ -2000,31 +2000,40 @@ MPP_RET h265d_reset(void *ctx) MPP_RET h265d_control(void *ctx, RK_S32 cmd, void *param) { - (void)ctx; - (void)cmd; - (void)param; + H265dContext_t *h265dctx = (H265dContext_t *)ctx; + + switch (cmd) { + case MPP_DEC_SET_DISABLE_ERROR: { + h265dctx->disable_error = *((RK_U32 *)param); + } + default : { + } break; + } + return MPP_OK; } MPP_RET h265d_callback(void *ctx, void *err_info) { H265dContext_t *h265dctx = (H265dContext_t *)ctx; - HEVCContext *s = (HEVCContext *)h265dctx->priv_data; - MppFrame frame = NULL; - RK_U32 i = 0; - if (s->first_nal_type >= 16 && s->first_nal_type <= 23) { - mpp_log("IS_IRAP frame found error"); - s->max_ra = INT_MAX; - } - // s->miss_ref_flag = 1; - mpp_buf_slot_get_prop(s->slots, s->ref->slot_index, SLOT_FRAME_PTR, &frame); - mpp_frame_set_errinfo(frame, MPP_FRAME_ERR_UNKNOW); - for (i = 0; i < MPP_ARRAY_ELEMS(s->DPB); i++) { - if (s->DPB[i].slot_index == s->ref->slot_index) { - s->DPB[i].error_flag = 1; + if (!h265dctx->disable_error) { + HEVCContext *s = (HEVCContext *)h265dctx->priv_data; + MppFrame frame = NULL; + RK_U32 i = 0; + + if (s->first_nal_type >= 16 && s->first_nal_type <= 23) { + mpp_log("IS_IRAP frame found error"); + s->max_ra = INT_MAX; + } + // s->miss_ref_flag = 1; + mpp_buf_slot_get_prop(s->slots, s->ref->slot_index, SLOT_FRAME_PTR, &frame); + mpp_frame_set_errinfo(frame, MPP_FRAME_ERR_UNKNOW); + for (i = 0; i < MPP_ARRAY_ELEMS(s->DPB); i++) { + if (s->DPB[i].slot_index == s->ref->slot_index) { + s->DPB[i].error_flag = 1; + } } - } (void) err_info; diff --git a/mpp/codec/inc/mpp_dec.h b/mpp/codec/inc/mpp_dec.h index dedc604a..1049bd29 100644 --- a/mpp/codec/inc/mpp_dec.h +++ b/mpp/codec/inc/mpp_dec.h @@ -40,6 +40,7 @@ struct MppDec_t { RK_U32 parser_need_split; RK_U32 parser_fast_mode; RK_U32 parser_internal_pts; + RK_U32 disable_error; // dec parser thread runtime resource context MppPacket mpp_pkt_in; diff --git a/mpp/codec/mpp_dec.cpp b/mpp/codec/mpp_dec.cpp index 2bf392e1..5a726862 100644 --- a/mpp/codec/mpp_dec.cpp +++ b/mpp/codec/mpp_dec.cpp @@ -196,6 +196,10 @@ static void mpp_put_frame(Mpp *mpp, MppFrame frame) mpp_list *list = mpp->mFrames; list->lock(); + if (mpp->mDec->disable_error) { + mpp_frame_set_errinfo(frame, 0); + mpp_frame_set_discard(frame, 0); + } list->add_at_tail(&frame, sizeof(frame)); if (mpp_debug & MPP_DBG_PTS) @@ -1093,6 +1097,9 @@ MPP_RET mpp_dec_control(MppDec *dec, MpiCmd cmd, void *param) RK_S32 *p = (RK_S32 *)param; *p = mpp_buf_slot_get_used_size(dec->frame_slots); } break; + case MPP_DEC_SET_DISABLE_ERROR: { + dec->disable_error = *((RK_U32 *)param); + } default : { } break; } diff --git a/mpp/mpp.cpp b/mpp/mpp.cpp index 0790f060..164cd60d 100644 --- a/mpp/mpp.cpp +++ b/mpp/mpp.cpp @@ -738,12 +738,11 @@ MPP_RET Mpp::control_dec(MpiCmd cmd, MppParam param) *((RK_S32 *)param) = mPackets->list_size(); ret = MPP_OK; } break; - case MPP_DEC_GET_VPUMEM_USED_COUNT: { + case MPP_DEC_GET_VPUMEM_USED_COUNT: + case MPP_DEC_SET_OUTPUT_FORMAT: + case MPP_DEC_SET_DISABLE_ERROR: { ret = mpp_dec_control(mDec, cmd, param); - } break; - case MPP_DEC_SET_OUTPUT_FORMAT: { - ret = mpp_dec_control(mDec, cmd, param); - } break; + } default : { } break; }