[x265] [PATCH] search: add lowres MV into search mv candidate list for search ME(CHANGESOUTPUT)

Deepthi Nandakumar deepthi at multicorewareinc.com
Thu May 14 15:30:49 CEST 2015


Ran the smoke test on this, the results were mixed - on some commandlines,
the encode efficiency benefits were really good though.

On Thu, May 14, 2015 at 10:53 AM, <gopu at multicorewareinc.com> wrote:

> # HG changeset patch
> # User Gopu Govindaswamy <gopu at multicorewareinc.com>
> # Date 1431581025 -19800
> #      Thu May 14 10:53:45 2015 +0530
> # Node ID def132fbcf33352b18a31015dfefff79e95d21d7
> # Parent  479087422e29a672d6e9bc8d0cd2a65649d71fe2
> search: add lowres MV into search mv candidate list for search
> ME(CHANGESOUTPUT)
>
> Add one more mv (lowres MV) into MV candidates list and this extra
> candidates
> applicable only for depth 2, the lowres MV's are calculated 16x16 blocks
>
> diff -r 479087422e29 -r def132fbcf33 source/encoder/search.cpp
> --- a/source/encoder/search.cpp Wed May 13 16:52:59 2015 -0700
> +++ b/source/encoder/search.cpp Thu May 14 10:53:45 2015 +0530
> @@ -1930,9 +1930,9 @@
>      do
>      {
>          if (meId < m_slice->m_numRefIdx[0])
> -            slave.singleMotionEstimation(*this, pme.mode, pme.pu,
> pme.puIdx, 0, meId);
> +            slave.singleMotionEstimation(*this, pme.mode, pme.cuGeom,
> pme.pu, pme.puIdx, 0, meId);
>          else
> -            slave.singleMotionEstimation(*this, pme.mode, pme.pu,
> pme.puIdx, 1, meId - m_slice->m_numRefIdx[0]);
> +            slave.singleMotionEstimation(*this, pme.mode, pme.cuGeom,
> pme.pu, pme.puIdx, 1, meId - m_slice->m_numRefIdx[0]);
>
>          meId = -1;
>          pme.m_lock.acquire();
> @@ -1943,20 +1943,25 @@
>      while (meId >= 0);
>  }
>
> -void Search::singleMotionEstimation(Search& master, Mode& interMode,
> const PredictionUnit& pu, int part, int list, int ref)
> +void Search::singleMotionEstimation(Search& master, Mode& interMode,
> const CUGeom& cuGeom, const PredictionUnit& pu, int part, int list, int ref)
>  {
>      uint32_t bits = master.m_listSelBits[list] + MVP_IDX_BITS;
>      bits += getTUBits(ref, m_slice->m_numRefIdx[list]);
>
>      MotionData* bestME = interMode.bestME[part];
>
> -    MV  mvc[(MD_ABOVE_LEFT + 1) * 2 + 1];
> +    // 12 mv candidates including lowresMV
> +    MV  mvc[(MD_ABOVE_LEFT + 1) * 2 + 2];
>      int numMvc = interMode.cu.getPMV(interMode.interNeighbours, list,
> ref, interMode.amvpCand[list][ref], mvc);
>
>      const MV* amvp = interMode.amvpCand[list][ref];
>      int mvpIdx = selectMVP(interMode.cu, pu, amvp, list, ref);
>      MV mvmin, mvmax, outmv, mvp = amvp[mvpIdx];
>
> +    MV lmv = getLowresMV(interMode.cu, cuGeom, list, ref);
> +    if (lmv.notZero())
> +        mvc[numMvc++] = lmv;
> +
>      setSearchRange(interMode.cu, mvp, m_param->searchRange, mvmin, mvmax);
>
>      int satdCost = m_me.motionEstimate(&m_slice->m_mref[list][ref],
> mvmin, mvmax, mvp, numMvc, mvc, m_param->searchRange, outmv);
> @@ -1990,7 +1995,8 @@
>      CUData& cu = interMode.cu;
>      Yuv* predYuv = &interMode.predYuv;
>
> -    MV mvc[(MD_ABOVE_LEFT + 1) * 2 + 1];
> +    // 12 mv candidates including lowresMV
> +    MV mvc[(MD_ABOVE_LEFT + 1) * 2 + 2];
>
>      const Slice *slice = m_slice;
>      int numPart     = cu.getNumPartInter();
> @@ -2039,6 +2045,10 @@
>                  int mvpIdx = selectMVP(cu, pu, amvp, list, ref);
>                  MV mvmin, mvmax, outmv, mvp = amvp[mvpIdx];
>
> +                MV lmv = getLowresMV(cu, cuGeom, list, ref);
> +                if (lmv.notZero())
> +                    mvc[numMvc++] = lmv;
> +
>                  setSearchRange(cu, mvp, m_param->searchRange, mvmin,
> mvmax);
>                  int satdCost =
> m_me.motionEstimate(&slice->m_mref[list][ref], mvmin, mvmax, mvp, numMvc,
> mvc, m_param->searchRange, outmv);
>
> @@ -2070,7 +2080,7 @@
>              {
>                  processPME(pme, *this);
>
> -                singleMotionEstimation(*this, interMode, pu, puIdx, 0,
> 0); /* L0-0 */
> +                singleMotionEstimation(*this, interMode, cuGeom, pu,
> puIdx, 0, 0); /* L0-0 */
>
>                  bDoUnidir = false;
>
> @@ -2096,6 +2106,10 @@
>                      int mvpIdx = selectMVP(cu, pu, amvp, list, ref);
>                      MV mvmin, mvmax, outmv, mvp = amvp[mvpIdx];
>
> +                    MV lmv = getLowresMV(cu, cuGeom, list, ref);
> +                    if (lmv.notZero())
> +                        mvc[numMvc++] = lmv;
> +
>                      setSearchRange(cu, mvp, m_param->searchRange, mvmin,
> mvmax);
>                      int satdCost =
> m_me.motionEstimate(&slice->m_mref[list][ref], mvmin, mvmax, mvp, numMvc,
> mvc, m_param->searchRange, outmv);
>
> @@ -3444,3 +3458,31 @@
>              cu.setQPSubParts(cu.getRefQP(0), 0, cuGeom.depth);
>      }
>  }
> +
> +MV Search::getLowresMV(const CUData& cu, const CUGeom& cuGeom, int list,
> int ref)
> +{
> +    MV lmv = 0;
> +    if (g_maxCUSize >> cuGeom.depth == 16)
> +    {
> +        int curPoc = m_slice->m_poc;
> +        int refPoc = m_slice->m_refPicList[list][ref]->m_poc;
> +        int diffPoc = abs(curPoc - refPoc);
> +
> +        if (diffPoc <= m_param->bframes + 1)
> +        {
> +            MV *mv = m_frame->m_lowres.lowresMvs[list][diffPoc - 1];
> +            uint32_t block_x = cu.m_cuPelX +
> g_zscanToPelX[cuGeom.absPartIdx];
> +            uint32_t block_y = cu.m_cuPelY +
> g_zscanToPelY[cuGeom.absPartIdx];
> +
> +            /* number of blocks per row in lowres*/
> +            uint32_t stride = ((m_param->sourceWidth / 2) +
> X265_LOWRES_CU_SIZE - 1) >> X265_LOWRES_CU_BITS;
> +
> +            uint32_t idx = ((block_y / 16) * stride) + (block_x / 16);
> +            /* check whether this motion search was performed by
> lookahead */
> +            if (mv[0].x != 0x7FFF)
> +                lmv = mv[idx];
>

The only change I made was to move this check up.

+        }
> +    }
> +
> +    return lmv;
> +}
> diff -r 479087422e29 -r def132fbcf33 source/encoder/search.h
> --- a/source/encoder/search.h   Wed May 13 16:52:59 2015 -0700
> +++ b/source/encoder/search.h   Thu May 14 10:53:45 2015 +0530
> @@ -319,6 +319,8 @@
>      void checkDQP(Mode& mode, const CUGeom& cuGeom);
>      void checkDQPForSplitPred(Mode& mode, const CUGeom& cuGeom);
>
> +    MV getLowresMV(const CUData& cu, const CUGeom& cuGeom, int list, int
> ref);
> +
>      class PME : public BondedTaskGroup
>      {
>      public:
> @@ -339,7 +341,7 @@
>      };
>
>      void     processPME(PME& pme, Search& slave);
> -    void     singleMotionEstimation(Search& master, Mode& interMode,
> const PredictionUnit& pu, int part, int list, int ref);
> +    void     singleMotionEstimation(Search& master, Mode& interMode,
> const CUGeom& cuGeom, const PredictionUnit& pu, int part, int list, int
> ref);
>
>  protected:
>
> _______________________________________________
> x265-devel mailing list
> x265-devel at videolan.org
> https://mailman.videolan.org/listinfo/x265-devel
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20150514/727b6b91/attachment.html>


More information about the x265-devel mailing list