[x265] simplify AMVPInfo to MV[2]

Satoshi Nakagawa nakagawa424 at oki.com
Thu Aug 21 11:38:07 CEST 2014


# HG changeset patch
# User Satoshi Nakagawa <nakagawa424 at oki.com>
# Date 1408613693 -32400
#      Thu Aug 21 18:34:53 2014 +0900
# Node ID de7b359fd9339231d6cdb02f9957cf8ef032ac87
# Parent  9461fc801cd2c339d6fee8eba0c00e6973e36125
simplify AMVPInfo to MV[2]

diff -r 9461fc801cd2 -r de7b359fd933 source/Lib/TLibCommon/CommonDef.h
--- a/source/Lib/TLibCommon/CommonDef.h	Wed Aug 20 14:57:41 2014 -0500
+++ b/source/Lib/TLibCommon/CommonDef.h	Thu Aug 21 18:34:53 2014 +0900
@@ -101,7 +101,7 @@
 #define MIN_QPSCALE                 0.21249999999999999
 #define MAX_MAX_QPSCALE             615.46574234477100
 
-#define AMVP_MAX_NUM_CANDS          2 // max number of final AMVP candidates
+#define AMVP_NUM_CANDS              2 // number of AMVP candidates
 #define MRG_MAX_NUM_CANDS           5 // max number of final merge candidates
 
 #define MAX_CHROMA_FORMAT_IDC       3 //  TODO: Remove me
diff -r 9461fc801cd2 -r de7b359fd933 source/Lib/TLibCommon/TComDataCU.cpp
--- a/source/Lib/TLibCommon/TComDataCU.cpp	Wed Aug 20 14:57:41 2014 -0500
+++ b/source/Lib/TLibCommon/TComDataCU.cpp	Thu Aug 21 18:34:53 2014 +0900
@@ -2000,9 +2000,9 @@
  * \param info
  * \param mvc
  */
-int TComDataCU::fillMvpCand(uint32_t partIdx, uint32_t partAddr, int picList, int refIdx, AMVPInfo* info, MV *mvc)
+int TComDataCU::fillMvpCand(uint32_t partIdx, uint32_t partAddr, int picList, int refIdx, MV* amvpCand, MV* mvc)
 {
-    info->m_num = 0;
+    int num = 0;
 
     //-- Get Spatial MV
     uint32_t partIdxLT, partIdxRT, partIdxLB;
@@ -2010,16 +2010,6 @@
     deriveLeftRightTopIdx(partIdx, partIdxLT, partIdxRT);
     deriveLeftBottomIdx(partIdx, partIdxLB);
 
-    uint32_t idx;
-    TComDataCU* tmpCU = getPUBelowLeft(idx, partIdxLB);
-    bool bAddedSmvp = (tmpCU != NULL) && (tmpCU->getPredictionMode(idx) != MODE_INTRA);
-
-    if (!bAddedSmvp)
-    {
-        tmpCU = getPULeft(idx, partIdxLB);
-        bAddedSmvp = (tmpCU != NULL) && (tmpCU->getPredictionMode(idx) != MODE_INTRA);
-    }
-
     MV mv[MD_ABOVE_LEFT + 1];
     MV mvOrder[MD_ABOVE_LEFT + 1];
     bool valid[MD_ABOVE_LEFT + 1];
@@ -2039,30 +2029,32 @@
 
     // Left predictor search
     if (valid[MD_BELOW_LEFT])
-        info->m_mvCand[info->m_num++] = mv[MD_BELOW_LEFT];
+        amvpCand[num++] = mv[MD_BELOW_LEFT];
     else if (valid[MD_LEFT])
-        info->m_mvCand[info->m_num++] = mv[MD_LEFT];
+        amvpCand[num++] = mv[MD_LEFT];
     else if (validOrder[MD_BELOW_LEFT])
-        info->m_mvCand[info->m_num++] = mvOrder[MD_BELOW_LEFT];
+        amvpCand[num++] = mvOrder[MD_BELOW_LEFT];
     else if (validOrder[MD_LEFT])
-        info->m_mvCand[info->m_num++] = mvOrder[MD_LEFT];
+        amvpCand[num++] = mvOrder[MD_LEFT];
+
+    bool bAddedSmvp = num > 0;
 
     // Above predictor search
     if (valid[MD_ABOVE_RIGHT])
-        info->m_mvCand[info->m_num++] = mv[MD_ABOVE_RIGHT];
+        amvpCand[num++] = mv[MD_ABOVE_RIGHT];
     else if (valid[MD_ABOVE])
-        info->m_mvCand[info->m_num++] = mv[MD_ABOVE];
+        amvpCand[num++] = mv[MD_ABOVE];
     else if (valid[MD_ABOVE_LEFT])
-        info->m_mvCand[info->m_num++] = mv[MD_ABOVE_LEFT];
+        amvpCand[num++] = mv[MD_ABOVE_LEFT];
 
     if (!bAddedSmvp)
     {
         if (validOrder[MD_ABOVE_RIGHT])
-            info->m_mvCand[info->m_num++] = mvOrder[MD_ABOVE_RIGHT];
+            amvpCand[num++] = mvOrder[MD_ABOVE_RIGHT];
         else if (validOrder[MD_ABOVE])
-            info->m_mvCand[info->m_num++] = mvOrder[MD_ABOVE];
+            amvpCand[num++] = mvOrder[MD_ABOVE];
         else if (validOrder[MD_ABOVE_LEFT])
-            info->m_mvCand[info->m_num++] = mvOrder[MD_ABOVE_LEFT];
+            amvpCand[num++] = mvOrder[MD_ABOVE_LEFT];
     }
 
     int numMvc = 0;
@@ -2075,12 +2067,12 @@
             mvc[numMvc++] = mvOrder[dir];
     }
 
