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 int32_t iLongTermFrameIdx = 0; int32_t iMaxLongTermFrameIdx = pRefPic->iMaxLongTermFrameIdx; #ifdef LONG_TERM_REF int32_t iCurrLTRFrameIdx = GetLTRFrameIndex (pRefPic, pCtx->iFrameNumOfAuMarkedLtr); #endif while ((pRefPic->uiLongRefCount[0] >= pCtx->pSps->iNumRefFrames) && (iLongTermFrameIdx <= iMaxLongTermFrameIdx)) { #ifdef LONG_TERM_REF if (iLongTermFrameIdx == iCurrLTRFrameIdx) { iLongTermFrameIdx++; continue; } #endif WelsDelLongFromListSetUnref (pRefPic, iLongTermFrameIdx); iLongTermFrameIdx++; } } if (pRefPic->uiShortRefCount[0] + pRefPic->uiLongRefCount[0] >= pCtx->pSps->iNumRefFrames) { //fail to remain one empty buffer in DPB WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "RemainOneBufferInDpbForEC(): empty one DPB failed for EC!"); iRet = ERR_INFO_REF_COUNT_OVERFLOW; } 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,REMOVE_TARGET); WelsDelLongFromListSetUnref(pRefPic,iLongTermFrameIdx,REMOVE_BASE); 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); } } return iRet; }
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 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; }
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; }