add DPB management if frame loss happens
This commit is contained in:
parent
1b1654e9c6
commit
d031509474
@ -174,8 +174,8 @@ void H264DecodeInstance (ISVCDecoder* pDecoder, const char* kpH264FileName, cons
|
||||
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 @@ label_exit:
|
||||
}
|
||||
|
||||
#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 main (int32_t iArgC, char* pArgV[]) {
|
||||
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) {
|
||||
|
@ -57,6 +57,10 @@ static int32_t SlidingWindow (PWelsDecoderContext pCtx);
|
||||
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 WelsMarkAsRef (PWelsDecoderContext pCtx) {
|
||||
|
||||
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 @@ int32_t WelsMarkAsRef (PWelsDecoderContext pCtx) {
|
||||
} 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 @@ int32_t WelsMarkAsRef (PWelsDecoderContext pCtx) {
|
||||
|
||||
} 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);
|
||||
}
|
||||
@ -484,4 +502,51 @@ static int32_t MarkAsLongTerm (PRefPic pRefPic, int32_t iFrameNum, int32_t iLong
|
||||
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;
|
||||
}
|
||||
|
||||
} // namespace WelsDec
|
||||
|
Loading…
x
Reference in New Issue
Block a user