[x265] [PATCH] search: dump best motion statistics for P and B slices into analysisdata file

Steve Borho steve at borho.org
Sat Sep 20 15:16:38 CEST 2014


On 09/18, gopu at multicorewareinc.com wrote:
> # HG changeset patch
> # User Gopu Govindaswamy <gopu at multicorewareinc.com>
> # Date 1411025249 -19800
> #      Thu Sep 18 12:57:29 2014 +0530
> # Node ID c2d80cbd47dc7219aee70a403b8337330bc1b798
> # Parent  e32bc023f232e10d0384d0cf4eec53f14419dabd
> search: dump best motion statistics for P and B slices into analysisdata file
> 
> diff -r e32bc023f232 -r c2d80cbd47dc source/Lib/TLibCommon/TComRom.h
> --- a/source/Lib/TLibCommon/TComRom.h	Thu Sep 18 10:50:04 2014 +0530
> +++ b/source/Lib/TLibCommon/TComRom.h	Thu Sep 18 12:57:29 2014 +0530
> @@ -64,6 +64,8 @@
>  #define MAX_TR_SIZE (1 << MAX_LOG2_TR_SIZE)
>  #define MAX_TS_SIZE (1 << MAX_LOG2_TS_SIZE)
>  
> +#define MAX_RECURSIVE 85 //maximum recursive call for each cu
> +
>  #define SLFASE_CONSTANT 0x5f4e4a53
>  
>  void initROM();
> diff -r e32bc023f232 -r c2d80cbd47dc source/encoder/analysis.cpp
> --- a/source/encoder/analysis.cpp	Thu Sep 18 10:50:04 2014 +0530
> +++ b/source/encoder/analysis.cpp	Thu Sep 18 12:57:29 2014 +0530
> @@ -356,6 +356,9 @@
>      }
>      else
>      {
> +        if (m_param->analysisMode != X265_ANALYSIS_OFF)

if (m_param->analysisMode)

> +            m_interAnalysisData = cu->m_pic->m_interData + (cu->getAddr() * MAX_RECURSIVE);
> +
>          if (m_param->rdLevel < 5)
>          {
>              TComDataCU* outBestCU = NULL;
> @@ -824,6 +827,9 @@
>                      /* Choose best mode; initialise outBestCU to 2Nx2N */
>                      outBestCU = m_interCU_2Nx2N[depth];
>                      std::swap(m_bestPredYuv[depth], m_modePredYuv[0][depth]);
> +
> +                    if (m_interAnalysisData)
> +                        m_interAnalysisData++;
>                  }
>  
>                  /* Compute Rect costs */
> @@ -1271,6 +1277,9 @@
>                  outTempCU->initEstData();
>                  if (m_param->bEnableCbfFastMode)
>                      doNotBlockPu = outBestCU->getQtRootCbf(0) != 0;
> +
> +                if (m_interAnalysisData)
> +                    m_interAnalysisData++;
>              }
>          }
>  
> @@ -1733,7 +1742,7 @@
>  
>      // do motion compensation only for Luma since luma cost alone is calculated
>      outTempCU->m_totalBits = 0;
> -    if (predInterSearch(outTempCU, outPredYuv, bUseMRG, false))
> +    if (predInterSearch(outTempCU, outPredYuv, bUseMRG, false, m_interAnalysisData))
>      {
>          int sizeIdx = outTempCU->getLog2CUSize(0) - 2;
>          uint32_t distortion = primitives.sa8d[sizeIdx](m_origYuv[depth]->getLumaAddr(), m_origYuv[depth]->getStride(),
> @@ -1757,7 +1766,7 @@
>      outTempCU->setPredModeSubParts(MODE_INTER, 0, depth);
>      outTempCU->setCUTransquantBypassSubParts(!!m_param->bLossless, 0, depth);
>  
> -    if (predInterSearch(outTempCU, m_tmpPredYuv[depth], bUseMRG, true))
> +    if (predInterSearch(outTempCU, m_tmpPredYuv[depth], bUseMRG, true, m_interAnalysisData))
>      {
>          encodeResAndCalcRdInterCU(outTempCU, m_origYuv[depth], m_tmpPredYuv[depth], m_tmpResiYuv[depth], m_bestResiYuv[depth], m_tmpRecoYuv[depth]);
>          checkDQP(outTempCU);
> diff -r e32bc023f232 -r c2d80cbd47dc source/encoder/analysis.h
> --- a/source/encoder/analysis.h	Thu Sep 18 10:50:04 2014 +0530
> +++ b/source/encoder/analysis.h	Thu Sep 18 12:57:29 2014 +0530
> @@ -100,6 +100,8 @@
>      StatisticLog  m_sliceTypeLog[3];
>      StatisticLog* m_log;
>  
> +    x265_inter_data* m_interAnalysisData;    // To store the inter analysis data per CU
> +
>      Analysis();
>      bool create(uint32_t totalDepth, uint32_t maxWidth);
>      void destroy();
> diff -r e32bc023f232 -r c2d80cbd47dc source/encoder/motion.cpp
> --- a/source/encoder/motion.cpp	Thu Sep 18 10:50:04 2014 +0530
> +++ b/source/encoder/motion.cpp	Thu Sep 18 12:57:29 2014 +0530
> @@ -530,7 +530,8 @@
>                                     int              numCandidates,
>                                     const MV *       mvc,
>                                     int              merange,
> -                                   MV &             outQMv)
> +                                   MV &             outQMv,
> +                                   bool *           isCostZero)
>  {
>      ALIGN_VAR_16(int, costs[16]);
>      size_t stride = ref->lumaStride;
> @@ -1050,6 +1051,13 @@
>      {
>          /* if there was zero residual at the clipped MVP, we can skip subpel
>           * refine, but we do need to include the mvcost in the returned cost */
> +
> +        /* require for sharing mode, if cost is zero no need to call subpelCompare
> +         * extract the best cost from mvcost and this is only for actual me, not required for
> +         * lowres me and isCostZero is NULL when the me is called from slicetype */
> +        if (isCostZero)
> +            *isCostZero = true;
> +
>          bcost = mvcost(bmv);
>      }
>      else if (ref->isLowres)
> diff -r e32bc023f232 -r c2d80cbd47dc source/encoder/motion.h
> --- a/source/encoder/motion.h	Thu Sep 18 10:50:04 2014 +0530
> +++ b/source/encoder/motion.h	Thu Sep 18 12:57:29 2014 +0530
> @@ -90,7 +90,7 @@
>  
>      inline int bufSATD(pixel *fref, intptr_t stride) { return satd(fenc, FENC_STRIDE, fref, stride); }
>  
> -    int motionEstimate(ReferencePlanes *ref, const MV & mvmin, const MV & mvmax, const MV & qmvp, int numCandidates, const MV * mvc, int merange, MV & outQMv);
> +    int motionEstimate(ReferencePlanes *ref, const MV & mvmin, const MV & mvmax, const MV & qmvp, int numCandidates, const MV * mvc, int merange, MV & outQMv, bool *isCostZero);

Is outCostZero necessary? Can it be derived from outQMv?

>      int subpelCompare(ReferencePlanes * ref, const MV &qmv, pixelcmp_t);
>  
> diff -r e32bc023f232 -r c2d80cbd47dc source/encoder/search.cpp
> --- a/source/encoder/search.cpp	Thu Sep 18 10:50:04 2014 +0530
> +++ b/source/encoder/search.cpp	Thu Sep 18 12:57:29 2014 +0530
> @@ -1667,7 +1667,7 @@
>  
>  /* search of the best candidate for inter prediction
>   * returns true if predYuv was filled with a motion compensated prediction */
> -bool Search::predInterSearch(TComDataCU* cu, TComYuv* predYuv, bool bMergeOnly, bool bChroma)
> +bool Search::predInterSearch(TComDataCU* cu, TComYuv* predYuv, bool bMergeOnly, bool bChroma, x265_inter_data* interAnalysisData)
>  {
>      MV amvpCand[2][MAX_NUM_REF][AMVP_NUM_CANDS];
>      MV mvc[(MD_ABOVE_LEFT + 1) * 2 + 1];
> @@ -1742,6 +1742,11 @@
>  
>          getBlkBits(partSize, slice->isInterP(), partIdx, lastMode, listSelBits);
>  
> +        // require for sharing mode, if the cost is zero no need to call subpelCompare
> +        // extract the best cost from mvcost based on MV
> +        bool costZero[2];
> +        bool isCostZero = false;
> +
>          // Uni-directional prediction
>          for (int l = 0; l < numPredDir; l++)
>          {
> @@ -1782,7 +1787,7 @@
>                  MV mvmin, mvmax, outmv, mvp = amvpCand[l][ref][mvpIdx];
>  
>                  setSearchRange(cu, mvp, merange, mvmin, mvmax);
> -                int satdCost = m_me.motionEstimate(&slice->m_mref[l][ref], mvmin, mvmax, mvp, numMvc, mvc, merange, outmv);
> +                int satdCost = m_me.motionEstimate(&slice->m_mref[l][ref], mvmin, mvmax, mvp, numMvc, mvc, merange, outmv, &isCostZero);
>  
>                  /* Get total cost of partition, but only include MV bit cost once */
>                  bits += m_me.bitcost(outmv);
> @@ -1799,10 +1804,24 @@
>                      list[l].ref = ref;
>                      list[l].cost = cost;
>                      list[l].bits = bits;
> +                    costZero[l] = isCostZero;
>                  }
>              }
>          }
>  
> +        if (m_param->analysisMode == X265_ANALYSIS_SAVE && interAnalysisData)
> +        {
> +            for (int32_t i = 0; i < 2; i++)
> +            {
> +                interAnalysisData->costZero[i] = costZero[i];
> +                interAnalysisData->mvx[i] = list[i].mv.x;
> +                interAnalysisData->mvy[i] = list[i].mv.y;
> +                interAnalysisData->ref[i] = list[i].ref;
> +            }
> +            interAnalysisData->zOrder = cu->getZorderIdxInCU();
> +            interAnalysisData->depth  = cu->getDepth(0);
> +        }
> +
>          // Bi-directional prediction
>          if (slice->isInterB() && !cu->isBipredRestriction() && list[0].cost != MAX_UINT && list[1].cost != MAX_UINT)
>          {
> diff -r e32bc023f232 -r c2d80cbd47dc source/encoder/search.h
> --- a/source/encoder/search.h	Thu Sep 18 10:50:04 2014 +0530
> +++ b/source/encoder/search.h	Thu Sep 18 12:57:29 2014 +0530
> @@ -84,7 +84,7 @@
>      void     estIntraPredChromaQT(TComDataCU* cu, TComYuv* fencYuv, TComYuv* predYuv, ShortYuv* resiYuv, TComYuv* reconYuv);
>  
>      // estimation inter prediction (non-skip)
> -    bool     predInterSearch(TComDataCU* cu, TComYuv* predYuv, bool bMergeOnly, bool bChroma);
> +    bool     predInterSearch(TComDataCU* cu, TComYuv* predYuv, bool bMergeOnly, bool bChroma, x265_inter_data* m_interAnalysisData);
>  
>      // encode residual and compute rd-cost for inter mode
>      void     encodeResAndCalcRdInterCU(TComDataCU* cu, TComYuv* fencYuv, TComYuv* predYuv, ShortYuv* resiYuv, ShortYuv* bestResiYuv, TComYuv* reconYuv);
> diff -r e32bc023f232 -r c2d80cbd47dc source/encoder/slicetype.cpp
> --- a/source/encoder/slicetype.cpp	Thu Sep 18 10:50:04 2014 +0530
> +++ b/source/encoder/slicetype.cpp	Thu Sep 18 12:57:29 2014 +0530
> @@ -1614,7 +1614,7 @@
>                  median_mv(mvp, mvc[0], mvc[1], mvc[2]);
>              }
>  
> -            *fenc_costs[i] = m_me.motionEstimate(i ? fref1 : wfref0, mvmin, mvmax, mvp, numc, mvc, m_merange, *fenc_mvs[i]);
> +            *fenc_costs[i] = m_me.motionEstimate(i ? fref1 : wfref0, mvmin, mvmax, mvp, numc, mvc, m_merange, *fenc_mvs[i], false);
>

You need to pass NULL here, not false

>              COPY2_IF_LT(bcost, *fenc_costs[i], listused, i + 1);
>          }
>          if (bBidir)
> _______________________________________________
> 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