On Fri, Jul 15, 2016 at 7:03 PM, <gopi.satykris...@multicorewareinc.com> wrote:
> # HG changeset patch > # User Gopi Satykrishna Akisetty <gopi.satykris...@multicorewareinc.com> > # Date 1468581281 -19800 > # Fri Jul 15 16:44:41 2016 +0530 > # Node ID 98a948623fdc745a37123f52a00fefeecaadaad7 > # Parent 43ca544799c240f6eefb66424dc73ec65b7dcfea > rc: add qpmin and qpmax options > > diff -r 43ca544799c2 -r 98a948623fdc doc/reST/cli.rst > --- a/doc/reST/cli.rst Fri Jul 15 12:43:23 2016 +0530 > +++ b/doc/reST/cli.rst Fri Jul 15 16:44:41 2016 +0530 > @@ -1434,6 +1434,14 @@ > The maximum single adjustment in QP allowed to rate control. > Default > 4 > > +.. option:: --qpmin <integer> > + > + sets a hard lower limit on QP allowed to ratecontrol. Default 0 > + > +.. option:: --qpmax <integer> > + > + sets a hard upper limit on QP allowed to ratecontrol. Default 69 > + > .. option:: --rc-grain, --no-rc-grain > > Enables a specialised ratecontrol algorithm for film grain content. > This > diff -r 43ca544799c2 -r 98a948623fdc source/CMakeLists.txt > --- a/source/CMakeLists.txt Fri Jul 15 12:43:23 2016 +0530 > +++ b/source/CMakeLists.txt Fri Jul 15 16:44:41 2016 +0530 > @@ -30,7 +30,7 @@ > mark_as_advanced(FPROFILE_USE FPROFILE_GENERATE NATIVE_BUILD) > > # X265_BUILD must be incremented each time the public API is changed > -set(X265_BUILD 88) > +set(X265_BUILD 89) > configure_file("${PROJECT_SOURCE_DIR}/x265.def.in" > "${PROJECT_BINARY_DIR}/x265.def") > configure_file("${PROJECT_SOURCE_DIR}/x265_config.h.in" > diff -r 43ca544799c2 -r 98a948623fdc source/common/param.cpp > --- a/source/common/param.cpp Fri Jul 15 12:43:23 2016 +0530 > +++ b/source/common/param.cpp Fri Jul 15 16:44:41 2016 +0530 > @@ -224,6 +224,8 @@ > param->rc.bEnableSlowFirstPass = 1; > param->rc.bStrictCbr = 0; > param->rc.bEnableGrain = 0; > + param->rc.qpMin = 0; > + param->rc.qpMax = QP_MAX_MAX; > > /* Video Usability Information (VUI) */ > param->vui.aspectRatioIdc = 0; > @@ -509,6 +511,7 @@ > bool bError = false; > bool bNameWasBool = false; > bool bValueWasNull = !value; > + bool bExtraParams = false; > char nameBuf[64]; > > if (!name) > @@ -747,6 +750,7 @@ > OPT("vbv-init") p->rc.vbvBufferInit = atof(value); > OPT("crf-max") p->rc.rfConstantMax = atof(value); > OPT("crf-min") p->rc.rfConstantMin = atof(value); > + OPT("qpmax") p->rc.qpMax = atoi(value); > OPT("crf") > { > p->rc.rfConstant = atof(value); > @@ -885,7 +889,14 @@ > OPT("max-luma") p->maxLuma = (uint16_t)atoi(value); > OPT("uhd-bd") p->uhdBluray = atobool(value); > else > - return X265_PARAM_BAD_NAME; > + bExtraParams = true; > + if (bExtraParams) > + { > + if (0) ; > + OPT("qpmin") p->rc.qpMin = atoi(value); > + else > + return X265_PARAM_BAD_NAME; > + } > #undef OPT > #undef atobool > #undef atoi > @@ -1208,6 +1219,10 @@ > "Strict-cbr cannot be applied without specifying target bitrate > or vbv bufsize"); > CHECK(param->analysisMode && (param->analysisMode < X265_ANALYSIS_OFF > || param->analysisMode > X265_ANALYSIS_LOAD), > "Invalid analysis mode. Analysis mode 0: OFF 1: SAVE : 2 LOAD"); > + CHECK(param->rc.qpMax < QP_MIN || param->rc.qpMax > QP_MAX_MAX, > + "qpmax exceeds supported range (0 to 69)"); > + CHECK(param->rc.qpMin < QP_MIN || param->rc.qpMin > QP_MAX_MAX, > + "qpmin exceeds supported range (0 to 69)"); > return check_failed; > } > > @@ -1463,7 +1478,7 @@ > else > s += sprintf(s, " bitrate=%d", p->rc.bitrate); > s += sprintf(s, " qcomp=%.2f qpmin=%d qpmax=%d qpstep=%d", > - p->rc.qCompress, QP_MIN, QP_MAX_SPEC, p->rc.qpStep); > + p->rc.qCompress, p->rc.qpMin, p->rc.qpMax, > p->rc.qpStep); > I suggest you print this only if they are different from the defaults, to avoid cluttering up the console output. > if (p->rc.bStatRead) > s += sprintf( s, " cplxblur=%.1f qblur=%.1f", > p->rc.complexityBlur, p->rc.qblur); > diff -r 43ca544799c2 -r 98a948623fdc source/encoder/analysis.cpp > --- a/source/encoder/analysis.cpp Fri Jul 15 12:43:23 2016 +0530 > +++ b/source/encoder/analysis.cpp Fri Jul 15 16:44:41 2016 +0530 > @@ -255,7 +255,7 @@ > cuPrevCost = origCUCost; > > int modCUQP = qp + dir; > - while (modCUQP >= QP_MIN && modCUQP <= QP_MAX_SPEC) > + while (modCUQP >= m_param->rc.qpMin && modCUQP <= QP_MAX_SPEC) > This should be qpMax? > { > recodeCU(parentCTU, cuGeom, modCUQP, qp); > cuCost = md.bestMode->rdCost; > @@ -2667,5 +2667,5 @@ > qp += qp_offset; > } > > - return x265_clip3(QP_MIN, QP_MAX_MAX, (int)(qp + 0.5)); > + return x265_clip3(m_param->rc.qpMin, m_param->rc.qpMax, (int)(qp + > 0.5)); > } > diff -r 43ca544799c2 -r 98a948623fdc source/encoder/frameencoder.cpp > --- a/source/encoder/frameencoder.cpp Fri Jul 15 12:43:23 2016 +0530 > +++ b/source/encoder/frameencoder.cpp Fri Jul 15 16:44:41 2016 +0530 > @@ -1127,7 +1127,7 @@ > { > double qpBase = curEncData.m_cuStat[cuAddr].baseQp; > int reEncode = > m_top->m_rateControl->rowDiagonalVbvRateControl(m_frame, row, &m_rce, > qpBase); > - qpBase = x265_clip3((double)QP_MIN, (double)QP_MAX_MAX, > qpBase); > + qpBase = x265_clip3((double)m_param->rc.qpMin, > (double)m_param->rc.qpMax, qpBase); > curEncData.m_rowStat[row].diagQp = qpBase; > curEncData.m_rowStat[row].diagQpScale = > x265_qp2qScale(qpBase); > > diff -r 43ca544799c2 -r 98a948623fdc source/encoder/ratecontrol.cpp > --- a/source/encoder/ratecontrol.cpp Fri Jul 15 12:43:23 2016 +0530 > +++ b/source/encoder/ratecontrol.cpp Fri Jul 15 16:44:41 2016 +0530 > @@ -284,7 +284,11 @@ > #define ABR_SCENECUT_INIT_QP_MIN (12) > #define CRF_INIT_QP (int)m_param->rc.rfConstant > for (int i = 0; i < 3; i++) > + { > m_lastQScaleFor[i] = x265_qp2qScale(m_param->rc.rateControlMode > == X265_RC_CRF ? CRF_INIT_QP : ABR_INIT_QP_MIN); > + m_lmin[i] = x265_qp2qScale(m_param->rc.qpMin); > + m_lmax[i] = x265_qp2qScale(m_param->rc.qpMax); > + } > > if (m_param->rc.rateControlMode == X265_RC_CQP) > { > @@ -808,13 +812,19 @@ > (double)m_param->rc.bitrate, > expectedBits * m_fps / (m_numEntries * 1000.), > avgq); > - if (expectedBits < allAvailableBits && avgq < QP_MIN + 2) > + if (expectedBits < allAvailableBits && avgq < m_param->rc.qpMin + > 2) > { > - x265_log(m_param, X265_LOG_WARNING, "try reducing target > bitrate\n"); > + if (m_param->rc.qpMin > 0) > + x265_log(m_param, X265_LOG_WARNING, "try reducing target > bitrate or reducing qp_min (currently %d)\n", m_param->rc.qpMin); > + else > + x265_log(m_param, X265_LOG_WARNING, "try reducing target > bitrate\n"); > } > - else if (expectedBits > allAvailableBits && avgq > QP_MAX_SPEC - > 2) > + else if (expectedBits > allAvailableBits && avgq > > m_param->rc.qpMax - 2) > { > - x265_log(m_param, X265_LOG_WARNING, "try increasing target > bitrate\n"); > + if (m_param->rc.qpMax < QP_MAX_MAX) > + x265_log(m_param, X265_LOG_WARNING, "try increasing > target bitrate or increasing qp_max (currently %d)\n", m_param->rc.qpMax); > + else > + x265_log(m_param, X265_LOG_WARNING, "try increasing > target bitrate\n"); > } > else if (!(m_2pass && m_isVbv)) > x265_log(m_param, X265_LOG_WARNING, "internal error\n"); > @@ -966,6 +976,8 @@ > double adjustment; > double prevBits = 0; > int t0, t1; > + double qScaleMin = x265_qp2qScale(m_param->rc.qpMin); > + double qScaleMax = x265_qp2qScale(m_param->rc.qpMax); > int iterations = 0 , adjMin, adjMax; > CHECKED_MALLOC(fills, double, m_numEntries + 1); > fills++; > @@ -985,7 +997,7 @@ > adjMin = 1; > while (adjMin && findUnderflow(fills, &t0, &t1, 1, endPos)) > { > - adjMin = fixUnderflow(t0, t1, adjustment, MIN_QPSCALE, > MAX_MAX_QPSCALE); > + adjMin = fixUnderflow(t0, t1, adjustment, qScaleMin, > qScaleMax); > t0 = t1; > } > } > @@ -995,7 +1007,7 @@ > /* fix underflows -- should be done after overflow, as we'd > better undersize target than underflowing VBV */ > adjMax = 1; > while (adjMax && findUnderflow(fills, &t0, &t1, 0, endPos)) > - adjMax = fixUnderflow(t0, t1, 1.001, MIN_QPSCALE, > MAX_MAX_QPSCALE ); > + adjMax = fixUnderflow(t0, t1, 1.001, qScaleMin, qScaleMax); > expectedBits = countExpectedBits(startPos, endPos); > } > while ((expectedBits < .995 * allAvailableBits) && > ((int64_t)(expectedBits+.5) > (int64_t)(prevBits+.5)) && > !(m_param->rc.rateControlMode == X265_RC_CRF)); > @@ -1216,7 +1228,7 @@ > * the scene-transition mini-gop */ > > double q = x265_qScale2qp(rateEstimateQscale(curFrame, rce)); > - q = x265_clip3((double)QP_MIN, (double)QP_MAX_MAX, q); > + q = x265_clip3((double)m_param->rc.qpMin, > (double)m_param->rc.qpMax, q); > m_qp = int(q + 0.5); > q = m_isGrainEnabled ? m_qp : q; > rce->qpaRc = curEncData.m_avgQpRc = curEncData.m_avgQpAq = q; > @@ -1254,7 +1266,7 @@ > if (curFrame->m_forceqp) > { > m_qp = (int32_t)(curFrame->m_forceqp + 0.5) - 1; > - m_qp = x265_clip3(QP_MIN, QP_MAX_MAX, m_qp); > + m_qp = x265_clip3(m_param->rc.qpMin, m_param->rc.qpMax, m_qp); > rce->qpaRc = curEncData.m_avgQpRc = curEncData.m_avgQpAq = m_qp; > if (m_isAbr || m_2pass) > { > @@ -1647,6 +1659,8 @@ > double abrBuffer = 2 * m_rateTolerance * m_bitrate; > if (m_2pass) > { > + double lmin = m_lmin[m_sliceType]; > + double lmax = m_lmax[m_sliceType]; > int64_t diff; > if (!m_isVbv) > { > @@ -1697,17 +1711,17 @@ > double sizeConstraint = 1 + expectedFullness; > qmax = X265_MAX(qmax, rce->newQScale); > if (expectedFullness < .05) > - qmax = MAX_MAX_QPSCALE; > - qmax = X265_MIN(qmax, MAX_MAX_QPSCALE); > + qmax = lmax; > + qmax = X265_MIN(qmax, lmax); > while (((expectedVbv < rce->expectedVbv/sizeConstraint) > && (q < qmax)) || > - ((expectedVbv < 0) && (q < MAX_MAX_QPSCALE))) > + ((expectedVbv < 0) && (q < lmax))) > { > q *= 1.05; > expectedSize = qScale2bits(rce, q); > expectedVbv = m_bufferFill + m_bufferRate - > expectedSize; > } > } > - q = x265_clip3(MIN_QPSCALE, MAX_MAX_QPSCALE, q); > + q = x265_clip3(lmin, lmax, q); > } > else > { > @@ -1724,7 +1738,8 @@ > * tolerances, the bit distribution approaches that of 2pass. > */ > > double overflow = 1; > - double lqmin = MIN_QPSCALE, lqmax = MAX_MAX_QPSCALE; > + double lqmin = m_lmin[m_sliceType]; > + double lqmax = m_lmax[m_sliceType]; > m_shortTermCplxSum *= 0.5; > m_shortTermCplxCount *= 0.5; > m_shortTermCplxSum += m_currentSatd / > (CLIP_DURATION(m_frameDuration) / BASE_FRAME_DURATION); > @@ -1810,7 +1825,7 @@ > x265_qp2qScale(ABR_INIT_QP_MAX); > q = X265_MIN(lqmax, q); > } > - q = x265_clip3(MIN_QPSCALE, MAX_MAX_QPSCALE, q); > + q = x265_clip3(lqmin, lqmax, q); > /* Set a min qp at scenechanges and transitions */ > if (m_isSceneTransition) > { > @@ -1974,6 +1989,8 @@ > { > // B-frames are not directly subject to VBV, > // since they are controlled by referenced P-frames' QPs. > + double lmin = m_lmin[m_sliceType]; > + double lmax = m_lmax[m_sliceType]; > double q0 = q; > if (m_isVbv && m_currentSatd > 0 && curFrame) > { > @@ -2087,20 +2104,20 @@ > if (m_rateFactorMaxIncrement) > { > double qpNoVbv = x265_qScale2qp(q0); > - double qmax = X265_MIN(MAX_MAX_QPSCALE,x265_qp2qScale(qpNoVbv > + m_rateFactorMaxIncrement)); > - return x265_clip3(MIN_QPSCALE, qmax, q); > + double qmax = X265_MIN(lmax,x265_qp2qScale(qpNoVbv + > m_rateFactorMaxIncrement)); > + return x265_clip3(lmin, qmax, q); > } > } > if (m_2pass) > { > - double min = log(MIN_QPSCALE); > - double max = log(MAX_MAX_QPSCALE); > + double min = log(lmin); > + double max = log(lmax); > q = (log(q) - min) / (max - min) - 0.5; > q = 1.0 / (1.0 + exp(-4 * q)); > q = q*(max - min) + min; > return exp(q); > } > - return x265_clip3(MIN_QPSCALE, MAX_MAX_QPSCALE, q); > + return x265_clip3(lmin, lmax, q); > } > > double RateControl::predictRowsSizeSum(Frame* curFrame, RateControlEntry* > rce, double qpVbv, int32_t& encodedBitsSoFar) > @@ -2215,8 +2232,8 @@ > int canReencodeRow = 1; > /* tweak quality based on difference from predicted size */ > double prevRowQp = qpVbv; > - double qpAbsoluteMax = QP_MAX_MAX; > - double qpAbsoluteMin = QP_MIN; > + double qpAbsoluteMax = m_param->rc.qpMax; > + double qpAbsoluteMin = m_param->rc.qpMin; > if (m_rateFactorMaxIncrement) > qpAbsoluteMax = X265_MIN(qpAbsoluteMax, rce->qpNoVbv + > m_rateFactorMaxIncrement); > > @@ -2435,7 +2452,7 @@ > avgQpRc += curEncData.m_rowStat[i].sumQpRc; > > avgQpRc /= slice->m_sps->numCUsInFrame; > - curEncData.m_avgQpRc = x265_clip3((double)QP_MIN, > (double)QP_MAX_MAX, avgQpRc); > + curEncData.m_avgQpRc = x265_clip3((double)m_param->rc.qpMin, > (double)m_param->rc.qpMax, avgQpRc); > rce->qpaRc = curEncData.m_avgQpRc; > } > > diff -r 43ca544799c2 -r 98a948623fdc source/encoder/ratecontrol.h > --- a/source/encoder/ratecontrol.h Fri Jul 15 12:43:23 2016 +0530 > +++ b/source/encoder/ratecontrol.h Fri Jul 15 16:44:41 2016 +0530 > @@ -162,6 +162,8 @@ > double m_accumPNorm; > double m_lastQScaleFor[3]; /* last qscale for a specific pict type, > used for max_diff & ipb factor stuff */ > double m_lstep; > + double m_lmin[3]; > + double m_lmax[3]; > double m_shortTermCplxSum; > double m_shortTermCplxCount; > double m_lastRceq; > diff -r 43ca544799c2 -r 98a948623fdc source/encoder/sao.cpp > --- a/source/encoder/sao.cpp Fri Jul 15 12:43:23 2016 +0530 > +++ b/source/encoder/sao.cpp Fri Jul 15 16:44:41 2016 +0530 > @@ -1197,7 +1197,7 @@ > > int qpCb = qp; > if (m_param->internalCsp == X265_CSP_I420) > - qpCb = x265_clip3(QP_MIN, QP_MAX_MAX, (int)g_chromaScale[qp + > slice->m_pps->chromaQpOffset[0]]); > + qpCb = x265_clip3(m_param->rc.qpMin, m_param->rc.qpMax, > (int)g_chromaScale[qp + slice->m_pps->chromaQpOffset[0]]); > else > qpCb = X265_MIN(qp + slice->m_pps->chromaQpOffset[0], > QP_MAX_SPEC); > > diff -r 43ca544799c2 -r 98a948623fdc source/x265.h > --- a/source/x265.h Fri Jul 15 12:43:23 2016 +0530 > +++ b/source/x265.h Fri Jul 15 16:44:41 2016 +0530 > @@ -1161,6 +1161,12 @@ > > /* internally enable if tune grain is set */ > int bEnableGrain; > + > + /* sets a hard upper limit on QP */ > + int qpMax; > + > + /* sets a hard lower limit on QP */ > + int qpMin; > } rc; > > /*== Video Usability Information ==*/ > diff -r 43ca544799c2 -r 98a948623fdc source/x265cli.h > --- a/source/x265cli.h Fri Jul 15 12:43:23 2016 +0530 > +++ b/source/x265cli.h Fri Jul 15 16:44:41 2016 +0530 > @@ -152,6 +152,8 @@ > { "pbratio", required_argument, NULL, 0 }, > { "qcomp", required_argument, NULL, 0 }, > { "qpstep", required_argument, NULL, 0 }, > + { "qpmin", required_argument, NULL, 0 }, > + { "qpmax", required_argument, NULL, 0 }, > { "ratetol", required_argument, NULL, 0 }, > { "cplxblur", required_argument, NULL, 0 }, > { "qblur", required_argument, NULL, 0 }, > @@ -388,6 +390,8 @@ > H1(" --pbratio <float> QP factor between P and B. > Default %.2f\n", param->rc.pbFactor); > H1(" --qcomp <float> Weight given to predicted > complexity. Default %.2f\n", param->rc.qCompress); > H1(" --qpstep <integer> The maximum single adjustment in > QP allowed to rate control. Default %d\n", param->rc.qpStep); > + H1(" --qpmin <integer> sets a hard lower limit on QP > allowed to ratecontrol. Default %d\n", param->rc.qpMin); > + H1(" --qpmax <integer> sets a hard upper limit on QP > allowed to ratecontrol. Default %d\n", param->rc.qpMax); > H1(" --cbqpoffs <integer> Chroma Cb QP Offset [-12..12]. > Default %d\n", param->cbQpOffset); > H1(" --crqpoffs <integer> Chroma Cr QP Offset [-12..12]. > Default %d\n", param->crQpOffset); > H1(" --scaling-list <string> Specify a file containing HM > style quant scaling lists or 'default' or 'off'. Default: off\n"); > _______________________________________________ > x265-devel mailing list > x265-devel@videolan.org > https://mailman.videolan.org/listinfo/x265-devel > -- Deepthi Nandakumar Engineering Manager, x265 Multicoreware, Inc
_______________________________________________ x265-devel mailing list x265-devel@videolan.org https://mailman.videolan.org/listinfo/x265-devel