<div dir="ltr">Thanks for review<br><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Mar 17, 2015 at 4:27 AM, Steve Borho <span dir="ltr"><<a href="mailto:steve@borho.org" target="_blank">steve@borho.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span class="">On 03/16, <a href="mailto:gopu@multicorewareinc.com">gopu@multicorewareinc.com</a> wrote:<br>
> # HG changeset patch<br>
> # User Gopu Govindaswamy <<a href="mailto:gopu@multicorewareinc.com">gopu@multicorewareinc.com</a>><br>
> # Date 1426504011 -19800<br>
> #      Mon Mar 16 16:36:51 2015 +0530<br>
> # Node ID 615b61dd2be5e8ef1a7fe2f22edcac6e437f300d<br>
> # Parent  6461985f33ac6fc5b205879bbb0f2a535226ca76<br>
> aq: implementation of Fine-grained Adaptive Quantization<br>
<br>
</span>nit: prefer lower case for Fine<br>
<span class=""><br></span></blockquote><div> </div><div>OK,<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span class="">
> Currently adaptive quantization adjusts the QP values on 64x64 pixel coding tree<br>
> units (CTUs) across a video frame. the new param option --max-dqp-depth will<br>
> enable quantization parameter (QP) to be adjusted to individual quantization<br>
> groups (QGs)<br>
><br>
> Example:<br>
> --max-dqp-depth=0 for 64x64 blocks<br>
> --max-dqp-depth=1 for 32x32 blocks<br>
> --max-dqp-depth=2 for 16x16 blocks<br>
<br>
</span>what if --ctu is not 64?  This patch crashes about 1/3 of the smoke tests<br></blockquote><div><br></div><div>Ok, this is my fault and i have added the validation in encoder configure like <br><br>if (p->rc.maxCuDQPDepth > (int32_t)(g_maxCUDepth - 1))<br></div><div>  then setting default value(depth) for maxCuDQPDepth= 0<br><br></div><div>the current patch will support onlyCU size  64x64, 32x32 and 16x16<br></div><div>for example if --ctu=32 the maxCUDepth is 2 and we will support depth 0 and 1 i.e 32x32 and 16x16 same for --ctu=16<br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div><div class="h5"><br>
> currently this feature not supported for block 8x8<br>
><br>
> sample test results for each depth<br>
><br>
> clip - ducks_take_off_420_720p50.y4m<br>
> preset=medium<br>
> max-dqp-depth 0 - encoded 500 frames in 36.86s (13.56 fps), 4575.09 kb/s,<br>
> Global PSNR: 29.587, SSIM Mean Y: 0.8309761 ( 7.721 dB)<br>
> max-dqp-depth 1 - encoded 500 frames in 43.00s (11.63 fps), 4606.96 kb/s,<br>
> Global PSNR: 29.590, SSIM Mean Y: 0.8313855 ( 7.731 dB)<br>
> max-dqp-depth 2 - encoded 500 frames in 35.47s (14.10 fps), 4599.65 kb/s,<br>
> Global PSNR: 29.575, SSIM Mean Y: 0.8311820 ( 7.726 dB)<br>
><br>
> preset=veryslow<br>
> max-dqp-depth 0 - encoded 500 frames in 499.24s (1.00 fps), 4407.79 kb/s,<br>
> Global PSNR: 29.890, SSIM Mean Y: 0.8419664 ( 8.013 dB)<br>
> max-dqp-depth 1 - encoded 500 frames in 497.96s (1.00 fps),<br>
> 4413.64 kb/s, Global PSNR: 29.884, SSIM Mean Y: 0.8420085 ( 8.014 dB)<br>
> max-dqp-depth 2 - encoded 500 frames in 511.36s (0.98 fps), 4428.71 kb/s,<br>
> Global PSNR: 29.877, SSIM Mean Y: 0.8419621 ( 8.012 dB)<br>
><br>
> -----------------------------------------<br>
> clip - Cactus_1920x1080_50.y4m<br>
> preset=medium<br>
> max-dqp-depth 0 - encoded 100 frames in 13.61s (7.35 fps), 2588.25 kb/s,<br>
> Global PSNR: 34.890, SSIMMean Y: 0.8685867 ( 8.814 dB)<br>
> max-dqp-depth 1 - encoded 100 frames in 12.15s (8.23 fps), 2629.22 kb/s,<br>
> Global PSNR: 34.901, SSIMMean Y: 0.8689989 ( 8.827 dB)<br>
> max-dqp-depth 2 - encoded 100 frames in 12.26s (8.16 fps), 2624.31 kb/s,<br>
> Global PSNR: 34.864, SSIMMean Y: 0.8688061 ( 8.821 dB)<br>
><br>
> preset=veryslow<br>
> max-dqp-depth 0 - encoded 100 frames in 138.68s (0.72 fps), 2277.00 kb/s,<br>
> Global PSNR: 35.118, SSIM Mean Y: 0.8725818 ( 8.948 dB)<br>
> max-dqp-depth 1 - encoded 100 frames in 137.21s (0.73 fps), 2293.83 kb/s,<br>
> Global PSNR: 35.117, SSIM Mean Y: 0.8725589 ( 8.947 dB)<br>
> max-dqp-depth 2 - encoded 100 frames in 134.96s (0.74 fps), 2299.79 kb/s,<br>
> Global PSNR: 35.109, SSIM Mean Y: 0.8727326 ( 8.953 dB)<br>
<br>
</div></div>this doesn't tell us much; I think the most compelling change from this<br>
commit will be in visual quality that is not easily measured.<br></blockquote><div> </div><div>OK,<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div><div class="h5"><br>
> diff -r 6461985f33ac -r 615b61dd2be5 source/common/cudata.cpp<br>
> --- a/source/common/cudata.cpp        Sun Mar 15 11:58:32 2015 -0500<br>
> +++ b/source/common/cudata.cpp        Mon Mar 16 16:36:51 2015 +0530<br>
> @@ -298,7 +298,7 @@<br>
>  }<br>
><br>
>  // initialize Sub partition<br>
> -void CUData::initSubCU(const CUData& ctu, const CUGeom& cuGeom)<br>
> +void CUData::initSubCU(const CUData& ctu, const CUGeom& cuGeom, const int qp)<br>
>  {<br>
>      m_absIdxInCTU   = cuGeom.absPartIdx;<br>
>      m_encData       = ctu.m_encData;<br>
> @@ -312,8 +312,11 @@<br>
>      m_cuAboveRight  = ctu.m_cuAboveRight;<br>
>      X265_CHECK(m_numPartitions == cuGeom.numPartitions, "initSubCU() size mismatch\n");<br>
><br>
> -    /* sequential memsets */<br>
> -    m_partSet((uint8_t*)m_qp, (uint8_t)ctu.m_qp[0]);<br>
> +    if (cuGeom.depth <= (uint32_t)m_encData->m_param->rc.maxCuDQPDepth)<br>
> +        m_partSet((uint8_t*)m_qp, (uint8_t)qp);<br>
> +    else<br>
> +        m_partSet((uint8_t*)m_qp, (uint8_t)ctu.m_qp[0]);<br>
> +<br>
>      m_partSet(m_log2CUSize,   (uint8_t)cuGeom.log2CUSize);<br>
>      m_partSet(m_lumaIntraDir, (uint8_t)DC_IDX);<br>
>      m_partSet(m_tqBypass,     (uint8_t)m_encData->m_param->bLossless);<br>
> diff -r 6461985f33ac -r 615b61dd2be5 source/common/cudata.h<br>
> --- a/source/common/cudata.h  Sun Mar 15 11:58:32 2015 -0500<br>
> +++ b/source/common/cudata.h  Mon Mar 16 16:36:51 2015 +0530<br>
> @@ -182,7 +182,7 @@<br>
>      static void calcCTUGeoms(uint32_t ctuWidth, uint32_t ctuHeight, uint32_t maxCUSize, uint32_t minCUSize, CUGeom cuDataArray[CUGeom::MAX_GEOMS]);<br>
><br>
>      void     initCTU(const Frame& frame, uint32_t cuAddr, int qp);<br>
> -    void     initSubCU(const CUData& ctu, const CUGeom& cuGeom);<br>
> +    void     initSubCU(const CUData& ctu, const CUGeom& cuGeom, const int qp);<br>
>      void     initLosslessCU(const CUData& cu, const CUGeom& cuGeom);<br>
><br>
>      void     copyPartFrom(const CUData& cu, const CUGeom& childGeom, uint32_t subPartIdx);<br>
> diff -r 6461985f33ac -r 615b61dd2be5 source/common/param.cpp<br>
> --- a/source/common/param.cpp Sun Mar 15 11:58:32 2015 -0500<br>
> +++ b/source/common/param.cpp Mon Mar 16 16:36:51 2015 +0530<br>
> @@ -210,6 +210,7 @@<br>
>      param->rc.zones = NULL;<br>
>      param->rc.bEnableSlowFirstPass = 0;<br>
>      param->rc.bStrictCbr = 0;<br>
> +    param->rc.maxCuDQPDepth = 0;<br>
><br>
>      /* Video Usability Information (VUI) */<br>
>      param->vui.aspectRatioIdc = 0;<br>
> @@ -839,6 +840,7 @@<br>
>      OPT2("pools", "numa-pools") p->numaPools = strdup(value);<br>
>      OPT("lambda-file") p->rc.lambdaFileName = strdup(value);<br>
>      OPT("analysis-file") p->analysisFileName = strdup(value);<br>
> +    OPT("max-dqp-depth") p->rc.maxCuDQPDepth = atoi(value);<br>
>      else<br>
>          return X265_PARAM_BAD_NAME;<br>
>  #undef OPT<br>
> diff -r 6461985f33ac -r 615b61dd2be5 source/common/quant.cpp<br>
> --- a/source/common/quant.cpp Sun Mar 15 11:58:32 2015 -0500<br>
> +++ b/source/common/quant.cpp Mon Mar 16 16:36:51 2015 +0530<br>
> @@ -225,13 +225,13 @@<br>
>      X265_FREE(m_fencShortBuf);<br>
>  }<br>
><br>
> -void Quant::setQPforQuant(const CUData& cu)<br>
> +void Quant::setQPforQuant(const CUData& cu, const int qp)<br>
>  {<br>
>      m_tqBypass = !!cu.m_tqBypass[0];<br>
>      if (m_tqBypass)<br>
>          return;<br>
>      m_nr = m_frameNr ? &m_frameNr[cu.m_encData->m_frameEncoderID] : NULL;<br>
> -    int qpy = cu.m_qp[0];<br>
> +    int qpy = qp ? qp : cu.m_qp[0];<br>
>      m_qpParam[TEXT_LUMA].setQpParam(qpy + QP_BD_OFFSET);<br>
>      setChromaQP(qpy + cu.m_slice->m_pps->chromaQpOffset[0], TEXT_CHROMA_U, cu.m_chromaFormat);<br>
>      setChromaQP(qpy + cu.m_slice->m_pps->chromaQpOffset[1], TEXT_CHROMA_V, cu.m_chromaFormat);<br>
> diff -r 6461985f33ac -r 615b61dd2be5 source/common/quant.h<br>
> --- a/source/common/quant.h   Sun Mar 15 11:58:32 2015 -0500<br>
> +++ b/source/common/quant.h   Mon Mar 16 16:36:51 2015 +0530<br>
> @@ -103,7 +103,7 @@<br>
>      bool allocNoiseReduction(const x265_param& param);<br>
><br>
>      /* CU setup */<br>
> -    void setQPforQuant(const CUData& cu);<br>
> +    void setQPforQuant(const CUData& cu, const int qp = 0);<br>
<br>
</div></div>I strongly dislike default values in C++ code. Also 'const int' is<br>
redundant for integer arguments.<br></blockquote><div> </div><div>OK , insted setting the default value i will pass this as a argument in function call<br><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div><div class="h5"><br>
>      uint32_t transformNxN(const CUData& cu, const pixel* fenc, uint32_t fencStride, const int16_t* residual, uint32_t resiStride, coeff_t* coeff,<br>
>                            uint32_t log2TrSize, TextType ttype, uint32_t absPartIdx, bool useTransformSkip);<br>
> diff -r 6461985f33ac -r 615b61dd2be5 source/encoder/analysis.cpp<br>
> --- a/source/encoder/analysis.cpp     Sun Mar 15 11:58:32 2015 -0500<br>
> +++ b/source/encoder/analysis.cpp     Mon Mar 16 16:36:51 2015 +0530<br>
> @@ -225,6 +225,10 @@<br>
>      bool mightSplit = !(cuGeom.flags & CUGeom::LEAF);<br>
>      bool mightNotSplit = !(cuGeom.flags & CUGeom::SPLIT_MANDATORY);<br>
><br>
> +    int32_t qp = 0;<br>
> +    if (depth <= (uint32_t)m_param->rc.maxCuDQPDepth)<br>
> +        qp = calculateQpforCuSize(parentCTU, cuGeom);<br>
> +<br>
>      if (m_param->analysisMode == X265_ANALYSIS_LOAD)<br>
>      {<br>
>          uint8_t* reuseDepth  = &m_reuseIntraDataCTU->depth[parentCTU.m_cuAddr * parentCTU.m_numPartitions];<br>
> @@ -234,11 +238,11 @@<br>
><br>
>          if (mightNotSplit && depth == reuseDepth[zOrder] && zOrder == cuGeom.absPartIdx)<br>
>          {<br>
> -            m_quant.setQPforQuant(parentCTU);<br>
> +            m_quant.setQPforQuant(parentCTU, qp);<br>
><br>
>              PartSize size = (PartSize)reusePartSizes[zOrder];<br>
>              Mode& mode = size == SIZE_2Nx2N ? md.pred[PRED_INTRA] : md.pred[PRED_INTRA_NxN];<br>
> -            mode.cu.initSubCU(parentCTU, cuGeom);<br>
> +            mode.cu.initSubCU(parentCTU, cuGeom, qp);<br>
>              checkIntra(mode, cuGeom, size, &reuseModes[zOrder], &reuseChromaModes[zOrder]);<br>
>              checkBestMode(mode, depth);<br>
><br>
> @@ -255,15 +259,15 @@<br>
>      }<br>
>      else if (mightNotSplit)<br>
>      {<br>
> -        m_quant.setQPforQuant(parentCTU);<br>
> +        m_quant.setQPforQuant(parentCTU, qp);<br>
<br>
</div></div>this seems wrong in general; shouldn't quant always use the QP set in<br>
the CU data structure? it seems like we should be ensuring<br>
m_quant.setQPforQuant() is always called after configuring the QP for<br>
the CU.<br></blockquote><div><br></div><div>we have a different qp for each CU size based on the --max-dqp-depth, in this case <br>when the qp is change for any CU size then need to configure this same QP for Quant also, <br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div><div class="h5"><br>
> -        md.pred[PRED_INTRA].cu.initSubCU(parentCTU, cuGeom);<br>
> +        md.pred[PRED_INTRA].cu.initSubCU(parentCTU, cuGeom, qp);<br>
>          checkIntra(md.pred[PRED_INTRA], cuGeom, SIZE_2Nx2N, NULL, NULL);<br>
>          checkBestMode(md.pred[PRED_INTRA], depth);<br>
><br>
>          if (cuGeom.log2CUSize == 3 && m_slice->m_sps->quadtreeTULog2MinSize < 3)<br>
>          {<br>
> -            md.pred[PRED_INTRA_NxN].cu.initSubCU(parentCTU, cuGeom);<br>
> +            md.pred[PRED_INTRA_NxN].cu.initSubCU(parentCTU, cuGeom, qp);<br>
>              checkIntra(md.pred[PRED_INTRA_NxN], cuGeom, SIZE_NxN, NULL, NULL);<br>
>              checkBestMode(md.pred[PRED_INTRA_NxN], depth);<br>
>          }<br>
> @@ -280,7 +284,7 @@<br>
>          Mode* splitPred = &md.pred[PRED_SPLIT];<br>
>          splitPred->initCosts();<br>
>          CUData* splitCU = &splitPred->cu;<br>
> -        splitCU->initSubCU(parentCTU, cuGeom);<br>
> +        splitCU->initSubCU(parentCTU, cuGeom, qp);<br>
><br>
>          uint32_t nextDepth = depth + 1;<br>
>          ModeDepth& nd = m_modeDepth[nextDepth];<br>
> @@ -496,6 +500,10 @@<br>
><br>
>      X265_CHECK(m_param->rdLevel >= 2, "compressInterCU_dist does not support RD 0 or 1\n");<br>
><br>
> +    int32_t qp = 0;<br>
> +    if (depth <= (uint32_t)m_param->rc.maxCuDQPDepth)<br>
> +        qp = calculateQpforCuSize(parentCTU, cuGeom);<br>
> +<br>
>      if (mightNotSplit && depth >= minDepth)<br>
>      {<br>
>          int bTryAmp = m_slice->m_sps->maxAMPDepth > depth && (cuGeom.log2CUSize < 6 || m_param->rdLevel > 4);<br>
> @@ -504,28 +512,28 @@<br>
>          PMODE pmode(*this, cuGeom);<br>
><br>
>          /* Initialize all prediction CUs based on parentCTU */<br>
> -        md.pred[PRED_MERGE].cu.initSubCU(parentCTU, cuGeom);<br>
> -        md.pred[PRED_SKIP].cu.initSubCU(parentCTU, cuGeom);<br>
> +        md.pred[PRED_MERGE].cu.initSubCU(parentCTU, cuGeom, qp);<br>
> +        md.pred[PRED_SKIP].cu.initSubCU(parentCTU, cuGeom, qp);<br>
>          if (bTryIntra)<br>
>          {<br>
> -            md.pred[PRED_INTRA].cu.initSubCU(parentCTU, cuGeom);<br>
> +            md.pred[PRED_INTRA].cu.initSubCU(parentCTU, cuGeom, qp);<br>
>              if (cuGeom.log2CUSize == 3 && m_slice->m_sps->quadtreeTULog2MinSize < 3 && m_param->rdLevel >= 5)<br>
> -                md.pred[PRED_INTRA_NxN].cu.initSubCU(parentCTU, cuGeom);<br>
> +                md.pred[PRED_INTRA_NxN].cu.initSubCU(parentCTU, cuGeom, qp);<br>
>              pmode.modes[pmode.m_jobTotal++] = PRED_INTRA;<br>
>          }<br>
> -        md.pred[PRED_2Nx2N].cu.initSubCU(parentCTU, cuGeom); pmode.modes[pmode.m_jobTotal++] = PRED_2Nx2N;<br>
> -        md.pred[PRED_BIDIR].cu.initSubCU(parentCTU, cuGeom);<br>
> +        md.pred[PRED_2Nx2N].cu.initSubCU(parentCTU, cuGeom, qp); pmode.modes[pmode.m_jobTotal++] = PRED_2Nx2N;<br>
> +        md.pred[PRED_BIDIR].cu.initSubCU(parentCTU, cuGeom, qp);<br>
>          if (m_param->bEnableRectInter)<br>
>          {<br>
> -            md.pred[PRED_2NxN].cu.initSubCU(parentCTU, cuGeom); pmode.modes[pmode.m_jobTotal++] = PRED_2NxN;<br>
> -            md.pred[PRED_Nx2N].cu.initSubCU(parentCTU, cuGeom); pmode.modes[pmode.m_jobTotal++] = PRED_Nx2N;<br>
> +            md.pred[PRED_2NxN].cu.initSubCU(parentCTU, cuGeom, qp); pmode.modes[pmode.m_jobTotal++] = PRED_2NxN;<br>
> +            md.pred[PRED_Nx2N].cu.initSubCU(parentCTU, cuGeom, qp); pmode.modes[pmode.m_jobTotal++] = PRED_Nx2N;<br>
>          }<br>
>          if (bTryAmp)<br>
>          {<br>
> -            md.pred[PRED_2NxnU].cu.initSubCU(parentCTU, cuGeom); pmode.modes[pmode.m_jobTotal++] = PRED_2NxnU;<br>
> -            md.pred[PRED_2NxnD].cu.initSubCU(parentCTU, cuGeom); pmode.modes[pmode.m_jobTotal++] = PRED_2NxnD;<br>
> -            md.pred[PRED_nLx2N].cu.initSubCU(parentCTU, cuGeom); pmode.modes[pmode.m_jobTotal++] = PRED_nLx2N;<br>
> -            md.pred[PRED_nRx2N].cu.initSubCU(parentCTU, cuGeom); pmode.modes[pmode.m_jobTotal++] = PRED_nRx2N;<br>
> +            md.pred[PRED_2NxnU].cu.initSubCU(parentCTU, cuGeom, qp); pmode.modes[pmode.m_jobTotal++] = PRED_2NxnU;<br>
> +            md.pred[PRED_2NxnD].cu.initSubCU(parentCTU, cuGeom, qp); pmode.modes[pmode.m_jobTotal++] = PRED_2NxnD;<br>
> +            md.pred[PRED_nLx2N].cu.initSubCU(parentCTU, cuGeom, qp); pmode.modes[pmode.m_jobTotal++] = PRED_nLx2N;<br>
> +            md.pred[PRED_nRx2N].cu.initSubCU(parentCTU, cuGeom, qp); pmode.modes[pmode.m_jobTotal++] = PRED_nRx2N;<br>
>          }<br>
><br>
>          pmode.tryBondPeers(*m_frame->m_encData->m_jobProvider, pmode.m_jobTotal);<br>
> @@ -654,7 +662,7 @@<br>
><br>
>          if (md.bestMode->rdCost == MAX_INT64 && !bTryIntra)<br>
>          {<br>
> -            md.pred[PRED_INTRA].cu.initSubCU(parentCTU, cuGeom);<br>
> +            md.pred[PRED_INTRA].cu.initSubCU(parentCTU, cuGeom, qp);<br>
>              checkIntraInInter(md.pred[PRED_INTRA], cuGeom);<br>
>              encodeIntraInInter(md.pred[PRED_INTRA], cuGeom);<br>
>              checkBestMode(md.pred[PRED_INTRA], depth);<br>
> @@ -680,7 +688,7 @@<br>
>          Mode* splitPred = &md.pred[PRED_SPLIT];<br>
>          splitPred->initCosts();<br>
>          CUData* splitCU = &splitPred->cu;<br>
> -        splitCU->initSubCU(parentCTU, cuGeom);<br>
> +        splitCU->initSubCU(parentCTU, cuGeom, qp);<br>
><br>
>          uint32_t nextDepth = depth + 1;<br>
>          ModeDepth& nd = m_modeDepth[nextDepth];<br>
> @@ -744,13 +752,17 @@<br>
>      bool mightNotSplit = !(cuGeom.flags & CUGeom::SPLIT_MANDATORY);<br>
>      uint32_t minDepth = topSkipMinDepth(parentCTU, cuGeom);<br>
><br>
> +    int32_t qp = 0;<br>
> +    if (depth <= (uint32_t)m_param->rc.maxCuDQPDepth)<br>
> +        qp = calculateQpforCuSize(parentCTU, cuGeom);<br>
> +<br>
>      if (mightNotSplit && depth >= minDepth)<br>
>      {<br>
>          bool bTryIntra = m_slice->m_sliceType != B_SLICE || m_param->bIntraInBFrames;<br>
><br>
>          /* Compute Merge Cost */<br>
> -        md.pred[PRED_MERGE].cu.initSubCU(parentCTU, cuGeom);<br>
> -        md.pred[PRED_SKIP].cu.initSubCU(parentCTU, cuGeom);<br>
> +        md.pred[PRED_MERGE].cu.initSubCU(parentCTU, cuGeom, qp);<br>
> +        md.pred[PRED_SKIP].cu.initSubCU(parentCTU, cuGeom, qp);<br>
>          checkMerge2Nx2N_rd0_4(md.pred[PRED_SKIP], md.pred[PRED_MERGE], cuGeom);<br>
><br>
>          bool earlyskip = false;<br>
> @@ -759,24 +771,24 @@<br>
><br>
>          if (!earlyskip)<br>
>          {<br>
> -            md.pred[PRED_2Nx2N].cu.initSubCU(parentCTU, cuGeom);<br>
> +            md.pred[PRED_2Nx2N].cu.initSubCU(parentCTU, cuGeom, qp);<br>
>              checkInter_rd0_4(md.pred[PRED_2Nx2N], cuGeom, SIZE_2Nx2N);<br>
><br>
>              if (m_slice->m_sliceType == B_SLICE)<br>
>              {<br>
> -                md.pred[PRED_BIDIR].cu.initSubCU(parentCTU, cuGeom);<br>
> +                md.pred[PRED_BIDIR].cu.initSubCU(parentCTU, cuGeom, qp);<br>
>                  checkBidir2Nx2N(md.pred[PRED_2Nx2N], md.pred[PRED_BIDIR], cuGeom);<br>
>              }<br>
><br>
>              Mode *bestInter = &md.pred[PRED_2Nx2N];<br>
>              if (m_param->bEnableRectInter)<br>
>              {<br>
> -                md.pred[PRED_Nx2N].cu.initSubCU(parentCTU, cuGeom);<br>
> +                md.pred[PRED_Nx2N].cu.initSubCU(parentCTU, cuGeom, qp);<br>
>                  checkInter_rd0_4(md.pred[PRED_Nx2N], cuGeom, SIZE_Nx2N);<br>
>                  if (md.pred[PRED_Nx2N].sa8dCost < bestInter->sa8dCost)<br>
>                      bestInter = &md.pred[PRED_Nx2N];<br>
><br>
> -                md.pred[PRED_2NxN].cu.initSubCU(parentCTU, cuGeom);<br>
> +                md.pred[PRED_2NxN].cu.initSubCU(parentCTU, cuGeom, qp);<br>
>                  checkInter_rd0_4(md.pred[PRED_2NxN], cuGeom, SIZE_2NxN);<br>
>                  if (md.pred[PRED_2NxN].sa8dCost < bestInter->sa8dCost)<br>
>                      bestInter = &md.pred[PRED_2NxN];<br>
> @@ -798,24 +810,24 @@<br>
><br>
>                  if (bHor)<br>
>                  {<br>
> -                    md.pred[PRED_2NxnU].cu.initSubCU(parentCTU, cuGeom);<br>
> +                    md.pred[PRED_2NxnU].cu.initSubCU(parentCTU, cuGeom, qp);<br>
>                      checkInter_rd0_4(md.pred[PRED_2NxnU], cuGeom, SIZE_2NxnU);<br>
>                      if (md.pred[PRED_2NxnU].sa8dCost < bestInter->sa8dCost)<br>
>                          bestInter = &md.pred[PRED_2NxnU];<br>
><br>
> -                    md.pred[PRED_2NxnD].cu.initSubCU(parentCTU, cuGeom);<br>
> +                    md.pred[PRED_2NxnD].cu.initSubCU(parentCTU, cuGeom, qp);<br>
>                      checkInter_rd0_4(md.pred[PRED_2NxnD], cuGeom, SIZE_2NxnD);<br>
>                      if (md.pred[PRED_2NxnD].sa8dCost < bestInter->sa8dCost)<br>
>                          bestInter = &md.pred[PRED_2NxnD];<br>
>                  }<br>
>                  if (bVer)<br>
>                  {<br>
> -                    md.pred[PRED_nLx2N].cu.initSubCU(parentCTU, cuGeom);<br>
> +                    md.pred[PRED_nLx2N].cu.initSubCU(parentCTU, cuGeom, qp);<br>
>                      checkInter_rd0_4(md.pred[PRED_nLx2N], cuGeom, SIZE_nLx2N);<br>
>                      if (md.pred[PRED_nLx2N].sa8dCost < bestInter->sa8dCost)<br>
>                          bestInter = &md.pred[PRED_nLx2N];<br>
><br>
> -                    md.pred[PRED_nRx2N].cu.initSubCU(parentCTU, cuGeom);<br>
> +                    md.pred[PRED_nRx2N].cu.initSubCU(parentCTU, cuGeom, qp);<br>
>                      checkInter_rd0_4(md.pred[PRED_nRx2N], cuGeom, SIZE_nRx2N);<br>
>                      if (md.pred[PRED_nRx2N].sa8dCost < bestInter->sa8dCost)<br>
>                          bestInter = &md.pred[PRED_nRx2N];<br>
> @@ -847,7 +859,7 @@<br>
>                  if ((bTryIntra && md.bestMode->cu.getQtRootCbf(0)) ||<br>
>                      md.bestMode->sa8dCost == MAX_INT64)<br>
>                  {<br>
> -                    md.pred[PRED_INTRA].cu.initSubCU(parentCTU, cuGeom);<br>
> +                    md.pred[PRED_INTRA].cu.initSubCU(parentCTU, cuGeom, qp);<br>
>                      checkIntraInInter(md.pred[PRED_INTRA], cuGeom);<br>
>                      encodeIntraInInter(md.pred[PRED_INTRA], cuGeom);<br>
>                      checkBestMode(md.pred[PRED_INTRA], depth);<br>
> @@ -865,7 +877,7 @@<br>
><br>
>                  if (bTryIntra || md.bestMode->sa8dCost == MAX_INT64)<br>
>                  {<br>
> -                    md.pred[PRED_INTRA].cu.initSubCU(parentCTU, cuGeom);<br>
> +                    md.pred[PRED_INTRA].cu.initSubCU(parentCTU, cuGeom, qp);<br>
>                      checkIntraInInter(md.pred[PRED_INTRA], cuGeom);<br>
>                      if (md.pred[PRED_INTRA].sa8dCost < md.bestMode->sa8dCost)<br>
>                          md.bestMode = &md.pred[PRED_INTRA];<br>
> @@ -893,7 +905,7 @@<br>
>                      {<br>
>                          /* generate recon pixels with no rate distortion considerations */<br>
>                          CUData& cu = md.bestMode->cu;<br>
> -                        m_quant.setQPforQuant(cu);<br>
> +                        m_quant.setQPforQuant(cu, qp);<br>
><br>
>                          uint32_t tuDepthRange[2];<br>
>                          cu.getInterTUQtDepthRange(tuDepthRange, 0);<br>
> @@ -918,7 +930,7 @@<br>
>                      {<br>
>                          /* generate recon pixels with no rate distortion considerations */<br>
>                          CUData& cu = md.bestMode->cu;<br>
> -                        m_quant.setQPforQuant(cu);<br>
> +                        m_quant.setQPforQuant(cu, qp);<br>
><br>
>                          uint32_t tuDepthRange[2];<br>
>                          cu.getIntraTUQtDepthRange(tuDepthRange, 0);<br>
> @@ -952,7 +964,7 @@<br>
>          Mode* splitPred = &md.pred[PRED_SPLIT];<br>
>          splitPred->initCosts();<br>
>          CUData* splitCU = &splitPred->cu;<br>
> -        splitCU->initSubCU(parentCTU, cuGeom);<br>
> +        splitCU->initSubCU(parentCTU, cuGeom, qp);<br>
><br>
>          uint32_t nextDepth = depth + 1;<br>
>          ModeDepth& nd = m_modeDepth[nextDepth];<br>
> @@ -1025,14 +1037,18 @@<br>
>      bool mightSplit = !(cuGeom.flags & CUGeom::LEAF);<br>
>      bool mightNotSplit = !(cuGeom.flags & CUGeom::SPLIT_MANDATORY);<br>
><br>
> +    int32_t qp = 0;<br>
> +    if (depth <= (uint32_t)m_param->rc.maxCuDQPDepth)<br>
> +        qp = calculateQpforCuSize(parentCTU, cuGeom);<br>
> +<br>
>      if (m_param->analysisMode == X265_ANALYSIS_LOAD)<br>
>      {<br>
>          uint8_t* reuseDepth  = &m_reuseInterDataCTU->depth[parentCTU.m_cuAddr * parentCTU.m_numPartitions];<br>
>          uint8_t* reuseModes  = &m_reuseInterDataCTU->modes[parentCTU.m_cuAddr * parentCTU.m_numPartitions];<br>
>          if (mightNotSplit && depth == reuseDepth[zOrder] && zOrder == cuGeom.absPartIdx && reuseModes[zOrder] == MODE_SKIP)<br>
>          {<br>
> -            md.pred[PRED_SKIP].cu.initSubCU(parentCTU, cuGeom);<br>
> -            md.pred[PRED_MERGE].cu.initSubCU(parentCTU, cuGeom);<br>
> +            md.pred[PRED_SKIP].cu.initSubCU(parentCTU, cuGeom, qp);<br>
> +            md.pred[PRED_MERGE].cu.initSubCU(parentCTU, cuGeom, qp);<br>
>              checkMerge2Nx2N_rd5_6(md.pred[PRED_SKIP], md.pred[PRED_MERGE], cuGeom, true);<br>
><br>
>              if (m_bTryLossless)<br>
> @@ -1051,20 +1067,20 @@<br>
><br>
>      if (mightNotSplit)<br>
>      {<br>
> -        md.pred[PRED_SKIP].cu.initSubCU(parentCTU, cuGeom);<br>
> -        md.pred[PRED_MERGE].cu.initSubCU(parentCTU, cuGeom);<br>
> +        md.pred[PRED_SKIP].cu.initSubCU(parentCTU, cuGeom, qp);<br>
> +        md.pred[PRED_MERGE].cu.initSubCU(parentCTU, cuGeom, qp);<br>
>          checkMerge2Nx2N_rd5_6(md.pred[PRED_SKIP], md.pred[PRED_MERGE], cuGeom, false);<br>
>          bool earlySkip = m_param->bEnableEarlySkip && md.bestMode && !md.bestMode->cu.getQtRootCbf(0);<br>
><br>
>          if (!earlySkip)<br>
>          {<br>
> -            md.pred[PRED_2Nx2N].cu.initSubCU(parentCTU, cuGeom);<br>
> +            md.pred[PRED_2Nx2N].cu.initSubCU(parentCTU, cuGeom, qp);<br>
>              checkInter_rd5_6(md.pred[PRED_2Nx2N], cuGeom, SIZE_2Nx2N, false);<br>
>              checkBestMode(md.pred[PRED_2Nx2N], cuGeom.depth);<br>
><br>
>              if (m_slice->m_sliceType == B_SLICE)<br>
>              {<br>
> -                md.pred[PRED_BIDIR].cu.initSubCU(parentCTU, cuGeom);<br>
> +                md.pred[PRED_BIDIR].cu.initSubCU(parentCTU, cuGeom, qp);<br>
>                  checkBidir2Nx2N(md.pred[PRED_2Nx2N], md.pred[PRED_BIDIR], cuGeom);<br>
>                  if (md.pred[PRED_BIDIR].sa8dCost < MAX_INT64)<br>
>                  {<br>
> @@ -1075,11 +1091,11 @@<br>
><br>
>              if (m_param->bEnableRectInter)<br>
>              {<br>
> -                md.pred[PRED_Nx2N].cu.initSubCU(parentCTU, cuGeom);<br>
> +                md.pred[PRED_Nx2N].cu.initSubCU(parentCTU, cuGeom, qp);<br>
>                  checkInter_rd5_6(md.pred[PRED_Nx2N], cuGeom, SIZE_Nx2N, false);<br>
>                  checkBestMode(md.pred[PRED_Nx2N], cuGeom.depth);<br>
><br>
> -                md.pred[PRED_2NxN].cu.initSubCU(parentCTU, cuGeom);<br>
> +                md.pred[PRED_2NxN].cu.initSubCU(parentCTU, cuGeom, qp);<br>
>                  checkInter_rd5_6(md.pred[PRED_2NxN], cuGeom, SIZE_2NxN, false);<br>
>                  checkBestMode(md.pred[PRED_2NxN], cuGeom.depth);<br>
>              }<br>
> @@ -1102,21 +1118,21 @@<br>
><br>
>                  if (bHor)<br>
>                  {<br>
> -                    md.pred[PRED_2NxnU].cu.initSubCU(parentCTU, cuGeom);<br>
> +                    md.pred[PRED_2NxnU].cu.initSubCU(parentCTU, cuGeom, qp);<br>
>                      checkInter_rd5_6(md.pred[PRED_2NxnU], cuGeom, SIZE_2NxnU, bMergeOnly);<br>
>                      checkBestMode(md.pred[PRED_2NxnU], cuGeom.depth);<br>
><br>
> -                    md.pred[PRED_2NxnD].cu.initSubCU(parentCTU, cuGeom);<br>
> +                    md.pred[PRED_2NxnD].cu.initSubCU(parentCTU, cuGeom, qp);<br>
>                      checkInter_rd5_6(md.pred[PRED_2NxnD], cuGeom, SIZE_2NxnD, bMergeOnly);<br>
>                      checkBestMode(md.pred[PRED_2NxnD], cuGeom.depth);<br>
>                  }<br>
>                  if (bVer)<br>
>                  {<br>
> -                    md.pred[PRED_nLx2N].cu.initSubCU(parentCTU, cuGeom);<br>
> +                    md.pred[PRED_nLx2N].cu.initSubCU(parentCTU, cuGeom, qp);<br>
>                      checkInter_rd5_6(md.pred[PRED_nLx2N], cuGeom, SIZE_nLx2N, bMergeOnly);<br>
>                      checkBestMode(md.pred[PRED_nLx2N], cuGeom.depth);<br>
><br>
> -                    md.pred[PRED_nRx2N].cu.initSubCU(parentCTU, cuGeom);<br>
> +                    md.pred[PRED_nRx2N].cu.initSubCU(parentCTU, cuGeom, qp);<br>
>                      checkInter_rd5_6(md.pred[PRED_nRx2N], cuGeom, SIZE_nRx2N, bMergeOnly);<br>
>                      checkBestMode(md.pred[PRED_nRx2N], cuGeom.depth);<br>
>                  }<br>
> @@ -1124,13 +1140,13 @@<br>
><br>
>              if (m_slice->m_sliceType != B_SLICE || m_param->bIntraInBFrames)<br>
>              {<br>
> -                md.pred[PRED_INTRA].cu.initSubCU(parentCTU, cuGeom);<br>
> +                md.pred[PRED_INTRA].cu.initSubCU(parentCTU, cuGeom, qp);<br>
>                  checkIntra(md.pred[PRED_INTRA], cuGeom, SIZE_2Nx2N, NULL, NULL);<br>
>                  checkBestMode(md.pred[PRED_INTRA], depth);<br>
><br>
>                  if (cuGeom.log2CUSize == 3 && m_slice->m_sps->quadtreeTULog2MinSize < 3)<br>
>                  {<br>
> -                    md.pred[PRED_INTRA_NxN].cu.initSubCU(parentCTU, cuGeom);<br>
> +                    md.pred[PRED_INTRA_NxN].cu.initSubCU(parentCTU, cuGeom, qp);<br>
>                      checkIntra(md.pred[PRED_INTRA_NxN], cuGeom, SIZE_NxN, NULL, NULL);<br>
>                      checkBestMode(md.pred[PRED_INTRA_NxN], depth);<br>
>                  }<br>
> @@ -1150,7 +1166,7 @@<br>
>          Mode* splitPred = &md.pred[PRED_SPLIT];<br>
>          splitPred->initCosts();<br>
>          CUData* splitCU = &splitPred->cu;<br>
> -        splitCU->initSubCU(parentCTU, cuGeom);<br>
> +        splitCU->initSubCU(parentCTU, cuGeom, qp);<br>
><br>
>          uint32_t nextDepth = depth + 1;<br>
>          ModeDepth& nd = m_modeDepth[nextDepth];<br>
> @@ -1896,7 +1912,7 @@<br>
>      return false;<br>
>  }<br>
><br>
> -int Analysis::calculateQpforCuSize(CUData& ctu, const CUGeom& cuGeom)<br>
> +int Analysis::calculateQpforCuSize(const CUData& ctu, const CUGeom& cuGeom)<br>
>  {<br>
>      uint32_t ctuAddr = ctu.m_cuAddr;<br>
>      FrameData& curEncData = *m_frame->m_encData;<br>
> diff -r 6461985f33ac -r 615b61dd2be5 source/encoder/analysis.h<br>
> --- a/source/encoder/analysis.h       Sun Mar 15 11:58:32 2015 -0500<br>
> +++ b/source/encoder/analysis.h       Mon Mar 16 16:36:51 2015 +0530<br>
> @@ -139,7 +139,7 @@<br>
>      /* generate residual and recon pixels for an entire CTU recursively (RD0) */<br>
>      void encodeResidue(const CUData& parentCTU, const CUGeom& cuGeom);<br>
><br>
> -    int calculateQpforCuSize(CUData& ctu, const CUGeom& cuGeom);<br>
> +    int calculateQpforCuSize(const CUData& ctu, const CUGeom& cuGeom);<br>
><br>
>      /* check whether current mode is the new best */<br>
>      inline void checkBestMode(Mode& mode, uint32_t depth)<br>
> diff -r 6461985f33ac -r 615b61dd2be5 source/encoder/encoder.cpp<br>
> --- a/source/encoder/encoder.cpp      Sun Mar 15 11:58:32 2015 -0500<br>
> +++ b/source/encoder/encoder.cpp      Mon Mar 16 16:36:51 2015 +0530<br>
> @@ -1551,15 +1551,11 @@<br>
>      bool bIsVbv = m_param->rc.vbvBufferSize > 0 && m_param->rc.vbvMaxBitrate > 0;<br>
><br>
>      if (!m_param->bLossless && (m_param->rc.aqMode || bIsVbv))<br>
> -    {<br>
>          pps->bUseDQP = true;<br>
> -        pps->maxCuDQPDepth = 0; /* TODO: make configurable? */<br>
> -    }<br>
>      else<br>
> -    {<br>
>          pps->bUseDQP = false;<br>
> -        pps->maxCuDQPDepth = 0;<br>
> -    }<br>
> +<br>
> +    pps->maxCuDQPDepth = m_param->rc.maxCuDQPDepth;<br>
><br>
>      pps->chromaQpOffset[0] = m_param->cbQpOffset;<br>
>      pps->chromaQpOffset[1] = m_param->crQpOffset;<br>
> @@ -1778,6 +1774,17 @@<br>
>          p->analysisMode = X265_ANALYSIS_OFF;<br>
>          x265_log(p, X265_LOG_WARNING, "Analysis save and load mode not supported for distributed mode analysis\n");<br>
>      }<br>
> +    bool bIsVbv = m_param->rc.vbvBufferSize > 0 && m_param->rc.vbvMaxBitrate > 0;<br>
> +    if (!m_param->bLossless && (m_param->rc.aqMode || bIsVbv))<br>
> +    {<br>
> +        if (p->rc.maxCuDQPDepth > (NUM_CU_DEPTH - 2))<br>
> +        {<br>
> +            p->rc.maxCuDQPDepth = 0;<br>
> +            x265_log(p, X265_LOG_WARNING, "The maxCUDQPDepth should be less than maxCUDepth - 1(0, 1 or 2) setting maxCUDQPDepth = %d \n", 0);<br>
> +        }<br>
> +    }<br>
> +    else<br>
> +        p->rc.maxCuDQPDepth = 0;<br>
<br>
</div></div>there should be some kind of a warning here explaining why the option<br>
the user asked for has been ignored<br></blockquote><div><br></div><div>OK,<br> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<span class=""><br>
>  }<br>
><br>
>  void Encoder::allocAnalysis(x265_analysis_data* analysis)<br>
> diff -r 6461985f33ac -r 615b61dd2be5 source/x265.h<br>
> --- a/source/x265.h   Sun Mar 15 11:58:32 2015 -0500<br>
> +++ b/source/x265.h   Mon Mar 16 16:36:51 2015 +0530<br>
> @@ -977,6 +977,13 @@<br>
>          /* Enable stricter conditions to check bitrate deviations in CBR mode. May compromise<br>
>           * quality to maintain bitrate adherence */<br>
>          int bStrictCbr;<br>
> +<br>
> +        /* Max depth of a minimum CuDQP for sub-LCU-level delta QP<br>
> +         * the default maxCuDQPDepth is 0 then the CuDQP signaled once per CTU, this param<br>
> +         * enable the CuDQP signaled for sub-LCU-level also, minimum maxCuDQPDepth is 0<br>
> +         * and max maxCuDQPDepth is equal to maxCUDepth, always the CuDQP signaled<br>
> +         * if currentDepth is less than or equal to maxCuDQPDepth */<br>
> +        int maxCuDQPDepth;<br>
<br>
</span>This is mixing LCU and CTU in the same paragraph. we've systematically<br>
removed all references to LCU in our public headers and docs and are<br>
using CTU everywhere. That's ignoring the fact that I can't make any<br>
sense of this description, as it's currently written.<br></blockquote><div><br></div><div>OK, i will modify the discription and update the rest Doc also<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<span class=""><br>
>      } rc;<br>
><br>
>      /*== Video Usability Information ==*/<br>
> diff -r 6461985f33ac -r 615b61dd2be5 source/x265cli.h<br>
> --- a/source/x265cli.h        Sun Mar 15 11:58:32 2015 -0500<br>
> +++ b/source/x265cli.h        Mon Mar 16 16:36:51 2015 +0530<br>
> @@ -202,6 +202,7 @@<br>
>      { "strict-cbr",           no_argument, NULL, 0 },<br>
>      { "temporal-layers",      no_argument, NULL, 0 },<br>
>      { "no-temporal-layers",   no_argument, NULL, 0 },<br>
> +    { "max-dqp-depth",  required_argument, NULL, 0 },<br>
>      { 0, 0, 0, 0 },<br>
>      { 0, 0, 0, 0 },<br>
>      { 0, 0, 0, 0 },<br>
</span>> _______________________________________________<br>
> x265-devel mailing list<br>
> <a href="mailto:x265-devel@videolan.org">x265-devel@videolan.org</a><br>
> <a href="https://mailman.videolan.org/listinfo/x265-devel" target="_blank">https://mailman.videolan.org/listinfo/x265-devel</a><br>
<span class=""><font color="#888888"><br>
--<br>
Steve Borho<br>
_______________________________________________<br>
x265-devel mailing list<br>
<a href="mailto:x265-devel@videolan.org">x265-devel@videolan.org</a><br>
<a href="https://mailman.videolan.org/listinfo/x265-devel" target="_blank">https://mailman.videolan.org/listinfo/x265-devel</a><br>
</font></span></blockquote></div><br><br clear="all"><br>-- <br><div class="gmail_signature">Thanks & Regards<br>Gopu G<br>Multicoreware Inc <br><br></div>
</div></div>