ref: 57043d16ad069bda72a555b84166510bcbd0636a
parent: 091e5cba0ae5006914c00ba0387cf29ab680f75f
author: Haibo Zhu <[email protected]>
date: Thu Dec 11 16:32:46 EST 2014
(1) Reset parameter set status and clear AU list when out of memory (2) Free un-complete malloc memory, keep the original state, special when increase memory
--- a/codec/decoder/core/inc/decoder.h
+++ b/codec/decoder/core/inc/decoder.h
@@ -143,6 +143,8 @@
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
--- a/codec/decoder/core/inc/decoder_core.h
+++ b/codec/decoder/core/inc/decoder_core.h
@@ -158,6 +158,8 @@
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__
--- a/codec/decoder/core/src/decoder.cpp
+++ b/codec/decoder/core/src/decoder.cpp
@@ -76,20 +76,26 @@
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,26 +118,32 @@
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;
@@ -138,7 +150,7 @@
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 @@
pPicNewBuf->ppPic = (PPicture*)WelsMalloc (kiNewSize * sizeof (PPicture), "PPicture*");
if (NULL == pPicNewBuf->ppPic) {
+ pPicNewBuf->iCapacity = 0;
+ DestroyPicBuff (&pPicNewBuf);
return 1;
}
@@ -203,7 +217,7 @@
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 @@
return 0;
}
-static void DestroyPicBuff (PPicBuff* ppPicBuf) {
+void DestroyPicBuff (PPicBuff* ppPicBuf) {
PPicBuff pPicBuf = NULL;
if (NULL == ppPicBuf || NULL == *ppPicBuf)
--- a/codec/decoder/core/src/decoder_core.cpp
+++ b/codec/decoder/core/src/decoder_core.cpp
@@ -1318,6 +1318,18 @@
-- 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;
--- a/codec/decoder/plus/src/welsDecoderExt.cpp
+++ b/codec/decoder/plus/src/welsDecoderExt.cpp
@@ -375,7 +375,8 @@
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 @@
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 @@
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;