[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