Skip to content
Snippets Groups Projects
InterSearch.cpp 223 KiB
Newer Older
  • Learn to ignore specific revisions
  • Taoran Lu's avatar
    Taoran Lu committed
          if (m_pcEncCfg->getReshaper() && (cs.slice->getReshapeInfo().getUseSliceReshaper() && m_pcReshape->getCTUFlag()) && !cu.firstPU->mhIntraFlag && !cu.ibc)
    
    Taoran Lu's avatar
    Taoran Lu committed
          {
            cs.getRecoBuf().Y().rspSignal(m_pcReshape->getFwdLUT());
          }
    #endif
    
    Xiaozhong Xu's avatar
    Xiaozhong Xu committed
        cs.addTU(CS::isDualITree(cs) ? cu : cs.area, partitioner.chType);
    
        Distortion distortion = 0;
    
        for (int comp = 0; comp < numValidComponents; comp++)
        {
          const ComponentID compID = ComponentID(comp);
    
    Xiaozhong Xu's avatar
    Xiaozhong Xu committed
          if (compID == COMPONENT_Y && !luma)
            continue;
          if (compID != COMPONENT_Y && !chroma)
            continue;
    
          CPelBuf reco = cs.getRecoBuf (compID);
          CPelBuf org  = cs.getOrgBuf  (compID);
    #if WCG_EXT
    
    Taoran Lu's avatar
    Taoran Lu committed
    #if JVET_M0427_INLOOP_RESHAPER
          if (m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled() || (
            m_pcEncCfg->getReshaper() && (cs.slice->getReshapeInfo().getUseSliceReshaper()&& m_pcReshape->getCTUFlag())))
    #else
    
          if( m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled() )
    
    Taoran Lu's avatar
    Taoran Lu committed
    #endif
    
          {
            const CPelBuf orgLuma = cs.getOrgBuf( cs.area.blocks[COMPONENT_Y] );
    
    Taoran Lu's avatar
    Taoran Lu committed
    #if JVET_M0427_INLOOP_RESHAPER
            if (compID == COMPONENT_Y)
            {
              const CompArea &areaY = cu.Y();
              CompArea      tmpArea1(COMPONENT_Y, areaY.chromaFormat, Position(0, 0), areaY.size());
              PelBuf tmpRecLuma = m_tmpStorageLCU.getBuf(tmpArea1);
              tmpRecLuma.copyFrom(reco);
              tmpRecLuma.rspSignal(m_pcReshape->getInvLUT());
              distortion += m_pcRdCost->getDistPart(org, tmpRecLuma, sps.getBitDepth(toChannelType(compID)), compID, DF_SSE_WTD, &orgLuma);
            }
            else
    #endif
    
            distortion += m_pcRdCost->getDistPart( org, reco, sps.getBitDepth( toChannelType( compID ) ), compID, DF_SSE_WTD, &orgLuma );
          }
          else
    #endif
          distortion += m_pcRdCost->getDistPart( org, reco, sps.getBitDepth( toChannelType( compID ) ), compID, DF_SSE );
        }
    
        m_CABACEstimator->resetBits();
    
        if( pps.getTransquantBypassEnabledFlag() )
        {
          m_CABACEstimator->cu_transquant_bypass_flag( cu );
        }
    
        PredictionUnit &pu = *cs.getPU( partitioner.chType );
    
        m_CABACEstimator->cu_skip_flag  ( cu );
    
        m_CABACEstimator->subblock_merge_flag( cu );
    
        m_CABACEstimator->triangle_mode ( cu );
    
        if (cu.mmvdSkip)
        {
          m_CABACEstimator->mmvd_merge_idx(pu);
        }
        else
    
        m_CABACEstimator->merge_idx     ( pu );
    
    
        cs.dist     = distortion;
        cs.fracBits = m_CABACEstimator->getEstFracBits();
        cs.cost     = m_pcRdCost->calcRdCost(cs.fracBits, cs.dist);
    
        return;
      }
    
      //  Residual coding.
    
    Xiaozhong Xu's avatar
    Xiaozhong Xu committed
      if (luma)
      {
        cs.getResiBuf().bufs[0].copyFrom(cs.getOrgBuf().bufs[0]);
    
    Taoran Lu's avatar
    Taoran Lu committed
    #if JVET_M0427_INLOOP_RESHAPER
        if (cs.slice->getReshapeInfo().getUseSliceReshaper() && m_pcReshape->getCTUFlag())
        {
          const CompArea &areaY = cu.Y();
          CompArea      tmpArea(COMPONENT_Y, areaY.chromaFormat, Position(0, 0), areaY.size());
          PelBuf tmpPred = m_tmpStorageLCU.getBuf(tmpArea);
          tmpPred.copyFrom(cs.getPredBuf(COMPONENT_Y));
    
    
    Taoran Lu's avatar
    Taoran Lu committed
          if (!cu.firstPU->mhIntraFlag && !cu.ibc)
    
    Taoran Lu's avatar
    Taoran Lu committed
            tmpPred.rspSignal(m_pcReshape->getFwdLUT());
          cs.getResiBuf(COMPONENT_Y).rspSignal(m_pcReshape->getFwdLUT());
          cs.getResiBuf(COMPONENT_Y).subtract(tmpPred);
        }
        else
    #endif
    
    Xiaozhong Xu's avatar
    Xiaozhong Xu committed
        cs.getResiBuf().bufs[0].subtract(cs.getPredBuf().bufs[0]);
      }
      if (chroma)
      {
        cs.getResiBuf().bufs[1].copyFrom(cs.getOrgBuf().bufs[1]);
        cs.getResiBuf().bufs[2].copyFrom(cs.getOrgBuf().bufs[2]);
        cs.getResiBuf().bufs[1].subtract(cs.getPredBuf().bufs[1]);
        cs.getResiBuf().bufs[2].subtract(cs.getPredBuf().bufs[2]);
      }
    
      Distortion zeroDistortion = 0;
    
      const TempCtx ctxStart( m_CtxCache, m_CABACEstimator->getCtx() );
    
    
    Xiaozhong Xu's avatar
    Xiaozhong Xu committed
      if (luma)
      {
        cs.getOrgResiBuf().bufs[0].copyFrom(cs.getResiBuf().bufs[0]);
      }
      if (chroma)
      {
        cs.getOrgResiBuf().bufs[1].copyFrom(cs.getResiBuf().bufs[1]);
        cs.getOrgResiBuf().bufs[2].copyFrom(cs.getResiBuf().bufs[2]);
      }
      xEstimateInterResidualQT(cs, partitioner, &zeroDistortion, luma, chroma);
    
      TransformUnit &firstTU = *cs.getTU( partitioner.chType );
    
      cu.rootCbf = false;
      m_CABACEstimator->resetBits();
      m_CABACEstimator->rqt_root_cbf( cu );
      const uint64_t  zeroFracBits = m_CABACEstimator->getEstFracBits();
      double zeroCost;
      {
    #if WCG_EXT
        if( m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled() )
        {
          zeroCost = cs.isLossless ? ( cs.cost + 1 ) : m_pcRdCost->calcRdCost( zeroFracBits, zeroDistortion, false );
        }
        else
    #endif
        zeroCost = cs.isLossless ? ( cs.cost + 1 ) : m_pcRdCost->calcRdCost( zeroFracBits, zeroDistortion );
      }
    
      const int  numValidTBlocks   = ::getNumberValidTBlocks( *cs.pcv );
      for (uint32_t i = 0; i < numValidTBlocks; i++)
      {
    
        cu.rootCbf |= TU::getCbfAtDepth(firstTU, ComponentID(i), 0);
    
      }
    
      // -------------------------------------------------------
      // If a block full of 0's is efficient, then just use 0's.
      // The costs at this point do not include header bits.
    
      if (zeroCost < cs.cost || !cu.rootCbf)
      {
        cu.rootCbf = false;
    
        cs.clearTUs();
    
        // add a new "empty" TU spanning the whole CU
        TransformUnit& tu = cs.addTU(cu, partitioner.chType);
    
        for (int comp = 0; comp < numValidComponents; comp++)
        {
          tu.rdpcm[comp] = RDPCM_OFF;
        }
        cu.firstTU = cu.lastTU = &tu;
      }
    
    
      // all decisions now made. Fully encode the CU, including the headers:
      m_CABACEstimator->getCtx() = ctxStart;
    
      uint64_t finalFracBits = xGetSymbolFracBitsInter( cs, partitioner );
      // we've now encoded the CU, and so have a valid bit cost
    
    Xiaozhong Xu's avatar
    Xiaozhong Xu committed
      if (!cu.rootCbf)
      {
        if (luma)
        {
          cs.getResiBuf().bufs[0].fill(0); // Clear the residual image, if we didn't code it.
        }
        if (chroma)
        {
          cs.getResiBuf().bufs[1].fill(0); // Clear the residual image, if we didn't code it.
          cs.getResiBuf().bufs[2].fill(0); // Clear the residual image, if we didn't code it.
        }
      }
    
      if (luma)
      {
    
    Taoran Lu's avatar
    Taoran Lu committed
    #if JVET_M0427_INLOOP_RESHAPER
        if (cu.rootCbf && cs.slice->getReshapeInfo().getUseSliceReshaper() && m_pcReshape->getCTUFlag())
        {
          const CompArea &areaY = cu.Y();
          CompArea      tmpArea(COMPONENT_Y, areaY.chromaFormat, Position(0, 0), areaY.size());
          PelBuf tmpPred = m_tmpStorageLCU.getBuf(tmpArea);
          tmpPred.copyFrom(cs.getPredBuf(COMPONENT_Y));
    
    
    Taoran Lu's avatar
    Taoran Lu committed
          if (!cu.firstPU->mhIntraFlag && !cu.ibc)
    
    Taoran Lu's avatar
    Taoran Lu committed
            tmpPred.rspSignal(m_pcReshape->getFwdLUT());
    
          cs.getRecoBuf(COMPONENT_Y).reconstruct(tmpPred, cs.getResiBuf(COMPONENT_Y), cs.slice->clpRng(COMPONENT_Y));
        }
        else
        {
    #endif
          cs.getRecoBuf().bufs[0].reconstruct(cs.getPredBuf().bufs[0], cs.getResiBuf().bufs[0], cs.slice->clpRngs().comp[0]);
    #if JVET_M0427_INLOOP_RESHAPER
    
    Taoran Lu's avatar
    Taoran Lu committed
          if (cs.slice->getReshapeInfo().getUseSliceReshaper() && m_pcReshape->getCTUFlag() && !cu.firstPU->mhIntraFlag && !cu.ibc)
    
    Taoran Lu's avatar
    Taoran Lu committed
          {
            cs.getRecoBuf().bufs[0].rspSignal(m_pcReshape->getFwdLUT());
          }
        }
    #endif
    
    Xiaozhong Xu's avatar
    Xiaozhong Xu committed
      }
      if (chroma)
      {
        cs.getRecoBuf().bufs[1].reconstruct(cs.getPredBuf().bufs[1], cs.getResiBuf().bufs[1], cs.slice->clpRngs().comp[1]);
        cs.getRecoBuf().bufs[2].reconstruct(cs.getPredBuf().bufs[2], cs.getResiBuf().bufs[2], cs.slice->clpRngs().comp[2]);
      }
    
    
      // update with clipped distortion and cost (previously unclipped reconstruction values were used)
      Distortion finalDistortion = 0;
    
      for (int comp = 0; comp < numValidComponents; comp++)
      {
        const ComponentID compID = ComponentID(comp);
    
    Xiaozhong Xu's avatar
    Xiaozhong Xu committed
        if (compID == COMPONENT_Y && !luma)
          continue;
        if (compID != COMPONENT_Y && !chroma)
          continue;
    
        CPelBuf reco = cs.getRecoBuf (compID);
        CPelBuf org  = cs.getOrgBuf  (compID);
    
    #if WCG_EXT
    
    Taoran Lu's avatar
    Taoran Lu committed
    #if JVET_M0427_INLOOP_RESHAPER 
        if (m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled() || ( 
          m_pcEncCfg->getReshaper() && (cs.slice->getReshapeInfo().getUseSliceReshaper() && m_pcReshape->getCTUFlag() ) ) )
    #else
    
        if( m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled() )
    
    Taoran Lu's avatar
    Taoran Lu committed
    #endif
    
        {
          const CPelBuf orgLuma = cs.getOrgBuf( cs.area.blocks[COMPONENT_Y] );
    
    Taoran Lu's avatar
    Taoran Lu committed
    #if JVET_M0427_INLOOP_RESHAPER
          if (compID == COMPONENT_Y)
          {
            const CompArea &areaY = cu.Y();
            CompArea      tmpArea1(COMPONENT_Y, areaY.chromaFormat, Position(0, 0), areaY.size());
            PelBuf tmpRecLuma = m_tmpStorageLCU.getBuf(tmpArea1);
            tmpRecLuma.copyFrom(reco);
            tmpRecLuma.rspSignal(m_pcReshape->getInvLUT());
            finalDistortion += m_pcRdCost->getDistPart(org, tmpRecLuma, sps.getBitDepth(toChannelType(compID)), compID, DF_SSE_WTD, &orgLuma);
          }
          else
    #endif
            finalDistortion += m_pcRdCost->getDistPart(org, reco, sps.getBitDepth(toChannelType(compID)), compID, DF_SSE_WTD, &orgLuma);
    
        }
        else
    #endif
        {
          finalDistortion += m_pcRdCost->getDistPart( org, reco, sps.getBitDepth( toChannelType( compID ) ), compID, DF_SSE );
        }
      }
    
      cs.dist     = finalDistortion;
      cs.fracBits = finalFracBits;
      cs.cost     = m_pcRdCost->calcRdCost(cs.fracBits, cs.dist);
    
      CHECK(cs.tus.size() == 0, "No TUs present");
    }
    
    uint64_t InterSearch::xGetSymbolFracBitsInter(CodingStructure &cs, Partitioner &partitioner)
    {
      uint64_t fracBits   = 0;
      CodingUnit &cu    = *cs.getCU( partitioner.chType );
    
      m_CABACEstimator->resetBits();
    
    
    Karsten Suehring's avatar
    Karsten Suehring committed
      if( cu.firstPU->mergeFlag && !cu.rootCbf )
    
      {
        cu.skip = true;
    
        if( cs.pps->getTransquantBypassEnabledFlag() )
        {
          m_CABACEstimator->cu_transquant_bypass_flag( cu );
        }
    
        m_CABACEstimator->cu_skip_flag  ( cu );
    
        m_CABACEstimator->subblock_merge_flag( cu );
    
        m_CABACEstimator->triangle_mode ( cu );
    
        if (cu.mmvdSkip)
        {
          m_CABACEstimator->mmvd_merge_idx(*cu.firstPU);
        }
        else
    
        m_CABACEstimator->merge_idx     ( *cu.firstPU );
        fracBits   += m_CABACEstimator->getEstFracBits();
      }
      else
      {
        CHECK( cu.skip, "Skip flag has to be off at this point!" );
    
        if( cs.pps->getTransquantBypassEnabledFlag() )
        {
          m_CABACEstimator->cu_transquant_bypass_flag( cu );
        }
    
    Xiaozhong Xu's avatar
    Xiaozhong Xu committed
        if (cu.Y().valid())
    
        m_CABACEstimator->cu_skip_flag( cu );
        m_CABACEstimator->pred_mode   ( cu );
        m_CABACEstimator->cu_pred_data( cu );
        CUCtx cuCtx;
        cuCtx.isDQPCoded = true;
        cuCtx.isChromaQpAdjCoded = true;
        m_CABACEstimator->cu_residual ( cu, partitioner, cuCtx );
        fracBits       += m_CABACEstimator->getEstFracBits();
      }
    
      return fracBits;
    }
    
    
    double InterSearch::xGetMEDistortionWeight(uint8_t gbiIdx, RefPicList eRefPicList)
    {
      if( gbiIdx != GBI_DEFAULT )
      {
        return fabs((double)getGbiWeight(gbiIdx, eRefPicList) / (double)g_GbiWeightBase);
      }
      else
      {
        return 0.5;
      }
    }
    bool InterSearch::xReadBufferedUniMv(PredictionUnit& pu, RefPicList eRefPicList, int32_t iRefIdx, Mv& pcMvPred, Mv& rcMv, uint32_t& ruiBits, Distortion& ruiCost)
    {
    
      if (m_uniMotions.isReadMode((uint32_t)eRefPicList, (uint32_t)iRefIdx))
    
        m_uniMotions.copyTo(rcMv, ruiCost, (uint32_t)eRefPicList, (uint32_t)iRefIdx);
    
    
        m_pcRdCost->setPredictor(pcMvPred);
        m_pcRdCost->setCostScale(0);
    
        unsigned imvShift = pu.cu->imv << 1;
        uint32_t uiMvBits = m_pcRdCost->getBitsOfVectorWithPredictor(rcMv.getHor(), rcMv.getVer(), imvShift);
    
        ruiBits += uiMvBits;
        ruiCost += m_pcRdCost->getCost(ruiBits);
        return true;
      }
      return false;
    }
    
    bool InterSearch::xReadBufferedAffineUniMv(PredictionUnit& pu, RefPicList eRefPicList, int32_t iRefIdx, Mv acMvPred[3], Mv acMv[3], uint32_t& ruiBits, Distortion& ruiCost)
    {
    
      if (m_uniMotions.isReadModeAffine((uint32_t)eRefPicList, (uint32_t)iRefIdx, pu.cu->affineType))
    
        m_uniMotions.copyAffineMvTo(acMv, ruiCost, (uint32_t)eRefPicList, (uint32_t)iRefIdx, pu.cu->affineType);
    
        m_pcRdCost->setCostScale(0);
    
        uint32_t uiMvBits = 0;
        for (int iVerIdx = 0; iVerIdx<(pu.cu->affineType ? 3 : 2); iVerIdx++)
        {
          if (iVerIdx)
          {
            m_pcRdCost->setPredictor(acMvPred[iVerIdx] + acMv[0] - acMvPred[0]);
          }
          else
          {
            m_pcRdCost->setPredictor(acMvPred[iVerIdx]);
          }
    
          uiMvBits += m_pcRdCost->getBitsOfVectorWithPredictor(acMv[iVerIdx].getHor(), acMv[iVerIdx].getVer(), 0);
    
        }
        ruiBits += uiMvBits;
        ruiCost += m_pcRdCost->getCost(ruiBits);
        return true;
      }
      return false;
    }
    void InterSearch::initWeightIdxBits()
    {
      for (int n = 0; n < GBI_NUM; ++n)
      {
    
        m_estWeightIdxBits[n] = deriveWeightIdxBits(n);
    
    void InterSearch::xClipMv( Mv& rcMv, const Position& pos, const struct Size& size, const SPS& sps )
    {
      int mvShift = MV_FRACTIONAL_BITS_INTERNAL;
      int offset = 8;
      int horMax = ( sps.getPicWidthInLumaSamples() + offset - ( int ) pos.x - 1 ) << mvShift;
      int horMin = ( -( int ) sps.getMaxCUWidth()   - offset - ( int ) pos.x + 1 ) << mvShift;
    
      int verMax = ( sps.getPicHeightInLumaSamples() + offset - ( int ) pos.y - 1 ) << mvShift;
      int verMin = ( -( int ) sps.getMaxCUHeight()   - offset - ( int ) pos.y + 1 ) << mvShift;
    
      if( sps.getWrapAroundEnabledFlag() )
      {
        int horMax = ( sps.getPicWidthInLumaSamples() + sps.getMaxCUWidth() - size.width + offset - ( int ) pos.x - 1 ) << mvShift;
        int horMin = ( -( int ) sps.getMaxCUWidth()                                      - offset - ( int ) pos.x + 1 ) << mvShift;
        rcMv.setHor( std::min( horMax, std::max( horMin, rcMv.getHor() ) ) );
        rcMv.setVer( std::min( verMax, std::max( verMin, rcMv.getVer() ) ) );
        return;
      }
    
      rcMv.setHor( std::min( horMax, std::max( horMin, rcMv.getHor() ) ) );
      rcMv.setVer( std::min( verMax, std::max( verMin, rcMv.getVer() ) ) );
    }
    
    
    #if JVET_M0444_SMVD
    void InterSearch::symmvdCheckBestMvp(
      PredictionUnit& pu, 
      PelUnitBuf& origBuf,
      Mv curMv,
      RefPicList curRefList, 
      AMVPInfo amvpInfo[2][33], 
      int32_t gbiIdx,
      Mv cMvPredSym[2],
      int32_t mvpIdxSym[2],
      Distortion& bestCost,
      bool skip
    )
    {
      RefPicList tarRefList = (RefPicList)(1 - curRefList);
      int32_t refIdxCur = pu.cu->slice->getSymRefIdx(curRefList);
      int32_t refIdxTar = pu.cu->slice->getSymRefIdx(tarRefList);
      
      MvField cCurMvField, cTarMvField;
      cCurMvField.setMvField(curMv, refIdxCur);
      AMVPInfo& amvpCur = amvpInfo[curRefList][refIdxCur];
      AMVPInfo& amvpTar = amvpInfo[tarRefList][refIdxTar];
      m_pcRdCost->setCostScale(0);
    
    
      // get prediction of eCurRefPicList
      PelUnitBuf predBufA = m_tmpPredStorage[curRefList].getBuf(UnitAreaRelative(*pu.cu, pu));
      const Picture* picRefA = pu.cu->slice->getRefPic(curRefList, cCurMvField.refIdx);
      Mv mvA = cCurMvField.mv;
      mvA.changePrecision(MV_PRECISION_QUARTER, MV_PRECISION_INTERNAL);
      clipMv(mvA, pu.cu->lumaPos(), pu.cu->lumaSize(), *pu.cs->sps);
      xPredInterBlk(COMPONENT_Y, pu, picRefA, mvA, predBufA, true, pu.cu->slice->clpRng(COMPONENT_Y), false, false);
    
      int32_t skipMvpIdx[2];
      skipMvpIdx[0] = skip ? mvpIdxSym[0] : -1;
      skipMvpIdx[1] = skip ? mvpIdxSym[1] : -1;
    
      for (int i = 0; i < amvpCur.numCand; i++)
      {
        for (int j = 0; j < amvpTar.numCand; j++)
        {
          if (skipMvpIdx[curRefList] == i && skipMvpIdx[tarRefList] == j)
            continue;
    
          cTarMvField.setMvField(curMv.getSymmvdMv(amvpCur.mvCand[i], amvpTar.mvCand[j]), refIdxTar);
    
          // get prediction of eTarRefPicList
          PelUnitBuf predBufB = m_tmpPredStorage[tarRefList].getBuf(UnitAreaRelative(*pu.cu, pu));
          const Picture* picRefB = pu.cu->slice->getRefPic(tarRefList, cTarMvField.refIdx);
          Mv mvB = cTarMvField.mv;
          mvB.changePrecision(MV_PRECISION_QUARTER, MV_PRECISION_INTERNAL);
          clipMv(mvB, pu.cu->lumaPos(), pu.cu->lumaSize(), *pu.cs->sps);
          xPredInterBlk(COMPONENT_Y, pu, picRefB, mvB, predBufB, true, pu.cu->slice->clpRng(COMPONENT_Y), false, false);
    
          PelUnitBuf bufTmp = m_tmpStorageLCU.getBuf(UnitAreaRelative(*pu.cu, pu));
          if (gbiIdx != GBI_DEFAULT)
            bufTmp.Y().addWeightedAvg(predBufA.Y(), predBufB.Y(), pu.cu->slice->clpRng(COMPONENT_Y), gbiIdx);
          else
            bufTmp.Y().addAvg(predBufA.Y(), predBufB.Y(), pu.cu->slice->clpRng(COMPONENT_Y));
    
          // calc distortion
          Distortion cost = m_pcRdCost->getDistPart(bufTmp.Y(), origBuf.Y(), pu.cs->sps->getBitDepth(CHANNEL_TYPE_LUMA), COMPONENT_Y, DF_HAD);
    
          m_pcRdCost->setPredictor(amvpCur.mvCand[i]);
          uint32_t bits = m_pcRdCost->getBitsOfVectorWithPredictor(curMv.hor, curMv.ver, (pu.cu->imv << 1));
          bits += m_auiMVPIdxCost[i][AMVP_MAX_NUM_CANDS];
          bits += m_auiMVPIdxCost[j][AMVP_MAX_NUM_CANDS];
          cost += m_pcRdCost->getCost(bits);
          if (cost < bestCost)
          {
            bestCost = cost;
            cMvPredSym[curRefList] = amvpCur.mvCand[i];
            cMvPredSym[tarRefList] = amvpTar.mvCand[j];
            mvpIdxSym[curRefList] = i;
            mvpIdxSym[tarRefList] = j;
          }
        }
      }
    }
    #endif