<div dir="ltr">The patch is not applying on default. Could you please rebase it on the latest default tip and resend the patch?</div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, Aug 23, 2019 at 12:40 PM <<a href="mailto:pooja@multicorewareinc.com">pooja@multicorewareinc.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"># HG changeset patch<br>
# User Pooja Venkatesan<br>
# Date 1566540185 -19800<br>
#      Fri Aug 23 11:33:05 2019 +0530<br>
# Node ID ff2a24a84069327711f08d8ea026bf7383013f21<br>
# Parent  de920e0a31831f52599f3937c3ee6945e88ed851<br>
motion: Modify "--refine-mv" option<br>
<br>
Add MV refinement level 1,2 and 3.<br>
Based on the MV refinement level, number of search increases.<br>
<br>
diff -r de920e0a3183 -r ff2a24a84069 doc/reST/cli.rst<br>
--- a/doc/reST/cli.rst  Tue Jul 23 17:03:51 2019 +0530<br>
+++ b/doc/reST/cli.rst  Fri Aug 23 11:33:05 2019 +0530<br>
@@ -997,11 +997,14 @@<br>
        the encoder settings. It is recommended to use :option:`--refine-intra` 4 with dynamic <br>
        refinement. Default disabled.<br>
<br>
-.. option:: --refine-mv<br>
-       <br>
+.. option:: --refine-mv <0..3><br>
+<br>
        Enables refinement of motion vector for scaled video. Evaluates the best <br>
-       motion vector by searching the surrounding eight integer and subpel pixel<br>
-       positions.<br>
+       motion vector based on the level selected. Default 0 - disabled.<br>
+<br>
+       Level 1 - Search around scaled MV.<br>
+       Level 2 - Level 1 + Search around best AMVP cand.<br>
+       Level 3 - Level 2 + Search around the other AMVP cand.<br>
<br>
 Options which affect the transform unit quad-tree, sometimes referred to<br>
 as the residual quad-tree (RQT).<br>
diff -r de920e0a3183 -r ff2a24a84069 source/common/param.cpp<br>
--- a/source/common/param.cpp   Tue Jul 23 17:03:51 2019 +0530<br>
+++ b/source/common/param.cpp   Fri Aug 23 11:33:05 2019 +0530<br>
@@ -1209,7 +1209,7 @@<br>
         OPT("scale-factor") p->scaleFactor = atoi(value);<br>
         OPT("refine-intra")p->intraRefine = atoi(value);<br>
         OPT("refine-inter")p->interRefine = atoi(value);<br>
-        OPT("refine-mv")p->mvRefine = atobool(value);<br>
+        OPT("refine-mv")p->mvRefine = atoi(value);<br>
         OPT("force-flush")p->forceFlush = atoi(value);<br>
         OPT("splitrd-skip") p->bEnableSplitRdSkip = atobool(value);<br>
         OPT("lowpass-dct") p->bLowPassDct = atobool(value);<br>
@@ -1650,6 +1650,8 @@<br>
           "Strict-cbr cannot be applied without specifying target bitrate or vbv bufsize");<br>
     CHECK((param->analysisSave || param->analysisLoad) && (param->analysisReuseLevel < 1 || param->analysisReuseLevel > 10),<br>
         "Invalid analysis refine level. Value must be between 1 and 10 (inclusive)");<br>
+    CHECK(param->analysisLoad && (param->mvRefine < 0 || param->mvRefine > 3),<br>
+        "Invalid mv refinement level. Value must be between 0 and 3 (inclusive)");<br>
     CHECK(param->scaleFactor > 2, "Invalid scale-factor. Supports factor <= 2");<br>
     CHECK(param->rc.qpMax < QP_MIN || param->rc.qpMax > QP_MAX_MAX,<br>
         "qpmax exceeds supported range (0 to 69)");<br>
diff -r de920e0a3183 -r ff2a24a84069 source/encoder/analysis.cpp<br>
--- a/source/encoder/analysis.cpp       Tue Jul 23 17:03:51 2019 +0530<br>
+++ b/source/encoder/analysis.cpp       Fri Aug 23 11:33:05 2019 +0530<br>
@@ -2488,14 +2488,18 @@<br>
                             MV mvp;<br>
<br>
                             int numMvc = mode.cu.getPMV(mode.interNeighbours, list, ref, mode.amvpCand[list][ref], mvc);<br>
