[x265] [PATCH] slicetype: select best mvp using neighbor mvs satd cost for Lowres ME

Steve Borho steve at borho.org
Tue Apr 21 18:23:18 CEST 2015


On 04/21, gopu at multicorewareinc.com wrote:
> # HG changeset patch
> # User Gopu Govindaswamy <gopu at multicorewareinc.com>
> # Date 1429608918 -19800
> #      Tue Apr 21 15:05:18 2015 +0530
> # Node ID d101822b9c3594c113a504e3e4e53d2746df0d1f
> # Parent  5c3443546cccea47316d59dbc4f892e1b6f8b1b5
> slicetype: select best mvp using neighbor mvs satd cost for Lowres ME
> 
> This patch [CHANGES OUTPUT], modified the lowres mvp selection logic, the Lowres
> mvp selected based on the four neighbor mv's satd cost insted of the medien
> operation

I've queued a simplified version with more comments and a better commit
message. The goal here is to make x265's lookahead estimate HEVC AMVP
selection instead of using H.264's median function which we had borrowed
from x264.

The new code models HEVC merge candidate analysis and AMVP motion
predictor selection in the lookahead. In theory this should make the
lookahead costs more predictive for HEVC slice costs, making better cost
estimates.

> diff -r 5c3443546ccc -r d101822b9c35 source/encoder/motion.h
> --- a/source/encoder/motion.h	Sat Apr 18 10:02:19 2015 -0700
> +++ b/source/encoder/motion.h	Tue Apr 21 15:05:18 2015 +0530
> @@ -37,8 +37,6 @@
>  {
>  protected:
>  
> -    intptr_t blockOffset;
> -    
>      int ctuAddr;
>      int absPartIdx;  // part index of PU, including CU offset within CTU
>  
> @@ -48,18 +46,19 @@
>      int blockwidth;
>      int blockheight;
>  
> +    MotionEstimate& operator =(const MotionEstimate&);
> +
> +public:
> +
> +    static const int COST_MAX = 1 << 28;
> +
>      pixelcmp_t sad;
>      pixelcmp_x3_t sad_x3;
>      pixelcmp_x4_t sad_x4;
>      pixelcmp_t satd;
>      pixelcmp_t chromaSatd;
>  
> -    MotionEstimate& operator =(const MotionEstimate&);
> -
> -public:
> -
> -    static const int COST_MAX = 1 << 28;
> -
> +    intptr_t blockOffset;
>      Yuv fencPUYuv;
>      int partEnum;
>      bool bChromaSATD;
> diff -r 5c3443546ccc -r d101822b9c35 source/encoder/slicetype.cpp
> --- a/source/encoder/slicetype.cpp	Sat Apr 18 10:02:19 2015 -0700
> +++ b/source/encoder/slicetype.cpp	Tue Apr 21 15:05:18 2015 +0530
> @@ -44,23 +44,6 @@
>  
>  namespace {
>  
> -inline int16_t median(int16_t a, int16_t b, int16_t c)
> -{
> -    int16_t t = (a - b) & ((a - b) >> 31);
> -
> -    a -= t;
> -    b += t;
> -    b -= (b - c) & ((b - c) >> 31);
> -    b += (a - b) & ((a - b) >> 31);
> -    return b;
> -}
> -
> -inline void median_mv(MV &dst, MV a, MV b, MV c)
> -{
> -    dst.x = median(a.x, b.x, c.x);
> -    dst.y = median(a.y, b.y, c.y);
> -}
> -
>  /* Compute variance to derive AC energy of each block */
>  inline uint32_t acEnergyVar(Frame *curFrame, uint64_t sum_ssd, int shift, int plane)
>  {
> @@ -85,6 +68,23 @@
>          return acEnergyVar(curFrame, primitives.cu[BLOCK_16x16].var(src, srcStride), 8, plane);
>  }
>  
> +inline int mergeCostEstimate(ReferencePlanes *ref, MV *mvc, intptr_t blockOffset, Yuv fencPUYuv, pixelcmp_t satd)
> +{
> +    int bcost = MAX_UINT, index = 0;
> +    pixel* fenc = fencPUYuv.m_buf[0];
> +
> +    for (int i = 0; i < 4; i++)
> +    {
> +        int cost = ref->lowresQPelCost(fenc, blockOffset, mvc[i], satd);
> +        if (cost < bcost)
> +        {
> +            bcost = cost;
> +            index = i;
> +        }
> +    }
> +    return index;
> +}
> +
>  } // end anonymous namespace
>  
>  /* Find the total AC energy of each block in all planes */
> @@ -2027,14 +2027,16 @@
>              continue;
>          }
>  
> -        int numc = 0;
> +        int numc = 0, idx = 0;
>          MV mvc[4], mvp;
>  
>          MV* fencMV = &fenc->lowresMvs[i][listDist[i]][cuXY];
>  
>          /* Reverse-order MV prediction */
>          mvc[0] = 0;
> +        mvc[1] = 0;
>          mvc[2] = 0;
> +        mvc[3] = 0;
>  #define MVC(mv) mvc[numc++] = mv;
>          if (cuX < widthInCU - 1)
>              MVC(fencMV[1]);
> @@ -2050,7 +2052,10 @@
>          if (numc <= 1)
>              mvp = mvc[0];
>          else
> -            median_mv(mvp, mvc[0], mvc[1], mvc[2]);
> +        {
> +            idx = mergeCostEstimate(i ? fref1 : wfref0, mvc, tld.me.blockOffset, tld.me.fencPUYuv, tld.me.satd);
> +            mvp = mvc[idx];
> +        }
>  
>          fencCost = tld.me.motionEstimate(i ? fref1 : wfref0, mvmin, mvmax, mvp, numc, mvc, s_merange, *fencMV);
>          COPY2_IF_LT(bcost, fencCost, listused, i + 1);
> _______________________________________________
> 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