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