<div dir="ltr"><div><div><div>Thanks, will queue these for overnight testing. <br><br></div>We discussed more improvements. <br></div><br>1. At 8x8, add the parent CU's corresponding lowres MV. <br></div>2. At higher depths, should we add an average of all child lowres MVs? Or add all child lowres MVs to the motion candidate list?<br><div><br><div><br></div></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, May 13, 2015 at 12:39 PM,  <span dir="ltr"><<a href="mailto:gopu@multicorewareinc.com" target="_blank">gopu@multicorewareinc.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"># HG changeset patch<br>
# User Gopu Govindaswamy <<a href="mailto:gopu@multicorewareinc.com">gopu@multicorewareinc.com</a>><br>
# Date 1431500901 -19800<br>
#      Wed May 13 12:38:21 2015 +0530<br>
# Node ID a8addf6307f7da8d28857297d8de08b255e6610b<br>
# Parent  6a8b7e35213670b6c4803bd1b1a0c16e57205968<br>
search: add lowres MV into search mv candidate list for search ME<br>
<br>
Add one more mv (lowres MV) into MV candidates list and this extra candidates<br>
applicable only for depth 2, the lowres MV's are calculated 16x16 blocks<br>
<br>
diff -r 6a8b7e352136 -r a8addf6307f7 source/encoder/search.cpp<br>
--- a/source/encoder/search.cpp Tue May 12 10:45:38 2015 -0500<br>
+++ b/source/encoder/search.cpp Wed May 13 12:38:21 2015 +0530<br>
@@ -1930,9 +1930,9 @@<br>
     do<br>
     {<br>
         if (meId < m_slice->m_numRefIdx[0])<br>
-            slave.singleMotionEstimation(*this, pme.mode, pme.pu, pme.puIdx, 0, meId);<br>
+            slave.singleMotionEstimation(*this, pme.mode, pme.pu, pme.puIdx, 0, meId, pme.cuGeom);<br>
         else<br>
-            slave.singleMotionEstimation(*this, pme.mode, pme.pu, pme.puIdx, 1, meId - m_slice->m_numRefIdx[0]);<br>
+            slave.singleMotionEstimation(*this, pme.mode, pme.pu, pme.puIdx, 1, meId - m_slice->m_numRefIdx[0], pme.cuGeom);<br>
<br>
         meId = -1;<br>
         pme.m_lock.acquire();<br>
@@ -1943,20 +1943,25 @@<br>
     while (meId >= 0);<br>
 }<br>
<br>
-void Search::singleMotionEstimation(Search& master, Mode& interMode, const PredictionUnit& pu, int part, int list, int ref)<br>
+void Search::singleMotionEstimation(Search& master, Mode& interMode, const PredictionUnit& pu, int part, int list, int ref, const CUGeom& cuGeom)<br>
 {<br>
     uint32_t bits = master.m_listSelBits[list] + MVP_IDX_BITS;<br>
     bits += getTUBits(ref, m_slice->m_numRefIdx[list]);<br>
<br>
     MotionData* bestME = interMode.bestME[part];<br>
<br>
-    MV  mvc[(MD_ABOVE_LEFT + 1) * 2 + 1];<br>
+    // 12 mv candidates including lowresMV<br>
+    MV  mvc[(MD_ABOVE_LEFT + 1) * 2 + 2];<br>
     int numMvc = interMode.cu.getPMV(interMode.interNeighbours, list, ref, interMode.amvpCand[list][ref], mvc);<br>
<br>
     const MV* amvp = interMode.amvpCand[list][ref];<br>
     int mvpIdx = selectMVP(interMode.cu, pu, amvp, list, ref);<br>
     MV mvmin, mvmax, outmv, mvp = amvp[mvpIdx];<br>
<br>
+    MV lmv = getLowresMV(interMode.cu, cuGeom, list);<br>
+    if (lmv.notZero())<br>
+        mvc[numMvc++] = lmv;<br>
+<br>
     setSearchRange(interMode.cu, mvp, m_param->searchRange, mvmin, mvmax);<br>
<br>
     int satdCost = m_me.motionEstimate(&m_slice->m_mref[list][ref], mvmin, mvmax, mvp, numMvc, mvc, m_param->searchRange, outmv);<br>
@@ -1990,7 +1995,8 @@<br>
     CUData& cu = interMode.cu;<br>
     Yuv* predYuv = &interMode.predYuv;<br>
<br>
-    MV mvc[(MD_ABOVE_LEFT + 1) * 2 + 1];<br>
+    // 12 mv candidates including lowresMV<br>
+    MV mvc[(MD_ABOVE_LEFT + 1) * 2 + 2];<br>
<br>
     const Slice *slice = m_slice;<br>
     int numPart     = cu.getNumPartInter();<br>
@@ -2039,6 +2045,10 @@<br>
                 int mvpIdx = selectMVP(cu, pu, amvp, list, ref);<br>
                 MV mvmin, mvmax, outmv, mvp = amvp[mvpIdx];<br>
<br>
+                MV lmv = getLowresMV(cu, cuGeom, list);<br>
+                if (lmv.notZero())<br>
+                    mvc[numMvc++] = lmv;<br>
+<br>
                 setSearchRange(cu, mvp, m_param->searchRange, mvmin, mvmax);<br>
                 int satdCost = m_me.motionEstimate(&slice->m_mref[list][ref], mvmin, mvmax, mvp, numMvc, mvc, m_param->searchRange, outmv);<br>
<br>
@@ -2070,7 +2080,7 @@<br>
             {<br>
                 processPME(pme, *this);<br>
<br>
-                singleMotionEstimation(*this, interMode, pu, puIdx, 0, 0); /* L0-0 */<br>
+                singleMotionEstimation(*this, interMode, pu, puIdx, 0, 0, cuGeom); /* L0-0 */<br>
<br>
                 bDoUnidir = false;<br>
<br>
@@ -2096,6 +2106,10 @@<br>
                     int mvpIdx = selectMVP(cu, pu, amvp, list, ref);<br>
                     MV mvmin, mvmax, outmv, mvp = amvp[mvpIdx];<br>
<br>
+                    MV lmv = getLowresMV(cu, cuGeom, list);<br>
+                    if (lmv.notZero())<br>
+                        mvc[numMvc++] = lmv;<br>
+<br>
                     setSearchRange(cu, mvp, m_param->searchRange, mvmin, mvmax);<br>
                     int satdCost = m_me.motionEstimate(&slice->m_mref[list][ref], mvmin, mvmax, mvp, numMvc, mvc, m_param->searchRange, outmv);<br>
<br>
@@ -3444,3 +3458,37 @@<br>
             cu.setQPSubParts(cu.getRefQP(0), 0, cuGeom.depth);<br>
     }<br>
 }<br>
