[x265] [PATCH] analysis: Dump the best MV statistics and re-use this for analysis load mode

gopu at multicorewareinc.com gopu at multicorewareinc.com
Mon Nov 10 11:54:51 CET 2014


# HG changeset patch
# User Gopu Govindaswamy <gopu at multicorewareinc.com>
# Date 1415611936 -19800
#      Mon Nov 10 15:02:16 2014 +0530
# Node ID 31b6ed10054e753331b65a5e08e512f2f5b22b2d
# Parent  1e04e178a349ff3a27ed0207cca7bdd9f0db4ff8
analysis: Dump the best MV statistics and re-use this for analysis load mode

this patch is to fix the bug in inter information sharing when using
analysis=load|save mode, existing algorithm always dump and share the last part
best MV for each prediction, but there is multiple part's each with its own
prediction, the fix is to dump and share all part best MV's for each prediction

diff -r 1e04e178a349 -r 31b6ed10054e source/common/common.h
--- a/source/common/common.h	Sun Nov 09 00:30:09 2014 -0600
+++ b/source/common/common.h	Mon Nov 10 15:02:16 2014 +0530
@@ -291,6 +291,7 @@
 #define MAX_NUM_REF                 16 // max. number of entries in picture reference list
 
 #define REF_NOT_VALID               -1
+#define MAX_NUM_PART                 4
 
 #define AMVP_NUM_CANDS              2 // number of AMVP candidates
 #define MRG_MAX_NUM_CANDS           5 // max number of final merge candidates
diff -r 1e04e178a349 -r 31b6ed10054e source/encoder/analysis.cpp
--- a/source/encoder/analysis.cpp	Sun Nov 09 00:30:09 2014 -0600
+++ b/source/encoder/analysis.cpp	Mon Nov 10 15:02:16 2014 +0530
@@ -1407,12 +1407,16 @@
 
     if (m_param->analysisMode == X265_ANALYSIS_LOAD && m_interAnalysisData)
     {
-        for (int32_t i = 0; i < numPredDir; i++)
+        for (uint32_t part = 0; part < interMode.cu.getNumPartInter(); part++)
         {
-            interMode.bestME[i].costZero = !!m_interAnalysisData->costZero[i];
-            interMode.bestME[i].mv.x = m_interAnalysisData->mvx[i];
-            interMode.bestME[i].mv.y = m_interAnalysisData->mvy[i];
-            interMode.bestME[i].ref = m_interAnalysisData->ref[i];
+            for (int32_t i = 0; i < numPredDir; i++)
+            {
+                interMode.bestME[part][i].costZero = !!m_interAnalysisData->costZero[i];
+                interMode.bestME[part][i].mv.x = m_interAnalysisData->mvx[i];
+                interMode.bestME[part][i].mv.y = m_interAnalysisData->mvy[i];
+                interMode.bestME[part][i].ref = m_interAnalysisData->ref[i];
+            }
+            m_interAnalysisData++;
         }
     }
     if (predInterSearch(interMode, cuGeom, false, false))
@@ -1425,17 +1429,20 @@
 
         if (m_param->analysisMode == X265_ANALYSIS_SAVE && m_interAnalysisData)
         {
-            for (int32_t i = 0; i < numPredDir; i++)
+            for (uint32_t part = 0; part < interMode.cu.getNumPartInter(); part++)
             {
-                m_interAnalysisData->costZero[i] = interMode.bestME[i].costZero;
-                m_interAnalysisData->mvx[i] = interMode.bestME[i].mv.x;
-                m_interAnalysisData->mvy[i] = interMode.bestME[i].mv.y;
-                m_interAnalysisData->ref[i] = interMode.bestME[i].ref;
+                for (int32_t i = 0; i < numPredDir; i++)
+                {
+                    m_interAnalysisData->costZero[i] = interMode.bestME[part][i].costZero;
+                    m_interAnalysisData->mvx[i] = interMode.bestME[part][i].mv.x;
+                    m_interAnalysisData->mvy[i] = interMode.bestME[part][i].mv.y;
+                    m_interAnalysisData->ref[i] = interMode.bestME[part][i].ref;
+                }
+                m_interAnalysisData->zOrder = cuGeom.encodeIdx;
+                m_interAnalysisData->depth  = cuGeom.depth;
+                m_interAnalysisData++;
             }
-            m_interAnalysisData->zOrder = cuGeom.encodeIdx;
-            m_interAnalysisData->depth  = cuGeom.depth;
         }
