diff --git a/mpp/codec/dec/h265/h265d_parser.c b/mpp/codec/dec/h265/h265d_parser.c index 49b37c73..86e41da3 100644 --- a/mpp/codec/dec/h265/h265d_parser.c +++ b/mpp/codec/dec/h265/h265d_parser.c @@ -1132,10 +1132,11 @@ static RK_S32 hevc_frame_start(HEVCContext *s) if (ret < 0) goto fail; - + s->miss_ref_flag = 0; ret = mpp_hevc_frame_rps(s); if(s->miss_ref_flag && !IS_IRAP(s)){ mpp_frame_set_errinfo(s->frame,VPU_FRAME_ERR_UNKNOW); + s->ref->error_flag = 1; } mpp_buf_slot_set_prop(s->slots, s->ref->slot_index, SLOT_FRAME, s->ref->frame); @@ -1484,6 +1485,22 @@ static RK_S32 split_nal_units(HEVCContext *s, RK_U8 *buf, RK_U32 length) continue; } if (buf[0] != 0 || buf[1] != 0 || buf[2] != 1) { + uint32_t state = -1; + int has_nal = 0; + for (i = 0; i < length; i++) { + state = (state << 8) | buf[i]; + if (((state >> 8) & 0xFFFFFF) == START_CODE){ + has_nal = 1; + i = i -3; + break; + } + } + + if(has_nal){ + length -= i; + buf += i; + continue; + } mpp_err( "No start code is found.\n"); ret = MPP_ERR_STREAM; goto fail; @@ -1857,6 +1874,7 @@ static RK_S32 hevc_init_context(H265dContext_t *h265dctx) for (i = 0; i < MPP_ARRAY_ELEMS(s->DPB); i++) { s->DPB[i].slot_index = 0xff; s->DPB[i].poc = INT_MAX; + s->DPB[i].error_flag = 0; mpp_frame_init(&s->DPB[i].frame); if (!s->DPB[i].frame) goto fail; @@ -1993,11 +2011,18 @@ MPP_RET h265d_callback(void *ctx, void *err_info) { H265dContext_t *h265dctx = (H265dContext_t *)ctx; HEVCContext *s = (HEVCContext *)h265dctx->priv_data; + RK_U32 i = 0; s->max_ra = INT_MAX; - s->miss_ref_flag = 1; + // s->miss_ref_flag = 1; mpp_buf_slot_get_prop(s->slots, s->ref->slot_index,SLOT_FRAME,&s->ref->frame); mpp_frame_set_errinfo(s->ref->frame,VPU_FRAME_ERR_UNKNOW); mpp_buf_slot_set_prop(s->slots, s->ref->slot_index, SLOT_FRAME, s->ref->frame); + 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; return MPP_OK; diff --git a/mpp/codec/dec/h265/h265d_parser.h b/mpp/codec/dec/h265/h265d_parser.h index 6b69646f..e6535411 100644 --- a/mpp/codec/dec/h265/h265d_parser.h +++ b/mpp/codec/dec/h265/h265d_parser.h @@ -564,6 +564,7 @@ typedef struct HEVCFrame { */ RK_U8 flags; RK_S32 slot_index; + RK_U8 error_flag; } HEVCFrame; typedef struct HEVCNAL { diff --git a/mpp/codec/dec/h265/h265d_refs.c b/mpp/codec/dec/h265/h265d_refs.c index 8b10fee6..e9c5523c 100644 --- a/mpp/codec/dec/h265/h265d_refs.c +++ b/mpp/codec/dec/h265/h265d_refs.c @@ -51,6 +51,7 @@ void mpp_hevc_unref_frame(HEVCContext *s, HEVCFrame *frame, int flags) h265d_dbg(H265D_DBG_REF, "unref_frame poc %d frame->slot_index %d \n", frame->poc, frame->slot_index); frame->poc = INT_MAX; frame->slot_index = 0xff; + frame->error_flag = 0; } } @@ -145,7 +146,7 @@ int mpp_hevc_set_new_ref(HEVCContext *s, MppFrame *mframe, int poc) frame->poc == poc && !s->nuh_layer_id) { mpp_err( "Duplicate POC in a sequence: %d.\n", poc); - s->miss_ref_flag = 1; + //s->miss_ref_flag = 1; return MPP_ERR_STREAM; } } @@ -334,10 +335,10 @@ static int add_candidate_ref(HEVCContext *s, RefPicList *list, return MPP_ERR_STREAM; if (!ref) { - s->miss_ref_flag = 1; ref = generate_missing_ref(s, poc); if (!ref) return MPP_ERR_NOMEM; + ref->error_flag = 1; } list->list[list->nb_refs] = ref->poc; @@ -348,7 +349,9 @@ static int add_candidate_ref(HEVCContext *s, RefPicList *list, mpp_buf_slot_set_flag(s->slots, ref->slot_index, SLOT_CODEC_USE); } mark_ref(ref, ref_flag); - + if(ref->error_flag){ + s->miss_ref_flag = 1; + } return 0; } diff --git a/mpp/legacy/vpu_api_legacy.cpp b/mpp/legacy/vpu_api_legacy.cpp index d67b7e12..2bf41a6e 100644 --- a/mpp/legacy/vpu_api_legacy.cpp +++ b/mpp/legacy/vpu_api_legacy.cpp @@ -32,6 +32,7 @@ VpuApi::VpuApi() #endif mpp_construct(&mpp_ctx, &mpi); frame_count = 0; + set_eos = 0; mpp_log_f("ok\n"); } @@ -129,6 +130,10 @@ RK_S32 VpuApi:: decode_getoutframe(DecoderOut_t *aDecOut) aDecOut->size = 0; return 0; } + if(set_eos){ + aDecOut->size = 0; + return VPU_API_EOS_STREAM_REACHED; + } if (MPP_OK == mpi->decode_get_frame(mpp_ctx, &mframe)) { MppBuffer buf; RK_U64 pts; @@ -189,7 +194,10 @@ RK_S32 VpuApi:: decode_getoutframe(DecoderOut_t *aDecOut) vframe->vpumem.offset = (RK_U32*)buf; } if (mpp_frame_get_eos(mframe)) { - aDecOut->nFlags = VPU_API_EOS_STREAM_REACHED; + set_eos = 1; + if(buf == NULL){ + aDecOut->size = 0; + } } mpp_free(mframe); } else { diff --git a/mpp/legacy/vpu_api_legacy.h b/mpp/legacy/vpu_api_legacy.h index e21b10a9..410c7f81 100644 --- a/mpp/legacy/vpu_api_legacy.h +++ b/mpp/legacy/vpu_api_legacy.h @@ -47,6 +47,7 @@ private: MppCtx mpp_ctx; MppApi *mpi; RK_U32 frame_count; + RK_U32 set_eos; #ifdef DUMP_YUV FILE *fp; #endif diff --git a/mpp/mpp.cpp b/mpp/mpp.cpp index b7518c41..d9115f56 100644 --- a/mpp/mpp.cpp +++ b/mpp/mpp.cpp @@ -304,7 +304,12 @@ MPP_RET Mpp::control(MpiCmd cmd, MppParam param) MPP_RET Mpp::reset() { + MppPacket mpkt = NULL; + RK_U32 flags = 0; mPackets->lock(); + if(mPackets->list_size()){ + mPackets->del_at_head(&mpkt, sizeof(mpkt)); + } mPackets->flush(); mPackets->unlock(); @@ -316,12 +321,24 @@ MPP_RET Mpp::reset() if (mType == MPP_CTX_DEC) { mpp_dec_reset(mDec); + mThreadCodec->lock(); mThreadCodec->signal(); + mThreadCodec->unlock(); mThreadCodec->wait(THREAD_RESET); } else { mpp_enc_reset(mEnc); } mThreadCodec->unlock(THREAD_RESET); + if(mpkt != NULL){ + flags = mpp_packet_get_flag(mpkt); + mpp_log("flags = %d",flags); + if(flags&MPP_PACKET_FLAG_EXTRA_DATA){ //avoid first packet is extara data was flushed & dec can work + put_packet(mpkt); + } + mpp_free(mpp_packet_get_data(mpkt)); + mpp_packet_deinit(&mpkt); + mpkt = NULL; + } return MPP_OK; }