-                            if (m_param->interRefine != 1)<br>
-                                mvp = mode.amvpCand[list][ref][mode.cu.m_mvpIdx[list][pu.puAbsPartIdx]];<br>
-                            else<br>
-                                mvp = interDataCTU->mv[list][cuIdx + part].word;<br>
+                            mvp = mode.amvpCand[list][ref][mode.cu.m_mvpIdx[list][pu.puAbsPartIdx]];<br>
                             if (m_param->mvRefine || m_param->interRefine == 1)<br>
                             {<br>
-                                MV outmv;<br>
-                                searchMV(mode, pu, list, ref, outmv, mvp, numMvc, mvc);<br>
+                                MV outmv, mvpSelect[3];<br>
+                                mvpSelect[0] = interDataCTU->mv[list][cuIdx + part].word;<br>
+                                switch (m_param->mvRefine)<br>
+                                {<br>
+                                case 3: mvpSelect[2] = mode.amvpCand[list][ref][!(mode.cu.m_mvpIdx[list][pu.puAbsPartIdx])];<br>
+                                case 2: mvpSelect[1] = mvp;<br>
+                                default: break;<br>
+                                }<br>
+                                searchMV(mode, list, ref, outmv, mvpSelect, numMvc, mvc);<br>
                                 mode.cu.setPUMv(list, outmv, pu.puAbsPartIdx, part);<br>
                             }<br>
                             mode.cu.m_mvd[list][pu.puAbsPartIdx] = mode.cu.m_mv[list][pu.puAbsPartIdx] - mode.amvpCand[list][ref][mode.cu.m_mvpIdx[list][pu.puAbsPartIdx]]/*mvp*/;<br>
diff -r de920e0a3183 -r ff2a24a84069 source/encoder/encoder.cpp<br>
--- a/source/encoder/encoder.cpp        Tue Jul 23 17:03:51 2019 +0530<br>
+++ b/source/encoder/encoder.cpp        Fri Aug 23 11:33:05 2019 +0530<br>
@@ -2983,11 +2983,11 @@<br>
             x265_log(p, X265_LOG_WARNING, "MV refinement requires analysis load, analysis-reuse-level 10. Disabling MV refine.\n");<br>
             p->mvRefine = 0;<br>
         }<br>
-        else if (p->interRefine >= 2)<br>
-        {<br>
-            x265_log(p, X265_LOG_WARNING, "MVs are recomputed when refine-inter >= 2. MV refinement not applicable. Disabling MV refine\n");<br>
-            p->mvRefine = 0;<br>
-        }<br>
+    }<br>
+    if (p->scaleFactor && p->analysisLoad && p->interRefine && p->analysisReuseLevel == 10 && !p->mvRefine)<br>
+    {<br>
+        x265_log(p, X265_LOG_WARNING, "Enabling MV refinement level 1 with scaling and analysis-reuse-level=10.\n");<br>
+        p->mvRefine = 1;<br>
     }<br>
<br>
     if (p->ctuDistortionRefine == CTU_DISTORTION_INTERNAL)<br>
diff -r de920e0a3183 -r ff2a24a84069 source/encoder/search.cpp<br>
--- a/source/encoder/search.cpp Tue Jul 23 17:03:51 2019 +0530<br>
+++ b/source/encoder/search.cpp Fri Aug 23 11:33:05 2019 +0530<br>
@@ -2152,23 +2152,27 @@<br>
         bestME[list].mvCost  = mvCost;<br>
     }<br>
 }<br>
