[x265] [PATCH] aq: implementation of fine-grained adaptive quantization

Deepthi Nandakumar deepthi at multicorewareinc.com
Wed Mar 25 01:15:39 CET 2015


Ok, agree it's best to hold it. But this patch should not change outputs
since the default aq-depth is still zero.

On Tue, Mar 24, 2015 at 7:59 PM, Steve Borho <steve at borho.org> wrote:

> On 03/23, gopu at multicorewareinc.com wrote:
> > # HG changeset patch
> > # User Gopu Govindaswamy <gopu at multicorewareinc.com>
> > # Date 1427100822 -19800
> > #      Mon Mar 23 14:23:42 2015 +0530
> > # Node ID 02f1b991ed9d4d30ad6ec7a4eefca94d5347ceaa
> > # Parent  cc496665280f9e9e4776327e9a1cc1b2eeffecbc
> > aq: implementation of fine-grained adaptive quantization
> >
> > Currently adaptive quantization adjusts the QP values on 64x64 pixel
> CodingTree
> > units (CTUs) across a video frame. the new param option --max-dqp-depth
> will
> > enable quantization parameter (QP) to be adjusted to individual
> quantization
> > groups (QGs)
>
> I have this flagged so I don't forget it, but I'm not going to review
> output changing patches until the regression tests run clean.
>
> > diff -r cc496665280f -r 02f1b991ed9d source/common/cudata.cpp
> > --- a/source/common/cudata.cpp        Sun Mar 22 22:16:45 2015 -0400
> > +++ b/source/common/cudata.cpp        Mon Mar 23 14:23:42 2015 +0530
> > @@ -298,7 +298,7 @@
> >  }
> >
> >  // initialize Sub partition
> > -void CUData::initSubCU(const CUData& ctu, const CUGeom& cuGeom)
> > +void CUData::initSubCU(const CUData& ctu, const CUGeom& cuGeom, int qp)
> >  {
> >      m_absIdxInCTU   = cuGeom.absPartIdx;
> >      m_encData       = ctu.m_encData;
> > @@ -312,8 +312,11 @@
> >      m_cuAboveRight  = ctu.m_cuAboveRight;
> >      X265_CHECK(m_numPartitions == cuGeom.numPartitions, "initSubCU()
> size mismatch\n");
> >
> > -    /* sequential memsets */
> > -    m_partSet((uint8_t*)m_qp, (uint8_t)ctu.m_qp[0]);
> > +    if (cuGeom.depth <= (uint32_t)m_encData->m_param->rc.maxCuDQPDepth
> && ctu.m_slice->m_pps->bUseDQP)
> > +        m_partSet((uint8_t*)m_qp, (uint8_t)qp);
> > +    else
> > +        m_partSet((uint8_t*)m_qp, (uint8_t)ctu.m_qp[0]);
> > +
> >      m_partSet(m_log2CUSize,   (uint8_t)cuGeom.log2CUSize);
> >      m_partSet(m_lumaIntraDir, (uint8_t)DC_IDX);
> >      m_partSet(m_tqBypass,     (uint8_t)m_encData->m_param->bLossless);
> > diff -r cc496665280f -r 02f1b991ed9d source/common/cudata.h
> > --- a/source/common/cudata.h  Sun Mar 22 22:16:45 2015 -0400
> > +++ b/source/common/cudata.h  Mon Mar 23 14:23:42 2015 +0530
> > @@ -182,7 +182,7 @@
> >      static void calcCTUGeoms(uint32_t ctuWidth, uint32_t ctuHeight,
> uint32_t maxCUSize, uint32_t minCUSize, CUGeom
> cuDataArray[CUGeom::MAX_GEOMS]);
> >
> >      void     initCTU(const Frame& frame, uint32_t cuAddr, int qp);
> > -    void     initSubCU(const CUData& ctu, const CUGeom& cuGeom);
> > +    void     initSubCU(const CUData& ctu, const CUGeom& cuGeom, int qp);
> >      void     initLosslessCU(const CUData& cu, const CUGeom& cuGeom);
> >
> >      void     copyPartFrom(const CUData& cu, const CUGeom& childGeom,
> uint32_t subPartIdx);
> > diff -r cc496665280f -r 02f1b991ed9d source/common/param.cpp
> > --- a/source/common/param.cpp Sun Mar 22 22:16:45 2015 -0400
> > +++ b/source/common/param.cpp Mon Mar 23 14:23:42 2015 +0530
> > @@ -208,6 +208,7 @@
> >      param->rc.zones = NULL;
> >      param->rc.bEnableSlowFirstPass = 0;
> >      param->rc.bStrictCbr = 0;
> > +    param->rc.maxCuDQPDepth = 0;
> >
> >      /* Video Usability Information (VUI) */
> >      param->vui.aspectRatioIdc = 0;
> > @@ -841,6 +842,7 @@
> >      OPT2("pools", "numa-pools") p->numaPools = strdup(value);
> >      OPT("lambda-file") p->rc.lambdaFileName = strdup(value);
> >      OPT("analysis-file") p->analysisFileName = strdup(value);
> > +    OPT("max-dqp-depth") p->rc.maxCuDQPDepth = atoi(value);
> >      else
> >          return X265_PARAM_BAD_NAME;
> >  #undef OPT
> > diff -r cc496665280f -r 02f1b991ed9d source/encoder/analysis.cpp
> > --- a/source/encoder/analysis.cpp     Sun Mar 22 22:16:45 2015 -0400
> > +++ b/source/encoder/analysis.cpp     Mon Mar 23 14:23:42 2015 +0530
> > @@ -225,6 +225,10 @@
> >      bool mightSplit = !(cuGeom.flags & CUGeom::LEAF);
> >      bool mightNotSplit = !(cuGeom.flags & CUGeom::SPLIT_MANDATORY);
> >
> > +    int32_t qp = 0;
> > +    if (depth <= (uint32_t)m_param->rc.maxCuDQPDepth &&
> parentCTU.m_slice->m_pps->bUseDQP)
> > +        qp = calculateQpforCuSize(parentCTU, cuGeom);
> > +
> >      if (m_param->analysisMode == X265_ANALYSIS_LOAD)
> >      {
> >          uint8_t* reuseDepth  =
> &m_reuseIntraDataCTU->depth[parentCTU.m_cuAddr * parentCTU.m_numPartitions];
> > @@ -234,11 +238,10 @@
> >
> >          if (mightNotSplit && depth == reuseDepth[zOrder] && zOrder ==
> cuGeom.absPartIdx)
> >          {
> > -            m_quant.setQPforQuant(parentCTU);
> > -
> >              PartSize size = (PartSize)reusePartSizes[zOrder];
> >              Mode& mode = size == SIZE_2Nx2N ? md.pred[PRED_INTRA] :
> md.pred[PRED_INTRA_NxN];
> > -            mode.cu.initSubCU(parentCTU, cuGeom);
> > +            mode.cu.initSubCU(parentCTU, cuGeom, qp);
> > +            m_quant.setQPforQuant(mode.cu);
> >              checkIntra(mode, cuGeom, size, &reuseModes[zOrder],
> &reuseChromaModes[zOrder]);
> >              checkBestMode(mode, depth);
> >
> > @@ -255,15 +258,14 @@
> >      }
> >      else if (mightNotSplit)
> >      {
> > -        m_quant.setQPforQuant(parentCTU);
> > -
> > -        md.pred[PRED_INTRA].cu.initSubCU(parentCTU, cuGeom);
> > +        md.pred[PRED_INTRA].cu.initSubCU(parentCTU, cuGeom, qp);
> > +        m_quant.setQPforQuant(md.pred[PRED_INTRA].cu);
> >          checkIntra(md.pred[PRED_INTRA], cuGeom, SIZE_2Nx2N, NULL, NULL);
> >          checkBestMode(md.pred[PRED_INTRA], depth);
> >
> >          if (cuGeom.log2CUSize == 3 &&
> m_slice->m_sps->quadtreeTULog2MinSize < 3)
> >          {
> > -            md.pred[PRED_INTRA_NxN].cu.initSubCU(parentCTU, cuGeom);
> > +            md.pred[PRED_INTRA_NxN].cu.initSubCU(parentCTU, cuGeom, qp);
> >              checkIntra(md.pred[PRED_INTRA_NxN], cuGeom, SIZE_NxN, NULL,
> NULL);
> >              checkBestMode(md.pred[PRED_INTRA_NxN], depth);
> >          }
> > @@ -280,7 +282,7 @@
> >          Mode* splitPred = &md.pred[PRED_SPLIT];
> >          splitPred->initCosts();
> >          CUData* splitCU = &splitPred->cu;
> > -        splitCU->initSubCU(parentCTU, cuGeom);
> > +        splitCU->initSubCU(parentCTU, cuGeom, qp);
> >
> >          uint32_t nextDepth = depth + 1;
> >          ModeDepth& nd = m_modeDepth[nextDepth];
> > @@ -496,6 +498,10 @@
> >
> >      X265_CHECK(m_param->rdLevel >= 2, "compressInterCU_dist does not
> support RD 0 or 1\n");
> >
> > +    int32_t qp = 0;
> > +    if (depth <= (uint32_t)m_param->rc.maxCuDQPDepth)
> > +        qp = calculateQpforCuSize(parentCTU, cuGeom);
> > +
> >      if (mightNotSplit && depth >= minDepth)
> >      {
> >          int bTryAmp = m_slice->m_sps->maxAMPDepth > depth &&
> (cuGeom.log2CUSize < 6 || m_param->rdLevel > 4);
> > @@ -504,28 +510,28 @@
> >          PMODE pmode(*this, cuGeom);
> >
> >          /* Initialize all prediction CUs based on parentCTU */
> > -        md.pred[PRED_MERGE].cu.initSubCU(parentCTU, cuGeom);
> > -        md.pred[PRED_SKIP].cu.initSubCU(parentCTU, cuGeom);
> > +        md.pred[PRED_MERGE].cu.initSubCU(parentCTU, cuGeom, qp);
> > +        md.pred[PRED_SKIP].cu.initSubCU(parentCTU, cuGeom, qp);
> >          if (bTryIntra)
> >          {
> > -            md.pred[PRED_INTRA].cu.initSubCU(parentCTU, cuGeom);
> > +            md.pred[PRED_INTRA].cu.initSubCU(parentCTU, cuGeom, qp);
> >              if (cuGeom.log2CUSize == 3 &&
> m_slice->m_sps->quadtreeTULog2MinSize < 3 && m_param->rdLevel >= 5)
> > -                md.pred[PRED_INTRA_NxN].cu.initSubCU(parentCTU, cuGeom);
> > +                md.pred[PRED_INTRA_NxN].cu.initSubCU(parentCTU, cuGeom,
> qp);
> >              pmode.modes[pmode.m_jobTotal++] = PRED_INTRA;
> >          }
> > -        md.pred[PRED_2Nx2N].cu.initSubCU(parentCTU, cuGeom);
> pmode.modes[pmode.m_jobTotal++] = PRED_2Nx2N;
> > -        md.pred[PRED_BIDIR].cu.initSubCU(parentCTU, cuGeom);
> > +        md.pred[PRED_2Nx2N].cu.initSubCU(parentCTU, cuGeom, qp);
> pmode.modes[pmode.m_jobTotal++] = PRED_2Nx2N;
> > +        md.pred[PRED_BIDIR].cu.initSubCU(parentCTU, cuGeom, qp);
> >          if (m_param->bEnableRectInter)
> >          {
> > -            md.pred[PRED_2NxN].cu.initSubCU(parentCTU, cuGeom);
> pmode.modes[pmode.m_jobTotal++] = PRED_2NxN;
> > -            md.pred[PRED_Nx2N].cu.initSubCU(parentCTU, cuGeom);
> pmode.modes[pmode.m_jobTotal++] = PRED_Nx2N;
> > +            md.pred[PRED_2NxN].cu.initSubCU(parentCTU, cuGeom, qp);
> pmode.modes[pmode.m_jobTotal++] = PRED_2NxN;
> > +            md.pred[PRED_Nx2N].cu.initSubCU(parentCTU, cuGeom, qp);
> pmode.modes[pmode.m_jobTotal++] = PRED_Nx2N;
> >          }
> >          if (bTryAmp)
> >          {
> > -            md.pred[PRED_2NxnU].cu.initSubCU(parentCTU, cuGeom);
> pmode.modes[pmode.m_jobTotal++] = PRED_2NxnU;
> > -            md.pred[PRED_2NxnD].cu.initSubCU(parentCTU, cuGeom);
> pmode.modes[pmode.m_jobTotal++] = PRED_2NxnD;
> > -            md.pred[PRED_nLx2N].cu.initSubCU(parentCTU, cuGeom);
> pmode.modes[pmode.m_jobTotal++] = PRED_nLx2N;
> > -            md.pred[PRED_nRx2N].cu.initSubCU(parentCTU, cuGeom);
> pmode.modes[pmode.m_jobTotal++] = PRED_nRx2N;
> > +            md.pred[PRED_2NxnU].cu.initSubCU(parentCTU, cuGeom, qp);
> pmode.modes[pmode.m_jobTotal++] = PRED_2NxnU;
> > +            md.pred[PRED_2NxnD].cu.initSubCU(parentCTU, cuGeom, qp);
> pmode.modes[pmode.m_jobTotal++] = PRED_2NxnD;
> > +            md.pred[PRED_nLx2N].cu.initSubCU(parentCTU, cuGeom, qp);
> pmode.modes[pmode.m_jobTotal++] = PRED_nLx2N;
> > +            md.pred[PRED_nRx2N].cu.initSubCU(parentCTU, cuGeom, qp);
> pmode.modes[pmode.m_jobTotal++] = PRED_nRx2N;
> >          }
> >
> >          pmode.tryBondPeers(*m_frame->m_encData->m_jobProvider,
> pmode.m_jobTotal);
> > @@ -654,7 +660,7 @@
> >
> >          if (md.bestMode->rdCost == MAX_INT64 && !bTryIntra)
> >          {
> > -            md.pred[PRED_INTRA].cu.initSubCU(parentCTU, cuGeom);
> > +            md.pred[PRED_INTRA].cu.initSubCU(parentCTU, cuGeom, qp);
> >              checkIntraInInter(md.pred[PRED_INTRA], cuGeom);
> >              encodeIntraInInter(md.pred[PRED_INTRA], cuGeom);
> >              checkBestMode(md.pred[PRED_INTRA], depth);
> > @@ -680,7 +686,7 @@
> >          Mode* splitPred = &md.pred[PRED_SPLIT];
> >          splitPred->initCosts();
> >          CUData* splitCU = &splitPred->cu;
> > -        splitCU->initSubCU(parentCTU, cuGeom);
> > +        splitCU->initSubCU(parentCTU, cuGeom, qp);
> >
> >          uint32_t nextDepth = depth + 1;
> >          ModeDepth& nd = m_modeDepth[nextDepth];
> > @@ -744,13 +750,17 @@
> >      bool mightNotSplit = !(cuGeom.flags & CUGeom::SPLIT_MANDATORY);
> >      uint32_t minDepth = topSkipMinDepth(parentCTU, cuGeom);
> >
> > +    int32_t qp = 0;
> > +    if (depth <= (uint32_t)m_param->rc.maxCuDQPDepth &&
> parentCTU.m_slice->m_pps->bUseDQP)
> > +        qp = calculateQpforCuSize(parentCTU, cuGeom);
> > +
> >      if (mightNotSplit && depth >= minDepth)
> >      {
> >          bool bTryIntra = m_slice->m_sliceType != B_SLICE ||
> m_param->bIntraInBFrames;
> >
> >          /* Compute Merge Cost */
> > -        md.pred[PRED_MERGE].cu.initSubCU(parentCTU, cuGeom);
> > -        md.pred[PRED_SKIP].cu.initSubCU(parentCTU, cuGeom);
> > +        md.pred[PRED_MERGE].cu.initSubCU(parentCTU, cuGeom, qp);
> > +        md.pred[PRED_SKIP].cu.initSubCU(parentCTU, cuGeom, qp);
> >          checkMerge2Nx2N_rd0_4(md.pred[PRED_SKIP], md.pred[PRED_MERGE],
> cuGeom);
> >
> >          bool earlyskip = false;
> > @@ -759,24 +769,24 @@
> >
> >          if (!earlyskip)
> >          {
> > -            md.pred[PRED_2Nx2N].cu.initSubCU(parentCTU, cuGeom);
> > +            md.pred[PRED_2Nx2N].cu.initSubCU(parentCTU, cuGeom, qp);
> >              checkInter_rd0_4(md.pred[PRED_2Nx2N], cuGeom, SIZE_2Nx2N);
> >
> >              if (m_slice->m_sliceType == B_SLICE)
> >              {
> > -                md.pred[PRED_BIDIR].cu.initSubCU(parentCTU, cuGeom);
> > +                md.pred[PRED_BIDIR].cu.initSubCU(parentCTU, cuGeom, qp);
> >                  checkBidir2Nx2N(md.pred[PRED_2Nx2N],
> md.pred[PRED_BIDIR], cuGeom);
> >              }
> >
> >              Mode *bestInter = &md.pred[PRED_2Nx2N];
> >              if (m_param->bEnableRectInter)
> >              {
> > -                md.pred[PRED_Nx2N].cu.initSubCU(parentCTU, cuGeom);
> > +                md.pred[PRED_Nx2N].cu.initSubCU(parentCTU, cuGeom, qp);
> >                  checkInter_rd0_4(md.pred[PRED_Nx2N], cuGeom, SIZE_Nx2N);
> >                  if (md.pred[PRED_Nx2N].sa8dCost < bestInter->sa8dCost)
> >                      bestInter = &md.pred[PRED_Nx2N];
> >
> > -                md.pred[PRED_2NxN].cu.initSubCU(parentCTU, cuGeom);
> > +                md.pred[PRED_2NxN].cu.initSubCU(parentCTU, cuGeom, qp);
> >                  checkInter_rd0_4(md.pred[PRED_2NxN], cuGeom, SIZE_2NxN);
> >                  if (md.pred[PRED_2NxN].sa8dCost < bestInter->sa8dCost)
> >                      bestInter = &md.pred[PRED_2NxN];
> > @@ -798,24 +808,24 @@
> >
> >                  if (bHor)
> >                  {
> > -                    md.pred[PRED_2NxnU].cu.initSubCU(parentCTU, cuGeom);
> > +                    md.pred[PRED_2NxnU].cu.initSubCU(parentCTU, cuGeom,
> qp);
> >                      checkInter_rd0_4(md.pred[PRED_2NxnU], cuGeom,
> SIZE_2NxnU);
> >                      if (md.pred[PRED_2NxnU].sa8dCost <
> bestInter->sa8dCost)
> >                          bestInter = &md.pred[PRED_2NxnU];
> >
> > -                    md.pred[PRED_2NxnD].cu.initSubCU(parentCTU, cuGeom);
> > +                    md.pred[PRED_2NxnD].cu.initSubCU(parentCTU, cuGeom,
> qp);
> >                      checkInter_rd0_4(md.pred[PRED_2NxnD], cuGeom,
> SIZE_2NxnD);
> >                      if (md.pred[PRED_2NxnD].sa8dCost <
> bestInter->sa8dCost)
> >                          bestInter = &md.pred[PRED_2NxnD];
> >                  }
> >                  if (bVer)
> >                  {
> > -                    md.pred[PRED_nLx2N].cu.initSubCU(parentCTU, cuGeom);
> > +                    md.pred[PRED_nLx2N].cu.initSubCU(parentCTU, cuGeom,
> qp);
> >                      checkInter_rd0_4(md.pred[PRED_nLx2N], cuGeom,
> SIZE_nLx2N);
> >                      if (md.pred[PRED_nLx2N].sa8dCost <
> bestInter->sa8dCost)
> >                          bestInter = &md.pred[PRED_nLx2N];
> >
> > -                    md.pred[PRED_nRx2N].cu.initSubCU(parentCTU, cuGeom);
> > +                    md.pred[PRED_nRx2N].cu.initSubCU(parentCTU, cuGeom,
> qp);
> >                      checkInter_rd0_4(md.pred[PRED_nRx2N], cuGeom,
> SIZE_nRx2N);
> >                      if (md.pred[PRED_nRx2N].sa8dCost <
> bestInter->sa8dCost)
> >                          bestInter = &md.pred[PRED_nRx2N];
> > @@ -847,7 +857,7 @@
> >                  if ((bTryIntra && md.bestMode->cu.getQtRootCbf(0)) ||
> >                      md.bestMode->sa8dCost == MAX_INT64)
> >                  {
> > -                    md.pred[PRED_INTRA].cu.initSubCU(parentCTU, cuGeom);
> > +                    md.pred[PRED_INTRA].cu.initSubCU(parentCTU, cuGeom,
> qp);
> >                      checkIntraInInter(md.pred[PRED_INTRA], cuGeom);
> >                      encodeIntraInInter(md.pred[PRED_INTRA], cuGeom);
> >                      checkBestMode(md.pred[PRED_INTRA], depth);
> > @@ -865,7 +875,7 @@
> >
> >                  if (bTryIntra || md.bestMode->sa8dCost == MAX_INT64)
> >                  {
> > -                    md.pred[PRED_INTRA].cu.initSubCU(parentCTU, cuGeom);
> > +                    md.pred[PRED_INTRA].cu.initSubCU(parentCTU, cuGeom,
> qp);
> >                      checkIntraInInter(md.pred[PRED_INTRA], cuGeom);
> >                      if (md.pred[PRED_INTRA].sa8dCost <
> md.bestMode->sa8dCost)
> >                          md.bestMode = &md.pred[PRED_INTRA];
> > @@ -952,7 +962,7 @@
> >          Mode* splitPred = &md.pred[PRED_SPLIT];
> >          splitPred->initCosts();
> >          CUData* splitCU = &splitPred->cu;
> > -        splitCU->initSubCU(parentCTU, cuGeom);
> > +        splitCU->initSubCU(parentCTU, cuGeom, qp);
> >
> >          uint32_t nextDepth = depth + 1;
> >          ModeDepth& nd = m_modeDepth[nextDepth];
> > @@ -1025,14 +1035,18 @@
> >      bool mightSplit = !(cuGeom.flags & CUGeom::LEAF);
> >      bool mightNotSplit = !(cuGeom.flags & CUGeom::SPLIT_MANDATORY);
> >
> > +    int32_t qp = 0;
> > +    if (depth <= (uint32_t)m_param->rc.maxCuDQPDepth &&
> parentCTU.m_slice->m_pps->bUseDQP)
> > +        qp = calculateQpforCuSize(parentCTU, cuGeom);
> > +
> >      if (m_param->analysisMode == X265_ANALYSIS_LOAD)
> >      {
> >          uint8_t* reuseDepth  =
> &m_reuseInterDataCTU->depth[parentCTU.m_cuAddr * parentCTU.m_numPartitions];
> >          uint8_t* reuseModes  =
> &m_reuseInterDataCTU->modes[parentCTU.m_cuAddr * parentCTU.m_numPartitions];
> >          if (mightNotSplit && depth == reuseDepth[zOrder] && zOrder ==
> cuGeom.absPartIdx && reuseModes[zOrder] == MODE_SKIP)
> >          {
> > -            md.pred[PRED_SKIP].cu.initSubCU(parentCTU, cuGeom);
> > -            md.pred[PRED_MERGE].cu.initSubCU(parentCTU, cuGeom);
> > +            md.pred[PRED_SKIP].cu.initSubCU(parentCTU, cuGeom, qp);
> > +            md.pred[PRED_MERGE].cu.initSubCU(parentCTU, cuGeom, qp);
> >              checkMerge2Nx2N_rd5_6(md.pred[PRED_SKIP],
> md.pred[PRED_MERGE], cuGeom, true);
> >
> >              if (m_bTryLossless)
> > @@ -1051,20 +1065,20 @@
> >
> >      if (mightNotSplit)
> >      {
> > -        md.pred[PRED_SKIP].cu.initSubCU(parentCTU, cuGeom);
> > -        md.pred[PRED_MERGE].cu.initSubCU(parentCTU, cuGeom);
> > +        md.pred[PRED_SKIP].cu.initSubCU(parentCTU, cuGeom, qp);
> > +        md.pred[PRED_MERGE].cu.initSubCU(parentCTU, cuGeom, qp);
> >          checkMerge2Nx2N_rd5_6(md.pred[PRED_SKIP], md.pred[PRED_MERGE],
> cuGeom, false);
> >          bool earlySkip = m_param->bEnableEarlySkip && md.bestMode &&
> !md.bestMode->cu.getQtRootCbf(0);
> >
> >          if (!earlySkip)
> >          {
> > -            md.pred[PRED_2Nx2N].cu.initSubCU(parentCTU, cuGeom);
> > +            md.pred[PRED_2Nx2N].cu.initSubCU(parentCTU, cuGeom, qp);
> >              checkInter_rd5_6(md.pred[PRED_2Nx2N], cuGeom, SIZE_2Nx2N,
> false);
> >              checkBestMode(md.pred[PRED_2Nx2N], cuGeom.depth);
> >
> >              if (m_slice->m_sliceType == B_SLICE)
> >              {
> > -                md.pred[PRED_BIDIR].cu.initSubCU(parentCTU, cuGeom);
> > +                md.pred[PRED_BIDIR].cu.initSubCU(parentCTU, cuGeom, qp);
> >                  checkBidir2Nx2N(md.pred[PRED_2Nx2N],
> md.pred[PRED_BIDIR], cuGeom);
> >                  if (md.pred[PRED_BIDIR].sa8dCost < MAX_INT64)
> >                  {
> > @@ -1075,11 +1089,11 @@
> >
> >              if (m_param->bEnableRectInter)
> >              {
> > -                md.pred[PRED_Nx2N].cu.initSubCU(parentCTU, cuGeom);
> > +                md.pred[PRED_Nx2N].cu.initSubCU(parentCTU, cuGeom, qp);
> >                  checkInter_rd5_6(md.pred[PRED_Nx2N], cuGeom, SIZE_Nx2N,
> false);
> >                  checkBestMode(md.pred[PRED_Nx2N], cuGeom.depth);
> >
> > -                md.pred[PRED_2NxN].cu.initSubCU(parentCTU, cuGeom);
> > +                md.pred[PRED_2NxN].cu.initSubCU(parentCTU, cuGeom, qp);
> >                  checkInter_rd5_6(md.pred[PRED_2NxN], cuGeom, SIZE_2NxN,
> false);
> >                  checkBestMode(md.pred[PRED_2NxN], cuGeom.depth);
> >              }
> > @@ -1102,21 +1116,21 @@
> >
> >                  if (bHor)
> >                  {
> > -                    md.pred[PRED_2NxnU].cu.initSubCU(parentCTU, cuGeom);
> > +                    md.pred[PRED_2NxnU].cu.initSubCU(parentCTU, cuGeom,
> qp);
> >                      checkInter_rd5_6(md.pred[PRED_2NxnU], cuGeom,
> SIZE_2NxnU, bMergeOnly);
> >                      checkBestMode(md.pred[PRED_2NxnU], cuGeom.depth);
> >
> > -                    md.pred[PRED_2NxnD].cu.initSubCU(parentCTU, cuGeom);
> > +                    md.pred[PRED_2NxnD].cu.initSubCU(parentCTU, cuGeom,
> qp);
> >                      checkInter_rd5_6(md.pred[PRED_2NxnD], cuGeom,
> SIZE_2NxnD, bMergeOnly);
> >                      checkBestMode(md.pred[PRED_2NxnD], cuGeom.depth);
> >                  }
> >                  if (bVer)
> >                  {
> > -                    md.pred[PRED_nLx2N].cu.initSubCU(parentCTU, cuGeom);
> > +                    md.pred[PRED_nLx2N].cu.initSubCU(parentCTU, cuGeom,
> qp);
> >                      checkInter_rd5_6(md.pred[PRED_nLx2N], cuGeom,
> SIZE_nLx2N, bMergeOnly);
> >                      checkBestMode(md.pred[PRED_nLx2N], cuGeom.depth);
> >
> > -                    md.pred[PRED_nRx2N].cu.initSubCU(parentCTU, cuGeom);
> > +                    md.pred[PRED_nRx2N].cu.initSubCU(parentCTU, cuGeom,
> qp);
> >                      checkInter_rd5_6(md.pred[PRED_nRx2N], cuGeom,
> SIZE_nRx2N, bMergeOnly);
> >                      checkBestMode(md.pred[PRED_nRx2N], cuGeom.depth);
> >                  }
> > @@ -1124,13 +1138,13 @@
> >
> >              if (m_slice->m_sliceType != B_SLICE ||
> m_param->bIntraInBFrames)
> >              {
> > -                md.pred[PRED_INTRA].cu.initSubCU(parentCTU, cuGeom);
> > +                md.pred[PRED_INTRA].cu.initSubCU(parentCTU, cuGeom, qp);
> >                  checkIntra(md.pred[PRED_INTRA], cuGeom, SIZE_2Nx2N,
> NULL, NULL);
> >                  checkBestMode(md.pred[PRED_INTRA], depth);
> >
> >                  if (cuGeom.log2CUSize == 3 &&
> m_slice->m_sps->quadtreeTULog2MinSize < 3)
> >                  {
> > -                    md.pred[PRED_INTRA_NxN].cu.initSubCU(parentCTU,
> cuGeom);
> > +                    md.pred[PRED_INTRA_NxN].cu.initSubCU(parentCTU,
> cuGeom, qp);
> >                      checkIntra(md.pred[PRED_INTRA_NxN], cuGeom,
> SIZE_NxN, NULL, NULL);
> >                      checkBestMode(md.pred[PRED_INTRA_NxN], depth);
> >                  }
> > @@ -1150,7 +1164,7 @@
> >          Mode* splitPred = &md.pred[PRED_SPLIT];
> >          splitPred->initCosts();
> >          CUData* splitCU = &splitPred->cu;
> > -        splitCU->initSubCU(parentCTU, cuGeom);
> > +        splitCU->initSubCU(parentCTU, cuGeom, qp);
> >
> >          uint32_t nextDepth = depth + 1;
> >          ModeDepth& nd = m_modeDepth[nextDepth];
> > @@ -1897,7 +1911,7 @@
> >      return false;
> >  }
> >
> > -int Analysis::calculateQpforCuSize(CUData& ctu, const CUGeom& cuGeom)
> > +int Analysis::calculateQpforCuSize(const CUData& ctu, const CUGeom&
> cuGeom)
> >  {
> >      uint32_t ctuAddr = ctu.m_cuAddr;
> >      FrameData& curEncData = *m_frame->m_encData;
> > diff -r cc496665280f -r 02f1b991ed9d source/encoder/analysis.h
> > --- a/source/encoder/analysis.h       Sun Mar 22 22:16:45 2015 -0400
> > +++ b/source/encoder/analysis.h       Mon Mar 23 14:23:42 2015 +0530
> > @@ -139,7 +139,7 @@
> >      /* generate residual and recon pixels for an entire CTU recursively
> (RD0) */
> >      void encodeResidue(const CUData& parentCTU, const CUGeom& cuGeom);
> >
> > -    int calculateQpforCuSize(CUData& ctu, const CUGeom& cuGeom);
> > +    int calculateQpforCuSize(const CUData& ctu, const CUGeom& cuGeom);
> >
> >      /* check whether current mode is the new best */
> >      inline void checkBestMode(Mode& mode, uint32_t depth)
> > diff -r cc496665280f -r 02f1b991ed9d source/encoder/encoder.cpp
> > --- a/source/encoder/encoder.cpp      Sun Mar 22 22:16:45 2015 -0400
> > +++ b/source/encoder/encoder.cpp      Mon Mar 23 14:23:42 2015 +0530
> > @@ -1557,15 +1557,11 @@
> >      bool bIsVbv = m_param->rc.vbvBufferSize > 0 &&
> m_param->rc.vbvMaxBitrate > 0;
> >
> >      if (!m_param->bLossless && (m_param->rc.aqMode || bIsVbv))
> > -    {
> >          pps->bUseDQP = true;
> > -        pps->maxCuDQPDepth = 0; /* TODO: make configurable? */
> > -    }
> >      else
> > -    {
> >          pps->bUseDQP = false;
> > -        pps->maxCuDQPDepth = 0;
> > -    }
> > +
> > +    pps->maxCuDQPDepth = m_param->rc.maxCuDQPDepth;
> >
> >      pps->chromaQpOffset[0] = m_param->cbQpOffset;
> >      pps->chromaQpOffset[1] = m_param->crQpOffset;
> > @@ -1788,6 +1784,20 @@
> >          p->analysisMode = X265_ANALYSIS_OFF;
> >          x265_log(p, X265_LOG_WARNING, "Analysis save and load mode not
> supported for distributed mode analysis\n");
> >      }
> > +    bool bIsVbv = m_param->rc.vbvBufferSize > 0 &&
> m_param->rc.vbvMaxBitrate > 0;
> > +    if (!m_param->bLossless && (m_param->rc.aqMode || bIsVbv))
> > +    {
> > +        if (p->rc.maxCuDQPDepth > (int32_t)(g_maxCUDepth - 1))
> > +        {
> > +            p->rc.maxCuDQPDepth = 0;
> > +            x265_log(p, X265_LOG_WARNING, "The maxCUDQPDepth should be
> less than (maxCUDepth - 1) setting maxCUDQPDepth = %d \n", 0);
> > +        }
> > +    }
> > +    else
> > +    {
> > +        p->rc.maxCuDQPDepth = 0;
> > +        x265_log(p, X265_LOG_WARNING, "The maxCUDQPDepth should be zero
> when vbv and aq Mode is disabled\n");
> > +    }
> >  }
> >
> >  void Encoder::allocAnalysis(x265_analysis_data* analysis)
> > diff -r cc496665280f -r 02f1b991ed9d source/x265.h
> > --- a/source/x265.h   Sun Mar 22 22:16:45 2015 -0400
> > +++ b/source/x265.h   Mon Mar 23 14:23:42 2015 +0530
> > @@ -978,6 +978,12 @@
> >          /* Enable stricter conditions to check bitrate deviations in
> CBR mode. May compromise
> >           * quality to maintain bitrate adherence */
> >          int bStrictCbr;
> > +
> > +        /* the new param option --max-dqp-depth will enable adaptive
> quantization to adjusts the QP values
> > +         * based on individual quantization groups (QGs), the QGs can
> be 64x64, 32x32 or 16x16 block
> > +         * the default : 0, QPs are adjusted for 64x64 pixel Coding
> tree uint (CTU),
> > +         * minimum is depth 0 and maximum is maxCUDepth - 1 */
> > +        int maxCuDQPDepth;
> >      } rc;
> >
> >      /*== Video Usability Information ==*/
> > diff -r cc496665280f -r 02f1b991ed9d source/x265cli.h
> > --- a/source/x265cli.h        Sun Mar 22 22:16:45 2015 -0400
> > +++ b/source/x265cli.h        Mon Mar 23 14:23:42 2015 +0530
> > @@ -204,6 +204,7 @@
> >      { "strict-cbr",           no_argument, NULL, 0 },
> >      { "temporal-layers",      no_argument, NULL, 0 },
> >      { "no-temporal-layers",   no_argument, NULL, 0 },
> > +    { "max-dqp-depth",  required_argument, NULL, 0 },
> >      { 0, 0, 0, 0 },
> >      { 0, 0, 0, 0 },
> >      { 0, 0, 0, 0 },
> > _______________________________________________
> > x265-devel mailing list
> > x265-devel at videolan.org
> > https://mailman.videolan.org/listinfo/x265-devel
>
> --
> Steve Borho
> _______________________________________________
> 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/20150325/4d060d80/attachment-0001.html>


More information about the x265-devel mailing list