ref: d03150947476ea806c2de8c367f6c34b7b17efa5
parent: 1b1654e9c6393bfbb491c47f261934d20b7f252b
author: huili2 <[email protected]>
date: Sun Apr 20 04:20:12 EDT 2014
add DPB management if frame loss happens
--- a/codec/console/dec/src/h264dec.cpp
+++ b/codec/console/dec/src/h264dec.cpp
@@ -174,8 +174,8 @@
fread (&iSliceSize, 1, sizeof (int32_t), fpTrack);
#else
for (i = 0; i < iFileSize; i++) {
- if (pBuf[iBufPos + i] == 0 && pBuf[iBufPos + i + 1] == 0 && pBuf[iBufPos + i + 2] == 0 &&
- pBuf[iBufPos + i + 3] == 1 && i > 0) {
+ if ((pBuf[iBufPos + i] == 0 && pBuf[iBufPos + i + 1] == 0 && pBuf[iBufPos + i + 2] == 0 && pBuf[iBufPos + i + 3] == 1
+ && i > 0) || (pBuf[iBufPos + i] == 0 && pBuf[iBufPos + i + 1] == 0 && pBuf[iBufPos + i + 2] == 1 && i > 0)) {
break;
}
}
@@ -303,7 +303,7 @@
}
#if (defined(ANDROID_NDK)||defined(APPLE_IOS))
-int32_t DecMain(int32_t iArgC, char* pArgV[]) {
+int32_t DecMain (int32_t iArgC, char* pArgV[]) {
#else
int32_t main (int32_t iArgC, char* pArgV[]) {
#endif
@@ -429,7 +429,8 @@
int32_t iHeight = 0;
- H264DecodeInstance (pDecoder, strInputFile.c_str(), !strOutputFile.empty() ? strOutputFile.c_str() : NULL, iWidth, iHeight,
+ H264DecodeInstance (pDecoder, strInputFile.c_str(), !strOutputFile.empty() ? strOutputFile.c_str() : NULL, iWidth,
+ iHeight,
(!strOptionFile.empty() ? strOptionFile.c_str() : NULL));
if (sDecParam.pFileNameRestructed != NULL) {
--- a/codec/decoder/core/src/manage_dec_ref.cpp
+++ b/codec/decoder/core/src/manage_dec_ref.cpp
@@ -57,6 +57,10 @@
static int32_t AddShortTermToList (PRefPic pRefPic, PPicture pPic);
static int32_t AddLongTermToList (PRefPic pRefPic, PPicture pPic, int32_t iLongTermFrameIdx);
static int32_t MarkAsLongTerm (PRefPic pRefPic, int32_t iFrameNum, int32_t iLongTermFrameIdx);
+#ifdef LONG_TERM_REF
+int32_t GetLTRFrameIndex (PRefPic pRefPic, int32_t iAncLTRFrameNum);
+#endif
+static int32_t RemainOneBufferInDpbForEC (PWelsDecoderContext pCtx);
static void SetUnRef (PPicture pRef) {
if (NULL != pRef) {
@@ -211,7 +215,6 @@
int32_t iRet = ERR_NONE;
- pCtx->pDec->bUsedAsRef = true;
pCtx->pDec->uiQualityId = pCtx->pCurDqLayer->sLayerInfo.sNalHeaderExt.uiQualityId;
pCtx->pDec->uiTemporalId = pCtx->pCurDqLayer->sLayerInfo.sNalHeaderExt.uiTemporalId;
@@ -232,8 +235,14 @@
} else {
if (pRefPicMarking->bAdaptiveRefPicMarkingModeFlag) {
iRet = MMCO (pCtx, pRefPicMarking);
- if (iRet != ERR_NONE)
- return iRet;
+ if (iRet != ERR_NONE) {
+ if (pCtx->iErrorConMethod != ERROR_CON_DISABLE) {
+ iRet = RemainOneBufferInDpbForEC (pCtx);
+ } else {
+ return iRet;
+ }
+ }
+
if (pCtx->bLastHasMmco5) {
pCtx->pDec->iFrameNum = 0;
pCtx->pDec->iFramePoc = 0;
@@ -241,14 +250,23 @@
} else {
iRet = SlidingWindow (pCtx);
- if (iRet != ERR_NONE)
- return iRet;
+ if (iRet != ERR_NONE) {
+ if (pCtx->iErrorConMethod != ERROR_CON_DISABLE) {
+ iRet = RemainOneBufferInDpbForEC (pCtx);
+ } else {
+ return iRet;
+ }
+ }
}
}
if (!pCtx->pDec->bIsLongRef) {
if (pRefPic->uiLongRefCount[LIST_0] + pRefPic->uiShortRefCount[LIST_0] >= WELS_MAX(1,pCtx->pSps->iNumRefFrames)) {
- return ERR_INFO_INVALID_MMCO_REF_NUM_OVERFLOW;
+ if (pCtx->iErrorConMethod != ERROR_CON_DISABLE) {
+ iRet = RemainOneBufferInDpbForEC (pCtx);
+ } else {
+ return ERR_INFO_INVALID_MMCO_REF_NUM_OVERFLOW;
+ }
}
AddShortTermToList (pRefPic, pCtx->pDec);
}
@@ -479,6 +497,53 @@
iRet = AddLongTermToList (pRefPic, pPic, iLongTermFrameIdx);
break;
}
+ }
+
+ return iRet;
+}
+
+#ifdef LONG_TERM_REF
+int32_t GetLTRFrameIndex (PRefPic pRefPic, int32_t iAncLTRFrameNum) {
+ int32_t iLTRFrameIndex = -1;
+ PPicture pPic;
+ for (int i = 0; i < pRefPic->uiLongRefCount[0]; ++i) {
+ pPic = pRefPic->pLongRefList[LIST_0][i];
+ if (pPic->iFrameNum == iAncLTRFrameNum) {
+ return (pPic->iLongTermFrameIdx);
+ }
+ }
+ return iLTRFrameIndex;
+}
+#endif
+
+static int32_t RemainOneBufferInDpbForEC (PWelsDecoderContext pCtx) {
+ int32_t iRet = ERR_NONE;
+ PRefPic pRefPic = &pCtx->sRefPic;
+ if (pRefPic->uiShortRefCount[0] + pRefPic->uiLongRefCount[0] < pCtx->pSps->iNumRefFrames)
+ return iRet;
+
+ if (pRefPic->uiShortRefCount[0] > 0) {
+ iRet = SlidingWindow (pCtx);
+ } else { //all LTR, remove the smallest long_term_frame_idx
+ uint32_t uiLongTermFrameIdx = 0;
+ uint32_t uiMaxLongTermFrameIdx = pRefPic->iMaxLongTermFrameIdx;
+#ifdef LONG_TERM_REF
+ uint32_t uiCurrLTRFrameIdx = GetLTRFrameIndex (pRefPic, pCtx->iFrameNumOfAuMarkedLtr);
+#endif
+ while ((pRefPic->uiLongRefCount[0] >= pCtx->pSps->iNumRefFrames) && (uiLongTermFrameIdx <= uiMaxLongTermFrameIdx)) {
+#ifdef LONG_TERM_REF
+ if (uiLongTermFrameIdx == uiCurrLTRFrameIdx) {
+ uiLongTermFrameIdx++;
+ continue;
+ }
+#endif
+ WelsDelLongFromListSetUnref (pRefPic, uiLongTermFrameIdx);
+ uiLongTermFrameIdx++;
+ }
+ }
+ if (pRefPic->uiShortRefCount[0] + pRefPic->uiLongRefCount[0] >= pCtx->pSps->iNumRefFrames) { //fail to remain one empty buffer in DPB
+ WelsLog (pCtx, WELS_LOG_WARNING, "RemainOneBufferInDpbForEC(): empty one DPB failed for EC!\n");
+ iRet = ERR_INFO_REF_COUNT_OVERFLOW;
}
return iRet;