-    if (info->m_num == 2)
+    if (num == 2)
     {
-        if (info->m_mvCand[0] == info->m_mvCand[1])
-            info->m_num = 1;
+        if (amvpCand[0] == amvpCand[1])
+            num = 1;
         else
-            /* AMVP_MAX_NUM_CANDS = 2 */
+            /* AMVP_NUM_CANDS = 2 */
             return numMvc;
     }
 
@@ -2126,7 +2118,7 @@
         }
         if (lcuIdx >= 0 && xGetColMVP(picList, lcuIdx, absPartAddr, colmv, refIdxCol))
         {
-            info->m_mvCand[info->m_num++] = colmv;
+            amvpCand[num++] = colmv;
             mvc[numMvc++] = colmv;
         }
         else
@@ -2136,17 +2128,16 @@
             xDeriveCenterIdx(partIdx, partIdxCenter);
             if (xGetColMVP(picList, curLCUIdx, partIdxCenter, colmv, refIdxCol))
             {
-                info->m_mvCand[info->m_num++] = colmv;
+                amvpCand[num++] = colmv;
                 mvc[numMvc++] = colmv;
             }
         }
         //----  co-located RightBottom Temporal Predictor  ---//
     }
 
-    while (info->m_num < AMVP_MAX_NUM_CANDS)
+    while (num < AMVP_NUM_CANDS)
     {
-        info->m_mvCand[info->m_num] = 0;
-        info->m_num++;
+        amvpCand[num++] = 0;
     }
 
     return numMvc;
diff -r 9461fc801cd2 -r de7b359fd933 source/Lib/TLibCommon/TComDataCU.h
--- a/source/Lib/TLibCommon/TComDataCU.h	Wed Aug 20 14:57:41 2014 -0500
+++ b/source/Lib/TLibCommon/TComDataCU.h	Thu Aug 21 18:34:53 2014 +0900
@@ -422,7 +422,7 @@
 
     void          getMvField(TComDataCU* cu, uint32_t absPartIdx, int picList, TComMvField& rcMvField);
 
-    int           fillMvpCand(uint32_t partIdx, uint32_t partAddr, int picList, int refIdx, AMVPInfo* info, MV *mvc);
+    int           fillMvpCand(uint32_t partIdx, uint32_t partAddr, int picList, int refIdx, MV* amvpCand, MV* mvc);
     bool          isDiffMER(int xN, int yN, int xP, int yP);
     void          getPartPosition(uint32_t partIdx, int& xP, int& yP, int& nPSW, int& nPSH);
     void          setMVPIdx(int picList, uint32_t idx, int mvpIdx) { m_mvpIdx[picList][idx] = (uint8_t)mvpIdx; }
diff -r 9461fc801cd2 -r de7b359fd933 source/Lib/TLibCommon/TComMotionInfo.h
--- a/source/Lib/TLibCommon/TComMotionInfo.h	Wed Aug 20 14:57:41 2014 -0500
+++ b/source/Lib/TLibCommon/TComMotionInfo.h	Thu Aug 21 18:34:53 2014 +0900
@@ -52,13 +52,6 @@
 // Type definition
 // ====================================================================================================================
 
