[x265] [PATCH 2 of 3] complexAnalysis: increase analysis for areas capped by VBV

Pradeep Ramachandran pradeep at multicorewareinc.com
Fri Jan 27 04:38:57 CET 2017


On Wed, Jan 25, 2017 at 6:55 PM, <bhavna at multicorewareinc.com> wrote:

> # HG changeset patch
> # User Bhavna Hariharan <bhavna at multicorewareinc.com>
> # Date 1485246147 -19800
> #      Tue Jan 24 13:52:27 2017 +0530
> # Node ID 639c197a700ab80e43a67fb29d8e0f6e5ad56e25
> # Parent  bdf2856cc3a1eafb9092bc52a2c2323b4fe92a95
> complexAnalysis: increase analysis for areas capped by VBV
>
> diff -r bdf2856cc3a1 -r 639c197a700a source/common/cudata.cpp
> --- a/source/common/cudata.cpp  Tue Jan 24 13:46:02 2017 +0530
> +++ b/source/common/cudata.cpp  Tue Jan 24 13:52:27 2017 +0530
> @@ -306,6 +306,8 @@
>      for (int8_t i = 0; i < NUM_TU_DEPTH; i++)
>          m_refTuDepth[i] = -1;
>
> +    m_vbvAffected = false;
> +
>      uint32_t widthInCU = m_slice->m_sps->numCuInWidth;
>      m_cuLeft = (m_cuAddr % widthInCU) ? m_encData->getPicCTU(m_cuAddr -
> 1) : NULL;
>      m_cuAbove = (m_cuAddr >= widthInCU) && !m_bFirstRowInSlice ?
> m_encData->getPicCTU(m_cuAddr - widthInCU) : NULL;
> diff -r bdf2856cc3a1 -r 639c197a700a source/common/cudata.h
> --- a/source/common/cudata.h    Tue Jan 24 13:46:02 2017 +0530
> +++ b/source/common/cudata.h    Tue Jan 24 13:52:27 2017 +0530
> @@ -164,6 +164,8 @@
>      static cubcast_t s_partSet[NUM_FULL_DEPTH]; // pointer to broadcast
> set functions per absolute depth
>      static uint32_t  s_numPartInCUSize;
>
> +    bool          m_vbvAffected;
> +
>      FrameData*    m_encData;
>      const Slice*  m_slice;
>
> diff -r bdf2856cc3a1 -r 639c197a700a source/encoder/analysis.cpp
> --- a/source/encoder/analysis.cpp       Tue Jan 24 13:46:02 2017 +0530
> +++ b/source/encoder/analysis.cpp       Tue Jan 24 13:52:27 2017 +0530
> @@ -139,7 +139,7 @@
>      invalidateContexts(0);
>  #endif
>
> -    int qp = setLambdaFromQP(ctu, m_slice->m_pps->bUseDQP ?
> calculateQpforCuSize(ctu, cuGeom) : m_slice->m_sliceQp);
> +    int qp = setLambdaFromQP(ctu, m_slice->m_pps->bUseDQP ?
> calculateQpforCuSize(ctu, cuGeom, 0) : m_slice->m_sliceQp);
>      ctu.setQPSubParts((int8_t)qp, 0, 0);
>
>      m_rqt[0].cur.load(initialContext);
> @@ -439,7 +439,7 @@
>                  m_rqt[nextDepth].cur.load(*nextContext);
>
>                  if (m_slice->m_pps->bUseDQP && nextDepth <=
> m_slice->m_pps->maxCuDQPDepth)
> -                    nextQP = setLambdaFromQP(parentCTU,
> calculateQpforCuSize(parentCTU, childGeom));
> +                    nextQP = setLambdaFromQP(parentCTU,
> calculateQpforCuSize(parentCTU, childGeom, 0));
>
>                  compressIntraCU(parentCTU, childGeom, nextQP);
>
> @@ -742,7 +742,7 @@
>                  m_rqt[nextDepth].cur.load(*nextContext);
>
>                  if (m_slice->m_pps->bUseDQP && nextDepth <=
> m_slice->m_pps->maxCuDQPDepth)
> -                    nextQP = setLambdaFromQP(parentCTU,
> calculateQpforCuSize(parentCTU, childGeom));
> +                    nextQP = setLambdaFromQP(parentCTU,
> calculateQpforCuSize(parentCTU, childGeom, 0));
>
>                  splitRefs[subPartIdx] = compressInterCU_dist(parentCTU,
> childGeom, nextQP);
>
> @@ -969,6 +969,9 @@
>
>  SplitData Analysis::compressInterCU_rd0_4(const CUData& parentCTU, const
> CUGeom& cuGeom, int32_t qp)
>  {
> +    if (m_param->complexAnalysis && parentCTU.m_vbvAffected &&
> calculateQpforCuSize(parentCTU, cuGeom, 1))
> +        return compressInterCU_rd5_6(parentCTU, cuGeom, qp);
> +
>      uint32_t depth = cuGeom.depth;
>      uint32_t cuAddr = parentCTU.m_cuAddr;
>      ModeDepth& md = m_modeDepth[depth];
> @@ -1100,7 +1103,7 @@
>                  m_rqt[nextDepth].cur.load(*nextContext);
>
>                  if (m_slice->m_pps->bUseDQP && nextDepth <=
> m_slice->m_pps->maxCuDQPDepth)
> -                    nextQP = setLambdaFromQP(parentCTU,
> calculateQpforCuSize(parentCTU, childGeom));
> +                    nextQP = setLambdaFromQP(parentCTU,
> calculateQpforCuSize(parentCTU, childGeom, 0));
>
>                  splitData[subPartIdx] = compressInterCU_rd0_4(parentCTU,
> childGeom, nextQP);
>
> @@ -1537,6 +1540,9 @@
>
>  SplitData Analysis::compressInterCU_rd5_6(const CUData& parentCTU, const
> CUGeom& cuGeom, int32_t qp)
>  {
> +    if (m_param->complexAnalysis && parentCTU.m_vbvAffected &&
> !calculateQpforCuSize(parentCTU, cuGeom, 1))
> +        return compressInterCU_rd0_4(parentCTU, cuGeom, qp);
> +
>      uint32_t depth = cuGeom.depth;
>      ModeDepth& md = m_modeDepth[depth];
>      md.bestMode = NULL;
> @@ -1662,7 +1668,7 @@
>                  m_rqt[nextDepth].cur.load(*nextContext);
>
>                  if (m_slice->m_pps->bUseDQP && nextDepth <=
> m_slice->m_pps->maxCuDQPDepth)
> -                    nextQP = setLambdaFromQP(parentCTU,
> calculateQpforCuSize(parentCTU, childGeom));
> +                    nextQP = setLambdaFromQP(parentCTU,
> calculateQpforCuSize(parentCTU, childGeom, 0));
>
>                  splitData[subPartIdx] = compressInterCU_rd5_6(parentCTU,
> childGeom, nextQP);
>
> @@ -2044,7 +2050,7 @@
>                  m_rqt[nextDepth].cur.load(*nextContext);
>
>                  if (m_slice->m_pps->bUseDQP && nextDepth <=
> m_slice->m_pps->maxCuDQPDepth)
> -                    nextQP = setLambdaFromQP(parentCTU,
> calculateQpforCuSize(parentCTU, childGeom));
> +                    nextQP = setLambdaFromQP(parentCTU,
> calculateQpforCuSize(parentCTU, childGeom, 0));
>
>                  qprdRefine(parentCTU, childGeom, nextQP, lqp);
>
> @@ -2874,7 +2880,7 @@
>      return false;
>  }
>
> -int Analysis::calculateQpforCuSize(const CUData& ctu, const CUGeom&
> cuGeom, double baseQp)
> +int Analysis::calculateQpforCuSize(const CUData& ctu, const CUGeom&
> cuGeom, int32_t complexCheck, double baseQp)
>  {
>      FrameData& curEncData = *m_frame->m_encData;
>      double qp = baseQp >= 0 ? baseQp : curEncData.m_cuStat[ctu.m_
> cuAddr].baseQp;
> @@ -2885,7 +2891,11 @@
>          loopIncr = 16;
>      /* Use cuTree offsets if cuTree enabled and frame is referenced, else
> use AQ offsets */
>      bool isReferenced = IS_REFERENCED(m_frame);
> -    double *qpoffs = (isReferenced && m_param->rc.cuTree) ?
> m_frame->m_lowres.qpCuTreeOffset : m_frame->m_lowres.qpAqOffset;
> +    double *qpoffs;
> +    if (complexCheck)
> +        qpoffs = m_frame->m_lowres.qpAqOffset;
> +    else
> +        qpoffs = (isReferenced && m_param->rc.cuTree) ? m_frame->m_lowres.qpCuTreeOffset
> : m_frame->m_lowres.qpAqOffset;
>      if (qpoffs)
>      {
>          uint32_t width = m_frame->m_fencPic->m_picWidth;
> @@ -2910,8 +2920,17 @@
>
>          qp_offset /= cnt;
>          qp += qp_offset;
> +        if (complexCheck)
> +        {
> +            int32_t offset = ((int)(qp_offset * 100 + .5));
> +            double threshold = (1 - ((X265_MAX_ANALYSIS_STRENGTH -
> m_param->complexAnalysis) * 0.5));
> +            int32_t max_threshold = ((int)(threshold * 100 + .5));
> +            if (offset < max_threshold)
> +                return 1;
> +            else
> +                return 0;
> +        }
>      }
> -
>      return x265_clip3(m_param->rc.qpMin, m_param->rc.qpMax, (int)(qp +
> 0.5));
>  }
>
> diff -r bdf2856cc3a1 -r 639c197a700a source/encoder/analysis.h
> --- a/source/encoder/analysis.h Tue Jan 24 13:46:02 2017 +0530
> +++ b/source/encoder/analysis.h Tue Jan 24 13:52:27 2017 +0530
> @@ -174,7 +174,7 @@
>      /* generate residual and recon pixels for an entire CTU recursively
> (RD0) */
>      void encodeResidue(const CUData& parentCTU, const CUGeom& cuGeom);
>
> -    int calculateQpforCuSize(const CUData& ctu, const CUGeom& cuGeom,
> double baseQP = -1);
> +    int calculateQpforCuSize(const CUData& ctu, const CUGeom& cuGeom,
> int32_t complexCheck, double baseQP = -1);
>
>      void calculateNormFactor(CUData& ctu, int qp);
>      void normFactor(const pixel* src, uint32_t blockSize, CUData& ctu,
> int qp, TextType ttype);
> diff -r bdf2856cc3a1 -r 639c197a700a source/encoder/frameencoder.cpp
> --- a/source/encoder/frameencoder.cpp   Tue Jan 24 13:46:02 2017 +0530
> +++ b/source/encoder/frameencoder.cpp   Tue Jan 24 13:52:27 2017 +0530
> @@ -1316,6 +1316,9 @@
>              && analysisFrameData->highDistortionCtuCount &&
> analysisFrameData->lowDistortionCtuCount)
>              curEncData.m_cuStat[cuAddr].baseQp +=
> analysisFrameData->offset[cuAddr];
>
> +        if (m_param->complexAnalysis && (int32_t)(m_rce.qpaRc -
> m_rce.qpNoVbv) > 0)
> +            ctu->m_vbvAffected = true;
> +
>          // Does all the CU analysis, returns best top level mode decision
>          Mode& best = tld.analysis.compressCTU(*ctu, *m_frame,
> m_cuGeoms[m_ctuGeomMap[cuAddr]], rowCoder);
>
> diff -r bdf2856cc3a1 -r 639c197a700a source/x265.h
> --- a/source/x265.h     Tue Jan 24 13:46:02 2017 +0530
> +++ b/source/x265.h     Tue Jan 24 13:52:27 2017 +0530
> @@ -390,6 +390,8 @@
>  #define X265_AQ_AUTO_VARIANCE        2
>  #define X265_AQ_AUTO_VARIANCE_BIASED 3
>
> +#define X265_MAX_ANALYSIS_STRENGTH   4
> +
>

Your range check in param.cpp should use this macro instead of a hard-coded
value now.


>  /* NOTE! For this release only X265_CSP_I420 and X265_CSP_I444 are
> supported */
>
>  /* Supported internal color space types (according to semantics of
> chroma_format_idc) */
> _______________________________________________
> 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/20170127/aa76d114/attachment-0001.html>


More information about the x265-devel mailing list