diff --git a/codec/decoder/core/inc/decoder.h b/codec/decoder/core/inc/decoder.h index 767da4c4..87efbcd6 100644 --- a/codec/decoder/core/inc/decoder.h +++ b/codec/decoder/core/inc/decoder.h @@ -143,6 +143,8 @@ void UpdateDecStatFreezingInfo (const bool kbIdrFlag, SDecoderStatistics* pDecSt void UpdateDecStatNoFreezingInfo (PWelsDecoderContext pCtx); //update decoder statistics information void UpdateDecStat (PWelsDecoderContext pCtx, const bool kbOutput); +//Destroy picutre buffer +void DestroyPicBuff (PPicBuff* ppPicBuf); #ifdef __cplusplus } #endif//__cplusplus diff --git a/codec/decoder/core/inc/decoder_core.h b/codec/decoder/core/inc/decoder_core.h index a69428a1..dc1b0067 100644 --- a/codec/decoder/core/inc/decoder_core.h +++ b/codec/decoder/core/inc/decoder_core.h @@ -158,6 +158,8 @@ void ForceResetCurrentAccessUnit (PAccessUnit pAu); void ForceClearCurrentNal (PAccessUnit pAu); bool bCheckRefPicturesComplete (PWelsDecoderContext pCtx); // Check whether all ref pictures are complete + +void ForceResetParaSetStatusAndAUList(PWelsDecoderContext pCtx); } // namespace WelsDec #endif//WELS_DECODER_CORE_H__ diff --git a/codec/decoder/core/src/decoder.cpp b/codec/decoder/core/src/decoder.cpp index c09f1134..2b8b2b8f 100644 --- a/codec/decoder/core/src/decoder.cpp +++ b/codec/decoder/core/src/decoder.cpp @@ -76,20 +76,26 @@ static int32_t CreatePicBuff (PWelsDecoderContext pCtx, PPicBuff* ppPicBuf, cons pPicBuf->ppPic = (PPicture*)WelsMalloc (kiSize * sizeof (PPicture), "PPicture*"); if (NULL == pPicBuf->ppPic) { + pPicBuf->iCapacity = 0; + DestroyPicBuff (&pPicBuf); return 1; } + for (iPicIdx = 0; iPicIdx < kiSize; ++ iPicIdx) { PPicture pPic = AllocPicture (pCtx, kiPicWidth, kiPicHeight); if (NULL == pPic) { + // init capacity first for free memory + pPicBuf->iCapacity = iPicIdx; + DestroyPicBuff (&pPicBuf); return 1; } pPicBuf->ppPic[iPicIdx] = pPic; } - // initialize context in queue +// initialize context in queue pPicBuf->iCapacity = kiSize; pPicBuf->iCurrentIdx = 0; - *ppPicBuf = pPicBuf; + * ppPicBuf = pPicBuf; return 0; } @@ -112,33 +118,39 @@ static int32_t IncreasePicBuff (PWelsDecoderContext pCtx, PPicBuff* ppPicBuf, co pPicNewBuf->ppPic = (PPicture*)WelsMalloc (kiNewSize * sizeof (PPicture), "PPicture*"); if (NULL == pPicNewBuf->ppPic) { + pPicNewBuf->iCapacity = 0; + DestroyPicBuff (&pPicNewBuf); return 1; } - // copy old PicBuf to new PicBuf - memcpy (pPicNewBuf->ppPic, pPicOldBuf->ppPic, kiOldSize * sizeof (PPicture)); - // increase new PicBuf for (iPicIdx = kiOldSize; iPicIdx < kiNewSize; ++ iPicIdx) { PPicture pPic = AllocPicture (pCtx, kiPicWidth, kiPicHeight); if (NULL == pPic) { + // Set maximum capacity as the new malloc memory at the tail + pPicNewBuf->iCapacity = iPicIdx; + DestroyPicBuff (&pPicNewBuf); return 1; } pPicNewBuf->ppPic[iPicIdx] = pPic; } - // initialize context in queue + + // copy old PicBuf to new PicBuf + memcpy (pPicNewBuf->ppPic, pPicOldBuf->ppPic, kiOldSize * sizeof (PPicture)); + +// initialize context in queue pPicNewBuf->iCapacity = kiNewSize; pPicNewBuf->iCurrentIdx = pPicOldBuf->iCurrentIdx; - *ppPicBuf = pPicNewBuf; - - for(int32_t i = 0; i < pPicNewBuf->iCapacity; i++) { + * ppPicBuf = pPicNewBuf; + + for (int32_t i = 0; i < pPicNewBuf->iCapacity; i++) { pPicNewBuf->ppPic[i]->bUsedAsRef = false; pPicNewBuf->ppPic[i]->bIsLongRef = false; pPicNewBuf->ppPic[i]->uiRefCount = 0; pPicNewBuf->ppPic[i]->bAvailableFlag = true; pPicNewBuf->ppPic[i]->bIsComplete = false; } - // remove old PicBuf +// remove old PicBuf if (pPicOldBuf->ppPic != NULL) { WelsFree (pPicOldBuf->ppPic, "pPicOldBuf->queue"); pPicOldBuf->ppPic = NULL; @@ -168,6 +180,8 @@ static int32_t DecreasePicBuff (PWelsDecoderContext pCtx, PPicBuff* ppPicBuf, co pPicNewBuf->ppPic = (PPicture*)WelsMalloc (kiNewSize * sizeof (PPicture), "PPicture*"); if (NULL == pPicNewBuf->ppPic) { + pPicNewBuf->iCapacity = 0; + DestroyPicBuff (&pPicNewBuf); return 1; } @@ -203,7 +217,7 @@ static int32_t DecreasePicBuff (PWelsDecoderContext pCtx, PPicBuff* ppPicBuf, co pPicNewBuf->iCapacity = kiNewSize; *ppPicBuf = pPicNewBuf; - for(int32_t i = 0; i < pPicNewBuf->iCapacity; i++) { + for (int32_t i = 0; i < pPicNewBuf->iCapacity; i++) { pPicNewBuf->ppPic[i]->bUsedAsRef = false; pPicNewBuf->ppPic[i]->bIsLongRef = false; pPicNewBuf->ppPic[i]->uiRefCount = 0; @@ -223,7 +237,7 @@ static int32_t DecreasePicBuff (PWelsDecoderContext pCtx, PPicBuff* ppPicBuf, co return 0; } -static void DestroyPicBuff (PPicBuff* ppPicBuf) { +void DestroyPicBuff (PPicBuff* ppPicBuf) { PPicBuff pPicBuf = NULL; if (NULL == ppPicBuf || NULL == *ppPicBuf) diff --git a/codec/decoder/core/src/decoder_core.cpp b/codec/decoder/core/src/decoder_core.cpp index 143ecb27..7cdb96f0 100644 --- a/codec/decoder/core/src/decoder_core.cpp +++ b/codec/decoder/core/src/decoder_core.cpp @@ -1318,6 +1318,18 @@ void ForceClearCurrentNal (PAccessUnit pAu) { -- pAu->uiAvailUnitsNum; } +void ForceResetParaSetStatusAndAUList (PWelsDecoderContext pCtx) { + pCtx->bSpsExistAheadFlag = false; + pCtx->bSubspsExistAheadFlag = false; + pCtx->bPpsExistAheadFlag = false; + + // Force clear the AU list + pCtx->pAccessUnitList->uiAvailUnitsNum = 0; + pCtx->pAccessUnitList->uiActualUnitsNum = 0; + pCtx->pAccessUnitList->uiStartPos = 0; + pCtx->pAccessUnitList->uiEndPos = 0; + pCtx->pAccessUnitList->bCompletedAuFlag = false; +} void CheckAvailNalUnitsListContinuity (PWelsDecoderContext pCtx, int32_t iStartIdx, int32_t iEndIdx) { PAccessUnit pCurAu = pCtx->pAccessUnitList; diff --git a/codec/decoder/plus/src/welsDecoderExt.cpp b/codec/decoder/plus/src/welsDecoderExt.cpp index 76ec1230..a93a418b 100644 --- a/codec/decoder/plus/src/welsDecoderExt.cpp +++ b/codec/decoder/plus/src/welsDecoderExt.cpp @@ -375,7 +375,8 @@ long CWelsDecoder::GetOption (DECODER_OPTION eOptID, void* pOption) { pDecoderStatistics->fAverageFrameSpeedInMs = (float) (m_pDecContext->dDecTime) / (m_pDecContext->sDecoderStatistics.uiDecodedFrameCount); pDecoderStatistics->fActualAverageFrameSpeedInMs = (float) (m_pDecContext->dDecTime) / - (m_pDecContext->sDecoderStatistics.uiDecodedFrameCount + m_pDecContext->sDecoderStatistics.uiFreezingIDRNum + m_pDecContext->sDecoderStatistics.uiFreezingNonIDRNum); + (m_pDecContext->sDecoderStatistics.uiDecodedFrameCount + m_pDecContext->sDecoderStatistics.uiFreezingIDRNum + + m_pDecContext->sDecoderStatistics.uiFreezingNonIDRNum); return cmResultSuccess; } @@ -439,6 +440,9 @@ DECODING_STATE CWelsDecoder::DecodeFrame2 (const unsigned char* kpSrc, eNalType = m_pDecContext->sCurNalHead.eNalUnitType; + if (m_pDecContext->iErrorCode & dsOutOfMemory) { + ForceResetParaSetStatusAndAUList (m_pDecContext); + } //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)) { @@ -480,11 +484,19 @@ DECODING_STATE CWelsDecoder::DecodeFrame2 (const unsigned char* kpSrc, m_pDecContext->sDecoderStatistics.uiDecodedFrameCount++; } int32_t iMbConcealedNum = m_pDecContext->iMbEcedNum + m_pDecContext->iMbEcedPropNum; - m_pDecContext->sDecoderStatistics.uiAvgEcRatio = m_pDecContext->iMbNum == 0 ? (m_pDecContext->sDecoderStatistics.uiAvgEcRatio * m_pDecContext->sDecoderStatistics.uiEcFrameNum) :((m_pDecContext->sDecoderStatistics.uiAvgEcRatio * m_pDecContext->sDecoderStatistics.uiEcFrameNum) + ((iMbConcealedNum * 100) / m_pDecContext->iMbNum)); - m_pDecContext->sDecoderStatistics.uiAvgEcPropRatio = m_pDecContext->iMbNum == 0 ? (m_pDecContext->sDecoderStatistics.uiAvgEcPropRatio * m_pDecContext->sDecoderStatistics.uiEcFrameNum) :((m_pDecContext->sDecoderStatistics.uiAvgEcPropRatio * m_pDecContext->sDecoderStatistics.uiEcFrameNum) + ((m_pDecContext->iMbEcedPropNum * 100) / m_pDecContext->iMbNum)); + m_pDecContext->sDecoderStatistics.uiAvgEcRatio = m_pDecContext->iMbNum == 0 ? + (m_pDecContext->sDecoderStatistics.uiAvgEcRatio * m_pDecContext->sDecoderStatistics.uiEcFrameNum) : (( + m_pDecContext->sDecoderStatistics.uiAvgEcRatio * m_pDecContext->sDecoderStatistics.uiEcFrameNum) + (( + iMbConcealedNum * 100) / m_pDecContext->iMbNum)); + m_pDecContext->sDecoderStatistics.uiAvgEcPropRatio = m_pDecContext->iMbNum == 0 ? + (m_pDecContext->sDecoderStatistics.uiAvgEcPropRatio * m_pDecContext->sDecoderStatistics.uiEcFrameNum) : (( + m_pDecContext->sDecoderStatistics.uiAvgEcPropRatio * m_pDecContext->sDecoderStatistics.uiEcFrameNum) + (( + m_pDecContext->iMbEcedPropNum * 100) / m_pDecContext->iMbNum)); m_pDecContext->sDecoderStatistics.uiEcFrameNum += (iMbConcealedNum == 0 ? 0 : 1); - m_pDecContext->sDecoderStatistics.uiAvgEcRatio = m_pDecContext->sDecoderStatistics.uiEcFrameNum == 0? 0 : m_pDecContext->sDecoderStatistics.uiAvgEcRatio / m_pDecContext->sDecoderStatistics.uiEcFrameNum; - m_pDecContext->sDecoderStatistics.uiAvgEcPropRatio = m_pDecContext->sDecoderStatistics.uiEcFrameNum == 0? 0 : m_pDecContext->sDecoderStatistics.uiAvgEcPropRatio / m_pDecContext->sDecoderStatistics.uiEcFrameNum; + m_pDecContext->sDecoderStatistics.uiAvgEcRatio = m_pDecContext->sDecoderStatistics.uiEcFrameNum == 0 ? 0 : + m_pDecContext->sDecoderStatistics.uiAvgEcRatio / m_pDecContext->sDecoderStatistics.uiEcFrameNum; + m_pDecContext->sDecoderStatistics.uiAvgEcPropRatio = m_pDecContext->sDecoderStatistics.uiEcFrameNum == 0 ? 0 : + m_pDecContext->sDecoderStatistics.uiAvgEcPropRatio / m_pDecContext->sDecoderStatistics.uiEcFrameNum; } iEnd = WelsTime(); m_pDecContext->dDecTime += (iEnd - iStart) / 1e3;