[x265] [PATCH] rc: add qpmin and qpmax options

Gopi Satykrishna Akisetty gopi.satykrishna at multicorewareinc.com
Tue Jul 19 14:35:52 CEST 2016


On Tue, Jul 19, 2016 at 10:54 AM, Deepthi Nandakumar <
deepthi at multicorewareinc.com> wrote:

>
>
> On Fri, Jul 15, 2016 at 7:03 PM, <gopi.satykrishna at multicorewareinc.com>
> wrote:
>
>> # HG changeset patch
>> # User Gopi Satykrishna Akisetty <gopi.satykrishna at 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?
>

It should be X265_MIN(m_param->rc.qpMax, QP_MAX_SPEC).

>              {
>>                  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 at videolan.org
>> https://mailman.videolan.org/listinfo/x265-devel
>>
>
>
>
> --
> Deepthi Nandakumar
> Engineering Manager, x265
> Multicoreware, Inc
>
> _______________________________________________
> 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/20160719/39fdbf00/attachment-0001.html>


More information about the x265-devel mailing list