diff --git a/codec/decoder/core/src/decoder_core.cpp b/codec/decoder/core/src/decoder_core.cpp index 9fa90822..e1cbc2bc 100644 --- a/codec/decoder/core/src/decoder_core.cpp +++ b/codec/decoder/core/src/decoder_core.cpp @@ -134,11 +134,13 @@ inline void HandleReferenceLostL0 (PWelsDecoderContext pCtx, PNalUnit pCurNal if (0 == pCurNal->sNalHeaderExt.uiTemporalId) { pCtx->bReferenceLostAtT0Flag = true; } + if (pCtx->iErrorConMethod == ERROR_CON_DISABLE) { #ifndef LONG_TERM_REF - if (pCtx->bReferenceLostAtT0Flag) { - ResetParameterSetsState (pCtx); - } + if (pCtx->bReferenceLostAtT0Flag) { + ResetParameterSetsState (pCtx); + } #endif + } pCtx->iErrorCode |= dsBitstreamError; } @@ -146,11 +148,13 @@ inline void HandleReferenceLost (PWelsDecoderContext pCtx, PNalUnit pCurNal) if ((0 == pCurNal->sNalHeaderExt.uiTemporalId) || (1 == pCurNal->sNalHeaderExt.uiTemporalId)) { pCtx->bReferenceLostAtT0Flag = true; } + if (pCtx->iErrorConMethod == ERROR_CON_DISABLE) { #ifndef LONG_TERM_REF - if (pCtx->bReferenceLostAtT0Flag) { - ResetParameterSetsState (pCtx); - } + if (pCtx->bReferenceLostAtT0Flag) { + ResetParameterSetsState (pCtx); + } #endif + } pCtx->iErrorCode |= dsRefLost; } @@ -901,13 +905,15 @@ int32_t UpdateAccessUnit (PWelsDecoderContext pCtx) { if (uiActualIdx == pCurAu->uiActualUnitsNum) { // no found IDR nal within incoming AU, need exit to avoid mosaic issue, 11/19/2009 WelsLog (pCtx, WELS_LOG_WARNING, "UpdateAccessUnit():::::Key frame lost.....CAN NOT find IDR from current AU.\n"); + if (pCtx->iErrorCode == ERROR_CON_DISABLE) { #ifdef LONG_TERM_REF - pCtx->iErrorCode |= dsNoParamSets; - return dsNoParamSets; + pCtx->iErrorCode |= dsNoParamSets; + return dsNoParamSets; #else - pCtx->iErrorCode |= dsRefLost; - return ERR_INFO_REFERENCE_PIC_LOST; + pCtx->iErrorCode |= dsRefLost; + return ERR_INFO_REFERENCE_PIC_LOST; #endif + } } } @@ -1580,9 +1586,8 @@ int32_t ConstructAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBufferI pCtx->pSps = pCurAu->pNalUnitsList[pCurAu->uiStartPos]->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader.pSps; pCtx->pPps = pCurAu->pNalUnitsList[pCurAu->uiStartPos]->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader.pPps; - //try to allocate or relocate DPB memory only when IDR arrival. - if (NAL_UNIT_CODED_SLICE_IDR == pCurAu->pNalUnitsList[pCurAu->uiStartPos]->sNalHeaderExt.sNalUnitHeader.eNalUnitType || - pCurAu->pNalUnitsList[pCurAu->uiStartPos]->sNalHeaderExt.bIdrFlag) { + //try to allocate or relocate DPB memory only when new sequence is coming. + if (pCtx->bNewSeqBegin) { WelsResetRefPic (pCtx); //clear ref pPic when IDR NAL iErr = SyncPictureResolutionExt (pCtx, pCtx->pSps->iMbWidth, pCtx->pSps->iMbHeight); diff --git a/codec/decoder/core/src/manage_dec_ref.cpp b/codec/decoder/core/src/manage_dec_ref.cpp index a922af7c..805afb71 100644 --- a/codec/decoder/core/src/manage_dec_ref.cpp +++ b/codec/decoder/core/src/manage_dec_ref.cpp @@ -109,6 +109,26 @@ void WelsResetRefPic (PWelsDecoderContext pCtx) { */ int32_t WelsInitRefList (PWelsDecoderContext pCtx, int32_t iPoc) { int32_t i, iCount = 0; + + if ((pCtx->bNewSeqBegin) && (pCtx->sRefPic.uiRefCount[LIST_0] <= 0) && (pCtx->eSliceType != I_SLICE && pCtx->eSliceType != SI_SLICE)) { + if (pCtx->iErrorConMethod != ERROR_CON_DISABLE) { //IDR lost!, recover it for future decoding with data all set to 0 + PPicture pRef = PrefetchPic (pCtx->pPicBuff[0]); + if (pRef != NULL) { + memset (pRef->pData[0], 0, pRef->iLinesize[0] * pRef->iHeightInPixel); + memset (pRef->pData[1], 0, pRef->iLinesize[1] * pRef->iHeightInPixel / 2); + memset (pRef->pData[2], 0, pRef->iLinesize[2] * pRef->iHeightInPixel / 2); + pRef->iFrameNum = 0; + pRef->iFramePoc = 0; + pRef->uiTemporalId = pRef->uiQualityId = 0; + AddShortTermToList (&pCtx->sRefPic, pRef); + } else { + WelsLog (pCtx, WELS_LOG_ERROR, "WelsInitRefList()::PrefetchPic for EC errors.\n"); + pCtx->iErrorCode |= dsOutOfMemory; + return ERR_INFO_REF_COUNT_OVERFLOW; + } + } + } + PPicture* ppShoreRefList = pCtx->sRefPic.pShortRefList[LIST_0]; PPicture* ppLongRefList = pCtx->sRefPic.pLongRefList[LIST_0]; memset (pCtx->sRefPic.pRefList[LIST_0], 0, MAX_REF_PIC_COUNT * sizeof (PPicture)); diff --git a/codec/decoder/core/src/pic_queue.cpp b/codec/decoder/core/src/pic_queue.cpp index 71fe57f9..aef58b2d 100644 --- a/codec/decoder/core/src/pic_queue.cpp +++ b/codec/decoder/core/src/pic_queue.cpp @@ -135,7 +135,7 @@ PPicture PrefetchPic (PPicBuff pPicBuf) { pPicBuf->iCurrentIdx = iPicIdx; return pPic; } - for (iPicIdx = 0 ; iPicIdx < pPicBuf->iCurrentIdx ; ++iPicIdx) { + for (iPicIdx = 0 ; iPicIdx <= pPicBuf->iCurrentIdx ; ++iPicIdx) { if (pPicBuf->ppPic[iPicIdx] != NULL && pPicBuf->ppPic[iPicIdx]->bAvailableFlag && !pPicBuf->ppPic[iPicIdx]->bUsedAsRef) { pPic = pPicBuf->ppPic[iPicIdx]; diff --git a/codec/decoder/plus/src/welsDecoderExt.cpp b/codec/decoder/plus/src/welsDecoderExt.cpp index 24cacb7f..71b33d4e 100644 --- a/codec/decoder/plus/src/welsDecoderExt.cpp +++ b/codec/decoder/plus/src/welsDecoderExt.cpp @@ -373,12 +373,14 @@ DECODING_STATE CWelsDecoder::DecodeFrame2 (const unsigned char* kpSrc, //for AVC bitstream (excluding AVC with temporal scalability, including TP), as long as error occur, SHOULD notify upper layer key frame loss. if ((IS_PARAM_SETS_NALS (eNalType) || NAL_UNIT_CODED_SLICE_IDR == eNalType) || (VIDEO_BITSTREAM_AVC == m_pDecContext->eVideoType)) { + if (m_pDecContext->iErrorConMethod == ERROR_CON_DISABLE) { #ifdef LONG_TERM_REF - m_pDecContext->bParamSetsLostFlag = true; + m_pDecContext->bParamSetsLostFlag = true; #else - m_pDecContext->bReferenceLostAtT0Flag = true; + m_pDecContext->bReferenceLostAtT0Flag = true; #endif - ResetParameterSetsState (m_pDecContext); //initial SPS&PPS ready flag + ResetParameterSetsState (m_pDecContext); //initial SPS&PPS ready flag + } } IWelsTrace::WelsVTrace (m_pTrace, IWelsTrace::WELS_LOG_INFO, "decode failed, failure type:%d \n",