static int32_t AssignLongTermIdx(PRefPic pRefPic,int32_t iFrameNum,int32_t iLongTermFrameIdx ) { PPicture pPic = NULL; int32_t iRet = ERR_NONE; WelsDelLongFromListSetUnref(pRefPic,iLongTermFrameIdx,REMOVE_TARGET); WelsDelLongFromListSetUnref(pRefPic,iLongTermFrameIdx,REMOVE_BASE); pPic = WelsDelShortFromList(pRefPic,iFrameNum,REMOVE_TARGET); if (pPic){ iRet = AddLongTermToList(pRefPic,pPic,iLongTermFrameIdx); }else{ return ERR_INFO_INVALID_REF_MARKING; } pPic = NULL; pPic = WelsDelShortFromList(pRefPic,iFrameNum,REMOVE_BASE); if (pPic){ iRet = AddLongTermToList(pRefPic,pPic,iLongTermFrameIdx); } return iRet; }
static int32_t MarkAsLongTerm (PRefPic pRefPic, int32_t iFrameNum, int32_t iLongTermFrameIdx) { PPicture pPic = NULL; int32_t i = 0; int32_t iRet = ERR_NONE; WelsDelLongFromListSetUnref (pRefPic, iLongTermFrameIdx); for (i = 0; i < pRefPic->uiRefCount[LIST_0]; i++) { pPic = pRefPic->pRefList[LIST_0][i]; if (pPic->iFrameNum == iFrameNum && !pPic->bIsLongRef) { iRet = AddLongTermToList (pRefPic, pPic, iLongTermFrameIdx); break; } } return iRet; }
static int32_t MMCOProcess (PWelsDecoderContext pCtx, uint32_t uiMmcoType, int32_t iShortFrameNum, uint32_t uiLongTermPicNum , int32_t iLongTermFrameIdx, int32_t iMaxLongTermFrameIdx) { PRefPic pRefPic = &pCtx->sRefPic; PPicture pPic = NULL; int32_t i = 0; int32_t iRet = ERR_NONE; switch (uiMmcoType) { case MMCO_SHORT2UNUSED: pPic = WelsDelShortFromListSetUnref (pRefPic, iShortFrameNum); if (pPic == NULL) { WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "MMCO_SHORT2UNUSED: delete a empty entry from short term list"); } break; case MMCO_LONG2UNUSED: pPic = WelsDelLongFromListSetUnref (pRefPic, uiLongTermPicNum); if (pPic == NULL) { WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "MMCO_LONG2UNUSED: delete a empty entry from long term list"); } break; case MMCO_SHORT2LONG: if (iLongTermFrameIdx > pRefPic->iMaxLongTermFrameIdx) { return ERR_INFO_INVALID_MMCO_LONG_TERM_IDX_EXCEED_MAX; } pPic = WelsDelShortFromList (pRefPic, iShortFrameNum); if (pPic == NULL) { WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "MMCO_LONG2LONG: delete a empty entry from short term list"); break; } WelsDelLongFromListSetUnref (pRefPic, iLongTermFrameIdx); #ifdef LONG_TERM_REF pCtx->bCurAuContainLtrMarkSeFlag = true; pCtx->iFrameNumOfAuMarkedLtr = iShortFrameNum; WelsLog (& (pCtx->sLogCtx), WELS_LOG_INFO, "ex_mark_avc():::MMCO_SHORT2LONG:::LTR marking....iFrameNum: %d", pCtx->iFrameNumOfAuMarkedLtr); #endif MarkAsLongTerm (pRefPic, iShortFrameNum, iLongTermFrameIdx); break; case MMCO_SET_MAX_LONG: pRefPic->iMaxLongTermFrameIdx = iMaxLongTermFrameIdx; for (i = 0 ; i < pRefPic->uiLongRefCount[LIST_0]; i++) { if (pRefPic->pLongRefList[LIST_0][i]->iLongTermFrameIdx > pRefPic->iMaxLongTermFrameIdx) { WelsDelLongFromListSetUnref (pRefPic, pRefPic->pLongRefList[LIST_0][i]->iLongTermFrameIdx); } } break; case MMCO_RESET: WelsResetRefPic (pCtx); pCtx->bLastHasMmco5 = true; break; case MMCO_LONG: if (iLongTermFrameIdx > pRefPic->iMaxLongTermFrameIdx) { return ERR_INFO_INVALID_MMCO_LONG_TERM_IDX_EXCEED_MAX; } WelsDelLongFromListSetUnref (pRefPic, iLongTermFrameIdx); if (pRefPic->uiLongRefCount[LIST_0] + pRefPic->uiShortRefCount[LIST_0] >= WELS_MAX (1, pCtx->pSps->iNumRefFrames)) { return ERR_INFO_INVALID_MMCO_REF_NUM_OVERFLOW; } #ifdef LONG_TERM_REF pCtx->bCurAuContainLtrMarkSeFlag = true; pCtx->iFrameNumOfAuMarkedLtr = pCtx->iFrameNum; WelsLog (& (pCtx->sLogCtx), WELS_LOG_INFO, "ex_mark_avc():::MMCO_LONG:::LTR marking....iFrameNum: %d", pCtx->iFrameNum); #endif iRet = AddLongTermToList (pRefPic, pCtx->pDec, iLongTermFrameIdx); break; default : break; } return iRet; }
int32_t WelsMarkAsRef (PWelsDecoderContext pCtx) { PRefPic pRefPic = &pCtx->sRefPic; PRefPicMarking pRefPicMarking = pCtx->pCurDqLayer->pRefPicMarking; PAccessUnit pCurAU = pCtx->pAccessUnitList; bool bIsIDRAU = false; uint32_t j; int32_t iRet = ERR_NONE; pCtx->pDec->uiQualityId = pCtx->pCurDqLayer->sLayerInfo.sNalHeaderExt.uiQualityId; pCtx->pDec->uiTemporalId = pCtx->pCurDqLayer->sLayerInfo.sNalHeaderExt.uiTemporalId; pCtx->pDec->iSpsId = pCtx->pSps->iSpsId; pCtx->pDec->iPpsId = pCtx->pPps->iPpsId; for (j = pCurAU->uiStartPos; j <= pCurAU->uiEndPos; j++) { if (pCurAU->pNalUnitsList[j]->sNalHeaderExt.sNalUnitHeader.eNalUnitType == NAL_UNIT_CODED_SLICE_IDR || pCurAU->pNalUnitsList[j]->sNalHeaderExt.bIdrFlag) { bIsIDRAU = true; break; } } if (bIsIDRAU) { if (pRefPicMarking->bLongTermRefFlag) { pCtx->sRefPic.iMaxLongTermFrameIdx = 0; AddLongTermToList (pRefPic, pCtx->pDec, 0); } else { pCtx->sRefPic.iMaxLongTermFrameIdx = -1; } } else { if (pRefPicMarking->bAdaptiveRefPicMarkingModeFlag) { iRet = MMCO (pCtx, pRefPicMarking); if (iRet != ERR_NONE) { if (pCtx->eErrorConMethod != ERROR_CON_DISABLE) { iRet = RemainOneBufferInDpbForEC (pCtx); WELS_VERIFY_RETURN_IF (iRet, iRet); } else { return iRet; } } if (pCtx->bLastHasMmco5) { pCtx->pDec->iFrameNum = 0; pCtx->pDec->iFramePoc = 0; } } else { iRet = SlidingWindow (pCtx); if (iRet != ERR_NONE) { if (pCtx->eErrorConMethod != ERROR_CON_DISABLE) { iRet = RemainOneBufferInDpbForEC (pCtx); WELS_VERIFY_RETURN_IF (iRet, iRet); } else { return iRet; } } } } if (!pCtx->pDec->bIsLongRef) { if (pRefPic->uiLongRefCount[LIST_0] + pRefPic->uiShortRefCount[LIST_0] >= WELS_MAX (1, pCtx->pSps->iNumRefFrames)) { if (pCtx->eErrorConMethod != ERROR_CON_DISABLE) { iRet = RemainOneBufferInDpbForEC (pCtx); WELS_VERIFY_RETURN_IF (iRet, iRet); } else { return ERR_INFO_INVALID_MMCO_REF_NUM_OVERFLOW; } } iRet = AddShortTermToList (pRefPic, pCtx->pDec); } return iRet; }
static int32_t MMCOProcess( PWelsDecoderContext pCtx,uint32_t uiMmcoType,bool_t bRefBasePic, int32_t iShortFrameNum,uint32_t uiLongTermPicNum ,int32_t iLongTermFrameIdx,int32_t iMaxLongTermFrameIdx ) { PRefPic pRefPic = &pCtx->sRefPic; PPicture pPic = NULL; int32_t i = 0; int32_t iRet = ERR_NONE; switch (uiMmcoType) { case MMCO_SHORT2UNUSED: pPic = WelsDelShortFromListSetUnref(pRefPic,iShortFrameNum,(ERemoveFlag) bRefBasePic); break; case MMCO_LONG2UNUSED: pPic = WelsDelLongFromListSetUnref(pRefPic,uiLongTermPicNum,(ERemoveFlag) bRefBasePic); break; case MMCO_SHORT2LONG: if(iLongTermFrameIdx > pRefPic->iMaxLongTermFrameIdx){ return ERR_INFO_INVALID_MMCO_LONG_TERM_IDX_EXCEED_MAX; } pPic = WelsDelShortFromList(pRefPic,iShortFrameNum,REMOVE_TARGET); WelsDelLongFromListSetUnref(pRefPic,iLongTermFrameIdx,REMOVE_TARGET); WelsDelShortFromList(pRefPic,iShortFrameNum,REMOVE_BASE); WelsDelLongFromListSetUnref(pRefPic,iLongTermFrameIdx,REMOVE_BASE); #ifdef LONG_TERM_REF pCtx->bCurAuContainLtrMarkSeFlag = true; pCtx->iFrameNumOfAuMarkedLtr = iShortFrameNum; WelsLog( pCtx, WELS_LOG_INFO, "ex_mark_avc():::MMCO_SHORT2LONG:::LTR marking....iFrameNum: %d\n", pCtx->iFrameNumOfAuMarkedLtr ); #endif MarkAsLongTerm(pRefPic,iShortFrameNum,iLongTermFrameIdx); break; case MMCO_SET_MAX_LONG: pRefPic->iMaxLongTermFrameIdx = iMaxLongTermFrameIdx; for (i = 0 ;i <pRefPic->uiLongRefCount[LIST_0];i++) { if (pRefPic->pLongRefList[LIST_0][i]->iLongTermFrameIdx > pRefPic->iMaxLongTermFrameIdx) { WelsDelLongFromListSetUnref(pRefPic,pRefPic->pLongRefList[LIST_0][i]->iLongTermFrameIdx,REMOVE_BASE_FIRST); } } break; case MMCO_RESET: WelsResetRefPic(pCtx); pCtx->bLastHasMmco5 = true; break; case MMCO_LONG: if(iLongTermFrameIdx > pRefPic->iMaxLongTermFrameIdx){ return ERR_INFO_INVALID_MMCO_LONG_TERM_IDX_EXCEED_MAX; } #ifdef LONG_TERM_REF pCtx->bCurAuContainLtrMarkSeFlag = true; pCtx->iFrameNumOfAuMarkedLtr = pCtx->iFrameNum; WelsLog( pCtx, WELS_LOG_INFO, "ex_mark_avc():::MMCO_LONG:::LTR marking....iFrameNum: %d\n", pCtx->iFrameNum ); #endif WelsDelLongFromListSetUnref(pRefPic,iLongTermFrameIdx,REMOVE_TARGET); WelsDelLongFromListSetUnref(pRefPic,iLongTermFrameIdx,REMOVE_BASE); iRet = AddLongTermToList(pRefPic,pCtx->pDec,iLongTermFrameIdx); break; default : break; } return iRet; }
int32_t WelsMarkAsRef(PWelsDecoderContext pCtx, const bool_t kbRefBaseMarkingFlag) { PRefPic pRefPic = &pCtx->sRefPic; PRefPicMarking pRefPicMarking = pCtx->pCurDqLayer->pRefPicMarking; PRefBasePicMarking pRefPicBaseMarking =pCtx->pCurDqLayer->pRefPicBaseMarking; PAccessUnit pCurAU = pCtx->pAccessUnitList; bool_t bIsIDRAU = FALSE; uint32_t j; int32_t iRet = ERR_NONE; if(pCtx->pCurDqLayer->bStoreRefBasePicFlag && (pCtx->pSps->iNumRefFrames<2)){ return ERR_INFO_INVALID_MMCO_REF_NUM_NOT_ENOUGH; } pCtx->pDec->bUsedAsRef = TRUE; pCtx->pDec->uiQualityId = pCtx->pCurDqLayer->sLayerInfo.sNalHeaderExt.uiQualityId; pCtx->pDec->uiTemporalId = pCtx->pCurDqLayer->sLayerInfo.sNalHeaderExt.uiTemporalId; pCtx->pDec->bRefBaseFlag = kbRefBaseMarkingFlag; for( j = pCurAU->uiStartPos; j <= pCurAU->uiEndPos; j++ ) { if (pCurAU->pNalUnitsList[j]->sNalHeaderExt.sNalUnitHeader.eNalUnitType== NAL_UNIT_CODED_SLICE_IDR|| pCurAU->pNalUnitsList[j]->sNalHeaderExt.bIdrFlag) { bIsIDRAU = TRUE; break; } } if(bIsIDRAU){ if (pRefPicMarking->bLongTermRefFlag){ pCtx->sRefPic.iMaxLongTermFrameIdx = 0; AddLongTermToList(pRefPic,pCtx->pDec,0); }else{ pCtx->sRefPic.iMaxLongTermFrameIdx = -1; } }else{ if (pRefPicBaseMarking->bAdaptiveRefBasePicMarkingModeFlag){ iRet = MMCOBase(pCtx,pRefPicBaseMarking); } if (iRet != ERR_NONE){ return iRet; } if (pRefPicMarking->bAdaptiveRefPicMarkingModeFlag){ iRet = MMCO(pCtx,pRefPicMarking); if( pCtx->bLastHasMmco5 ) { pCtx->pDec->iFrameNum = 0; pCtx->pDec->iFramePoc = 0; } if (pRefPic->uiLongRefCount[LIST_0]+pRefPic->uiShortRefCount[LIST_0] > pCtx->pSps->iNumRefFrames){ return ERR_INFO_INVALID_MMCO_REF_NUM_OVERFLOW; } }else{ iRet = SlidingWindow(pCtx); } } if (!pCtx->pDec->bIsLongRef){ AddShortTermToList(pRefPic,pCtx->pDec); } return iRet; }