[x265] [PATCH] improved getInerMergeCandidates(); cached MVs before finding merge candidates

Steve Borho steve at borho.org
Wed Mar 18 17:14:21 CET 2015


On 03/18, ashok at multicorewareinc.com wrote:
> # HG changeset patch
> # User Ashok Kumar Mishra<ashok at multicorewareinc.com>
> # Date 1426661940 -19800
> #      Wed Mar 18 12:29:00 2015 +0530
> # Node ID abd266927ba37f11e7f6751ad64dcd8d716e4fb9
> # Parent  ca0a4b2c53c54431a3b8471bbf4dadf6ee62c8c5
> improved getInerMergeCandidates(); cached MVs before finding merge candidates
> There is little performance improvement with the new function.

queeud for testing

> diff -r ca0a4b2c53c5 -r abd266927ba3 source/common/cudata.cpp
> --- a/source/common/cudata.cpp	Wed Mar 18 08:09:12 2015 +0530
> +++ b/source/common/cudata.cpp	Wed Mar 18 12:29:00 2015 +0530
> @@ -1221,21 +1221,6 @@
>      outPartAddr = (partAddrTable[partType][partIdx] * m_numPartitions) >> 4;
>  }
>  
> -void CUData::getMvField(const CUData* cu, uint32_t absPartIdx, int picList, MVField& outMvField) const
> -{
> -    if (cu)
> -    {
> -        outMvField.mv = cu->m_mv[picList][absPartIdx];
> -        outMvField.refIdx = cu->m_refIdx[picList][absPartIdx];
> -    }
> -    else
> -    {
> -        // OUT OF BOUNDARY
> -        outMvField.mv = 0;
> -        outMvField.refIdx = REF_NOT_VALID;
> -    }
> -}
> -
>  void CUData::deriveLeftRightTopIdx(uint32_t partIdx, uint32_t& partIdxLT, uint32_t& partIdxRT) const
>  {
>      partIdxLT = m_absIdxInCTU;
> @@ -1357,17 +1342,17 @@
>      return outPartIdxRB;
>  }
>  
> -bool CUData::hasEqualMotion(uint32_t absPartIdx, const CUData& candCU, uint32_t candAbsPartIdx) const
> +bool CUData::hasEqualMotion(InterNeighbourMV* cand1, InterNeighbourMV* cand2) const
>  {
> -    if (m_interDir[absPartIdx] != candCU.m_interDir[candAbsPartIdx])
> +    if (cand1->interDir != cand2->interDir)
>          return false;
>  
> -    for (uint32_t refListIdx = 0; refListIdx < 2; refListIdx++)
> +    for (uint32_t refList = 0; refList < 2; refList++)
>      {
> -        if (m_interDir[absPartIdx] & (1 << refListIdx))
> +        if (cand1->interDir & (1 << refList))
>          {
> -            if (m_mv[refListIdx][absPartIdx] != candCU.m_mv[refListIdx][candAbsPartIdx] ||
> -                m_refIdx[refListIdx][absPartIdx] != candCU.m_refIdx[refListIdx][candAbsPartIdx])
> +            if (cand1->mv[refList] != cand2->mv[refList] ||
> +                cand1->refIdx[refList] != cand2->refIdx[refList])
>                  return false;
>          }
>      }
> @@ -1376,10 +1361,10 @@
>  }
>  
>  /* Construct list of merging candidates, returns count */
> -uint32_t CUData::getInterMergeCandidates(uint32_t absPartIdx, uint32_t puIdx, MVField(*candMvField)[2], uint8_t* candDir) const
> +uint32_t CUData::getInterMergeCandidates(uint32_t puIdx, MVField(*candMvField)[2], uint8_t* candDir, InterNeighbourMV *neighbours) const
>  {
> -    uint32_t absPartAddr = m_absIdxInCTU + absPartIdx;
>      const bool isInterB = m_slice->isInterB();
> +    const int maxList = isInterB ? 2 : 1;
>  
>      const uint32_t maxNumMergeCand = m_slice->m_maxNumMergeCand;
>  
> @@ -1405,86 +1390,75 @@
>      xP = ((tmp >> 4) * cuSize) >> 2;
>      yP = ((tmp & 0xF) * cuSize) >> 2;
>  
> +    int leftCUAvailable = ((0x3b >> partMode) & 1) | !puIdx;
> +    int topCUAvailable = ((0xcd >> partMode) & 1) | !puIdx;
> +
>      uint32_t count = 0;
> -
> -    uint32_t partIdxLT, partIdxRT, partIdxLB = deriveLeftBottomIdx(puIdx);
> -    PartSize curPS = (PartSize)m_partSize[absPartIdx];
> -    
>      // left
> -    uint32_t leftPartIdx = 0;
> -    const CUData* cuLeft = getPULeft(leftPartIdx, partIdxLB);
> -    bool isAvailableA1 = cuLeft &&
> -        cuLeft->isDiffMER(xP - 1, yP + nPSH - 1, xP, yP) &&
> -        !(puIdx == 1 && (curPS == SIZE_Nx2N || curPS == SIZE_nLx2N || curPS == SIZE_nRx2N)) &&
> -        cuLeft->isInter(leftPartIdx);
> +    bool isAvailableA1 = isDiffMER(xP - 1, yP + nPSH - 1, xP, yP) &&
> +        !!leftCUAvailable && (neighbours[MD_LEFT].unifiedRef != -1);
>      if (isAvailableA1)
>      {
> +        // get MV and reference idx from left CU
> +        for (int i = 0; i < maxList; i++)
> +        {
> +            candMvField[count][i].mv     = neighbours[MD_LEFT].mv[i];
> +            candMvField[count][i].refIdx = neighbours[MD_LEFT].refIdx[i];
> +        }
>          // get Inter Dir
> -        candDir[count] = cuLeft->m_interDir[leftPartIdx];
> -        // get Mv from Left
> -        cuLeft->getMvField(cuLeft, leftPartIdx, 0, candMvField[count][0]);
> -        if (isInterB)
> -            cuLeft->getMvField(cuLeft, leftPartIdx, 1, candMvField[count][1]);
> +        candDir[count] = neighbours[MD_LEFT].interDir;
>  
>          if (++count == maxNumMergeCand)
>              return maxNumMergeCand;
>      }
>  
> -    deriveLeftRightTopIdx(puIdx, partIdxLT, partIdxRT);
> -
>      // above
> -    uint32_t abovePartIdx = 0;
> -    const CUData* cuAbove = getPUAbove(abovePartIdx, partIdxRT);
> -    bool isAvailableB1 = cuAbove &&
> -        cuAbove->isDiffMER(xP + nPSW - 1, yP - 1, xP, yP) &&
> -        !(puIdx == 1 && (curPS == SIZE_2NxN || curPS == SIZE_2NxnU || curPS == SIZE_2NxnD)) &&
> -        cuAbove->isInter(abovePartIdx);
> -    if (isAvailableB1 && (!isAvailableA1 || !cuLeft->hasEqualMotion(leftPartIdx, *cuAbove, abovePartIdx)))
> +    bool isAvailableB1 = isDiffMER(xP + nPSW - 1, yP - 1, xP, yP) &&
> +        !!topCUAvailable && (neighbours[MD_ABOVE].unifiedRef != -1);
> +    if (isAvailableB1 && (!isAvailableA1 || !hasEqualMotion(neighbours + MD_LEFT, neighbours + MD_ABOVE)))
>      {
> +        // get MV and reference idx from above CU
> +        for (int i = 0; i < maxList; i++)
> +        {
> +            candMvField[count][i].mv     = neighbours[MD_ABOVE].mv[i];
> +            candMvField[count][i].refIdx = neighbours[MD_ABOVE].refIdx[i];
> +        }
>          // get Inter Dir
> -        candDir[count] = cuAbove->m_interDir[abovePartIdx];
> -        // get Mv from Left
> -        cuAbove->getMvField(cuAbove, abovePartIdx, 0, candMvField[count][0]);
> -        if (isInterB)
> -            cuAbove->getMvField(cuAbove, abovePartIdx, 1, candMvField[count][1]);
> +        candDir[count] = neighbours[MD_ABOVE].interDir;
>  
>          if (++count == maxNumMergeCand)
>              return maxNumMergeCand;
>      }
>  
>      // above right
> -    uint32_t aboveRightPartIdx = 0;
> -    const CUData* cuAboveRight = getPUAboveRight(aboveRightPartIdx, partIdxRT);
> -    bool isAvailableB0 = cuAboveRight &&
> -        cuAboveRight->isDiffMER(xP + nPSW, yP - 1, xP, yP) &&
> -        cuAboveRight->isInter(aboveRightPartIdx);
> -    if (isAvailableB0 && (!isAvailableB1 || !cuAbove->hasEqualMotion(abovePartIdx, *cuAboveRight, aboveRightPartIdx)))
> +    bool isAvailableB0 = isDiffMER(xP + nPSW, yP - 1, xP, yP) && (neighbours[MD_ABOVE_RIGHT].unifiedRef != -1);
> +    if (isAvailableB0 && (!isAvailableB1 || !hasEqualMotion(neighbours + MD_ABOVE, neighbours + MD_ABOVE_RIGHT)))
>      {
> +        // get MV and reference idx from above right
> +        for (int i = 0; i < maxList; i++)
> +        {
> +            candMvField[count][i].mv     = neighbours[MD_ABOVE_RIGHT].mv[i];
> +            candMvField[count][i].refIdx = neighbours[MD_ABOVE_RIGHT].refIdx[i];
> +        }
>          // get Inter Dir
> -        candDir[count] = cuAboveRight->m_interDir[aboveRightPartIdx];
> -        // get Mv from Left
> -        cuAboveRight->getMvField(cuAboveRight, aboveRightPartIdx, 0, candMvField[count][0]);
> -        if (isInterB)
> -            cuAboveRight->getMvField(cuAboveRight, aboveRightPartIdx, 1, candMvField[count][1]);
> +        candDir[count] = neighbours[MD_ABOVE_RIGHT].interDir;
>  
>          if (++count == maxNumMergeCand)
>              return maxNumMergeCand;
>      }
>  
>      // left bottom
> -    uint32_t leftBottomPartIdx = 0;
> -    const CUData* cuLeftBottom = this->getPUBelowLeft(leftBottomPartIdx, partIdxLB);
> -    bool isAvailableA0 = cuLeftBottom &&
> -        cuLeftBottom->isDiffMER(xP - 1, yP + nPSH, xP, yP) &&
> -        cuLeftBottom->isInter(leftBottomPartIdx);
> -    if (isAvailableA0 && (!isAvailableA1 || !cuLeft->hasEqualMotion(leftPartIdx, *cuLeftBottom, leftBottomPartIdx)))
> +    bool isAvailableA0 = isDiffMER(xP - 1, yP + nPSH, xP, yP) && (neighbours[MD_BELOW_LEFT].unifiedRef != -1);
> +    if (isAvailableA0 && (!isAvailableA1 || !hasEqualMotion(neighbours + MD_LEFT, neighbours + MD_BELOW_LEFT)))
>      {
> +        // get MV and reference idx from left bottom
> +        for (int i = 0; i < maxList; i++)
> +        {
> +            candMvField[count][i].mv     = neighbours[MD_BELOW_LEFT].mv[i];
> +            candMvField[count][i].refIdx = neighbours[MD_BELOW_LEFT].refIdx[i];
> +        }
>          // get Inter Dir
> -        candDir[count] = cuLeftBottom->m_interDir[leftBottomPartIdx];
> -        // get Mv from Left
> -        cuLeftBottom->getMvField(cuLeftBottom, leftBottomPartIdx, 0, candMvField[count][0]);
> -        if (isInterB)
> -            cuLeftBottom->getMvField(cuLeftBottom, leftBottomPartIdx, 1, candMvField[count][1]);
> +        candDir[count] = neighbours[MD_BELOW_LEFT].interDir;
>  
>          if (++count == maxNumMergeCand)
>              return maxNumMergeCand;
> @@ -1493,83 +1467,53 @@
>      // above left
>      if (count < 4)
>      {
> -        uint32_t aboveLeftPartIdx = 0;
> -        const CUData* cuAboveLeft = getPUAboveLeft(aboveLeftPartIdx, absPartAddr);
> -        bool isAvailableB2 = cuAboveLeft &&
> -            cuAboveLeft->isDiffMER(xP - 1, yP - 1, xP, yP) &&
> -            cuAboveLeft->isInter(aboveLeftPartIdx);
> -        if (isAvailableB2 && (!isAvailableA1 || !cuLeft->hasEqualMotion(leftPartIdx, *cuAboveLeft, aboveLeftPartIdx))
> -            && (!isAvailableB1 || !cuAbove->hasEqualMotion(abovePartIdx, *cuAboveLeft, aboveLeftPartIdx)))
> +        bool isAvailableB2 = isDiffMER(xP - 1, yP - 1, xP, yP) && (neighbours[MD_ABOVE_LEFT].unifiedRef != -1);
> +        if (isAvailableB2 && (!isAvailableA1 || !hasEqualMotion(neighbours + MD_LEFT, neighbours + MD_ABOVE_LEFT))
> +            && (!isAvailableB1 || !hasEqualMotion(neighbours + MD_ABOVE, neighbours + MD_ABOVE_LEFT)))
>          {
> +            // get MV and reference idx from above left
> +            for (int i = 0; i < maxList; i++)
> +            {
> +                candMvField[count][i].mv     = neighbours[MD_ABOVE_LEFT].mv[i];
> +                candMvField[count][i].refIdx = neighbours[MD_ABOVE_LEFT].refIdx[i];
> +            }
>              // get Inter Dir
> -            candDir[count] = cuAboveLeft->m_interDir[aboveLeftPartIdx];
> -            // get Mv from Left
> -            cuAboveLeft->getMvField(cuAboveLeft, aboveLeftPartIdx, 0, candMvField[count][0]);
> -            if (isInterB)
> -                cuAboveLeft->getMvField(cuAboveLeft, aboveLeftPartIdx, 1, candMvField[count][1]);
> -
> -            if (++count == maxNumMergeCand)
> -                return maxNumMergeCand;
> -        }
> -    }
> -    if (m_slice->m_sps->bTemporalMVPEnabled)
> -    {
> -        uint32_t partIdxRB = deriveRightBottomIdx(puIdx);
> -        MV colmv;
> -        int ctuIdx = -1;
> -
> -        // image boundary check
> -        if (m_encData->getPicCTU(m_cuAddr)->m_cuPelX + g_zscanToPelX[partIdxRB] + UNIT_SIZE < m_slice->m_sps->picWidthInLumaSamples &&
> -            m_encData->getPicCTU(m_cuAddr)->m_cuPelY + g_zscanToPelY[partIdxRB] + UNIT_SIZE < m_slice->m_sps->picHeightInLumaSamples)
> -        {
> -            uint32_t absPartIdxRB = g_zscanToRaster[partIdxRB];
> -            uint32_t numUnits = s_numPartInCUSize;
> -            bool bNotLastCol = lessThanCol(absPartIdxRB, numUnits - 1, numUnits); // is not at the last column of CTU
> -            bool bNotLastRow = lessThanRow(absPartIdxRB, numUnits - 1, numUnits); // is not at the last row    of CTU
> -
> -            if (bNotLastCol && bNotLastRow)
> -            {
> -                absPartAddr = g_rasterToZscan[absPartIdxRB + numUnits + 1];
> -                ctuIdx = m_cuAddr;
> -            }
> -            else if (bNotLastCol)
> -                absPartAddr = g_rasterToZscan[(absPartIdxRB + numUnits + 1) & (numUnits - 1)];
> -            else if (bNotLastRow)
> -            {
> -                absPartAddr = g_rasterToZscan[absPartIdxRB + 1];
> -                ctuIdx = m_cuAddr + 1;
> -            }
> -            else // is the right bottom corner of CTU
> -                absPartAddr = 0;
> -        }
> -
> -        int maxList = isInterB ? 2 : 1;
> -        int dir = 0, refIdx = 0;
> -        for (int list = 0; list < maxList; list++)
> -        {
> -            bool bExistMV = ctuIdx >= 0 && getColMVP(colmv, refIdx, list, ctuIdx, absPartAddr);
> -            if (!bExistMV)
> -            {
> -                uint32_t partIdxCenter = deriveCenterIdx(puIdx);
> -                bExistMV = getColMVP(colmv, refIdx, list, m_cuAddr, partIdxCenter);
> -            }
> -            if (bExistMV)
> -            {
> -                dir |= (1 << list);
> -                candMvField[count][list].mv = colmv;
> -                candMvField[count][list].refIdx = refIdx;
> -            }
> -        }
> -
> -        if (dir != 0)
> -        {
> -            candDir[count] = (uint8_t)dir;
> +            candDir[count] = neighbours[MD_ABOVE_LEFT].interDir;
>  
>              if (++count == maxNumMergeCand)
>                  return maxNumMergeCand;
>          }
>      }
>  
> +    if ((m_slice->m_sps->bTemporalMVPEnabled) && (neighbours[MD_COLLOCATED].unifiedRef != -1))
> +    {
> +        int16_t dir = 0, refIdx = 0;
> +        for (int picList = 0; picList < maxList; picList++)
> +        {
> +            uint32_t cuAddr = neighbours[MD_COLLOCATED].cuAddr[picList];
> +            const Frame* colPic = m_slice->m_refPicList[m_slice->isInterB() && !m_slice->m_colFromL0Flag][m_slice->m_colRefIdx];
> +            const CUData* colCU = colPic->m_encData->getPicCTU(cuAddr);
> +
> +            // Scale the vector
> +            int tempRefIdx = neighbours[MD_COLLOCATED].refIdx[picList];
> +            int colRefPOC = colCU->m_slice->m_refPOCList[tempRefIdx >> 4][tempRefIdx & 0xf];
> +            int colPOC = colCU->m_slice->m_poc;
> +
> +            int curRefPOC = m_slice->m_refPOCList[picList][refIdx];
> +            int curPOC = m_slice->m_poc;
> +
> +            candMvField[count][picList].mv = scaleMvByPOCDist(neighbours[MD_COLLOCATED].mv[picList], curPOC, curRefPOC, colPOC, colRefPOC);
> +
> +            dir |= (1 << picList);
> +            candDir[count] = (uint8_t)dir;
> +            candMvField[count][picList].refIdx = refIdx;
> +        }
> +
> +        if (++count == maxNumMergeCand)
> +            return maxNumMergeCand;
> +    }
> +
> +    // Create new candidates by mixing the previous ones.
>      if (isInterB)
>      {
>          const uint32_t cutoff = count * (count - 1);
> @@ -1586,6 +1530,7 @@
>                  // get Mv from cand[i] and cand[j]
>                  int refIdxL0 = candMvField[i][0].refIdx;
>                  int refIdxL1 = candMvField[j][1].refIdx;
> +
>                  int refPOCL0 = m_slice->m_refPOCList[0][refIdxL0];
>                  int refPOCL1 = m_slice->m_refPOCList[1][refIdxL1];
>                  if (!(refPOCL0 == refPOCL1 && candMvField[i][0].mv == candMvField[j][1].mv))
> @@ -1602,31 +1547,30 @@
>              }
>          }
>      }
> -    int numRefIdx = (isInterB) ? X265_MIN(m_slice->m_numRefIdx[0], m_slice->m_numRefIdx[1]) : m_slice->m_numRefIdx[0];
> -    int r = 0;
> -    int refcnt = 0;
> +
> +    int maxIdx = (isInterB) ? X265_MIN(m_slice->m_numRefIdx[0], m_slice->m_numRefIdx[1]) : m_slice->m_numRefIdx[0];
> +    for (int i = 0; i < maxIdx; i++)
> +    {
> +        candDir[count] = isInterB ? 3 : 1;
> +        candMvField[count][0].mv.word = 0;
> +        candMvField[count][1].mv.word = 0;
> +        candMvField[count][0].refIdx = i;
> +        candMvField[count][1].refIdx = isInterB ? i : -1;
> +
> +        if (++count == maxNumMergeCand)
> +            return maxNumMergeCand;
> +    }
> +
> +    // Generate null motion vector with reference index 0.
>      while (count < maxNumMergeCand)
>      {
> -        candDir[count] = 1;
> +        candDir[count] = isInterB ? 3 : 1;
>          candMvField[count][0].mv.word = 0;
> -        candMvField[count][0].refIdx = r;
> -
> -        if (isInterB)
> -        {
> -            candDir[count] = 3;
> -            candMvField[count][1].mv.word = 0;
> -            candMvField[count][1].refIdx = r;
> -        }
> +        candMvField[count][1].mv.word = 0;
> +        candMvField[count][0].refIdx  = 0;
> +        candMvField[count][1].refIdx  = isInterB ? 0 : -1;
>  
>          count++;
> -
> -        if (refcnt == numRefIdx - 1)
> -            r = 0;
> -        else
> -        {
> -            ++r;
> -            ++refcnt;
> -        }
>      }
>  
>      return count;
> @@ -1822,12 +1766,12 @@
>  
>      for (int i = 0; i < 2; i++)
>      {
> -        // Get the MV.
> +        // Get MV and reference idx.
>          neighbour->mv[i] = tmpCU->m_mv[i][idx];
> -
> -        // Get the reference idx.
>          neighbour->refIdx[i] = tmpCU->m_refIdx[i][idx];
>      }
> +
> +    neighbour->interDir = tmpCU->m_interDir[idx];
>  }
>  
>  void CUData::clipMv(MV& outMV) const
> @@ -1883,40 +1827,6 @@
>      return false;
>  }
>  
> -bool CUData::getColMVP(MV& outMV, int& outRefIdx, int picList, int cuAddr, int partUnitIdx) const
> -{
> -    const Frame* colPic = m_slice->m_refPicList[m_slice->isInterB() && !m_slice->m_colFromL0Flag][m_slice->m_colRefIdx];
> -    const CUData* colCU = colPic->m_encData->getPicCTU(cuAddr);
> -
> -    uint32_t absPartAddr = partUnitIdx & TMVP_UNIT_MASK;
> -    if (colCU->m_predMode[partUnitIdx] == MODE_NONE || colCU->isIntra(absPartAddr))
> -        return false;
> -
> -    int colRefPicList = m_slice->m_bCheckLDC ? picList : m_slice->m_colFromL0Flag;
> -
> -    int colRefIdx = colCU->m_refIdx[colRefPicList][absPartAddr];
> -
> -    if (colRefIdx < 0)
> -    {
> -        colRefPicList = !colRefPicList;
> -        colRefIdx = colCU->m_refIdx[colRefPicList][absPartAddr];
> -
> -        if (colRefIdx < 0)
> -            return false;
> -    }
> -
> -    // Scale the vector
> -    int colRefPOC = colCU->m_slice->m_refPOCList[colRefPicList][colRefIdx];
> -    int colPOC = colCU->m_slice->m_poc;
> -    MV colmv = colCU->m_mv[colRefPicList][absPartAddr];
> -
> -    int curRefPOC = m_slice->m_refPOCList[picList][outRefIdx];
> -    int curPOC = m_slice->m_poc;
> -
> -    outMV = scaleMvByPOCDist(colmv, curPOC, curRefPOC, colPOC, colRefPOC);
> -    return true;
> -}
> -
>  // Cache the collocated MV.
>  bool CUData::getCollocatedMV(int cuAddr, int partUnitIdx, InterNeighbourMV *neighbour) const
>  {
> diff -r ca0a4b2c53c5 -r abd266927ba3 source/common/cudata.h
> --- a/source/common/cudata.h	Wed Mar 18 08:09:12 2015 +0530
> +++ b/source/common/cudata.h	Wed Mar 18 12:29:00 2015 +0530
> @@ -98,6 +98,8 @@
>  // Structure that keeps the neighbour's MV information.
>  struct InterNeighbourMV
>  {
> +    // Neighbour inter dir.
> +    uint8_t interDir;
>      // Neighbour MV. The index represents the list.
>      MV mv[2];
>  
> @@ -216,7 +218,7 @@
>      uint8_t  getCbf(uint32_t absPartIdx, TextType ttype, uint32_t tuDepth) const { return (m_cbf[ttype][absPartIdx] >> tuDepth) & 0x1; }
>      uint8_t  getQtRootCbf(uint32_t absPartIdx) const                             { return m_cbf[0][absPartIdx] || m_cbf[1][absPartIdx] || m_cbf[2][absPartIdx]; }
>      int8_t   getRefQP(uint32_t currAbsIdxInCTU) const;
> -    uint32_t getInterMergeCandidates(uint32_t absPartIdx, uint32_t puIdx, MVField (*candMvField)[2], uint8_t* candDir) const;
> +    uint32_t getInterMergeCandidates(uint32_t puIdx, MVField (*candMvField)[2], uint8_t* candDir, InterNeighbourMV *neighbours) const;
>      void     clipMv(MV& outMV) const;
>      int      getPMV(InterNeighbourMV *neighbours, uint32_t reference_list, uint32_t refIdx, MV* amvpCand, MV* pmv) const;
>      void     getNeighbourMV(uint32_t puIdx, uint32_t absPartIdx, InterNeighbourMV* neighbours) const;
> @@ -260,23 +262,18 @@
>      int8_t getLastCodedQP(uint32_t absPartIdx) const;
>      int  getLastValidPartIdx(int absPartIdx) const;
>  
> -    bool hasEqualMotion(uint32_t absPartIdx, const CUData& candCU, uint32_t candAbsPartIdx) const;
> -
>      /* Check whether the current PU and a spatial neighboring PU are in same merge region */
>      bool isDiffMER(int xN, int yN, int xP, int yP) const { return ((xN >> 2) != (xP >> 2)) || ((yN >> 2) != (yP >> 2)); }
>  
> +    bool hasEqualMotion(InterNeighbourMV* cand1, InterNeighbourMV* cand2) const;
>      // add possible motion vector predictor candidates
>      bool getDirectPMV(MV& pmv, InterNeighbourMV *neighbours, uint32_t picList, uint32_t refIdx) const;
>      bool getIndirectPMV(MV& outMV, InterNeighbourMV *neighbours, uint32_t reference_list, uint32_t refIdx) const;
>      void getInterNeighbourMV(InterNeighbourMV *neighbour, uint32_t partUnitIdx, MVP_DIR dir) const;
> -
> -    bool getColMVP(MV& outMV, int& outRefIdx, int picList, int cuAddr, int absPartIdx) const;
>      bool getCollocatedMV(int cuAddr, int partUnitIdx, InterNeighbourMV *neighbour) const;
> -
> -    MV scaleMvByPOCDist(const MV& inMV, int curPOC, int curRefPOC, int colPOC, int colRefPOC) const;
> +    MV   scaleMvByPOCDist(const MV& inMV, int curPOC, int curRefPOC, int colPOC, int colRefPOC) const;
>  
>      void     deriveLeftRightTopIdx(uint32_t puIdx, uint32_t& partIdxLT, uint32_t& partIdxRT) const;
> -
>      uint32_t deriveCenterIdx(uint32_t puIdx) const;
>      uint32_t deriveRightBottomIdx(uint32_t puIdx) const;
>      uint32_t deriveLeftBottomIdx(uint32_t puIdx) const;
> diff -r ca0a4b2c53c5 -r abd266927ba3 source/encoder/analysis.cpp
> --- a/source/encoder/analysis.cpp	Wed Mar 18 08:09:12 2015 +0530
> +++ b/source/encoder/analysis.cpp	Wed Mar 18 12:29:00 2015 +0530
> @@ -1216,9 +1216,12 @@
>      bestPred->cu.setPredModeSubParts(MODE_INTER);
>      bestPred->cu.m_mergeFlag[0] = true;
>  
> +    merge.cu.getNeighbourMV(0, 0, merge.interNeighbours);
> +
>      MVField candMvField[MRG_MAX_NUM_CANDS][2]; // double length for mv of both lists
>      uint8_t candDir[MRG_MAX_NUM_CANDS];
> -    uint32_t numMergeCand = tempPred->cu.getInterMergeCandidates(0, 0, candMvField, candDir);
> +    uint32_t numMergeCand = tempPred->cu.getInterMergeCandidates(0, candMvField, candDir, merge.interNeighbours);
> +
>      PredictionUnit pu(merge.cu, cuGeom, 0);
>  
>      bestPred->sa8dCost = MAX_INT64;
> @@ -1317,9 +1320,11 @@
>      skip.cu.setPartSizeSubParts(SIZE_2Nx2N);
>      skip.cu.m_mergeFlag[0] = true;
>  
> +    merge.cu.getNeighbourMV(0, 0, merge.interNeighbours);
> +
>      MVField candMvField[MRG_MAX_NUM_CANDS][2]; // double length for mv of both lists
>      uint8_t candDir[MRG_MAX_NUM_CANDS];
> -    uint32_t numMergeCand = merge.cu.getInterMergeCandidates(0, 0, candMvField, candDir);
> +    uint32_t numMergeCand = merge.cu.getInterMergeCandidates(0, candMvField, candDir, merge.interNeighbours);
>      PredictionUnit pu(merge.cu, cuGeom, 0);
>  
>      bool foundCbf0Merge = false;
> diff -r ca0a4b2c53c5 -r abd266927ba3 source/encoder/search.cpp
> --- a/source/encoder/search.cpp	Wed Mar 18 08:09:12 2015 +0530
> +++ b/source/encoder/search.cpp	Wed Mar 18 12:29:00 2015 +0530
> @@ -1808,13 +1808,16 @@
>  }
>  
>  /* estimation of best merge coding of an inter PU (2Nx2N merge PUs are evaluated as their own mode) */
> -uint32_t Search::mergeEstimation(CUData& cu, const CUGeom& cuGeom, const PredictionUnit& pu, int puIdx, MergeData& m)
> +uint32_t Search::mergeEstimation(Mode& interMode, const CUGeom& cuGeom, const PredictionUnit& pu, int puIdx, MergeData& m)
>  {
> +    CUData& cu = interMode.cu;
>      X265_CHECK(cu.m_partSize[0] != SIZE_2Nx2N, "mergeEstimation() called for 2Nx2N\n");
>  
> +    interMode.cu.getNeighbourMV(puIdx, pu.puAbsPartIdx, interMode.interNeighbours);
> +
>      MVField  candMvField[MRG_MAX_NUM_CANDS][2];
>      uint8_t  candDir[MRG_MAX_NUM_CANDS];
> -    uint32_t numMergeCand = cu.getInterMergeCandidates(pu.puAbsPartIdx, puIdx, candMvField, candDir);
> +    uint32_t numMergeCand = cu.getInterMergeCandidates(puIdx, candMvField, candDir, interMode.interNeighbours);
>  
>      if (cu.isBipredRestriction())
>      {
> @@ -2021,7 +2024,7 @@
>          /* find best cost merge candidate. note: 2Nx2N merge and bidir are handled as separate modes */
>          if (cu.m_partSize[0] != SIZE_2Nx2N)
>          {
> -            mrgCost = mergeEstimation(cu, cuGeom, pu, puIdx, merge);
> +            mrgCost = mergeEstimation(interMode, cuGeom, pu, puIdx, merge);
>  
>              if (bMergeOnly && mrgCost != MAX_UINT)
>              {
> diff -r ca0a4b2c53c5 -r abd266927ba3 source/encoder/search.h
> --- a/source/encoder/search.h	Wed Mar 18 08:09:12 2015 +0530
> +++ b/source/encoder/search.h	Wed Mar 18 12:29:00 2015 +0530
> @@ -371,7 +371,7 @@
>      /* inter/ME helper functions */
>      void     checkBestMVP(MV* amvpCand, MV cMv, MV& mvPred, int& mvpIdx, uint32_t& outBits, uint32_t& outCost) const;
>      void     setSearchRange(const CUData& cu, MV mvp, int merange, MV& mvmin, MV& mvmax) const;
> -    uint32_t mergeEstimation(CUData& cu, const CUGeom& cuGeom, const PredictionUnit& pu, int puIdx, MergeData& m);
> +    uint32_t mergeEstimation(Mode& interMode, const CUGeom& cuGeom, const PredictionUnit& pu, int puIdx, MergeData& m);
>      static void getBlkBits(PartSize cuMode, bool bPSlice, int puIdx, uint32_t lastMode, uint32_t blockBit[3]);
>  
>      /* intra helper functions */
> _______________________________________________
> x265-devel mailing list
> x265-devel at videolan.org
> https://mailman.videolan.org/listinfo/x265-devel

-- 
Steve Borho


More information about the x265-devel mailing list