-        m_interAnalysisData++;
     }
     else
     {
@@ -1453,12 +1460,16 @@
 
     if (m_param->analysisMode == X265_ANALYSIS_LOAD && m_interAnalysisData)
     {
-        for (int32_t i = 0; i < numPredDir; i++)
+        for (uint32_t part = 0; part < interMode.cu.getNumPartInter(); part++)
         {
-            interMode.bestME[i].costZero = !!m_interAnalysisData->costZero[i];
-            interMode.bestME[i].mv.x = m_interAnalysisData->mvx[i];
-            interMode.bestME[i].mv.y = m_interAnalysisData->mvy[i];
-            interMode.bestME[i].ref = m_interAnalysisData->ref[i];
+            for (int32_t i = 0; i < numPredDir; i++)
+            {
+                interMode.bestME[part][i].costZero = !!m_interAnalysisData->costZero[i];
+                interMode.bestME[part][i].mv.x = m_interAnalysisData->mvx[i];
+                interMode.bestME[part][i].mv.y = m_interAnalysisData->mvy[i];
+                interMode.bestME[part][i].ref = m_interAnalysisData->ref[i];
+            }
+            m_interAnalysisData++;
         }
     }
     if (predInterSearch(interMode, cuGeom, bMergeOnly, true))
@@ -1467,17 +1478,20 @@
         encodeResAndCalcRdInterCU(interMode, cuGeom);
         if (m_param->analysisMode == X265_ANALYSIS_SAVE && m_interAnalysisData)
         {
-            for (int32_t i = 0; i < numPredDir; i++)
+            for (uint32_t part = 0; part < interMode.cu.getNumPartInter(); part++)
             {
-                m_interAnalysisData->costZero[i] = interMode.bestME[i].costZero;
-                m_interAnalysisData->mvx[i] = interMode.bestME[i].mv.x;
-                m_interAnalysisData->mvy[i] = interMode.bestME[i].mv.y;
-                m_interAnalysisData->ref[i] = interMode.bestME[i].ref;
+                for (int32_t i = 0; i < numPredDir; i++)
+                {
+                    m_interAnalysisData->costZero[i] = interMode.bestME[part][i].costZero;
+                    m_interAnalysisData->mvx[i] = interMode.bestME[part][i].mv.x;
+                    m_interAnalysisData->mvy[i] = interMode.bestME[part][i].mv.y;
+                    m_interAnalysisData->ref[i] = interMode.bestME[part][i].ref;
+                }
+                m_interAnalysisData->zOrder = cuGeom.encodeIdx;
+                m_interAnalysisData->depth  = cuGeom.depth;
+                m_interAnalysisData++;
             }
-            m_interAnalysisData->zOrder = cuGeom.encodeIdx;
-            m_interAnalysisData->depth  = cuGeom.depth;
         }
-        m_interAnalysisData++;
     }
     else
     {
diff -r 1e04e178a349 -r 31b6ed10054e source/encoder/search.cpp
--- a/source/encoder/search.cpp	Sun Nov 09 00:30:09 2014 -0600
+++ b/source/encoder/search.cpp	Mon Nov 10 15:02:16 2014 +0530
@@ -1907,15 +1907,15 @@
 
     /* tie goes to the smallest ref ID, just like --no-pme */
     ScopedLock _lock(master.m_outputLock);
-    if (cost < interMode.bestME[list].cost ||
-       (cost == interMode.bestME[list].cost && ref < interMode.bestME[list].ref))
+    if (cost < interMode.bestME[part][list].cost ||
+       (cost == interMode.bestME[part][list].cost && ref < interMode.bestME[part][list].ref))
     {
-        interMode.bestME[list].mv = outmv;
-        interMode.bestME[list].mvp = mvp;
-        interMode.bestME[list].mvpIdx = mvpIdx;
-        interMode.bestME[list].ref = ref;
-        interMode.bestME[list].cost = cost;
-        interMode.bestME[list].bits = bits;
+        interMode.bestME[part][list].mv = outmv;
+        interMode.bestME[part][list].mvp = mvp;
+        interMode.bestME[part][list].mvpIdx = mvpIdx;
+        interMode.bestME[part][list].ref = ref;
+        interMode.bestME[part][list].cost = cost;
+        interMode.bestME[part][list].bits = bits;
     }
 }
 
@@ -1988,17 +1988,17 @@
         uint32_t bidirCost = MAX_UINT;
         int bidirBits = 0;
 
