Merge pull request #1627 from HaiboZhu/Debug_potential_out_of_memory

Reset parameter set status and clear AU list when out of memory
This commit is contained in:
huili2 2014-12-15 17:39:36 +08:00
commit 8fb4048241
5 changed files with 59 additions and 17 deletions

View File

@ -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

View File

@ -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__

View File

@ -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)

View File

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

View File

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