[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