[x265] [PATCH] Basic support for tweaking rate control using zones

Deepthi Nandakumar deepthi at multicorewareinc.com
Tue Dec 23 07:03:19 CET 2014


Hi,

Thanks for your patch. I'm not quite sure any of our regular users need
this as of now. We will keep this on standby though - until any requests
come in.

On Mon, Dec 22, 2014 at 6:09 AM, Adam Marcus <adampetermarcus at gmail.com>
wrote:

> # HG changeset patch
> # User amarcu5 <adampetermarcus at gmail.com>
> # Date 1419207231 0
> # Node ID 188f80215b37a34289f4124614bf66211fe63314
> # Parent  8d2f418829c894c25da79daa861f16c61e5060d7
> Support for tweaking rate control using zones
>
> diff --git a/source/common/param.cpp b/source/common/param.cpp
> --- a/source/common/param.cpp
> +++ b/source/common/param.cpp
> @@ -205,6 +205,8 @@
>      param->rc.statFileName = NULL;
>      param->rc.complexityBlur = 20;
>      param->rc.qblur = 0.5;
> +    param->rc.zoneCount = 0;
> +    param->rc.zones = NULL;
>      param->rc.bEnableSlowFirstPass = 0;
>
>
>      /* Video Usability Information (VUI) */
> @@ -694,6 +696,35 @@
>          p->rc.qp = atoi(value);
>          p->rc.rateControlMode = X265_RC_CQP;
>      }
> +    OPT("zones")
> +    {
> +        p->rc.zoneCount = 1;
> +        const char* c;
> +        for (c = value; *c; c++) {
> +            p->rc.zoneCount += (*c == '/');
> +        }
> +        p->rc.zones = X265_MALLOC(x265_zone, p->rc.zoneCount);
> +        c = value;
> +        for (int i = 0; i < p->rc.zoneCount; i++ )
> +        {
> +            int len;
> +            if (3 == sscanf(c, "%d,%d,q=%d%n",
> &p->rc.zones[i].startFrame, &p->rc.zones[i].endFrame, &p->rc.zones[i].qp,
> &len))
> +            {
> +                p->rc.zones[i].bForceQp = 1;
> +            }
> +            else if (3 == sscanf(c, "%d,%d,b=%f%n",
> &p->rc.zones[i].startFrame, &p->rc.zones[i].endFrame,
> &p->rc.zones[i].bitrateFactor, &len))
> +            {
> +                p->rc.zones[i].bForceQp = 0;
> +            }
> +            else
> +            {
> +                bError = true;
> +                break;
> +            }
> +            c += len + 1;
> +        }
> +
> +    }
>      OPT("input-res") bError |= sscanf(value, "%dx%d", &p->sourceWidth,
> &p->sourceHeight) != 2;
>      OPT("input-csp") p->internalCsp = parseName(value,
> x265_source_csp_names, bError);
>      OPT("me")        p->searchMethod = parseName(value,
> x265_motion_est_names, bError);
> diff --git a/source/encoder/ratecontrol.cpp
> b/source/encoder/ratecontrol.cpp
> --- a/source/encoder/ratecontrol.cpp
> +++ b/source/encoder/ratecontrol.cpp
> @@ -169,6 +169,18 @@
>          return acEnergyVar(curFrame, primitives.var[BLOCK_16x16](src,
> srcStride), 8, bChroma);
>  }
>
>
> +/* Returns the zone for the current frame */
> +x265_zone* RateControl::getZone()
> +{
> +    for (int i = m_param->rc.zoneCount - 1; i >= 0; i--)
> +    {
> +        x265_zone *z = &m_param->rc.zones[i];
> +        if (m_framesDone + 1 >= z->startFrame && m_framesDone <
> z->endFrame)
> +            return z;
> +    }
> +    return NULL;
> +}
> +
>  /* Find the total AC energy of each block in all planes */
>  uint32_t RateControl::acEnergyCu(Frame* curFrame, uint32_t block_x,
> uint32_t block_y)
>  {
> @@ -1153,6 +1165,15 @@
>          else
>              m_qp = m_qpConstant[m_sliceType];
>          curEncData.m_avgQpAq = curEncData.m_avgQpRc = m_qp;
> +
> +        x265_zone* zone = getZone();
> +        if (zone)
> +        {
> +            if (zone->bForceQp)
> +                m_qp += zone->qp - m_qpConstant[P_SLICE];
> +            else
> +                m_qp -= 6.0 * X265_LOG2(zone->bitrateFactor);
> +        }
>      }
>      if (m_sliceType != B_SLICE)
>      {
> @@ -1242,6 +1263,14 @@
>          m_accumPNorm = mask * (1 + m_accumPNorm);
>      }
>
>
> +    x265_zone* zone = getZone();
> +    if (zone)
> +    {
> +        if (zone->bForceQp)
> +            q = x265_qp2qScale(zone->qp);
> +        else
> +            q /= zone->bitrateFactor;
> +    }
>      return q;
>  }
>
>
> @@ -2071,6 +2100,15 @@
>          m_lastRceq = q;
>          q /= rateFactor;
>      }
> +
> +    x265_zone* zone = getZone();
> +    if (zone)
> +    {
> +        if (zone->bForceQp)
> +            q = x265_qp2qScale(zone->qp);
> +        else
> +            q /= zone->bitrateFactor;
> +    }
>      return q;
>  }
>
>
> @@ -2361,5 +2399,7 @@
>      X265_FREE(m_rce2Pass);
>      for (int i = 0; i < 2; i++)
>          X265_FREE(m_cuTreeStats.qpBuffer[i]);
> +
> +    X265_FREE(m_param->rc.zones);
>  }
>
>
> diff --git a/source/encoder/ratecontrol.h b/source/encoder/ratecontrol.h
> --- a/source/encoder/ratecontrol.h
> +++ b/source/encoder/ratecontrol.h
> @@ -247,6 +247,7 @@
>      int m_amortizeFrames;
>      double m_amortizeFraction;
>
>
> +    x265_zone* getZone();
>      double getQScale(RateControlEntry *rce, double rateFactor);
>      double rateEstimateQscale(Frame* pic, RateControlEntry *rce); // main
> logic for calculating QP based on ABR
>      void accumPQpUpdate();
> diff --git a/source/x265.cpp b/source/x265.cpp
> --- a/source/x265.cpp
> +++ b/source/x265.cpp
> @@ -150,6 +150,7 @@
>      { "vbv-init",       required_argument, NULL, 0 },
>      { "bitrate",        required_argument, NULL, 0 },
>      { "qp",             required_argument, NULL, 'q' },
> +    { "zones",          required_argument, NULL, 0 },
>      { "aq-mode",        required_argument, NULL, 0 },
>      { "aq-strength",    required_argument, NULL, 0 },
>      { "ipratio",        required_argument, NULL, 0 },
> @@ -435,6 +436,12 @@
>      H0("   --b-adapt <0..2>              0 - none, 1 - fast, 2 - full
> (trellis) adaptive B frame scheduling. Default %d\n",
> param->bFrameAdaptive);
>      H0("   --[no-]b-pyramid              Use B-frames as references.
> Default %s\n", OPT(param->bBPyramid));
>      H0("   --ref <integer>               max number of L0 references to
> be allowed (1 .. 16) Default %d\n", param->maxNumReferences);
> +    H1("   --zones <zone0>/<zone1>/...   Tweak the bitrate of regions of
> the video\n");
> +    H1("                                 Each zone is of the form\n");
> +    H1("                                   <start frame>,<end
> frame>,<option>\n");
> +    H1("                                   where <option> is either\n");
> +    H1("                                       q=<integer> (force QP)\n");
> +    H1("                                   or  b=<float> (bitrate
> multiplier)\n");
>      H1("   --qpfile <string>             Force frametypes and QPs for
> some or all frames\n");
>      H1("                                 Format of each line: framenumber
> frametype QP\n");
>      H1("                                 QP is optional (none lets x265
> choose). Frametypes: I,i,P,B,b.\n");
> diff --git a/source/x265.h b/source/x265.h
> --- a/source/x265.h
> +++ b/source/x265.h
> @@ -328,6 +328,16 @@
>  static const char * const x265_interlace_names[] = { "prog", "tff",
> "bff", 0 };
>  static const char * const x265_analysis_names[] = { "off", "save",
> "load", 0 };
>
>
> +/* Zones: override ratecontrol for specific sections of the video.
> + * If zones overlap, whichever comes later in the list takes precedence.
> */
> +typedef struct x265_zone
> +{
> +    int startFrame, endFrame;   /* range of frame numbers */
> +    int bForceQp;               /* whether to use qp vs bitrate factor */
> +    int qp;
> +    float bitrateFactor;
> +} x265_zone;
> +
>  /* x265 input parameters
>   *
>   * For version safety you may use x265_param_alloc/free() to manage the
> @@ -867,6 +877,10 @@
>
>
>          /* Enable slow and a more detailed first pass encode in multi
> pass rate control */
>          int       bEnableSlowFirstPass;
> +
> +        /* ratecontrol overrides */
> +        int        zoneCount;
> +        x265_zone* zones;
>
>
>          /* specify a text file which contains MAX_MAX_QP + 1 floating
> point
>           * values to be copied into x265_lambda_tab and a second set of
>
>
> _______________________________________________
> 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/20141223/257c0571/attachment-0001.html>


More information about the x265-devel mailing list