From ef02ca75fffdfe8b22efa7f310523100234713be Mon Sep 17 00:00:00 2001 From: "leo.ding" Date: Thu, 15 Jun 2017 21:29:01 +0800 Subject: [PATCH] [h264d]: fix bug: when judge whether is end of frame 1. when had slice data and current nalu is SPS PPS AUD SEI, thus it can consider that last nalu is the end of frame. 2. when pps is missing, frame data is continue, and use first_mb_in_slice to judge last nalu is end of frame. Change-Id: I1ccf3ca415e6b04dcd7fe7fc9c357fd600fa5803 Signed-off-by: leo.ding --- mpp/codec/dec/h264/h264d_api.c | 4 +- mpp/codec/dec/h264/h264d_global.h | 2 +- mpp/codec/dec/h264/h264d_parse.c | 81 ++++++++++++++++--------------- 3 files changed, 44 insertions(+), 43 deletions(-) diff --git a/mpp/codec/dec/h264/h264d_api.c b/mpp/codec/dec/h264/h264d_api.c index 34ca5a78..d3877547 100644 --- a/mpp/codec/dec/h264/h264d_api.c +++ b/mpp/codec/dec/h264/h264d_api.c @@ -264,7 +264,7 @@ static MPP_RET init_dec_ctx(H264_DecCtx_t *p_Dec) p_Dec->spt_decode_mtds = MPP_DEC_BY_FRAME; p_Dec->next_state = SliceSTATE_ResetSlice; p_Dec->nalu_ret = NALU_NULL; - p_Dec->is_first_frame = 1; + p_Dec->have_slice_data = 0; p_Dec->last_frame_slot_idx = -1; memset(&p_Dec->errctx, 0, sizeof(H264dErrCtx_t)); __RETURN: @@ -422,7 +422,7 @@ MPP_RET h264d_reset(void *decoder) //!< reset decoder parameter p_Dec->next_state = SliceSTATE_ResetSlice; p_Dec->nalu_ret = NALU_NULL; - p_Dec->is_first_frame = 1; + p_Dec->have_slice_data = 0; p_Dec->is_new_frame = 0; p_Dec->is_parser_end = 0; p_Dec->dxva_ctx->strm_offset = 0; diff --git a/mpp/codec/dec/h264/h264d_global.h b/mpp/codec/dec/h264/h264d_global.h index 109f01b3..48f4a58d 100644 --- a/mpp/codec/dec/h264/h264d_global.h +++ b/mpp/codec/dec/h264/h264d_global.h @@ -1132,7 +1132,7 @@ typedef struct h264_dec_ctx_t { RK_U32 spt_decode_mtds; //!< support decoder methods NALU_STATUS nalu_ret; //!< current nalu state SLICE_STATUS next_state; //!< RKV_SLICE_STATUS - RK_U8 is_first_frame; + RK_U8 have_slice_data; RK_U8 is_new_frame; RK_U8 is_parser_end; RK_U8 mvc_valid; diff --git a/mpp/codec/dec/h264/h264d_parse.c b/mpp/codec/dec/h264/h264d_parse.c index a70077e1..49ed0b4d 100644 --- a/mpp/codec/dec/h264/h264d_parse.c +++ b/mpp/codec/dec/h264/h264d_parse.c @@ -369,6 +369,7 @@ static MPP_RET store_cur_nalu(H264dCurCtx_t *p_Cur, H264dCurStream_t *p_strm, H2 p_Inp->spspps_offset = 0; } } + return ret = MPP_OK; __FAILED: return ret; @@ -378,52 +379,60 @@ static MPP_RET judge_is_new_frame(H264dCurCtx_t *p_Cur, H264dCurStream_t *p_strm { MPP_RET ret = MPP_ERR_UNKNOW; RK_U32 nalu_header_bytes = 0; - RK_U32 first_mb_in_slice = 0; BitReadCtx_t *p_bitctx = &p_Cur->bitctx; - RK_U32 forbidden_bit = -1; - RK_U32 nal_reference_idc = -1; - RK_U32 svc_extension_flag = -1; - memset(p_bitctx, 0, sizeof(BitReadCtx_t)); - mpp_set_bitread_ctx(p_bitctx, p_strm->nalu_buf, 4); - mpp_set_pre_detection(p_bitctx); + { + RK_U32 forbidden_bit = -1; + RK_U32 nal_reference_idc = -1; + RK_U32 svc_extension_flag = -1; + mpp_set_bitread_ctx(p_bitctx, p_strm->nalu_buf, 4); + mpp_set_pre_detection(p_bitctx); - READ_BITS(p_bitctx, 1, &forbidden_bit); - ASSERT(forbidden_bit == 0); - READ_BITS(p_bitctx, 2, &nal_reference_idc); - READ_BITS(p_bitctx, 5, &p_strm->nalu_type); + READ_BITS(p_bitctx, 1, &forbidden_bit); + ASSERT(forbidden_bit == 0); + READ_BITS(p_bitctx, 2, &nal_reference_idc); + READ_BITS(p_bitctx, 5, &p_strm->nalu_type); - nalu_header_bytes = 1; - if ((p_strm->nalu_type == NALU_TYPE_PREFIX) || (p_strm->nalu_type == NALU_TYPE_SLC_EXT)) { - READ_BITS(p_bitctx, 1, &svc_extension_flag); - if (svc_extension_flag) { - H264D_WARNNING("svc_extension is not supported."); - goto __FAILED; - } else { - if (p_strm->nalu_type == NALU_TYPE_SLC_EXT) { - p_strm->nalu_type = NALU_TYPE_SLICE; + nalu_header_bytes = 1; + if ((p_strm->nalu_type == NALU_TYPE_PREFIX) || (p_strm->nalu_type == NALU_TYPE_SLC_EXT)) { + READ_BITS(p_bitctx, 1, &svc_extension_flag); + if (svc_extension_flag) { + H264D_WARNNING("svc_extension is not supported."); + goto __FAILED; + } else { + if (p_strm->nalu_type == NALU_TYPE_SLC_EXT) { + p_strm->nalu_type = NALU_TYPE_SLICE; + } } + nalu_header_bytes += 3; } - nalu_header_bytes += 3; } - //-- parse slice - if ( p_strm->nalu_type == NALU_TYPE_SLICE || p_strm->nalu_type == NALU_TYPE_IDR) { + if ((p_strm->nalu_len == 1) + && (p_strm->nalu_type == NALU_TYPE_SEI + || p_strm->nalu_type == NALU_TYPE_SPS + || p_strm->nalu_type == NALU_TYPE_PPS + || p_strm->nalu_type == NALU_TYPE_AUD)) { + if (p_Cur->p_Dec->have_slice_data) { + p_Cur->p_Dec->is_new_frame = 1; + } + p_Cur->p_Dec->have_slice_data = 0; + } else if ((p_strm->nalu_len > 1) + && (p_strm->nalu_type == NALU_TYPE_SLICE + || p_strm->nalu_type == NALU_TYPE_IDR)) { + RK_U32 first_mb_in_slice = 0; mpp_set_bitread_ctx(p_bitctx, (p_strm->nalu_buf + nalu_header_bytes), 4); // reset mpp_set_pre_detection(p_bitctx); READ_UE(p_bitctx, &first_mb_in_slice); - //!< get time stamp if (first_mb_in_slice == 0) { p_Cur->last_dts = p_Cur->curr_dts; p_Cur->last_pts = p_Cur->curr_pts; p_Cur->curr_dts = p_Cur->p_Inp->in_dts; p_Cur->curr_pts = p_Cur->p_Inp->in_pts; - if (!p_Cur->p_Dec->is_first_frame) { + if (p_Cur->p_Dec->have_slice_data) { p_Cur->p_Dec->is_new_frame = 1; - } - p_Cur->p_Dec->is_first_frame = 0; - + p_Cur->p_Dec->have_slice_data = 1; } } @@ -515,7 +524,6 @@ MPP_RET close_stream_file(H264dInputCtx_t *p_Inp) MPP_RET parse_prepare(H264dInputCtx_t *p_Inp, H264dCurCtx_t *p_Cur) { MPP_RET ret = MPP_ERR_UNKNOW; - RK_U32 nalu_header_bytes = 0; H264_DecCtx_t *p_Dec = p_Inp->p_Dec; H264dCurStream_t *p_strm = &p_Cur->strm; @@ -546,15 +554,8 @@ MPP_RET parse_prepare(H264dInputCtx_t *p_Inp, H264dCurCtx_t *p_Cur) FUN_CHECK(ret = realloc_buffer(&p_strm->nalu_buf, &p_strm->nalu_max_size, NALU_BUF_ADD_SIZE)); } p_strm->nalu_buf[p_strm->nalu_len++] = *p_strm->curdata; - if (p_strm->nalu_len == 1) { - p_strm->nalu_type = p_strm->nalu_buf[0] & 0x1F; - nalu_header_bytes += 1; - if ((p_strm->nalu_type == NALU_TYPE_PREFIX) - || (p_strm->nalu_type == NALU_TYPE_SLC_EXT)) { - nalu_header_bytes += 3; - } - } - if (p_strm->nalu_len == (nalu_header_bytes + 4)) { + if ((p_strm->nalu_len == 1) + || (p_strm->nalu_len == 5)) { FUN_CHECK(ret = judge_is_new_frame(p_Cur, p_strm)); if (p_Cur->p_Dec->is_new_frame) { FUN_CHECK(ret = add_empty_nalu(&p_Cur->strm)); @@ -784,7 +785,7 @@ MPP_RET parse_prepare_extra_data(H264dInputCtx_t *p_Inp, H264dCurCtx_t *p_Cur) p_strm->nalu_len = parse_nal_size(p_Inp->nal_size, p_strm->curdata); if (p_strm->nalu_len <= 0 || p_strm->nalu_len >= p_Inp->in_length) { p_Cur->p_Dec->is_new_frame = 1; - p_Cur->p_Dec->is_first_frame = 1; + p_Cur->p_Dec->have_slice_data = 0; pkt_impl->length = 0; p_Inp->in_length = 0; p_strm->nalu_len = 0; @@ -815,7 +816,7 @@ MPP_RET parse_prepare_extra_data(H264dInputCtx_t *p_Inp, H264dCurCtx_t *p_Cur) } if (p_Inp->in_length < p_Inp->nal_size) { p_Cur->p_Dec->is_new_frame = 1; - p_Cur->p_Dec->is_first_frame = 1; + p_Cur->p_Dec->have_slice_data = 0; pkt_impl->length = 0; p_Inp->in_length = 0; p_strm->nalu_len = 0;