Merge pull request #744 from huili2/ec_IdrLoss

enable the case for IDR loss
This commit is contained in:
Licai Guo 2014-04-24 16:47:36 +08:00
commit fe23d53acc
4 changed files with 44 additions and 17 deletions

View File

@ -134,11 +134,13 @@ inline void HandleReferenceLostL0 (PWelsDecoderContext pCtx, PNalUnit pCurNal
if (0 == pCurNal->sNalHeaderExt.uiTemporalId) {
pCtx->bReferenceLostAtT0Flag = true;
}
if (pCtx->iErrorConMethod == ERROR_CON_DISABLE) {
#ifndef LONG_TERM_REF
if (pCtx->bReferenceLostAtT0Flag) {
ResetParameterSetsState (pCtx);
}
if (pCtx->bReferenceLostAtT0Flag) {
ResetParameterSetsState (pCtx);
}
#endif
}
pCtx->iErrorCode |= dsBitstreamError;
}
@ -146,11 +148,13 @@ inline void HandleReferenceLost (PWelsDecoderContext pCtx, PNalUnit pCurNal)
if ((0 == pCurNal->sNalHeaderExt.uiTemporalId) || (1 == pCurNal->sNalHeaderExt.uiTemporalId)) {
pCtx->bReferenceLostAtT0Flag = true;
}
if (pCtx->iErrorConMethod == ERROR_CON_DISABLE) {
#ifndef LONG_TERM_REF
if (pCtx->bReferenceLostAtT0Flag) {
ResetParameterSetsState (pCtx);
}
if (pCtx->bReferenceLostAtT0Flag) {
ResetParameterSetsState (pCtx);
}
#endif
}
pCtx->iErrorCode |= dsRefLost;
}
@ -901,13 +905,15 @@ int32_t UpdateAccessUnit (PWelsDecoderContext pCtx) {
if (uiActualIdx ==
pCurAu->uiActualUnitsNum) { // no found IDR nal within incoming AU, need exit to avoid mosaic issue, 11/19/2009
WelsLog (pCtx, WELS_LOG_WARNING, "UpdateAccessUnit():::::Key frame lost.....CAN NOT find IDR from current AU.\n");
if (pCtx->iErrorCode == ERROR_CON_DISABLE) {
#ifdef LONG_TERM_REF
pCtx->iErrorCode |= dsNoParamSets;
return dsNoParamSets;
pCtx->iErrorCode |= dsNoParamSets;
return dsNoParamSets;
#else
pCtx->iErrorCode |= dsRefLost;
return ERR_INFO_REFERENCE_PIC_LOST;
pCtx->iErrorCode |= dsRefLost;
return ERR_INFO_REFERENCE_PIC_LOST;
#endif
}
}
}
@ -1580,9 +1586,8 @@ int32_t ConstructAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBufferI
pCtx->pSps = pCurAu->pNalUnitsList[pCurAu->uiStartPos]->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader.pSps;
pCtx->pPps = pCurAu->pNalUnitsList[pCurAu->uiStartPos]->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader.pPps;
//try to allocate or relocate DPB memory only when IDR arrival.
if (NAL_UNIT_CODED_SLICE_IDR == pCurAu->pNalUnitsList[pCurAu->uiStartPos]->sNalHeaderExt.sNalUnitHeader.eNalUnitType ||
pCurAu->pNalUnitsList[pCurAu->uiStartPos]->sNalHeaderExt.bIdrFlag) {
//try to allocate or relocate DPB memory only when new sequence is coming.
if (pCtx->bNewSeqBegin) {
WelsResetRefPic (pCtx); //clear ref pPic when IDR NAL
iErr = SyncPictureResolutionExt (pCtx, pCtx->pSps->iMbWidth, pCtx->pSps->iMbHeight);

View File

@ -109,6 +109,26 @@ void WelsResetRefPic (PWelsDecoderContext pCtx) {
*/
int32_t WelsInitRefList (PWelsDecoderContext pCtx, int32_t iPoc) {
int32_t i, iCount = 0;
if ((pCtx->bNewSeqBegin) && (pCtx->sRefPic.uiRefCount[LIST_0] <= 0) && (pCtx->eSliceType != I_SLICE && pCtx->eSliceType != SI_SLICE)) {
if (pCtx->iErrorConMethod != ERROR_CON_DISABLE) { //IDR lost!, recover it for future decoding with data all set to 0
PPicture pRef = PrefetchPic (pCtx->pPicBuff[0]);
if (pRef != NULL) {
memset (pRef->pData[0], 0, pRef->iLinesize[0] * pRef->iHeightInPixel);
memset (pRef->pData[1], 0, pRef->iLinesize[1] * pRef->iHeightInPixel / 2);
memset (pRef->pData[2], 0, pRef->iLinesize[2] * pRef->iHeightInPixel / 2);
pRef->iFrameNum = 0;
pRef->iFramePoc = 0;
pRef->uiTemporalId = pRef->uiQualityId = 0;
AddShortTermToList (&pCtx->sRefPic, pRef);
} else {
WelsLog (pCtx, WELS_LOG_ERROR, "WelsInitRefList()::PrefetchPic for EC errors.\n");
pCtx->iErrorCode |= dsOutOfMemory;
return ERR_INFO_REF_COUNT_OVERFLOW;
}
}
}
PPicture* ppShoreRefList = pCtx->sRefPic.pShortRefList[LIST_0];
PPicture* ppLongRefList = pCtx->sRefPic.pLongRefList[LIST_0];
memset (pCtx->sRefPic.pRefList[LIST_0], 0, MAX_REF_PIC_COUNT * sizeof (PPicture));

View File

@ -135,7 +135,7 @@ PPicture PrefetchPic (PPicBuff pPicBuf) {
pPicBuf->iCurrentIdx = iPicIdx;
return pPic;
}
for (iPicIdx = 0 ; iPicIdx < pPicBuf->iCurrentIdx ; ++iPicIdx) {
for (iPicIdx = 0 ; iPicIdx <= pPicBuf->iCurrentIdx ; ++iPicIdx) {
if (pPicBuf->ppPic[iPicIdx] != NULL && pPicBuf->ppPic[iPicIdx]->bAvailableFlag
&& !pPicBuf->ppPic[iPicIdx]->bUsedAsRef) {
pPic = pPicBuf->ppPic[iPicIdx];

View File

@ -373,12 +373,14 @@ DECODING_STATE CWelsDecoder::DecodeFrame2 (const unsigned char* kpSrc,
//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)) {
if (m_pDecContext->iErrorConMethod == ERROR_CON_DISABLE) {
#ifdef LONG_TERM_REF
m_pDecContext->bParamSetsLostFlag = true;
m_pDecContext->bParamSetsLostFlag = true;
#else
m_pDecContext->bReferenceLostAtT0Flag = true;
m_pDecContext->bReferenceLostAtT0Flag = true;
#endif
ResetParameterSetsState (m_pDecContext); //initial SPS&PPS ready flag
ResetParameterSetsState (m_pDecContext); //initial SPS&PPS ready flag
}
}
IWelsTrace::WelsVTrace (m_pTrace, IWelsTrace::WELS_LOG_INFO, "decode failed, failure type:%d \n",