-        interMode.bestME[0].cost = MAX_UINT;
-        interMode.bestME[1].cost = MAX_UINT;
+        interMode.bestME[puIdx][0].cost = MAX_UINT;
+        interMode.bestME[puIdx][1].cost = MAX_UINT;
 
         getBlkBits((PartSize)cu.m_partSize[0], slice->isInterP(), puIdx, lastMode, m_listSelBits);
 
         /* Uni-directional prediction */
-        if (m_param->analysisMode == X265_ANALYSIS_LOAD && interMode.bestME[0].ref >= 0)
+        if (m_param->analysisMode == X265_ANALYSIS_LOAD && interMode.bestME[puIdx][0].ref >= 0)
         {
             for (int l = 0; l < numPredDir; l++)
             {
-                int ref = interMode.bestME[l].ref;
+                int ref = interMode.bestME[puIdx][l].ref;
                 uint32_t bits = m_listSelBits[l] + MVP_IDX_BITS;
                 bits += getTUBits(ref, numRefIdx[l]);
 
@@ -2030,13 +2030,13 @@
 
                 MV mvmin, mvmax, outmv, mvp = interMode.amvpCand[l][ref][mvpIdx];
                 m_me.setMVP(mvp);
-                MV bmv(interMode.bestME[l].mv.x, interMode.bestME[l].mv.y);
+                MV bmv(interMode.bestME[puIdx][l].mv.x, interMode.bestME[puIdx][l].mv.y);
 
                 int satdCost;
-                if (interMode.bestME[l].costZero)
+                if (interMode.bestME[puIdx][l].costZero)
                     satdCost = m_me.mvcost(bmv);
                 else
-                    satdCost = interMode.bestME[l].cost;
+                    satdCost = interMode.bestME[puIdx][l].cost;
 
                 /* Get total cost of partition, but only include MV bit cost once */
                 bits += m_me.bitcost(bmv);
@@ -2045,14 +2045,14 @@
                 /* Refine MVP selection, updates: mvp, mvpIdx, bits, cost */
                 checkBestMVP(interMode.amvpCand[l][ref], outmv, mvp, mvpIdx, bits, cost);
 
-                if (cost < interMode.bestME[l].cost)
+                if (cost < interMode.bestME[puIdx][l].cost)
                 {
-                    interMode.bestME[l].mv = outmv;
-                    interMode.bestME[l].mvp = mvp;
-                    interMode.bestME[l].mvpIdx = mvpIdx;
-                    interMode.bestME[l].ref = ref;
-                    interMode.bestME[l].cost = cost;
-                    interMode.bestME[l].bits = bits;
+                    interMode.bestME[puIdx][l].mv = outmv;
+                    interMode.bestME[puIdx][l].mvp = mvp;
+                    interMode.bestME[puIdx][l].mvpIdx = mvpIdx;
+                    interMode.bestME[puIdx][l].ref = ref;
+                    interMode.bestME[puIdx][l].cost = cost;
+                    interMode.bestME[puIdx][l].bits = bits;
                 }
             }
         }
@@ -2148,31 +2148,31 @@
                     /* Refine MVP selection, updates: mvp, mvpIdx, bits, cost */
                     checkBestMVP(interMode.amvpCand[l][ref], outmv, mvp, mvpIdx, bits, cost);
 
-                    if (cost < interMode.bestME[l].cost)
+                    if (cost < interMode.bestME[puIdx][l].cost)
                     {
-                        interMode.bestME[l].mv = outmv;
-                        interMode.bestME[l].mvp = mvp;
-                        interMode.bestME[l].mvpIdx = mvpIdx;
-                        interMode.bestME[l].ref = ref;
-                        interMode.bestME[l].cost = cost;
-                        interMode.bestME[l].bits = bits;
+                        interMode.bestME[puIdx][l].mv = outmv;
+                        interMode.bestME[puIdx][l].mvp = mvp;
+                        interMode.bestME[puIdx][l].mvpIdx = mvpIdx;
+                        interMode.bestME[puIdx][l].ref = ref;
+                        interMode.bestME[puIdx][l].cost = cost;
+                        interMode.bestME[puIdx][l].bits = bits;
                     }
                 }
             }
         }
 
         /* Bi-directional prediction */
