<div dir="ltr"><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Nov 6, 2017 at 11:42 AM, <span dir="ltr"><<a href="mailto:aruna@multicorewareinc.com" target="_blank">aruna@multicorewareinc.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"># HG changeset patch<br>
# User Aruna Matheswaran <<a href="mailto:aruna@multicorewareinc.com">aruna@multicorewareinc.com</a>><br>
# Date 1509948124 -19800<br>
# Mon Nov 06 11:32:04 2017 +0530<br>
# Node ID 8a121d8cc134cc348466e5d63a6a02<wbr>d1531d8055<br>
# Parent aa9649a2aa8c30bcb84ee8287839fa<wbr>877978d4a7<br>
Add vbv-end to denote VBV emptiness after inserting all the frames into it.<br></blockquote><div><br></div><div>Pushed to default branch. Thanks.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
diff -r aa9649a2aa8c -r 8a121d8cc134 doc/reST/cli.rst<br>
--- a/doc/reST/cli.rst Mon Nov 06 09:43:36 2017 +0530<br>
+++ b/doc/reST/cli.rst Mon Nov 06 11:32:04 2017 +0530<br>
@@ -1496,6 +1496,24 @@<br>
Default 0.9<br>
<br>
**Range of values:** fractional: 0 - 1.0, or kbits: 2 .. bufsize<br>
+<br>
+.. option:: --vbv-end <float><br>
+<br>
+ Final buffer emptiness. The portion of the decode buffer that must be<br>
+ available after all the specified frames have been inserted into the<br>
+ decode buffer. Specified as a fractional value between 0 and 1, or in<br>
+ kbits. Default 0 (disabled)<br>
+<br>
+ This enables basic support for chunk-parallel encoding where each segment<br>
+ can specify the starting and ending state of the VBV buffer so that VBV<br>
+ compliance can be maintained when chunks are independently encoded and<br>
+ stitched together.<br>
+<br>
+.. option:: --vbv-end-fr-adj <float><br>
+<br>
+ Frame from which qp has to be adjusted to achieve final decode buffer<br>
+ emptiness. Specified as a fraction of the total frames. Fractions > 0 are<br>
+ supported only when the total number of frames is known. Default 0.<br>
<br>
.. option:: --qp, -q <integer><br>
<br>
diff -r aa9649a2aa8c -r 8a121d8cc134 source/CMakeLists.txt<br>
--- a/source/CMakeLists.txt Mon Nov 06 09:43:36 2017 +0530<br>
+++ b/source/CMakeLists.txt Mon Nov 06 11:32:04 2017 +0530<br>
@@ -29,7 +29,7 @@<br>
option(STATIC_LINK_CRT "Statically link C runtime for release builds" OFF)<br>
mark_as_advanced(FPROFILE_USE FPROFILE_GENERATE NATIVE_BUILD)<br>
# X265_BUILD must be incremented each time the public API is changed<br>
-set(X265_BUILD 139)<br>
+set(X265_BUILD 140)<br>
configure_file("${PROJECT_<wbr>SOURCE_DIR}/<a href="http://x265.def.in" rel="noreferrer" target="_blank">x265.def.in</a>"<br>
"${PROJECT_BINARY_DIR}/x265.<wbr>def")<br>
configure_file("${PROJECT_<wbr>SOURCE_DIR}/<a href="http://x265_config.h.in" rel="noreferrer" target="_blank">x265_config.h.in</a>"<br>
diff -r aa9649a2aa8c -r 8a121d8cc134 source/common/param.cpp<br>
--- a/source/common/param.cpp Mon Nov 06 09:43:36 2017 +0530<br>
+++ b/source/common/param.cpp Mon Nov 06 11:32:04 2017 +0530<br>
@@ -212,6 +212,8 @@<br>
param->rc.vbvMaxBitrate = 0;<br>
param->rc.vbvBufferSize = 0;<br>
param->rc.vbvBufferInit = 0.9;<br>
+ param->vbvBufferEnd = 0;<br>
+ param->vbvEndFrameAdjust = 0;<br>
param->rc.rfConstant = 28;<br>
param->rc.bitrate = 0;<br>
param->rc.qCompress = 0.6;<br>
@@ -982,6 +984,8 @@<br>
OPT("force-flush")p-><wbr>forceFlush = atoi(value);<br>
OPT("splitrd-skip") p->bEnableSplitRdSkip = atobool(value);<br>
OPT("lowpass-dct") p->bLowPassDct = atobool(value);<br>
+ OPT("vbv-end") p->vbvBufferEnd = atof(value);<br>
+ OPT("vbv-end-fr-adj") p->vbvEndFrameAdjust = atof(value);<br>
else<br>
return X265_PARAM_BAD_NAME;<br>
}<br>
@@ -1300,6 +1304,12 @@<br>
"Maximum local bit rate can not be less than zero");<br>
CHECK(param->rc.vbvBufferInit < 0,<br>
"Valid initial VBV buffer occupancy must be a fraction 0 - 1, or size in kbits");<br>
+ CHECK(param->vbvBufferEnd < 0,<br>
+ "Valid final VBV buffer emptiness must be a fraction 0 - 1, or size in kbits");<br>
+ CHECK(param->vbvEndFrameAdjust < 0,<br>
+ "Valid vbv-end-fr-adj must be a fraction 0 - 1");<br>
+ CHECK(!param->totalFrames && param->vbvEndFrameAdjust,<br>
+ "vbv-end-fr-adj cannot be enabled when total number of frames is unknown");<br>
CHECK(param->rc.bitrate < 0,<br>
"Target bitrate can not be less than zero");<br>
CHECK(param->rc.qCompress < 0.5 || param->rc.qCompress > 1.0,<br>
@@ -1423,9 +1433,15 @@<br>
}<br>
<br>
if (param->rc.vbvBufferSize)<br>
- x265_log(param, X265_LOG_INFO, "VBV/HRD buffer / max-rate / init : %d / %d / %.3f\n",<br>
- param->rc.vbvBufferSize, param->rc.vbvMaxBitrate, param->rc.vbvBufferInit);<br>
-<br>
+ {<br>
+ if (param->vbvBufferEnd)<br>
+ x265_log(param, X265_LOG_INFO, "VBV/HRD buffer / max-rate / init / end / fr-adj: %d / %d / %.3f / %.3f / %.3f\n",<br>
+ param->rc.vbvBufferSize, param->rc.vbvMaxBitrate, param->rc.vbvBufferInit, param->vbvBufferEnd, param->vbvEndFrameAdjust);<br>
+ else<br>
+ x265_log(param, X265_LOG_INFO, "VBV/HRD buffer / max-rate / init : %d / %d / %.3f\n",<br>
+ param->rc.vbvBufferSize, param->rc.vbvMaxBitrate, param->rc.vbvBufferInit);<br>
+ }<br>
+<br>
char buf[80] = { 0 };<br>
char tmp[40];<br>
#define TOOLOPT(FLAG, STR) if (FLAG) appendtool(param, buf, sizeof(buf), STR);<br>
@@ -1602,8 +1618,10 @@<br>
{<br>
s += sprintf(s, " vbv-maxrate=%d vbv-bufsize=%d vbv-init=%.1f",<br>
p->rc.vbvMaxBitrate, p->rc.vbvBufferSize, p->rc.vbvBufferInit);<br>
+ if (p->vbvBufferEnd)<br>
+ s += sprintf(s, " vbv-end=%.1f vbv-end-fr-adj=%.1f", p->vbvBufferEnd, p->vbvEndFrameAdjust);<br>
if (p->rc.rateControlMode == X265_RC_CRF)<br>
- s += sprintf(s, " crf-max=%.1f crf-min=%.1f", p->rc.rfConstantMax, p->rc.rfConstantMin);<br>
+ s += sprintf(s, " crf-max=%.1f crf-min=%.1f", p->rc.rfConstantMax, p->rc.rfConstantMin);<br>
}<br>
}<br>
else if (p->rc.rateControlMode == X265_RC_CQP)<br>
diff -r aa9649a2aa8c -r 8a121d8cc134 source/encoder/ratecontrol.cpp<br>
--- a/source/encoder/ratecontrol.<wbr>cpp Mon Nov 06 09:43:36 2017 +0530<br>
+++ b/source/encoder/ratecontrol.<wbr>cpp Mon Nov 06 11:32:04 2017 +0530<br>
@@ -218,6 +218,7 @@<br>
m_param->rc.vbvBufferSize = x265_clip3(0, 2000000, m_param->rc.vbvBufferSize);<br>
m_param->rc.vbvMaxBitrate = x265_clip3(0, 2000000, m_param->rc.vbvMaxBitrate);<br>
m_param->rc.vbvBufferInit = x265_clip3(0.0, 2000000.0, m_param->rc.vbvBufferInit);<br>
+ m_param->vbvBufferEnd = x265_clip3(0.0, 2000000.0, m_param->vbvBufferEnd);<br>
m_singleFrameVbv = 0;<br>
m_rateTolerance = 1.0;<br>
<br>
@@ -255,6 +256,11 @@<br>
m_param->rc.vbvMaxBitrate = 0;<br>
}<br>
m_isVbv = m_param->rc.vbvMaxBitrate > 0 && m_param->rc.vbvBufferSize > 0;<br>
+ if (m_param->vbvBufferEnd && !m_isVbv)<br>
+ {<br>
+ x265_log(m_param, X265_LOG_WARNING, "vbv-end requires VBV parameters, ignored\n");<br>
+ m_param->vbvBufferEnd = 0;<br>
+ }<br>
if (m_param->bEmitHRDSEI && !m_isVbv)<br>
{<br>
x265_log(m_param, X265_LOG_WARNING, "NAL HRD parameters require VBV parameters, ignored\n");<br>
@@ -339,6 +345,10 @@<br>
<br>
if (m_param->rc.vbvBufferInit > 1.)<br>
m_param->rc.vbvBufferInit = x265_clip3(0.0, 1.0, m_param->rc.vbvBufferInit / m_param->rc.vbvBufferSize);<br>
+ if (m_param->vbvBufferEnd > 1.)<br>
+ m_param->vbvBufferEnd = x265_clip3(0.0, 1.0, m_param->vbvBufferEnd / m_param->rc.vbvBufferSize);<br>
+ if (m_param->vbvEndFrameAdjust > 1.)<br>
+ m_param->vbvEndFrameAdjust = x265_clip3(0.0, 1.0, m_param->vbvEndFrameAdjust);<br>
m_param->rc.vbvBufferInit = x265_clip3(0.0, 1.0, X265_MAX(m_param->rc.<wbr>vbvBufferInit, m_bufferRate / m_bufferSize));<br>
m_bufferFillFinal = m_bufferSize * m_param->rc.vbvBufferInit;<br>
m_bufferFillActual = m_bufferFillFinal;<br>
@@ -2160,29 +2170,51 @@<br>
curBits = predictSize(&m_pred[predType], frameQ[type], (double)satd);<br>
bufferFillCur -= curBits;<br>
}<br>
-<br>
- /* Try to get the buffer at least 50% filled, but don't set an impossible goal. */<br>
- double finalDur = 1;<br>
- if (m_param->rc.bStrictCbr)<br>
+ if (m_param->vbvBufferEnd && rce->encodeOrder >= m_param->vbvEndFrameAdjust * m_param->totalFrames)<br>
{<br>
- finalDur = x265_clip3(0.4, 1.0, totalDuration);<br>
+ bool loopBreak = false;<br>
+ double bufferDiff = m_param->vbvBufferEnd - (m_bufferFill / m_bufferSize);<br>
+ targetFill = m_bufferFill + m_bufferSize * (bufferDiff / (m_param->totalFrames - rce->encodeOrder));<br>
+ if (bufferFillCur < targetFill)<br>
+ {<br>
+ q *= 1.01;<br>
+ loopTerminate |= 1;<br>
+ loopBreak = true;<br>
+ }<br>
+ if (bufferFillCur > m_param->vbvBufferEnd * m_bufferSize)<br>
+ {<br>
+ q /= 1.01;<br>
+ loopTerminate |= 2;<br>
+ loopBreak = true;<br>
+ }<br>
+ if (!loopBreak)<br>
+ break;<br>
}<br>
- targetFill = X265_MIN(m_bufferFill + totalDuration * m_vbvMaxRate * 0.5 , m_bufferSize * (1 - 0.5 * finalDur));<br>
- if (bufferFillCur < targetFill)<br>
+ else<br>
{<br>
- q *= 1.01;<br>
- loopTerminate |= 1;<br>
- continue;<br>
+ /* Try to get the buffer at least 50% filled, but don't set an impossible goal. */<br>
+ double finalDur = 1;<br>
+ if (m_param->rc.bStrictCbr)<br>
+ {<br>
+ finalDur = x265_clip3(0.4, 1.0, totalDuration);<br>
+ }<br>
+ targetFill = X265_MIN(m_bufferFill + totalDuration * m_vbvMaxRate * 0.5, m_bufferSize * (1 - 0.5 * finalDur));<br>
+ if (bufferFillCur < targetFill)<br>
+ {<br>
+ q *= 1.01;<br>
+ loopTerminate |= 1;<br>
+ continue;<br>
+ }<br>
+ /* Try to get the buffer not more than 80% filled, but don't set an impossible goal. */<br>
+ targetFill = x265_clip3(m_bufferSize * (1 - 0.2 * finalDur), m_bufferSize, m_bufferFill - totalDuration * m_vbvMaxRate * 0.5);<br>
+ if (m_isCbr && bufferFillCur > targetFill && !m_isSceneTransition)<br>
+ {<br>
+ q /= 1.01;<br>
+ loopTerminate |= 2;<br>
+ continue;<br>
+ }<br>
+ break;<br>
}<br>
- /* Try to get the buffer not more than 80% filled, but don't set an impossible goal. */<br>
- targetFill = x265_clip3(m_bufferSize * (1 - 0.2 * finalDur), m_bufferSize, m_bufferFill - totalDuration * m_vbvMaxRate * 0.5);<br>
- if (m_isCbr && bufferFillCur > targetFill && !m_isSceneTransition)<br>
- {<br>
- q /= 1.01;<br>
- loopTerminate |= 2;<br>
- continue;<br>
- }<br>
- break;<br>
}<br>
q = X265_MAX(q0 / 2, q);<br>
}<br>
diff -r aa9649a2aa8c -r 8a121d8cc134 source/test/rate-control-<wbr>tests.txt<br>
--- a/source/test/rate-control-<wbr>tests.txt Mon Nov 06 09:43:36 2017 +0530<br>
+++ b/source/test/rate-control-<wbr>tests.txt Mon Nov 06 11:32:04 2017 +0530<br>
@@ -25,7 +25,7 @@<br>
big_buck_bunny_360p24.y4m,--<wbr>preset medium --bitrate 400 --vbv-bufsize 600 --vbv-maxrate 600 --no-wpp --aud --hrd --tune fast-decode<br>
sita_1920x1080_30.yuv,--preset superfast --bitrate 3000 --vbv-bufsize 3000 --vbv-maxrate 3000 --aud --strict-cbr --no-wpp<br>
sintel_trailer_2k_480p24.y4m, --preset slow --crf 24 --vbv-bufsize 150 --vbv-maxrate 150 --dynamic-rd 1.53<br>
-<br>
+BasketballDrive_1920x1080_50.<wbr>y4m,--preset medium --bitrate 10000 --vbv-bufsize 15000 --vbv-maxrate 11500 --vbv-end 0.9 --vbv-end-fr-adj 0.7<br>
<br>
<br>
# multi-pass rate control tests<br>
diff -r aa9649a2aa8c -r 8a121d8cc134 source/x265.h<br>
--- a/source/x265.h Mon Nov 06 09:43:36 2017 +0530<br>
+++ b/source/x265.h Mon Nov 06 11:32:04 2017 +0530<br>
@@ -1514,6 +1514,16 @@<br>
* This DCT approximation is less computational intensive and gives results close to<br>
* standard DCT for QP >= 23 */<br>
int bLowPassDct;<br>
+<br>
+ /* Sets the portion of the decode buffer that must be available after all the<br>
+ * specified frames have been inserted into the decode buffer. If it is less<br>
+ * than 1, then the final buffer available is vbv-end * vbvBufferSize. Otherwise,<br>
+ * it is interpreted as the final buffer available in kbits. Default 0 (disabled) */<br>
+ double vbvBufferEnd;<br>
+<br>
+ /* Frame from which qp has to be adjusted to hit final decode buffer emptiness.<br>
+ * Specified as a fraction of the total frames. Default 0 */<br>
+ double vbvEndFrameAdjust;<br>
} x265_param;<br>
<br>
/* x265_param_alloc:<br>
diff -r aa9649a2aa8c -r 8a121d8cc134 source/x265cli.h<br>
--- a/source/x265cli.h Mon Nov 06 09:43:36 2017 +0530<br>
+++ b/source/x265cli.h Mon Nov 06 11:32:04 2017 +0530<br>
@@ -147,6 +147,8 @@<br>
{ "vbv-maxrate", required_argument, NULL, 0 },<br>
{ "vbv-bufsize", required_argument, NULL, 0 },<br>
{ "vbv-init", required_argument, NULL, 0 },<br>
+ { "vbv-end", required_argument, NULL, 0 },<br>
+ { "vbv-end-fr-adj", required_argument, NULL, 0 },<br>
{ "bitrate", required_argument, NULL, 0 },<br>
{ "qp", required_argument, NULL, 'q' },<br>
{ "aq-mode", required_argument, NULL, 0 },<br>
@@ -443,6 +445,8 @@<br>
H0(" --vbv-maxrate <integer> Max local bitrate (kbit/s). Default %d\n", param->rc.vbvMaxBitrate);<br>
H0(" --vbv-bufsize <integer> Set size of the VBV buffer (kbit). Default %d\n", param->rc.vbvBufferSize);<br>
H0(" --vbv-init <float> Initial VBV buffer occupancy (fraction of bufsize or in kbits). Default %.2f\n", param->rc.vbvBufferInit);<br>
+ H0(" --vbv-end <float> Final VBV buffer emptiness (fraction of bufsize or in kbits). Default 0 (disabled)");<br>
+ H0(" --vbv-end-fr-adj <float> Frame from which qp has to be adjusted to achieve final decode buffer emptiness. Default 0");<br>
H0(" --pass Multi pass rate control.\n"<br>
" - 1 : First pass, creates stats file\n"<br>
" - 2 : Last pass, does not overwrite stats file\n"<br>
<br>______________________________<wbr>_________________<br>
x265-devel mailing list<br>
<a href="mailto:x265-devel@videolan.org">x265-devel@videolan.org</a><br>
<a href="https://mailman.videolan.org/listinfo/x265-devel" rel="noreferrer" target="_blank">https://mailman.videolan.org/<wbr>listinfo/x265-devel</a><br>
<br></blockquote></div><br></div></div>