[x265] improve getInterMergeCandidates() (Re: add static const for local tables)

Satoshi Nakagawa nakagawa424 at oki.com
Sat Feb 8 14:59:41 CET 2014


further cleanup for getInterMergeCandidates()

# HG changeset patch
# User Satoshi Nakagawa <nakagawa424 at oki.com>
# Date 1391867438 -32400
#      Sat Feb 08 22:50:38 2014 +0900
# Branch mrg
# Node ID e74cb7ea8645e073c3102b70f023073e80bbb524
# Parent  fa9f7b56d4d870f5ebef47bb1007995c2d71ce1a
improve getInterMergeCandidates()

diff -r fa9f7b56d4d8 -r e74cb7ea8645 source/Lib/TLibCommon/TComDataCU.cpp
--- a/source/Lib/TLibCommon/TComDataCU.cpp	Fri Feb 07 21:37:17 2014 +0530
+++ b/source/Lib/TLibCommon/TComDataCU.cpp	Sat Feb 08 22:50:38 2014 +0900
@@ -1914,19 +1914,19 @@
  * \param numValidMergeCand
  */
 void TComDataCU::getInterMergeCandidates(uint32_t absPartIdx, uint32_t puIdx, TComMvField* mvFieldNeighbours, UChar* interDirNeighbours,
-                                         int& numValidMergeCand, int mrgCandIdx)
+                                         int& numValidMergeCand)
 {
     uint32_t absPartAddr = m_absIdxInLCU + absPartIdx;
-    bool abCandIsInter[MRG_MAX_NUM_CANDS];
-
-    for (uint32_t i = 0; i < getSlice()->getMaxNumMergeCand(); ++i)
+    const uint32_t maxNumMergeCand = getSlice()->getMaxNumMergeCand();
+    const bool isInterB = getSlice()->isInterB();
+
+    for (uint32_t i = 0; i < maxNumMergeCand; ++i)
     {
-        abCandIsInter[i] = false;
         mvFieldNeighbours[(i << 1)].refIdx = NOT_VALID;
         mvFieldNeighbours[(i << 1) + 1].refIdx = NOT_VALID;
     }
 
-    numValidMergeCand = getSlice()->getMaxNumMergeCand();
+    numValidMergeCand = maxNumMergeCand;
     // compute the location of the current PU
     int xP, yP, nPSW, nPSH;
     this->getPartPosition(puIdx, xP, yP, nPSW, nPSH);
@@ -1935,7 +1935,6 @@
 
     uint32_t partIdxLT, partIdxRT, partIdxLB;
     PartSize curPS = getPartitionSize(absPartIdx);
-    deriveLeftRightTopIdxGeneral(absPartIdx, puIdx, partIdxLT, partIdxRT);
     deriveLeftBottomIdxGeneral(absPartIdx, puIdx, partIdxLB);
 
     //left
@@ -1948,27 +1947,24 @@
         !cuLeft->isIntra(leftPartIdx);
     if (isAvailableA1)
     {
-        abCandIsInter[count] = true;
         // get Inter Dir
         interDirNeighbours[count] = cuLeft->getInterDir(leftPartIdx);
         // get Mv from Left
         cuLeft->getMvField(cuLeft, leftPartIdx, REF_PIC_LIST_0, mvFieldNeighbours[count << 1]);
-        if (getSlice()->isInterB())
+        if (isInterB)
         {
             cuLeft->getMvField(cuLeft, leftPartIdx, REF_PIC_LIST_1, mvFieldNeighbours[(count << 1) + 1]);
         }
-        if (mrgCandIdx == count)
+        count++;
+        // early termination
+        if (count == maxNumMergeCand)
         {
             return;
         }
-        count++;
     }
 
-    // early termination
-    if (count == getSlice()->getMaxNumMergeCand())
-    {
-        return;
-    }
+    deriveLeftRightTopIdxGeneral(absPartIdx, puIdx, partIdxLT, partIdxRT);
+
     // above
     uint32_t abovePartIdx = 0;
     TComDataCU* cuAbove = 0;
@@ -1979,25 +1975,20 @@
         !cuAbove->isIntra(abovePartIdx);
     if (isAvailableB1 && (!isAvailableA1 || !cuLeft->hasEqualMotion(leftPartIdx, cuAbove, abovePartIdx)))
     {
-        abCandIsInter[count] = true;
         // get Inter Dir
         interDirNeighbours[count] = cuAbove->getInterDir(abovePartIdx);
         // get Mv from Left
         cuAbove->getMvField(cuAbove, abovePartIdx, REF_PIC_LIST_0, mvFieldNeighbours[count << 1]);
-        if (getSlice()->isInterB())
+        if (isInterB)
         {
             cuAbove->getMvField(cuAbove, abovePartIdx, REF_PIC_LIST_1, mvFieldNeighbours[(count << 1) + 1]);
         }
-        if (mrgCandIdx == count)
+        count++;
+        // early termination
+        if (count == maxNumMergeCand)
         {
             return;
         }
-        count++;
-    }
-    // early termination
-    if (count == getSlice()->getMaxNumMergeCand())
-    {
-        return;
     }
 
     // above right
@@ -2009,25 +2000,20 @@
         !cuAboveRight->isIntra(aboveRightPartIdx);
     if (isAvailableB0 && (!isAvailableB1 || !cuAbove->hasEqualMotion(abovePartIdx, cuAboveRight, aboveRightPartIdx)))
     {
-        abCandIsInter[count] = true;
         // get Inter Dir
         interDirNeighbours[count] = cuAboveRight->getInterDir(aboveRightPartIdx);
         // get Mv from Left
         cuAboveRight->getMvField(cuAboveRight, aboveRightPartIdx, REF_PIC_LIST_0, mvFieldNeighbours[count << 1]);
-        if (getSlice()->isInterB())
+        if (isInterB)
         {
             cuAboveRight->getMvField(cuAboveRight, aboveRightPartIdx, REF_PIC_LIST_1, mvFieldNeighbours[(count << 1) + 1]);
         }
-        if (mrgCandIdx == count)
+        count++;
+        // early termination
+        if (count == maxNumMergeCand)
         {
             return;
         }
-        count++;
-    }
-    // early termination
-    if (count == getSlice()->getMaxNumMergeCand())
-    {
-        return;
     }
 
     //left bottom
@@ -2039,26 +2025,22 @@
         !cuLeftBottom->isIntra(leftBottomPartIdx);
     if (isAvailableA0 && (!isAvailableA1 || !cuLeft->hasEqualMotion(leftPartIdx, cuLeftBottom, leftBottomPartIdx)))
     {
-        abCandIsInter[count] = true;
         // get Inter Dir
         interDirNeighbours[count] = cuLeftBottom->getInterDir(leftBottomPartIdx);
         // get Mv from Left
         cuLeftBottom->getMvField(cuLeftBottom, leftBottomPartIdx, REF_PIC_LIST_0, mvFieldNeighbours[count << 1]);
-        if (getSlice()->isInterB())
+        if (isInterB)
         {
             cuLeftBottom->getMvField(cuLeftBottom, leftBottomPartIdx, REF_PIC_LIST_1, mvFieldNeighbours[(count << 1) + 1]);
         }
-        if (mrgCandIdx == count)
+        count++;
+        // early termination
+        if (count == maxNumMergeCand)
         {
             return;
         }
-        count++;
     }
-    // early termination
-    if (count == getSlice()->getMaxNumMergeCand())
-    {
-        return;
-    }
+
     // above left
     if (count < 4)
     {
@@ -2071,32 +2053,26 @@
         if (isAvailableB2 && (!isAvailableA1 || !cuLeft->hasEqualMotion(leftPartIdx, cuAboveLeft, aboveLeftPartIdx))
             && (!isAvailableB1 || !cuAbove->hasEqualMotion(abovePartIdx, cuAboveLeft, aboveLeftPartIdx)))
         {
-            abCandIsInter[count] = true;
             // get Inter Dir
             interDirNeighbours[count] = cuAboveLeft->getInterDir(aboveLeftPartIdx);
             // get Mv from Left
             cuAboveLeft->getMvField(cuAboveLeft, aboveLeftPartIdx, REF_PIC_LIST_0, mvFieldNeighbours[count << 1]);
-            if (getSlice()->isInterB())
+            if (isInterB)
             {
                 cuAboveLeft->getMvField(cuAboveLeft, aboveLeftPartIdx, REF_PIC_LIST_1, mvFieldNeighbours[(count << 1) + 1]);
             }
-            if (mrgCandIdx == count)
+            count++;
+            // early termination
+            if (count == maxNumMergeCand)
             {
                 return;
             }
-            count++;
         }
     }
-    // early termination
-    if (count == getSlice()->getMaxNumMergeCand())
-    {
-        return;
-    }
     if (getSlice()->getEnableTMVPFlag())
     {
         //>> MTK colocated-RightBottom
         uint32_t partIdxRB;
-        int lcuIdx;
 
         deriveRightBottomIdx(puIdx, partIdxRB);
 
@@ -2105,14 +2081,13 @@
 
         MV colmv;
         int refIdx;
+        int lcuIdx = -1;
 
         if ((m_pic->getCU(m_cuAddr)->getCUPelX() + g_rasterToPelX[uiAbsPartIdxTmp] + m_pic->getMinCUWidth()) >= m_slice->getSPS()->getPicWidthInLumaSamples())  // image boundary check
         {
-            lcuIdx = -1;
         }
         else if ((m_pic->getCU(m_cuAddr)->getCUPelY() + g_rasterToPelY[uiAbsPartIdxTmp] + m_pic->getMinCUHeight()) >= m_slice->getSPS()->getPicHeightInLumaSamples())
         {
-            lcuIdx = -1;
         }
         else
         {
@@ -2125,7 +2100,6 @@
             else if (uiAbsPartIdxTmp % numPartInCUWidth < numPartInCUWidth - 1)       // is not at the last column of LCU But is last row of LCU
             {
                 absPartAddr = g_rasterToZscan[(uiAbsPartIdxTmp + numPartInCUWidth + 1) % m_pic->getNumPartInCU()];
-                lcuIdx = -1;
             }
             else if (uiAbsPartIdxTmp / numPartInCUWidth < m_pic->getNumPartInHeight() - 1) // is not at the last row of LCU But is last column of LCU
             {
@@ -2135,7 +2109,6 @@
             else //is the right bottom corner of LCU
             {
                 absPartAddr = 0;
-                lcuIdx = -1;
             }
         }
 
@@ -2157,7 +2130,7 @@
             mvFieldNeighbours[2 * arrayAddr].setMvField(colmv, refIdx);
         }
 
-        if (getSlice()->isInterB())
+        if (isInterB)
         {
             bExistMV = lcuIdx >= 0 && xGetColMVP(REF_PIC_LIST_1, lcuIdx, absPartAddr, colmv, refIdx);
             if (bExistMV == false)
@@ -2174,70 +2147,63 @@
         if (dir != 0)
         {
             interDirNeighbours[arrayAddr] = dir;
-            abCandIsInter[arrayAddr] = true;
-
-            if (mrgCandIdx == count)
+
+            count++;
+            // early termination
+            if (count == maxNumMergeCand)
             {
                 return;
             }
-            count++;
         }
     }
-    // early termination
-    if (count == getSlice()->getMaxNumMergeCand())
+
+    uint32_t arrayAddr = count;
+
+    if (isInterB)
     {
-        return;
-    }
-    uint32_t arrayAddr = count;
-    uint32_t cutoff = arrayAddr;
-
-    if (getSlice()->isInterB())
-    {
-        // TODO: TComRom??
-        uint32_t priorityList0[12] = { 0, 1, 0, 2, 1, 2, 0, 3, 1, 3, 2, 3 };
-        uint32_t priorityList1[12] = { 1, 0, 2, 0, 2, 1, 3, 0, 3, 1, 3, 2 };
-
-        for (int idx = 0; idx < cutoff * (cutoff - 1) && arrayAddr != getSlice()->getMaxNumMergeCand(); idx++)
+        const int cutoff = count * (count - 1);
+        uint32_t priorityList0 = 0xEDC984; // { 0, 1, 0, 2, 1, 2, 0, 3, 1, 3, 2, 3 }
+        uint32_t priorityList1 = 0xB73621; // { 1, 0, 2, 0, 2, 1, 3, 0, 3, 1, 3, 2 }
+
+        for (int idx = 0; idx < cutoff; idx++)
         {
-            int i = priorityList0[idx];
-            int j = priorityList1[idx];
-            if (abCandIsInter[i] && abCandIsInter[j] && (interDirNeighbours[i] & 0x1) && (interDirNeighbours[j] & 0x2))
+            int i = priorityList0 & 3;
+            int j = priorityList1 & 3;
+            priorityList0 >>= 2;
+            priorityList1 >>= 2;
+
+            if ((interDirNeighbours[i] & 0x1) && (interDirNeighbours[j] & 0x2))
             {
-                abCandIsInter[arrayAddr] = true;
-                interDirNeighbours[arrayAddr] = 3;
-
                 // get Mv from cand[i] and cand[j]
-                mvFieldNeighbours[arrayAddr << 1].setMvField(mvFieldNeighbours[i << 1].mv, mvFieldNeighbours[i << 1].refIdx);
-                mvFieldNeighbours[(arrayAddr << 1) + 1].setMvField(mvFieldNeighbours[(j << 1) + 1].mv, mvFieldNeighbours[(j << 1) + 1].refIdx);
-
-                int refPOCL0 = m_slice->getRefPOC(REF_PIC_LIST_0, mvFieldNeighbours[(arrayAddr << 1)].refIdx);
-                int refPOCL1 = m_slice->getRefPOC(REF_PIC_LIST_1, mvFieldNeighbours[(arrayAddr << 1) + 1].refIdx);
-                if (refPOCL0 == refPOCL1 && mvFieldNeighbours[(arrayAddr << 1)].mv == mvFieldNeighbours[(arrayAddr << 1) + 1].mv)
+                int refIdxL0 = mvFieldNeighbours[i << 1].refIdx;
+                int refIdxL1 = mvFieldNeighbours[(j << 1) + 1].refIdx;
+                int refPOCL0 = m_slice->getRefPOC(REF_PIC_LIST_0, refIdxL0);
+                int refPOCL1 = m_slice->getRefPOC(REF_PIC_LIST_1, refIdxL1);
+                if (!(refPOCL0 == refPOCL1 && mvFieldNeighbours[i << 1].mv == mvFieldNeighbours[(j << 1) + 1].mv))
                 {
-                    abCandIsInter[arrayAddr] = false;
-                }
-                else
-                {
+                    mvFieldNeighbours[arrayAddr << 1].setMvField(mvFieldNeighbours[i << 1].mv, refIdxL0);
+                    mvFieldNeighbours[(arrayAddr << 1) + 1].setMvField(mvFieldNeighbours[(j << 1) + 1].mv, refIdxL1);
+                    interDirNeighbours[arrayAddr] = 3;
+
                     arrayAddr++;
+                    // early termination
+                    if (arrayAddr == maxNumMergeCand)
+                    {
+                        return;
+                    }
                 }
             }
         }
     }
-    // early termination
-    if (arrayAddr == getSlice()->getMaxNumMergeCand())
-    {
-        return;
-    }
-    int numRefIdx = (getSlice()->isInterB()) ? X265_MIN(m_slice->getNumRefIdx(REF_PIC_LIST_0), m_slice->getNumRefIdx(REF_PIC_LIST_1)) : m_slice->getNumRefIdx(REF_PIC_LIST_0);
+    int numRefIdx = (isInterB) ? X265_MIN(m_slice->getNumRefIdx(REF_PIC_LIST_0), m_slice->getNumRefIdx(REF_PIC_LIST_1)) : m_slice->getNumRefIdx(REF_PIC_LIST_0);
     int r = 0;
     int refcnt = 0;
-    while (arrayAddr < getSlice()->getMaxNumMergeCand())
+    while (arrayAddr < maxNumMergeCand)
     {
-        abCandIsInter[arrayAddr] = true;
         interDirNeighbours[arrayAddr] = 1;
         mvFieldNeighbours[arrayAddr << 1].setMvField(MV(0, 0), r);
 
-        if (getSlice()->isInterB())
+        if (isInterB)
         {
             interDirNeighbours[arrayAddr] = 3;
             mvFieldNeighbours[(arrayAddr << 1) + 1].setMvField(MV(0, 0), r);
@@ -2253,8 +2219,6 @@
             ++refcnt;
         }
     }
-
-    numValidMergeCand = arrayAddr;
 }
 
 /** Check whether the current PU and a spatial neighboring PU are in a same ME region.
diff -r fa9f7b56d4d8 -r e74cb7ea8645 source/Lib/TLibCommon/TComDataCU.h
--- a/source/Lib/TLibCommon/TComDataCU.h	Fri Feb 07 21:37:17 2014 +0530
+++ b/source/Lib/TLibCommon/TComDataCU.h	Sat Feb 08 22:50:38 2014 +0900
@@ -435,7 +435,7 @@
     void          deriveLeftBottomIdxAdi(uint32_t& partIdxLB, uint32_t partOffset, uint32_t partDepth);
 
     bool          hasEqualMotion(uint32_t absPartIdx, TComDataCU* candCU, uint32_t candAbsPartIdx);
-    void          getInterMergeCandidates(uint32_t absPartIdx, uint32_t puIdx, TComMvField* mFieldNeighbours, UChar* interDirNeighbours, int& numValidMergeCand, int mrgCandIdx = -1);
+    void          getInterMergeCandidates(uint32_t absPartIdx, uint32_t puIdx, TComMvField* mFieldNeighbours, UChar* interDirNeighbours, int& numValidMergeCand);
     void          deriveLeftRightTopIdxGeneral(uint32_t absPartIdx, uint32_t partIdx, uint32_t& partIdxLT, uint32_t& partIdxRT);
     void          deriveLeftBottomIdxGeneral(uint32_t absPartIdx, uint32_t partIdx, uint32_t& partIdxLB);






 
From: chen  <chenm003 at 163.com>
Subject: Re: [x265] add static const for local tables
Date: Fri, 7 Feb 2014 14:30:25 +0800 (CST)

> diff --git a/source/Lib/TLibCommon/TComDataCU.cpp b/source/Lib/TLibCommon/TComDataCU.cpp
> index 8b2636c..452a464 100644
> --- a/source/Lib/TLibCommon/TComDataCU.cpp
> +++ b/source/Lib/TLibCommon/TComDataCU.cpp
> @@ -2194,13 +2194,16 @@ void TComDataCU::getInterMergeCandidates(uint32_t absPartIdx, uint32_t puIdx, TC
>      if (getSlice()->isInterB())
>      {
>          // TODO: TComRom??
> -        uint32_t priorityList0[12] = { 0, 1, 0, 2, 1, 2, 0, 3, 1, 3, 2, 3 };
> -        uint32_t priorityList1[12] = { 1, 0, 2, 0, 2, 1, 3, 0, 3, 1, 3, 2 };
> +        uint32_t priorityList0 = 0xEDC984; // { 0, 1, 0, 2, 1, 2, 0, 3, 1, 3, 2, 3 }
> +        uint32_t priorityList1 = 0xB73621; // { 1, 0, 2, 0, 2, 1, 3, 0, 3, 1, 3, 2 }
>          for (int idx = 0; idx < cutoff * (cutoff - 1) && arrayAddr != getSlice()->getMaxNumMergeCand(); idx
>          {
> -            int i = priorityList0[idx];
> -            int j = priorityList1[idx];
> +            int i = priorityList0 & 3;
> +            int j = priorityList1 & 3;
> +            priorityList0 >>= 2;
> +            priorityList1 >>= 2;
> +
>              if (abCandIsInter[i] && abCandIsInter[j] && (interDirNeighbours[i] & 0x1) && (interDirNeighbour
>              {
>                  abCandIsInter[arrayAddr] = true;
> 
> At 2014-02-07 08:44:02,"Satoshi Nakagawa" <nakagawa424 at oki.com> wrote:
>># HG changeset patch
>># User Satoshi Nakagawa <nakagawa424 at oki.com>
>># Date 1391733642 -32400
>>#      Fri Feb 07 09:40:42 2014 +0900
>># Node ID 0564ff2d14d17ec46ea27d5cb20a770c1b80144f
>># Parent  40bec5582eca28ec0bc896e4e9412d580e42f4e4
>>add static const for local tables


More information about the x265-devel mailing list