HTM-16.2代码(5)——predInterSearch

predInterSearch是视频编码中的关键步骤,涉及运动估计ME和运动补偿MC。它遍历所有参考帧,进行ME计算,如xEstimateMvPredAMVP和xMotionEstimation,然后通过MC选择最优参数。对于B帧,可能涉及list0和list1两个参考图像列表。函数还处理不同CU和PU的运动信息计算,包括AMVPInfo和TComMv,并调用motionCompensation进行实际的运动补偿操作。
摘要由CSDN通过智能技术生成

predInterSearch主要的工作是ME(运动估计)和MC(运动补偿)。
函数中有一个bTestNormalMC变量,它表示是否进行正常的MC过程,正常的MC过程就是进行ME再进行MC。
正常的MC流程是,遍历所有的参考帧,进行ME(运动估计:xEstimateMvPredAMVP和xMotionEstimation),然后记录AVP或者MV的信息,进行MC(运动补偿,目的是选出最优的参数),然后更新最优的参数,遍历完所有的参考帧之后,就选出了最优的参数了;然后循环结束,接着进行正式的MC(运动补偿)。
TEncSearch::predInterSearch的详解:
(1)定义若干变量,注意AMVPInfo和TComMv等信息,它保存者运动信息
(2)遍历当前CU被分成的若干个PU
1)一个帧最多可以参考16个其他的帧
2)调用xGetBlkBits,计算CU在ePartSize模式下所需要消耗的比特数
3)计算当前PU的索引和大小
4)遍历两个参考图像列表(list0和list1)
a)遍历当前帧的所有参考帧:
①调用xEstimateMvPredAMVP,进行MV预测和AMVP的计算
②记录这个参考帧计算出来的MVP索引,数量等信息
③更新最优的参数
④计算比特数
⑤如果使用了list1(即B帧)
Ⅰ)如果list0和list1之间有映射(即这个帧同时出现在list0和list1中),那么直接把在list0中的计算信息复制过来就行了。
Ⅱ)如果没有映射,那么调用xMotionEstimation进行运动估计。
⑥如果对于使用list0的帧(P帧和B帧),调用xMotionEstimation进行运动估计。
⑦复制AMVP信息
⑧选择最优的MVP
⑨设置各种计算出来的运动信息
5)如果当前帧是B帧
a)并且list1是空的(getMvdL1ZeroFlag标志为真),那么调用motionCompensation进行运动补偿运算
b)对当前CU的4个子CU进行遍历计算:
①如果是第一个子CU,并且getMvdL1ZeroFlag为false,那么调用motionCompensation进行运动补偿计算
②遍历当前帧的所有参考帧:
Ⅰ)调用xMotionEstimation,进行运动估计
Ⅱ)调用xCopyAMVPInfo复制AMVP信息,调用xCheckBestMVP选择最好的MVP
Ⅲ)如果找到了更优的方式,那么更新信息,并且如果不是第一个子CU的话,还需要调用motionCompensation进行运动补偿
③如果没有选择出更优的代价,那么复制AMVP信息,选择最优的MVP等
6)设置各种MV的信息
7)同样,还是设置各种MVP以及MV的信息
8)对于分割类型不是2Nx2N(即当前CU没有划分)
a)调用xGetInterPredictionError进行运动补偿(该函数内部实质是调用motionCompensation)
b)调用xMergeEstimation,合并估计信息
9)调用motionCompensation进行运动补偿计算
(3)调用setWpScalingDistParam,设置wp(加权预测)参数

