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 <[email protected]> wrote: > # HG changeset patch > # User amarcu5 <[email protected]> > # 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 > [email protected] > https://mailman.videolan.org/listinfo/x265-devel > >
_______________________________________________ x265-devel mailing list [email protected] https://mailman.videolan.org/listinfo/x265-devel
