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

Steve Borho steve at borho.org
Wed May 20 00:18:42 CEST 2015


On 05/19, gopu at multicorewareinc.com wrote:
> # HG changeset patch
> # User Gopu Govindaswamy <gopu at multicorewareinc.com>
> # Date 1432035244 -19800
> #      Tue May 19 17:04:04 2015 +0530
> # Node ID 9cab90d3b70085081f142a792a70cfde622ef720
> # Parent  d7b100e51e828833eee006f1da93e499ac161d28
> search: add lowres MV into search MV candidate list for search ME

I've pushed this with a few more modifications, once I verified to
myself it is working correctly.

It is an unambiguous compression win for presets which use hex search,
and an even bigger win for the presets which use the diamond search.

For the slower presets, which use STAR (aka the three-step search from
the HM), the effect is hit or miss. Sometimes better, sometimes worse,
sometimes a mix. The issue is that finding a better MV for one block
might cause a later block to have a larger MVD.. it is making a random
adjustment to the motion field, the net effect of which is impossible to
predict.

The lookahead deliberately does its block raster scan backwards (bottom
to top instead of top to bottom, and right to left instead of left to
right) and uses predictors in the opposite direction (bot, bot-right,
right) so that its motion field is different from the one generally
found by the main encode.. this was done on purpose in x264 to make the
lowres motion vectors unique from the encoder predictors and thus more
valuable.  But I can see where this might be counter-productive in
certain situations, but I don't see any way to predict when that will be
the case.

If it looks like the lowres MV field is more often than not
counter-productive when STAR me method is used, then we can
disable the combination. We should probably disable all candidates when
the full search is used.

> diff -r d7b100e51e82 -r 9cab90d3b700 source/encoder/search.cpp
> --- a/source/encoder/search.cpp	Mon May 18 18:24:08 2015 -0500
> +++ b/source/encoder/search.cpp	Tue May 19 17:04:04 2015 +0530
> @@ -1950,13 +1950,18 @@
>  
>      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, pu, 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, pu, 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);
>  
> @@ -2096,6 +2106,10 @@
>                      int mvpIdx = selectMVP(cu, pu, amvp, list, ref);
>                      MV mvmin, mvmax, outmv, mvp = amvp[mvpIdx];
>  
> +                    MV lmv = getLowresMV(cu, pu, 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,30 @@
>              cu.setQPSubParts(cu.getRefQP(0), 0, cuGeom.depth);
>      }
>  }
> +
> +MV Search::getLowresMV(const CUData& cu, const PredictionUnit& pu, int list, int ref)
> +{
> +    MV lmv = 0;
> +    if ((PartSize)cu.m_partSize[0] == SIZE_2Nx2N)
> +    {
> +        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];
> +            if (mv[0].x == 0x7FFF)
> +                return lmv;
> +
> +            uint32_t block_x, block_y;
> +            block_x = cu.m_cuPelX + g_zscanToPelX[pu.puAbsPartIdx] + pu.width / 2;
> +            block_y = cu.m_cuPelY + g_zscanToPelY[pu.puAbsPartIdx] + pu.height / 2;
> +
> +            /* number of blocks per row in lowres */
> +            uint32_t stride = m_frame->m_lowres.maxBlocksInRow;
> +            uint32_t idx = ((block_y / 16) * stride) + (block_x / 16);
> +            lmv = mv[idx];
> +        }
> +    }
> +    return lmv;
> +}
> diff -r d7b100e51e82 -r 9cab90d3b700 source/encoder/search.h
> --- a/source/encoder/search.h	Mon May 18 18:24:08 2015 -0500
> +++ b/source/encoder/search.h	Tue May 19 17:04:04 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 PredictionUnit& pu, int list, int ref);
> +
>      class PME : public BondedTaskGroup
>      {
>      public:
> _______________________________________________
> x265-devel mailing list
> x265-devel at videolan.org
> https://mailman.videolan.org/listinfo/x265-devel

-- 
Steve Borho


More information about the x265-devel mailing list