+<br>
+MV Search::getLowresMV(const CUData& cu, const CUGeom& cuGeom, int list)<br>
+{<br>
+    MV lmv;<br>
+    if (g_maxCUSize >> cuGeom.depth == 16)<br>
+    {<br>
+        int curPoc = m_slice->m_poc;<br>
+        int refPoc = m_slice->m_refPicList[list][0]->m_poc;<br>
+        int diffPoc = abs(curPoc - refPoc);<br>
+<br>
+        if (diffPoc <= m_param->bframes + 1)<br>
+        {<br>
+            MV *mv = m_frame->m_lowres.lowresMvs[list][diffPoc - 1];<br>
+            uint32_t block_x = cu.m_cuPelX + g_zscanToPelX[cuGeom.absPartIdx];<br>
+            uint32_t block_y = cu.m_cuPelY + g_zscanToPelY[cuGeom.absPartIdx];<br>
+<br>
+            /* number of blocks per row in lowres*/<br>
+            uint32_t stride = (m_frame->m_fencPic->m_picWidth + (16 - 1)) / 16;<br>
+<br>
+            uint32_t idx = ((block_y / 16) * stride) + (block_x / 16);<br>
+            /* check whether this motion search was performed by lookahead */<br>
+            if (mv[idx].x != 0x7FFF)<br>
+                lmv = mv[idx];<br>
+            else<br>
+                lmv = 0;<br>
+        }<br>
+        else<br>
+            lmv = 0;<br>
+    }<br>
+    else<br>
+        lmv = 0;<br>
+<br>
+    return lmv;<br>
+}<br>
diff -r 6a8b7e352136 -r a8addf6307f7 source/encoder/search.h<br>
--- a/source/encoder/search.h   Tue May 12 10:45:38 2015 -0500<br>
+++ b/source/encoder/search.h   Wed May 13 12:38:21 2015 +0530<br>
@@ -319,6 +319,8 @@<br>
     void checkDQP(Mode& mode, const CUGeom& cuGeom);<br>
     void checkDQPForSplitPred(Mode& mode, const CUGeom& cuGeom);<br>
<br>
+    MV getLowresMV(const CUData& cu, const CUGeom& cuGeom, int list);<br>
+<br>
     class PME : public BondedTaskGroup<br>
     {<br>
     public:<br>
@@ -339,7 +341,7 @@<br>
     };<br>
<br>
     void     processPME(PME& pme, Search& slave);<br>
-    void     singleMotionEstimation(Search& master, Mode& interMode, const PredictionUnit& pu, int part, int list, int ref);<br>
+    void     singleMotionEstimation(Search& master, Mode& interMode, const PredictionUnit& pu, int part, int list, int ref, const CUGeom& cuGeom);<br>
<br>
 protected:<br>
<br>
_______________________________________________<br>
x265-devel mailing list<br>
<a href="mailto:x265-devel@videolan.org">x265-devel@videolan.org</a><br>
<a href="https://mailman.videolan.org/listinfo/x265-devel" target="_blank">https://mailman.videolan.org/listinfo/x265-devel</a><br>
</blockquote></div><br></div>