[x265] [PATCH] Basic support for tweaking rate control using zones
Adam Marcus
adampetermarcus at gmail.com
Mon Dec 22 01:39:54 CET 2014
# 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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20141222/ee8bb982/attachment-0001.html>
More information about the x265-devel
mailing list