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

ashok at multicorewareinc.com ashok at multicorewareinc.com
Wed Mar 18 09:31:15 CET 2015


# 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.

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 */


More information about the x265-devel mailing list