[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