VTM3.0代码阅读:xPredAffineInterSearch函数

xPredAffineInterSearch函数在predInterSearch函数中被调用,用来计算Affine_ME模式,进行4参数和6参数Affine_ME模式的计算。函数流程和普通的interME的函数流程很像,即和predInterSearch函数流程很相似:初始化、单向、双向、数据存储。函数中调用xEstimateAffineAMVP函数,得到AffineME模式的各控制点的CPM...
摘要由CSDN通过智能技术生成

xPredAffineInterSearch函数在predInterSearch函数中被调用,用来计算Affine_ME模式,进行4参数和6参数Affine_ME模式的计算。
函数流程和普通的interME的函数流程很像,即和predInterSearch函数流程很相似:初始化、单向、双向、数据存储。

函数中调用xEstimateAffineAMVP函数,得到AffineME模式的各控制点的CPMVP。
函数中调用xAffineMotionEstimation函数,由xEstimateAffineAMVP得到的CPMVP,进行Affine_ME,得到AffineME模式的MV。

xEstimateAffineAMVP函数xAffineMotionEstimation函数,这两个函数以后要细看

void InterSearch::xPredAffineInterSearch( PredictionUnit&       pu,
                                          PelUnitBuf&           origBuf,
                                          int                   puIdx,
                                          uint32_t&             lastMode,
                                          Distortion&           affineCost,
                                          Mv                    hevcMv[2][33]
                                        , Mv                    mvAffine4Para[2][33][3]
                                        , int                   refIdx4Para[2]
#if JVET_L0646_GBI 
                                        , uint8_t               gbiIdx
                                        , bool                  enforceGBiPred
                                        , uint32_t              gbiIdxBits
#endif
                                         )
{
   
  const Slice &slice = *pu.cu->slice;

  affineCost = std::numeric_limits<Distortion>::max();

  Mv        cMvZero;
  Mv        aacMv[2][3];
  Mv        cMvBi[2][3];
  Mv        cMvTemp[2][33][3];

  int       iNumPredDir = slice.isInterP() ? 1 : 2;

  int mvNum = 2;
  mvNum = pu.cu->affineType ? 3 : 2;		//3控制点、2控制点

  // Mvp
  Mv        cMvPred[2][33][3];
  Mv        cMvPredBi[2][33][3];
  int       aaiMvpIdxBi[2][33];
  int       aaiMvpIdx[2][33];
  int       aaiMvpNum[2][33];

  AffineAMVPInfo aacAffineAMVPInfo[2][33];
  AffineAMVPInfo affiAMVPInfoTemp[2];

  int           iRefIdx[2]={
   0,0}; // If un-initialized, may cause SEGV in bi-directional prediction iterative stage.
  int           iRefIdxBi[2];

  uint32_t          uiMbBits[3] = {
   1, 1, 0};

  int           iRefStart, iRefEnd;

  PartSize      ePartSize = pu.cu->partSize;

  int           bestBiPRefIdxL1 = 0;
  int           bestBiPMvpL1 = 0;
  Distortion	biPDistTemp = std::numeric_limits<Distortion>::max();

  Distortion    uiCost[2] = {
    std::numeric_limits<Distortion>::max(), std::numeric_limits<Distortion>::max() };
  Distortion    uiCostBi  = std::numeric_limits<Distortion>::max();
  Distortion    uiCostTemp;

  uint32_t      uiBits[3];
  uint32_t      uiBitsTemp;
  Distortion    bestBiPDist = std::numeric_limits<Distortion>::max();

  Distortion    uiCostTempL0[MAX_NUM_REF];
  for (int iNumRef=0; iNumRef < MAX_NUM_REF; iNumRef++)
  {
   
    uiCostTempL0[iNumRef] = std::numeric_limits<Distortion>::max();
  }
  uint32_t uiBitsTempL0[MAX_NUM_REF];

  Mv            mvValidList1[4];
  int           refIdxValidList1 = 0;
  uint32_t      bitsValidList1 = MAX_UINT;
  Distortion	costValidList1 = std::numeric_limits<Distortion>::max();
  Mv            mvHevc[3];

  xGetBlkBits( ePartSize, slice.isInterP(), puIdx, lastMode, uiMbBits);

  pu.cu->affine = true;
  pu.mergeFlag = false;

#if JVET_L0646_GBI
  if( gbiIdx != GBI_DEFAULT )
  {
   
    pu.cu->GBiIdx = gbiIdx;
  }
#endif

  // Uni-directional prediction				//单向预测
  for ( int iRefList = 0; iRefList < iNumPredDir; iRefList++ )
  {
   
    RefPicList  eRefPicList = ( iRefList ? REF_PIC_LIST_1 : REF_PIC_LIST_0 );
#if JVET_L0293_CPR
    int refPicNumber = slice.getNumRefIdx(eRefPicList);
    if (slice.getSPS()->getSpsNext().getCPRMode() && eRefPicList == REF_PIC_LIST_0)
    {
   
      refPicNumber--;
    }
    for (int iRefIdxTemp = 0; iRefIdxTemp < refPicNumber; iRefIdxTemp++)	//对L0、L1中的所有参考帧loop
#else
    for ( int iRefIdxTemp = 0; iRefIdxTemp < slice.getNumRefIdx(eRefPicList); iRefIdxTemp++ )
#endif
    {
   
      // Get RefIdx bits
      uiBitsTemp = uiMbBits[iRefList];
      if ( slice.getNumRefIdx(eRefPicList) > 1 )
      {
   
        uiBitsTemp += iRefIdxTemp+1;
        if ( iRefIdxTemp == slice.getNumRefIdx(eRefPicList)-1 )
        {
   
          uiBitsTemp--;
        }
      }

      // Do Affine AMVP				//xEstimateAffineAMVP	得到CPMVP
      xEstimateAffineAMVP( pu, affiAMVPInfoTemp[eRefPicList], origBuf, eRefPicList, iRefIdxTemp, cMvPred[iRefList][iRefIdxTemp], &biPDistTemp );
      aaiMvpIdx[iRefList][iRefIdxTemp] = pu.mvpIdx[eRefPicList];
      aaiMvpNum[iRefList][iRefIdxTemp] = pu.mvpNum[eRefPicList];;
      if ( pu.cu->affineType == AFFINEMODEL_6PARAM && refIdx4Para[iRefList] != iRefIdxTemp )
      {
   
        xCopyAffineAMVPInfo( affiAMVPInfoTemp[eRefPicList], aacAffineAMVPInfo[iRefList][iRefIdxTemp] );
        continue;
      }

      // set hevc ME result as start search position when it is best than mvp
      for ( int i=0; i<3; i++ )
      {
   
        mvHevc[i] = hevcMv[iRefList][iRefIdxTemp];	//这里先计算一下以hevcMv为3个控制点mv得到的cost。类似L1002中所说的平移mv
      }
      PelUnitBuf predBuf = m_tmpStorageLCU.getBuf( UnitAreaRelative(*pu.cu, pu) );
													// xGetAffineTemplateCost	得到AffineAMVP的失真,mvHevc的失真
      Distortion uiCandCost = xGetAffineTemplateCost(pu, origBuf, predBuf, mvHevc, aaiMvpIdx[iRefList][iRefIdxTemp],
                                                     AMVP_MAX_NUM_CANDS, eRefPicList, iRefIdxTemp);
#if JVET_L0260_AFFINE_ME
      if (pu.cu->affineType == AFFINEMODEL_4PARAM && m_affMVListSize
#if JVET_L0646_GBI
        && (!pu.cu->cs->sps->getSpsNext().getUseGBi() || gbiIdx == GBI_DEFAULT)
#endif        
        )											//4参数模型
      {
   
        int shift = MAX_CU_DEPTH;
        for (int i = 0; i < m_affMVListSize; i++)	//这里需要看看m_affMVList的构成过程
        {
   
          AffineMVInfo *mvInfo = m_affMVList + ((m_affMVListIdx - i - 1 + m_affMVListMaxSize) % (m_affMVListMaxSize));
          //check;
          int j = 0;
          for (; j < i; j++)
          {
   
            AffineMVInfo *prevMvInfo = m_affMVList + ((m_affMVListIdx - j - 1 + m_affMVListMaxSize) % (m_affMVListMaxSize));
            if ((mvInfo->affMVs[iRefList][iRefIdxTemp][0] == prevMvInfo->affMVs[iRefList][iRefIdxTemp][0]) &&
              (mvInfo->affMVs[iRefList][iRefIdxTemp][1] == prevMvInfo->affMVs[iRefList][iRefIdxTemp][1])
              && (mvInfo->x == prevMvInfo->x) && (mvInfo->y == prevMvInfo->y)
              && (mvInfo->w == prevMvInfo->w)
              )
            {
   
              break;
            }
          }
          if (j < i)
            continue;

          Mv mvTmp[3], *nbMv = mvInfo->affMVs[iRefList][iRefIdxTemp];	//以下的处理得到一组CPMVP,即mvTmp[3]
          int vx, vy;
          int dMvHorX, dMvHorY, dMvVerX, dMvVerY;
          int mvScaleHor = nbMv[0].getHor() << shift;
          int mvScaleVer = nbMv[0].getVer() << shift;
          Mv dMv = nbMv[1] - nbMv[0];
#if REMOVE_MV_ADAPT_PREC
          mvScaleHor <<= VCEG_AZ07_MV_ADD_PRECISION_BIT_FO
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值