[x265] [PATCH] dqp: add logic to encode DQP at depth zero and above as well

Steve Borho steve at borho.org
Sat Mar 7 08:07:07 CET 2015


On 03/05, gopu at multicorewareinc.com wrote:
> # HG changeset patch
> # User Gopu Govindaswamy <gopu at multicorewareinc.com>
> # Date 1425540797 -19800
> #      Thu Mar 05 13:03:17 2015 +0530
> # Node ID ce2bd9e51497631f038110c227e164fe0ffcb5bf
> # Parent  ea9bdb10353fcb06cea1045ba0186c22c448df63
> dqp: add logic to encode DQP at depth zero and above as well
> 
> Added the logic to check dqp for all sub-CU level
> checkDQP function moved into base class search

queued for testing

> diff -r ea9bdb10353f -r ce2bd9e51497 source/encoder/analysis.cpp
> --- a/source/encoder/analysis.cpp	Wed Mar 04 13:20:55 2015 +0530
> +++ b/source/encoder/analysis.cpp	Thu Mar 05 13:03:17 2015 +0530
> @@ -312,11 +312,11 @@
>              addSplitFlagCost(*splitPred, cuGeom.depth);
>          else
>              updateModeCost(*splitPred);
> +
> +        checkDQPForSplitPred(splitPred->cu, cuGeom);
>          checkBestMode(*splitPred, depth);
>      }
>  
> -    checkDQP(md.bestMode->cu, cuGeom);
> -
>      /* Copy best data to encData CTU and recon */
>      md.bestMode->cu.copyToPic(depth);
>      if (md.bestMode != &md.pred[PRED_SPLIT])
> @@ -711,6 +711,7 @@
>          else
>              updateModeCost(*splitPred);
>  
> +        checkDQPForSplitPred(splitPred->cu, cuGeom);
>          checkBestMode(*splitPred, depth);
>      }
>  
> @@ -724,8 +725,6 @@
>          cuStat.avgCost[depth] = (temp + md.bestMode->rdCost) / cuStat.count[depth];
>      }
>  
> -    checkDQP(md.bestMode->cu, cuGeom);
> -
>      /* Copy best data to encData CTU and recon */
>      md.bestMode->cu.copyToPic(depth);
>      if (md.bestMode != &md.pred[PRED_SPLIT])
> @@ -996,8 +995,9 @@
>              checkBestMode(*splitPred, cuGeom.depth);
>          else if (splitPred->sa8dCost < md.bestMode->sa8dCost)
>              md.bestMode = splitPred;
> +
> +        checkDQPForSplitPred(md.bestMode->cu, cuGeom);
>      }
> -
>      if (mightNotSplit)
>      {
>          /* early-out statistics */
> @@ -1008,8 +1008,6 @@
>          cuStat.avgCost[depth] = (temp + md.bestMode->rdCost) / cuStat.count[depth];
>      }
>  
> -    checkDQP(md.bestMode->cu, cuGeom);
> -
>      /* Copy best data to encData CTU and recon */
>      md.bestMode->cu.copyToPic(depth);
>      if (md.bestMode != &md.pred[PRED_SPLIT] && m_param->rdLevel)
> @@ -1184,11 +1182,10 @@
>          else
>              updateModeCost(*splitPred);
>  
> +        checkDQPForSplitPred(splitPred->cu, cuGeom);
>          checkBestMode(*splitPred, depth);
>      }
>  
> -    checkDQP(md.bestMode->cu, cuGeom);
> -
>      /* Copy best data to encData CTU and recon */
>      md.bestMode->cu.copyToPic(depth);
>      if (md.bestMode != &md.pred[PRED_SPLIT])
> @@ -1296,6 +1293,7 @@
>      bestPred->cu.setPUMv(1, candMvField[bestSadCand][1].mv, 0, 0);
>      bestPred->cu.setPURefIdx(0, (int8_t)candMvField[bestSadCand][0].refIdx, 0, 0);
>      bestPred->cu.setPURefIdx(1, (int8_t)candMvField[bestSadCand][1].refIdx, 0, 0);
> +    checkDQP(bestPred->cu, cuGeom);
>  }
>  
>  /* sets md.bestMode if a valid merge candidate is found, else leaves it NULL */
> @@ -1432,6 +1430,7 @@
>          if (m_param->analysisMode == X265_ANALYSIS_SAVE)
>              *m_reuseBestMergeCand = bestPred->cu.m_mvpIdx[0][0];
>      }
> +    checkDQP(bestPred->cu, cuGeom);
>  }
>  
>  void Analysis::checkInter_rd0_4(Mode& interMode, const CUGeom& cuGeom, PartSize partSize)
> @@ -1759,7 +1758,6 @@
>                                                           predV, predYuv.m_csize);
>      }
>  
> -    checkDQP(cu, cuGeom);
>      cu.updatePic(cuGeom.depth);
>  }
>  
> @@ -1788,34 +1786,6 @@
>      }
>  }
>  
> -void Analysis::checkDQP(CUData& cu, const CUGeom& cuGeom)
> -{
> -    if (m_slice->m_pps->bUseDQP && cuGeom.depth <= m_slice->m_pps->maxCuDQPDepth)
> -    {
> -        if (cu.m_cuDepth[0] > cuGeom.depth) // detect splits
> -        {
> -            bool hasResidual = false;
> -            for (uint32_t absPartIdx = 0; absPartIdx < cu.m_numPartitions; absPartIdx++)
> -            {
> -                if (cu.getQtRootCbf(absPartIdx))
> -                {
> -                    hasResidual = true;
> -                    break;
> -                }
> -            }
> -            if (hasResidual)
> -                cu.setQPSubCUs(cu.getRefQP(0), 0, cuGeom.depth);
> -            else
> -                cu.setQPSubParts(cu.getRefQP(0), 0, cuGeom.depth);
> -        }
> -        else
> -        {
> -            if (!cu.getCbf(0, TEXT_LUMA, 0) && !cu.getCbf(0, TEXT_CHROMA_U, 0) && !cu.getCbf(0, TEXT_CHROMA_V, 0))
> -                cu.setQPSubParts(cu.getRefQP(0), 0, cuGeom.depth);
> -        }
> -    }
> -}
> -
>  uint32_t Analysis::topSkipMinDepth(const CUData& parentCTU, const CUGeom& cuGeom)
>  {
>      /* Do not attempt to code a block larger than the largest block in the
> diff -r ea9bdb10353f -r ce2bd9e51497 source/encoder/analysis.h
> --- a/source/encoder/analysis.h	Wed Mar 04 13:20:55 2015 +0530
> +++ b/source/encoder/analysis.h	Thu Mar 05 13:03:17 2015 +0530
> @@ -132,9 +132,6 @@
>      /* add the RD cost of coding a split flag (0 or 1) to the given mode */
>      void addSplitFlagCost(Mode& mode, uint32_t depth);
>  
> -    /* update CBF flags and QP values to be internally consistent */
> -    void checkDQP(CUData& cu, const CUGeom& cuGeom);
> -
>      /* work-avoidance heuristics for RD levels < 5 */
>      uint32_t topSkipMinDepth(const CUData& parentCTU, const CUGeom& cuGeom);
>      bool recursionDepthCheck(const CUData& parentCTU, const CUGeom& cuGeom, const Mode& bestMode);
> diff -r ea9bdb10353f -r ce2bd9e51497 source/encoder/search.cpp
> --- a/source/encoder/search.cpp	Wed Mar 04 13:20:55 2015 +0530
> +++ b/source/encoder/search.cpp	Thu Mar 05 13:03:17 2015 +0530
> @@ -1184,8 +1184,8 @@
>          const Yuv* fencYuv = intraMode.fencYuv;
>          intraMode.psyEnergy = m_rdCost.psyCost(cuGeom.log2CUSize - 2, fencYuv->m_buf[0], fencYuv->m_size, intraMode.reconYuv.m_buf[0], intraMode.reconYuv.m_size);
>      }
> -
>      updateModeCost(intraMode);
> +    checkDQP(cu, cuGeom);
>  }
>  
>  /* Note that this function does not save the best intra prediction, it must
> @@ -1404,6 +1404,7 @@
>  
>      m_entropyCoder.store(intraMode.contexts);
>      updateModeCost(intraMode);
> +    checkDQP(intraMode.cu, cuGeom);
>  }
>  
>  uint32_t Search::estIntraPredQT(Mode &intraMode, const CUGeom& cuGeom, const uint32_t depthRange[2], uint8_t* sharedModes)
> @@ -2627,6 +2628,7 @@
>      interMode.coeffBits = coeffBits;
>      interMode.mvBits = bits - coeffBits;
>      updateModeCost(interMode);
> +    checkDQP(interMode.cu, cuGeom);
>  }
>  
>  void Search::residualTransformQuantInter(Mode& mode, const CUGeom& cuGeom, uint32_t absPartIdx, uint32_t tuDepth, const uint32_t depthRange[2])
> @@ -3444,3 +3446,49 @@
>          candModeList[maxIndex] = mode;
>      }
>  }
> +
> +void Search::checkDQP(CUData& cu, const CUGeom& cuGeom)
> +{
> +    if (cu.m_slice->m_pps->bUseDQP && cuGeom.depth <= cu.m_slice->m_pps->maxCuDQPDepth)
> +    {
> +        if (cu.getQtRootCbf(0))
> +        {
> +            /* When analysing RDO with DQP bits, the entropy encoder should add the cost of DQP bits here
> +             * i.e Encode QP */
> +        }
> +        else
> +        {
> +            cu.setQPSubParts(cu.getRefQP(0), 0, cuGeom.depth);
> +        }
> +    }
> +}
> +
> +void Search::checkDQPForSplitPred(CUData& cu, const CUGeom& cuGeom)
> +{
> +    if ((cuGeom.depth == cu.m_slice->m_pps->maxCuDQPDepth) && cu.m_slice->m_pps->bUseDQP)
> +    {
> +        bool hasResidual = false;
> +
> +        /* Check if any sub-CU has a non-zero QP */
> +        for (uint32_t blkIdx = 0; blkIdx < cuGeom.numPartitions; blkIdx++)
> +        {
> +            if (cu.getQtRootCbf(blkIdx))
> +            {
> +                hasResidual = true;
> +                break;
> +            }
> +        }
> +        if (hasResidual)
> +        {
> +            /* TODO: Encode QP, and recalculate RD cost of splitPred */
> +            /* For all zero CBF sub-CUs, reset QP to RefQP (so that deltaQP is not signalled).
> +            When the non-zero CBF sub-CU is found, stop */
> +            bool ret = false;
> +            ret = cu.setQPSubCUs(cu.getRefQP(0), 0, cuGeom.depth);
> +            X265_CHECK(ret, "set sub QP CU failed\n");
> +        }
> +        else
> +            /* No residual within this CU or subCU, so reset QP to RefQP */
> +            cu.setQPSubParts(cu.getRefQP(0), 0, cuGeom.depth);
> +    }
> +}
> diff -r ea9bdb10353f -r ce2bd9e51497 source/encoder/search.h
> --- a/source/encoder/search.h	Wed Mar 04 13:20:55 2015 +0530
> +++ b/source/encoder/search.h	Thu Mar 05 13:03:17 2015 +0530
> @@ -281,6 +281,10 @@
>      // pick be chroma mode from available using just sa8d costs
>      void     getBestIntraModeChroma(Mode& intraMode, const CUGeom& cuGeom);
>  
> +    /* update CBF flags and QP values to be internally consistent */
> +    void checkDQP(CUData& cu, const CUGeom& cuGeom);
> +    void checkDQPForSplitPred(CUData& cu, const CUGeom& cuGeom);
> +
>      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