예제 #1
0
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;
}
예제 #2
0
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;
}
예제 #3
0
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;
}
예제 #4
0
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;
}
예제 #5
0
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;
}
예제 #6
0
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;
}