[x265] [PATCH] motion: Modify "--refine-mv" option

Aruna Matheswaran aruna at multicorewareinc.com
Wed Sep 4 09:21:50 CEST 2019


The patch is not applying on default. Could you please rebase it on the
latest default tip and resend the patch?

On Fri, Aug 23, 2019 at 12:40 PM <pooja at multicorewareinc.com> wrote:

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


-- 
Regards,
Aruna
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20190904/ce67b1ec/attachment-0001.html>


More information about the x265-devel mailing list