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

Deepthi Nandakumar deepthi at multicorewareinc.com
Wed May 13 10:37:49 CEST 2015


Thanks, will queue these for overnight testing.

We discussed more improvements.

1. At 8x8, add the parent CU's corresponding lowres MV.
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?



On Wed, May 13, 2015 at 12:39 PM, <gopu at multicorewareinc.com> wrote:

> # HG changeset patch
> # User Gopu Govindaswamy <gopu at multicorewareinc.com>
> # Date 1431500901 -19800
> #      Wed May 13 12:38:21 2015 +0530
> # Node ID a8addf6307f7da8d28857297d8de08b255e6610b
> # Parent  6a8b7e35213670b6c4803bd1b1a0c16e57205968
> search: add lowres MV into search mv candidate list for search ME
>
> 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 6a8b7e352136 -r a8addf6307f7 source/encoder/search.cpp
> --- a/source/encoder/search.cpp Tue May 12 10:45:38 2015 -0500
> +++ b/source/encoder/search.cpp Wed May 13 12:38:21 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.pu,
> pme.puIdx, 0, meId, pme.cuGeom);
>          else
> -            slave.singleMotionEstimation(*this, pme.mode, pme.pu,
> pme.puIdx, 1, meId - m_slice->m_numRefIdx[0]);
> +            slave.singleMotionEstimation(*this, pme.mode, pme.pu,
> pme.puIdx, 1, meId - m_slice->m_numRefIdx[0], pme.cuGeom);
>
>          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 PredictionUnit& pu, int part, int list, int ref, const CUGeom& cuGeom)
>  {
>      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);
> +    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);
> +                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, pu, puIdx, 0, 0,
> cuGeom); /* 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);
> +                    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,37 @@
>              cu.setQPSubParts(cu.getRefQP(0), 0, cuGeom.depth);
>      }
>  }
> +
> +MV Search::getLowresMV(const CUData& cu, const CUGeom& cuGeom, int list)
> +{
> +    MV lmv;
> +    if (g_maxCUSize >> cuGeom.depth == 16)
> +    {
> +        int curPoc = m_slice->m_poc;
> +        int refPoc = m_slice->m_refPicList[list][0]->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_frame->m_fencPic->m_picWidth + (16 - 1))
> / 16;
> +
> +            uint32_t idx = ((block_y / 16) * stride) + (block_x / 16);
> +            /* check whether this motion search was performed by
> lookahead */
> +            if (mv[idx].x != 0x7FFF)
> +                lmv = mv[idx];
> +            else
> +                lmv = 0;
> +        }
> +        else
> +            lmv = 0;
> +    }
> +    else
> +        lmv = 0;
> +
> +    return lmv;
> +}
> diff -r 6a8b7e352136 -r a8addf6307f7 source/encoder/search.h
> --- a/source/encoder/search.h   Tue May 12 10:45:38 2015 -0500
> +++ b/source/encoder/search.h   Wed May 13 12:38:21 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);
> +
>      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 PredictionUnit& pu, int part, int list, int ref, const CUGeom&
> cuGeom);
>
>  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/20150513/ec3f4d20/attachment-0001.html>


More information about the x265-devel mailing list