//! search of the best candidate for inter prediction
#if AMP_MRG
#if  NH_3D_FAST_TEXTURE_ENCODING
Void TEncSearch::predInterSearch( TComDataCU* pcCU, TComYuv* pcOrgYuv, TComYuv* pcPredYuv, TComYuv* pcResiYuv, TComYuv* pcRecoYuv DEBUG_STRING_FN_DECLARE(sDebug), Bool bFMD, Bool bUseRes, Bool bUseMRG )
#else
Void TEncSearch::predInterSearch( TComDataCU* pcCU, TComYuv* pcOrgYuv, TComYuv* pcPredYuv, TComYuv* pcResiYuv, TComYuv* pcRecoYuv DEBUG_STRING_FN_DECLARE(sDebug), Bool bUseRes, Bool bUseMRG )
#endif
#else
Void TEncSearch::predInterSearch( TComDataCU* pcCU, TComYuv* pcOrgYuv, TComYuv* pcPredYuv, TComYuv* pcResiYuv, TComYuv* pcRecoYuv, Bool bUseRes )
#endif
{

#if NH_MV
  D_PRINT_INC_INDENT(g_traceModeCheck,  "predInterSearch");
#endif

  for(UInt i=0; i<NUM_REF_PIC_LIST_01; i++)
  {
    m_acYuvPred[i].clear();
  }
  m_cYuvPredTemp.clear();
  pcPredYuv->clear();

  if ( !bUseRes )
  {
    pcResiYuv->clear();
  }

  pcRecoYuv->clear();

  TComMv       cMvSrchRngLT;
  TComMv       cMvSrchRngRB;

  TComMv       cMvZero;
  TComMv       TempMv; //kolya

  TComMv       cMv[2];
  TComMv       cMvBi[2];
  TComMv       cMvTemp[2][33];

  Int          iNumPart    = pcCU->getNumPartitions();//PU的个数
  Int          iNumPredDir = pcCU->getSlice()->isInterP() ? 1 : 2;//预测的方向的个数(B帧有两个,前向和后向;P帧有一个,前向)

  TComMv       cMvPred[2][33];// 记录了每一个前向参考帧的MV

  TComMv       cMvPredBi[2][33];// 记录了每一个后向参考帧的MV
  Int          aaiMvpIdxBi[2][33];// 记录了每一个后向参考帧的MVP的索引

  Int          aaiMvpIdx[2][33];// 记录了每一个前向参考帧的MVP的索引
  Int          aaiMvpNum[2][33];// 记录了每一个帧的MVP的数量

  AMVPInfo     aacAMVPInfo[2][33];// 记录每一个帧的MVP的信息

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

  UInt         uiPartAddr;
  Int          iRoiWidth, iRoiHeight;

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

  UInt         uiLastMode = 0;
  Int          iRefStart, iRefEnd;

  PartSize     ePartSize = pcCU->getPartitionSize( 0 );

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

#if NH_3D_IV_MERGE
  TComMvField cMvFieldNeighbours[MRG_MAX_NUM_CANDS_MEM << 1]; // double length for mv of both lists
  UChar uhInterDirNeighbours[MRG_MAX_NUM_CANDS_MEM];
#else
  TComMvField cMvFieldNeighbours[MRG_MAX_NUM_CANDS << 1]; // double length for mv of both lists
  UChar uhInterDirNeighbours[MRG_MAX_NUM_CANDS];
#endif

  Int numValidMergeCand = 0 ;

  for ( Int iPartIdx = 0; iPartIdx < iNumPart; iPartIdx++ )// 遍历当前块被分成的各个PU
  {
#if NH_MV
    D_PRINT_INC_INDENT(g_traceModeCheck, "iPartIdx: " + n2s(iPartIdx) );
#endif

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

    UInt         uiBits[3];
    UInt         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();
    }
    UInt         uiBitsTempL0[MAX_NUM_REF];

    TComMv       mvValidList1;
    Int          refIdxValidList1 = 0;
    UInt         bitsValidList1 = MAX_UINT;
    Distortion   costValidList1 = std::numeric_limits<Distortion>::max();

    xGetBlkBits( ePartSize, pcCU->getSlice()->isInterP(), iPartIdx, uiLastMode, uiMbBits);//计算CUePartSize模式下所需要消耗的比特数

    pcCU->getPartIndexAndSize( iPartIdx, uiPartAddr, iRoiWidth, iRoiHeight );// 得到当前PU的索引和大小
#if NH_3D_VSP
    pcCU->setVSPFlagSubParts( 0, uiPartAddr, iPartIdx, pcCU->getDepth(uiPartAddr) );
#endif

#if AMP_MRG
    Bool bTestNormalMC = true;//bTestNormalMC表示是否进行正常的MC过程,正常的MC过程就是进行ME再进行MC
#if  NH_3D_FAST_TEXTURE_ENCODING
    if (bFMD||( bUseMRG && pcCU->getWidth( 0 ) > 8 && iNumPart == 2 ))
#else            
    if ( bUseMRG && pcCU->getWidth( 0 ) > 8 && iNumPart == 2 )
#endif

    {
      bTestNormalMC = false;
    }

    if (bTestNormalMC)
    {
#endif

    //  Uni-directional prediction
    for ( Int iRefList = 0; iRefList < iNumPredDir; iRefList++ )// 遍历两个参考图像列表(如果是P帧,只参考一个列表;如果是B帧,会参考两个列表)
    {
#if NH_MV
      D_PRINT_INC_INDENT(g_traceModeCheck,  "iRefList: " + n2s(iRefList) );
#endif

      RefPicList  eRefPicList = ( iRefList ? REF_PIC_LIST_1 : REF_PIC_LIST_0 ); // 选出参考列表

      for ( Int iRefIdxTemp = 0; iRefIdxTemp < pcCU->getSlice()->getNumRefIdx(eRefPicList); iRefIdxTemp++ )// 遍历这个参考列表的所有参考帧
      {
#if NH_MV
        D_PRINT_INC_INDENT(g_traceModeCheck,  "iRefIdxTemp: " + n2s(iRefIdxTemp) );
#endif

        uiBitsTemp = uiMbBits
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值