-void Search::searchMV(Mode& interMode, const PredictionUnit& pu, int list, int ref, MV& outmv, MV mvp, int numMvc, MV* mvc)<br>
+void Search::searchMV(Mode& interMode, int list, int ref, MV& outmv, MV mvp[3], int numMvc, MV* mvc)<br>
 {<br>
     CUData& cu = interMode.cu;<br>
-    const Slice *slice = m_slice;<br>
-    MV mv;<br>
-    if (m_param->interRefine == 1)<br>
-        mv = mvp;<br>
-    else<br>
-        mv = cu.m_mv[list][pu.puAbsPartIdx];<br>
+    MV mv, mvmin, mvmax;<br>
     cu.clipMv(mv);<br>
-    MV mvmin, mvmax;<br>
-    setSearchRange(cu, mv, m_param->searchRange, mvmin, mvmax);<br>
-    if (m_param->interRefine == 1)<br>
-        m_me.motionEstimate(&m_slice->m_mref[list][ref], mvmin, mvmax, mv, numMvc, mvc, m_param->searchRange, outmv, m_param->maxSlices,<br>
+    int cand = 0, bestcost = INT_MAX;<br>
+    do<br>
+    {<br>
+        if (cand && (mvp[cand] == mvp[cand - 1] || (cand == 2 && mvp[cand] == mvp[cand - 2])))<br>
+            continue;<br>
+        MV bestMV;<br>
+        mv = mvp[cand];<br>
+        setSearchRange(cu, mv, m_param->searchRange, mvmin, mvmax);<br>
+        int cost = m_me.motionEstimate(&m_slice->m_mref[list][ref], mvmin, mvmax, mv, numMvc, mvc, m_param->searchRange, bestMV, m_param->maxSlices,<br>
         m_param->bSourceReferenceEstimation ? m_slice->m_refFrameList[list][ref]->m_fencPic->getLumaAddr(0) : 0);<br>
-    else<br>
-        m_me.refineMV(&slice->m_mref[list][ref], mvmin, mvmax, mv, outmv);<br>
+        if (bestcost > cost)<br>
+        {<br>
+            bestcost = cost;<br>
+            outmv = bestMV;<br>
+        }<br>
+    }while (++cand < m_param->mvRefine);<br>
 }<br>
 /* find the best inter prediction for each PU of specified mode */<br>
 void Search::predInterSearch(Mode& interMode, const CUGeom& cuGeom, bool bChromaMC, uint32_t refMasks[2])<br>
@@ -2229,7 +2233,6 @@<br>
                 int ref = -1;<br>
                 if (useAsMVP)<br>
                     ref = interDataCTU->refIdx[list][cuIdx + puIdx];<br>
-<br>
                 else<br>
                     ref = bestME[list].ref;<br>
                 if (ref < 0)<br>
@@ -2243,7 +2246,7 @@<br>
                 const MV* amvp = interMode.amvpCand[list][ref];<br>
                 int mvpIdx = selectMVP(cu, pu, amvp, list, ref);<br>
                 MV mvmin, mvmax, outmv, mvp;<br>
-                if (useAsMVP)<br>
+                if (useAsMVP && !m_param->mvRefine)<br>
                 {<br>
                     mvp = interDataCTU->mv[list][cuIdx + puIdx].word;<br>
                     mvpIdx = interDataCTU->mvpIdx[list][cuIdx + puIdx];<br>
@@ -2259,11 +2262,44 @@<br>
                 }<br>
                 setSearchRange(cu, mvp, m_param->searchRange, mvmin, mvmax);<br>
                 MV mvpIn = mvp;<br>
+                int satdCost;<br>
                 if (m_param->analysisMultiPassRefine && m_param->rc.bStatRead && mvpIdx == bestME[list].mvpIdx)<br>
                     mvpIn = bestME[list].mv;<br>
-                    <br>
-                int satdCost = m_me.motionEstimate(&slice->m_mref[list][ref], mvmin, mvmax, mvpIn, numMvc, mvc, m_param->searchRange, outmv, m_param->maxSlices, <br>
-                  m_param->bSourceReferenceEstimation ? m_slice->m_refFrameList[list][ref]->m_fencPic->getLumaAddr(0) : 0);<br>
+                if (useAsMVP && m_param->mvRefine)<br>
+                {<br>
+                    MV bestmv, mvpSel[3];<br>
+                    int mvpIdxSel[3];<br>
+                    satdCost = m_me.COST_MAX;<br>
+                    switch (m_param->mvRefine)<br>
+                    {<br>
+                    case 3: mvpSel[2] = interMode.amvpCand[list][ref][!mvpIdx];<br>
+                            mvpIdxSel[2] = !mvpIdx;<br>
+                    case 2: mvpSel[1] = interMode.amvpCand[list][ref][mvpIdx];<br>
+                            mvpIdxSel[1] = mvpIdx;<br>
+                    case 1: mvpSel[0] = interDataCTU->mv[list][cuIdx + puIdx].word;<br>
+                            mvpIdxSel[0] = interDataCTU->mvpIdx[list][cuIdx + puIdx];<br>
+                    }<br>
+                    for (int cand = 0; cand < m_param->mvRefine; cand++)<br>
+                    {<br>
+                        if (cand && (mvpSel[cand] == mvpSel[cand - 1] || (cand == 2 && mvpSel[cand] == mvpSel[cand - 2])))<br>
+                            continue;<br>
+                        setSearchRange(cu, mvp, m_param->searchRange, mvmin, mvmax);<br>
+                        int bcost = m_me.motionEstimate(&m_slice->m_mref[list][ref], mvmin, mvmax, mvpSel[cand], numMvc, mvc, m_param->searchRange, bestmv, m_param->maxSlices,<br>
+                            m_param->bSourceReferenceEstimation ? m_slice->m_refFrameList[list][ref]->m_fencPic->getLumaAddr(0) : 0);<br>
+                        if (satdCost > bcost)<br>
+                        {<br>
+                            satdCost = bcost;<br>
+                            outmv = bestmv;<br>
+                            mvp = mvpSel[cand];<br>
+                            mvpIdx = mvpIdxSel[cand];<br>
+                        }<br>
+                    }<br>
+                }<br>
+                else<br>
+                {<br>
+                    satdCost = m_me.motionEstimate(&slice->m_mref[list][ref], mvmin, mvmax, mvpIn, numMvc, mvc, m_param->searchRange, outmv, m_param->maxSlices,<br>
+                        m_param->bSourceReferenceEstimation ? m_slice->m_refFrameList[list][ref]->m_fencPic->getLumaAddr(0) : 0);<br>
+                }<br>
<br>
                 /* Get total cost of partition, but only include MV bit cost once */<br>
                 bits += m_me.bitcost(outmv);<br>
diff -r de920e0a3183 -r ff2a24a84069 source/encoder/search.h<br>
--- a/source/encoder/search.h   Tue Jul 23 17:03:51 2019 +0530<br>
+++ b/source/encoder/search.h   Fri Aug 23 11:33:05 2019 +0530<br>
@@ -310,7 +310,7 @@<br>
<br>
     // estimation inter prediction (non-skip)<br>
     void     predInterSearch(Mode& interMode, const CUGeom& cuGeom, bool bChromaMC, uint32_t masks[2]);<br>
-    void     searchMV(Mode& interMode, const PredictionUnit& pu, int list, int ref, MV& outmv, MV mvp, int numMvc, MV* mvc);<br>
+    void     searchMV(Mode& interMode, int list, int ref, MV& outmv, MV mvp[3], int numMvc, MV* mvc);<br>
     // encode residual and compute rd-cost for inter mode<br>
     void     encodeResAndCalcRdInterCU(Mode& interMode, const CUGeom& cuGeom);<br>
     void     encodeResAndCalcRdSkipCU(Mode& interMode);<br>
diff -r de920e0a3183 -r ff2a24a84069 source/x265cli.h<br>
--- a/source/x265cli.h  Tue Jul 23 17:03:51 2019 +0530<br>
+++ b/source/x265cli.h  Fri Aug 23 11:33:05 2019 +0530<br>
@@ -297,8 +297,7 @@<br>
     { "dhdr10-opt",           no_argument, NULL, 0},<br>
     { "no-dhdr10-opt",        no_argument, NULL, 0},<br>
     { "dolby-vision-profile",  required_argument, NULL, 0 },<br>
-    { "refine-mv",            no_argument, NULL, 0 },<br>
-    { "no-refine-mv",         no_argument, NULL, 0 },<br>
+    { "refine-mv",      required_argument, NULL, 0 },<br>
     { "refine-ctu-distortion", required_argument, NULL, 0 },<br>
     { "force-flush",    required_argument, NULL, 0 },<br>
     { "splitrd-skip",         no_argument, NULL, 0 },<br>
@@ -549,7 +548,7 @@<br>
         "                                    - 3 : Functionality of (1) + irrespective of size evaluate all inter modes.\n"<br>
         "                                Default:%d\n", param->interRefine);<br>
     H0("   --[no-]dynamic-refine         Dynamically changes refine-inter level for each CU. Default %s\n", OPT(param->bDynamicRefine));<br>
-    H0("   --[no-]refine-mv              Enable mv refinement for load mode. Default %s\n", OPT(param->mvRefine));<br>
+    H0("   --refine-mv <0..3>            Enable mv refinement for load mode. Default %d\n", param->mvRefine);<br>
     H0("   --refine-ctu-distortion       Store/normalize ctu distortion in analysis-save/load.\n"<br>
         "                                    - 0 : Disabled.\n"<br>
         "                                    - 1 : Store/Load ctu distortion to/from the file specified in analysis-save/load.\n"<br>
_______________________________________________<br>
x265-devel mailing list<br>
<a href="mailto:x265-devel@videolan.org" target="_blank">x265-devel@videolan.org</a><br>
<a href="https://mailman.videolan.org/listinfo/x265-devel" rel="noreferrer" target="_blank">https://mailman.videolan.org/listinfo/x265-devel</a><br>
</blockquote></div><br clear="all"><div><br></div>-- <br><div dir="ltr" class="gmail_signature"><div dir="ltr"><font face="georgia, serif">Regards,</font><div><font face="georgia, serif">Aruna</font></div></div></div>