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; }