-        if (slice->isInterB() && !cu.isBipredRestriction() && interMode.bestME[0].cost != MAX_UINT && interMode.bestME[1].cost != MAX_UINT)
+        if (slice->isInterB() && !cu.isBipredRestriction() && interMode.bestME[puIdx][0].cost != MAX_UINT && interMode.bestME[puIdx][1].cost != MAX_UINT)
         {
-            bidir[0] = interMode.bestME[0];
-            bidir[1] = interMode.bestME[1];
+            bidir[0] = interMode.bestME[puIdx][0];
+            bidir[1] = interMode.bestME[puIdx][1];
 
             /* Generate reference subpels */
-            PicYuv* refPic0  = slice->m_refPicList[0][interMode.bestME[0].ref]->m_reconPic;
-            PicYuv* refPic1  = slice->m_refPicList[1][interMode.bestME[1].ref]->m_reconPic;
+            PicYuv* refPic0  = slice->m_refPicList[0][interMode.bestME[puIdx][0].ref]->m_reconPic;
+            PicYuv* refPic1  = slice->m_refPicList[1][interMode.bestME[puIdx][1].ref]->m_reconPic;
             Yuv*    bidirYuv = m_rqt[cuGeom.depth].bidirPredYuv;
-            predInterLumaPixel(bidirYuv[0], *refPic0, interMode.bestME[0].mv);
-            predInterLumaPixel(bidirYuv[1], *refPic1, interMode.bestME[1].mv);
+            predInterLumaPixel(bidirYuv[0], *refPic0, interMode.bestME[puIdx][0].mv);
+            predInterLumaPixel(bidirYuv[1], *refPic1, interMode.bestME[puIdx][1].mv);
 
             pixel *pred0 = bidirYuv[0].getLumaAddr(m_puAbsPartIdx);
             pixel *pred1 = bidirYuv[1].getLumaAddr(m_puAbsPartIdx);
@@ -2181,10 +2181,10 @@
             primitives.pixelavg_pp[partEnum](tmpPredYuv.m_buf[0], tmpPredYuv.m_size, pred0, bidirYuv[0].m_size, pred1, bidirYuv[1].m_size, 32);
             int satdCost = m_me.bufSATD(tmpPredYuv.m_buf[0], tmpPredYuv.m_size);
 
-            bidirBits = interMode.bestME[0].bits + interMode.bestME[1].bits + m_listSelBits[2] - (m_listSelBits[0] + m_listSelBits[1]);
+            bidirBits = interMode.bestME[puIdx][0].bits + interMode.bestME[puIdx][1].bits + m_listSelBits[2] - (m_listSelBits[0] + m_listSelBits[1]);
             bidirCost = satdCost + m_rdCost.getCost(bidirBits);
 
-            bool bTryZero = interMode.bestME[0].mv.notZero() || interMode.bestME[1].mv.notZero();
+            bool bTryZero = interMode.bestME[puIdx][0].mv.notZero() || interMode.bestME[puIdx][1].mv.notZero();
             if (bTryZero)
             {
                 /* Do not try zero MV if unidir motion predictors are beyond
@@ -2196,32 +2196,32 @@
                 mvmin <<= 2;
                 mvmax <<= 2;
 
-                bTryZero &= interMode.bestME[0].mvp.checkRange(mvmin, mvmax);
-                bTryZero &= interMode.bestME[1].mvp.checkRange(mvmin, mvmax);
+                bTryZero &= interMode.bestME[puIdx][0].mvp.checkRange(mvmin, mvmax);
+                bTryZero &= interMode.bestME[puIdx][1].mvp.checkRange(mvmin, mvmax);
             }
             if (bTryZero)
             {
                 /* coincident blocks of the two reference pictures */
-                pixel *ref0 = m_slice->m_mref[0][interMode.bestME[0].ref].getLumaAddr(cu.m_cuAddr, cuGeom.encodeIdx + m_puAbsPartIdx);
-                pixel *ref1 = m_slice->m_mref[1][interMode.bestME[1].ref].getLumaAddr(cu.m_cuAddr, cuGeom.encodeIdx + m_puAbsPartIdx);
+                pixel *ref0 = m_slice->m_mref[0][interMode.bestME[puIdx][0].ref].getLumaAddr(cu.m_cuAddr, cuGeom.encodeIdx + m_puAbsPartIdx);
+                pixel *ref1 = m_slice->m_mref[1][interMode.bestME[puIdx][1].ref].getLumaAddr(cu.m_cuAddr, cuGeom.encodeIdx + m_puAbsPartIdx);
                 intptr_t refStride = slice->m_mref[0][0].lumaStride;
 
                 primitives.pixelavg_pp[partEnum](tmpPredYuv.m_buf[0], tmpPredYuv.m_size, ref0, refStride, ref1, refStride, 32);
                 satdCost = m_me.bufSATD(tmpPredYuv.m_buf[0], tmpPredYuv.m_size);
 
-                MV mvp0 = interMode.bestME[0].mvp;
-                int mvpIdx0 = interMode.bestME[0].mvpIdx;
-                uint32_t bits0 = interMode.bestME[0].bits - m_me.bitcost(interMode.bestME[0].mv, mvp0) + m_me.bitcost(mvzero, mvp0);
-
-                MV mvp1 = interMode.bestME[1].mvp;
-                int mvpIdx1 = interMode.bestME[1].mvpIdx;
-                uint32_t bits1 = interMode.bestME[1].bits - m_me.bitcost(interMode.bestME[1].mv, mvp1) + m_me.bitcost(mvzero, mvp1);
+                MV mvp0 = interMode.bestME[puIdx][0].mvp;
+                int mvpIdx0 = interMode.bestME[puIdx][0].mvpIdx;
+                uint32_t bits0 = interMode.bestME[puIdx][0].bits - m_me.bitcost(interMode.bestME[puIdx][0].mv, mvp0) + m_me.bitcost(mvzero, mvp0);
+
+                MV mvp1 = interMode.bestME[puIdx][1].mvp;
+                int mvpIdx1 = interMode.bestME[puIdx][1].mvpIdx;
+                uint32_t bits1 = interMode.bestME[puIdx][1].bits - m_me.bitcost(interMode.bestME[puIdx][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 */
-                checkBestMVP(interMode.amvpCand[0][interMode.bestME[0].ref], mvzero, mvp0, mvpIdx0, bits0, cost);
-                checkBestMVP(interMode.amvpCand[1][interMode.bestME[1].ref], mvzero, mvp1, mvpIdx1, bits1, cost);
+                checkBestMVP(interMode.amvpCand[0][interMode.bestME[puIdx][0].ref], mvzero, mvp0, mvpIdx0, bits0, cost);
+                checkBestMVP(interMode.amvpCand[1][interMode.bestME[puIdx][1].ref], mvzero, mvp1, mvpIdx1, bits1, cost);
 
                 if (cost < bidirCost)
                 {
@@ -2243,7 +2243,7 @@
         }
 
         /* select best option and store into CU */
-        if (mrgCost < bidirCost && mrgCost < interMode.bestME[0].cost && mrgCost < interMode.bestME[1].cost)
+        if (mrgCost < bidirCost && mrgCost < interMode.bestME[puIdx][0].cost && mrgCost < interMode.bestME[puIdx][1].cost)
         {
             cu.m_mergeFlag[m_puAbsPartIdx] = true;
             cu.m_mvpIdx[0][m_puAbsPartIdx] = merge.index; // merge candidate ID is stored in L0 MVP idx
@@ -2255,39 +2255,39 @@
 
             totalmebits += merge.bits;
         }
-        else if (bidirCost < interMode.bestME[0].cost && bidirCost < interMode.bestME[1].cost)
+        else if (bidirCost < interMode.bestME[puIdx][0].cost && bidirCost < interMode.bestME[puIdx][1].cost)
         {
             lastMode = 2;
 
             cu.m_mergeFlag[m_puAbsPartIdx] = false;
             cu.setPUInterDir(3, m_puAbsPartIdx, puIdx);
             cu.setPUMv(0, bidir[0].mv, m_puAbsPartIdx, puIdx);
-            cu.setPURefIdx(0, interMode.bestME[0].ref, m_puAbsPartIdx, puIdx);
+            cu.setPURefIdx(0, interMode.bestME[puIdx][0].ref, m_puAbsPartIdx, puIdx);
             cu.m_mvd[0][m_puAbsPartIdx] = bidir[0].mv - bidir[0].mvp;
             cu.m_mvpIdx[0][m_puAbsPartIdx] = bidir[0].mvpIdx;
 
             cu.setPUMv(1, bidir[1].mv, m_puAbsPartIdx, puIdx);
-            cu.setPURefIdx(1, interMode.bestME[1].ref, m_puAbsPartIdx, puIdx);
+            cu.setPURefIdx(1, interMode.bestME[puIdx][1].ref, m_puAbsPartIdx, puIdx);
             cu.m_mvd[1][m_puAbsPartIdx] = bidir[1].mv - bidir[1].mvp;
             cu.m_mvpIdx[1][m_puAbsPartIdx] = bidir[1].mvpIdx;
 
             totalmebits += bidirBits;
         }
-        else if (interMode.bestME[0].cost <= interMode.bestME[1].cost)
+        else if (interMode.bestME[puIdx][0].cost <= interMode.bestME[puIdx][1].cost)
         {
             lastMode = 0;
 
             cu.m_mergeFlag[m_puAbsPartIdx] = false;
             cu.setPUInterDir(1, m_puAbsPartIdx, puIdx);
-            cu.setPUMv(0, interMode.bestME[0].mv, m_puAbsPartIdx, puIdx);
-            cu.setPURefIdx(0, interMode.bestME[0].ref, m_puAbsPartIdx, puIdx);
-            cu.m_mvd[0][m_puAbsPartIdx] = interMode.bestME[0].mv - interMode.bestME[0].mvp;
-            cu.m_mvpIdx[0][m_puAbsPartIdx] = interMode.bestME[0].mvpIdx;
+            cu.setPUMv(0, interMode.bestME[puIdx][0].mv, m_puAbsPartIdx, puIdx);
+            cu.setPURefIdx(0, interMode.bestME[puIdx][0].ref, m_puAbsPartIdx, puIdx);
+            cu.m_mvd[0][m_puAbsPartIdx] = interMode.bestME[puIdx][0].mv - interMode.bestME[puIdx][0].mvp;
+            cu.m_mvpIdx[0][m_puAbsPartIdx] = interMode.bestME[puIdx][0].mvpIdx;
 
             cu.setPURefIdx(1, REF_NOT_VALID, m_puAbsPartIdx, puIdx);
             cu.setPUMv(1, mvzero, m_puAbsPartIdx, puIdx);
 
-            totalmebits += interMode.bestME[0].bits;
+            totalmebits += interMode.bestME[puIdx][0].bits;
         }
         else
         {
@@ -2295,15 +2295,15 @@
 
             cu.m_mergeFlag[m_puAbsPartIdx] = false;
             cu.setPUInterDir(2, m_puAbsPartIdx, puIdx);
-            cu.setPUMv(1, interMode.bestME[1].mv, m_puAbsPartIdx, puIdx);
-            cu.setPURefIdx(1, interMode.bestME[1].ref, m_puAbsPartIdx, puIdx);
-            cu.m_mvd[1][m_puAbsPartIdx] = interMode.bestME[1].mv - interMode.bestME[1].mvp;
-            cu.m_mvpIdx[1][m_puAbsPartIdx] = interMode.bestME[1].mvpIdx;
+            cu.setPUMv(1, interMode.bestME[puIdx][1].mv, m_puAbsPartIdx, puIdx);
+            cu.setPURefIdx(1, interMode.bestME[puIdx][1].ref, m_puAbsPartIdx, puIdx);
+            cu.m_mvd[1][m_puAbsPartIdx] = interMode.bestME[puIdx][1].mv - interMode.bestME[puIdx][1].mvp;
+            cu.m_mvpIdx[1][m_puAbsPartIdx] = interMode.bestME[puIdx][1].mvpIdx;
 
             cu.setPURefIdx(0, REF_NOT_VALID, m_puAbsPartIdx, puIdx);
             cu.setPUMv(0, mvzero, m_puAbsPartIdx, puIdx);
 
-            totalmebits += interMode.bestME[1].bits;
+            totalmebits += interMode.bestME[puIdx][1].bits;
         }
 
         prepMotionCompensation(cu, cuGeom, puIdx);
diff -r 1e04e178a349 -r 31b6ed10054e source/encoder/search.h
--- a/source/encoder/search.h	Sun Nov 09 00:30:09 2014 -0600
+++ b/source/encoder/search.h	Mon Nov 10 15:02:16 2014 +0530
@@ -84,7 +84,7 @@
     Yuv        reconYuv;
     Entropy    contexts;
 
-    MotionData bestME[2];
+    MotionData bestME[MAX_NUM_PART][2];
     MV         amvpCand[2][MAX_NUM_REF][AMVP_NUM_CANDS];
 
     uint64_t   rdCost;     // sum of partition (psy) RD costs          (sse(fenc, recon) + lambda2 * bits)


More information about the x265-devel mailing list