/** * fills the pRefPic.pRefList. */ int32_t WelsInitRefList (PWelsDecoderContext pCtx, int32_t iPoc) { int32_t i, iCount = 0; if ((pCtx->sRefPic.uiShortRefCount[LIST_0] + pCtx->sRefPic.uiLongRefCount[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)); //short for (i = 0; i < pCtx->sRefPic.uiShortRefCount[LIST_0]; ++i) { pCtx->sRefPic.pRefList[LIST_0][iCount++ ] = ppShoreRefList[i]; } //long for (i = 0; i < pCtx->sRefPic.uiLongRefCount[LIST_0] ; ++i) { pCtx->sRefPic.pRefList[LIST_0][iCount++ ] = ppLongRefList[i]; } pCtx->sRefPic.uiRefCount[LIST_0] = iCount; return ERR_NONE; }
/** * fills the pRefPic.pRefList. */ int32_t WelsInitRefList (PWelsDecoderContext pCtx, int32_t iPoc) { int32_t i, iCount = 0; if ((pCtx->sRefPic.uiShortRefCount[LIST_0] + pCtx->sRefPic.uiLongRefCount[LIST_0] <= 0) && (pCtx->eSliceType != I_SLICE && pCtx->eSliceType != SI_SLICE)) { if (pCtx->eErrorConMethod != 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) { // IDR lost, set new pRef->bIsComplete = false; // Set complete flag to false for lost IDR ref picture pRef->iSpsId = pCtx->pSps->iSpsId; pRef->iPpsId = pCtx->pPps->iPpsId; pCtx->iErrorCode |= dsDataErrorConcealed; bool bCopyPrevious = ((ERROR_CON_FRAME_COPY_CROSS_IDR == pCtx->eErrorConMethod) || (ERROR_CON_SLICE_COPY_CROSS_IDR == pCtx->eErrorConMethod) || (ERROR_CON_SLICE_COPY_CROSS_IDR_FREEZE_RES_CHANGE == pCtx->eErrorConMethod) || (ERROR_CON_SLICE_MV_COPY_CROSS_IDR == pCtx->eErrorConMethod) || (ERROR_CON_SLICE_MV_COPY_CROSS_IDR_FREEZE_RES_CHANGE == pCtx->eErrorConMethod)) && (NULL != pCtx->pPreviousDecodedPictureInDpb); bCopyPrevious = bCopyPrevious && (pRef->iWidthInPixel == pCtx->pPreviousDecodedPictureInDpb->iWidthInPixel) && (pRef->iHeightInPixel == pCtx->pPreviousDecodedPictureInDpb->iHeightInPixel); if (!bCopyPrevious) { memset (pRef->pData[0], 128, pRef->iLinesize[0] * pRef->iHeightInPixel); memset (pRef->pData[1], 128, pRef->iLinesize[1] * pRef->iHeightInPixel / 2); memset (pRef->pData[2], 128, pRef->iLinesize[2] * pRef->iHeightInPixel / 2); } else if (pRef == pCtx->pPreviousDecodedPictureInDpb) { WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "WelsInitRefList()::EC memcpy overlap."); } else { memcpy (pRef->pData[0], pCtx->pPreviousDecodedPictureInDpb->pData[0], pRef->iLinesize[0] * pRef->iHeightInPixel); memcpy (pRef->pData[1], pCtx->pPreviousDecodedPictureInDpb->pData[1], pRef->iLinesize[1] * pRef->iHeightInPixel / 2); memcpy (pRef->pData[2], pCtx->pPreviousDecodedPictureInDpb->pData[2], pRef->iLinesize[2] * pRef->iHeightInPixel / 2); } pRef->iFrameNum = 0; pRef->iFramePoc = 0; pRef->uiTemporalId = pRef->uiQualityId = 0; ExpandReferencingPicture (pRef->pData, pRef->iWidthInPixel, pRef->iHeightInPixel, pRef->iLinesize, pCtx->sExpandPicFunc.pfExpandLumaPicture, pCtx->sExpandPicFunc.pfExpandChromaPicture); AddShortTermToList (&pCtx->sRefPic, pRef); } else { WelsLog (& (pCtx->sLogCtx), WELS_LOG_ERROR, "WelsInitRefList()::PrefetchPic for EC errors."); 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_DPB_COUNT * sizeof (PPicture)); //short for (i = 0; i < pCtx->sRefPic.uiShortRefCount[LIST_0]; ++i) { pCtx->sRefPic.pRefList[LIST_0][iCount++ ] = ppShoreRefList[i]; } //long for (i = 0; i < pCtx->sRefPic.uiLongRefCount[LIST_0] ; ++i) { pCtx->sRefPic.pRefList[LIST_0][iCount++ ] = ppLongRefList[i]; } pCtx->sRefPic.uiRefCount[LIST_0] = iCount; return ERR_NONE; }