-/// parameters for AMVP
-struct AMVPInfo
-{
-    MV  m_mvCand[AMVP_MAX_NUM_CANDS +1];   ///< array of motion vector predictor candidates
-    int m_num;                             ///< number of motion vector predictor candidates
-};
-
 typedef struct
 {
     MV*   m_mvMemBlock;
diff -r 9461fc801cd2 -r de7b359fd933 source/Lib/TLibEncoder/TEncSearch.cpp
--- a/source/Lib/TLibEncoder/TEncSearch.cpp	Wed Aug 20 14:57:41 2014 -0500
+++ b/source/Lib/TLibEncoder/TEncSearch.cpp	Thu Aug 21 18:34:53 2014 +0900
@@ -1851,7 +1851,8 @@
  */
 bool TEncSearch::predInterSearch(TComDataCU* cu, TComYuv* predYuv, bool bMergeOnly, bool bChroma)
 {
-    AMVPInfo amvpInfo[2][MAX_NUM_REF];
+    MV amvpCand[2][MAX_NUM_REF][AMVP_NUM_CANDS];
+    MV mvc[(MD_ABOVE_LEFT + 1) * 2 + 1];
 
     Slice *slice        = cu->m_slice;
     TComPicYuv *fenc    = slice->m_pic->getPicYuvOrg();
@@ -1931,17 +1932,16 @@
                 uint32_t bits = listSelBits[l] + MVP_IDX_BITS;
                 bits += getTUBits(ref, numRefIdx[l]);
 
-                MV mvc[(MD_ABOVE_LEFT + 1) * 2 + 1];
-                int numMvc = cu->fillMvpCand(partIdx, partAddr, l, ref, &amvpInfo[l][ref], mvc);
+                int numMvc = cu->fillMvpCand(partIdx, partAddr, l, ref, amvpCand[l][ref], mvc);
 
                 // Pick the best possible MVP from AMVP candidates based on least residual
                 uint32_t bestCost = MAX_INT;
                 int mvpIdx = 0;
                 int merange = m_param->searchRange;
 
-                for (int i = 0; i < amvpInfo[l][ref].m_num; i++)
+                for (int i = 0; i < AMVP_NUM_CANDS; i++)
                 {
-                    MV mvCand = amvpInfo[l][ref].m_mvCand[i];
+                    MV mvCand = amvpCand[l][ref][i];
 
                     // NOTE: skip mvCand if Y is > merange and -FN>1
                     if (m_bFrameParallel && (mvCand.y >= (merange + 1) * 4))
@@ -1961,7 +1961,7 @@
                     }
                 }
 
-                MV mvmin, mvmax, outmv, mvp = amvpInfo[l][ref].m_mvCand[mvpIdx];
+                MV mvmin, mvmax, outmv, mvp = amvpCand[l][ref][mvpIdx];
 
                 xSetSearchRange(cu, mvp, merange, mvmin, mvmax);
                 int satdCost = m_me.motionEstimate(&slice->m_mref[l][ref], mvmin, mvmax, mvp, numMvc, mvc, merange, outmv);
@@ -1971,7 +1971,7 @@
                 uint32_t cost = (satdCost - m_me.mvcost(outmv)) + m_rdCost.getCost(bits);
 
                 /* Refine MVP selection, updates: mvp, mvpIdx, bits, cost */
-                xCheckBestMVP(&amvpInfo[l][ref], outmv, mvp, mvpIdx, bits, cost);
+                xCheckBestMVP(amvpCand[l][ref], outmv, mvp, mvpIdx, bits, cost);
 
                 if (cost < list[l].cost)
                 {
@@ -2039,19 +2039,17 @@
 
                 MV mvp0 = list[0].mvp;
                 int mvpIdx0 = list[0].mvpIdx;
-                m_me.setMVP(mvp0);
-                uint32_t bits0 = list[0].bits - m_me.bitcost(list[0].mv) + m_me.bitcost(mvzero);
+                uint32_t bits0 = list[0].bits - m_me.bitcost(list[0].mv, mvp0) + m_me.bitcost(mvzero, mvp0);
 
                 MV mvp1 = list[1].mvp;
                 int mvpIdx1 = list[1].mvpIdx;
-                m_me.setMVP(mvp1);
-                uint32_t bits1 = list[1].bits - m_me.bitcost(list[1].mv) + m_me.bitcost(mvzero);
+                uint32_t bits1 = list[1].bits - m_me.bitcost(list[1].mv, mvp1) + m_me.bitcost(mvzero, mvp1);
 
                 uint32_t cost = satdCost + m_rdCost.getCost(bits0) + m_rdCost.getCost(bits1);
 
                 /* refine MVP selection for zero mv, updates: mvp, mvpidx, bits, cost */
-                xCheckBestMVP(&amvpInfo[0][list[0].ref], mvzero, mvp0, mvpIdx0, bits0, cost);
-                xCheckBestMVP(&amvpInfo[1][list[1].ref], mvzero, mvp1, mvpIdx1, bits1, cost);
+                xCheckBestMVP(amvpCand[0][list[0].ref], mvzero, mvp0, mvpIdx0, bits0, cost);
+                xCheckBestMVP(amvpCand[1][list[1].ref], mvzero, mvp1, mvpIdx1, bits1, cost);
 
                 if (cost < bidirCost)
                 {
@@ -2190,37 +2188,19 @@
 }
 
 /* Check if using an alternative MVP would result in a smaller MVD + signal bits */
-void TEncSearch::xCheckBestMVP(AMVPInfo* amvpInfo, MV mv, MV& mvPred, int& outMvpIdx, uint32_t& outBits, uint32_t& outCost)
+void TEncSearch::xCheckBestMVP(MV* amvpCand, MV mv, MV& mvPred, int& outMvpIdx, uint32_t& outBits, uint32_t& outCost)
 {
-    X265_CHECK(amvpInfo->m_mvCand[outMvpIdx] == mvPred, "xCheckBestMVP: unexpected mvPred\n");
-
-    m_me.setMVP(mvPred);
-    int bestMvpIdx = outMvpIdx;
-    int mvBitsOrig = m_me.bitcost(mv) + MVP_IDX_BITS;
-    int bestMvBits = mvBitsOrig;
-
-    for (int mvpIdx = 0; mvpIdx < amvpInfo->m_num; mvpIdx++)
+    X265_CHECK(amvpCand[outMvpIdx] == mvPred, "xCheckBestMVP: unexpected mvPred\n");
+
+    int mvpIdx = !outMvpIdx;
+    MV mvp = amvpCand[mvpIdx];
+    int diffBits = m_me.bitcost(mv, mvp) - m_me.bitcost(mv, mvPred);
+    if (diffBits < 0)
     {
-        if (mvpIdx == outMvpIdx)
-            continue;
-
-        m_me.setMVP(amvpInfo->m_mvCand[mvpIdx]);
-        int mvbits = m_me.bitcost(mv) + MVP_IDX_BITS;
-
-        if (mvbits < bestMvBits)
-        {
-            bestMvBits = mvbits;
-            bestMvpIdx = mvpIdx;
-        }
-    }
-
-    if (bestMvpIdx != outMvpIdx) // if changed
-    {
-        mvPred = amvpInfo->m_mvCand[bestMvpIdx];
-
-        outMvpIdx = bestMvpIdx;
+        outMvpIdx = mvpIdx;
+        mvPred = mvp;
         uint32_t origOutBits = outBits;
-        outBits = origOutBits - mvBitsOrig + bestMvBits;
+        outBits = origOutBits + diffBits;
         outCost = (outCost - m_rdCost.getCost(origOutBits)) + m_rdCost.getCost(outBits);
     }
 }
diff -r 9461fc801cd2 -r de7b359fd933 source/Lib/TLibEncoder/TEncSearch.h
--- a/source/Lib/TLibEncoder/TEncSearch.h	Wed Aug 20 14:57:41 2014 -0500
+++ b/source/Lib/TLibEncoder/TEncSearch.h	Thu Aug 21 18:34:53 2014 +0900
@@ -216,7 +216,7 @@
     // Inter search (AMP)
     // --------------------------------------------------------------------------------------------
 
-    void xCheckBestMVP(AMVPInfo* amvpInfo, MV cMv, MV& mvPred, int& mvpIdx,
+    void xCheckBestMVP(MV* amvpCand, MV cMv, MV& mvPred, int& mvpIdx,
                        uint32_t& outBits, uint32_t& outCost);
 
     void xGetBlkBits(PartSize cuMode, bool bPSlice, int partIdx, uint32_t lastMode, uint32_t blockBit[3]);
diff -r 9461fc801cd2 -r de7b359fd933 source/encoder/bitcost.h
--- a/source/encoder/bitcost.h	Wed Aug 20 14:57:41 2014 -0500
+++ b/source/encoder/bitcost.h	Thu Aug 21 18:34:53 2014 +0900
@@ -45,12 +45,18 @@
     inline uint16_t mvcost(const MV& mv) const      { return m_cost_mvx[mv.x] + m_cost_mvy[mv.y]; }
 
     // return bit cost of motion vector difference, without lambda
-    inline uint16_t bitcost(const MV& mv) const
+    inline uint32_t bitcost(const MV& mv) const
     {
-        return (uint16_t)(s_bitsizes[abs(mv.x - m_mvp.x)] +
+        return (uint32_t)(s_bitsizes[abs(mv.x - m_mvp.x)] +
                           s_bitsizes[abs(mv.y - m_mvp.y)] + 0.5f);
     }
 
+    static inline uint32_t bitcost(const MV& mv, const MV& mvp)
+    {
+        return (uint32_t)(s_bitsizes[abs(mv.x - mvp.x)] +
+                          s_bitsizes[abs(mv.y - mvp.y)] + 0.5f);
+    }
+
     static void destroy();
 
 protected:


More information about the x265-devel mailing list