[x265] [PATCH] Introduce CLI/param options to control min and max VBV fullness
Aruna Matheswaran
aruna at multicorewareinc.com
Tue Sep 1 17:10:37 CEST 2020
>From 672d4b53dd35ea4b847ae3177403f526f74cda4e Mon Sep 17 00:00:00 2001
From: Aruna <aruna at multicorewareinc.com>
Date: Tue, 1 Sep 2020 19:59:17 +0530
Subject: [PATCH] Introduce CLI/param options to control min and max VBV
fullness
---
doc/reST/cli.rst | 18 +++++++++++++++---
source/CMakeLists.txt | 2 +-
source/common/param.cpp | 14 ++++++++++++--
source/encoder/ratecontrol.cpp | 4 ++--
source/x265.h | 8 ++++++++
source/x265cli.h | 2 ++
6 files changed, 40 insertions(+), 8 deletions(-)
diff --git a/doc/reST/cli.rst b/doc/reST/cli.rst
index 02828e390..18ca17d35 100644
--- a/doc/reST/cli.rst
+++ b/doc/reST/cli.rst
@@ -1671,8 +1671,8 @@ Quality, rate control and rate distortion options
.. 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
+ Final buffer fullness. The portion of the decode buffer that must be
+ full 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)
@@ -1684,8 +1684,20 @@ Quality, rate control and rate distortion options
.. 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
+ fullness. Specified as a fraction of the total frames. Fractions > 0 are
supported only when the total number of frames is known. Default 0.
+
+.. option:: --min-vbv-fullness <double>
+
+ Minimum VBV fullness percentage to be maintained. Specified as a
fractional
+ value ranging between 0 and 100. Default 50 i.e, Tries to keep the
buffer at least
+ 50% full at any point in time.
+
+.. option:: --max-vbv-fullness <double>
+
+ Maximum VBV fullness percentage to be maintained. Specified as a
fractional
+ value ranging between 0 and 100. Default 80 i.e Tries to keep the
buffer at max 80%
+ full at any point in time.
.. option:: --qp, -q <integer>
diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt
index 1d1f8cacf..d9ed3983e 100644
--- a/source/CMakeLists.txt
+++ b/source/CMakeLists.txt
@@ -29,7 +29,7 @@ option(NATIVE_BUILD "Target the build CPU" OFF)
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 195)
+set(X265_BUILD 196)
configure_file("${PROJECT_SOURCE_DIR}/x265.def.in"
"${PROJECT_BINARY_DIR}/x265.def")
configure_file("${PROJECT_SOURCE_DIR}/x265_config.h.in"
diff --git a/source/common/param.cpp b/source/common/param.cpp
index 240568445..f356074a4 100644
--- a/source/common/param.cpp
+++ b/source/common/param.cpp
@@ -255,6 +255,8 @@ void x265_param_default(x265_param* param)
param->rc.vbvBufferInit = 0.9;
param->vbvBufferEnd = 0;
param->vbvEndFrameAdjust = 0;
+ param->minVbvFullness = 50;
+ param->maxVbvFullness = 80;
param->rc.rfConstant = 28;
param->rc.bitrate = 0;
param->rc.qCompress = 0.6;
@@ -1375,6 +1377,8 @@ int x265_param_parse(x265_param* p, const char* name,
const char* value)
sscanf(value, "%d,%d,%d", &p->hmeRange[0], &p->hmeRange[1],
&p->hmeRange[2]);
p->bEnableHME = true;
}
+ OPT("min-vbv-fullness") p->minVbvFullness = atof(value);
+ OPT("max-vbv-fullness") p->maxVbvFullness = atof(value);
else
return X265_PARAM_BAD_NAME;
}
@@ -1714,6 +1718,10 @@ int x265_check_params(x265_param* param)
"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->minVbvFullness < 0 && param->minVbvFullness > 100,
+ "min-vbv-fullness must be a fraction 0 - 100");
+ CHECK(param->maxVbvFullness < 0 && param->maxVbvFullness > 100,
+ "max-vbv-fullness must be a fraction 0 - 100");
CHECK(param->rc.bitrate < 0,
"Target bitrate can not be less than zero");
CHECK(param->rc.qCompress < 0.5 || param->rc.qCompress > 1.0,
@@ -2127,8 +2135,8 @@ char *x265_param2string(x265_param* p, int padx, int
pady)
BOOL(p->rc.bEnableSlowFirstPass, "slow-firstpass");
if (p->rc.vbvBufferSize)
{
- s += sprintf(s, " vbv-maxrate=%d vbv-bufsize=%d vbv-init=%.1f",
- p->rc.vbvMaxBitrate, p->rc.vbvBufferSize,
p->rc.vbvBufferInit);
+ s += sprintf(s, " vbv-maxrate=%d vbv-bufsize=%d vbv-init=%.1f
min-vbv-fullness=%.1f max-vbv-fullness=%.1f",
+ p->rc.vbvMaxBitrate, p->rc.vbvBufferSize,
p->rc.vbvBufferInit, p->minVbvFullness, p->maxVbvFullness);
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)
@@ -2436,6 +2444,8 @@ void x265_copy_params(x265_param* dst, x265_param*
src)
dst->rc.vbvMaxBitrate = src->rc.vbvMaxBitrate;
dst->rc.vbvBufferInit = src->rc.vbvBufferInit;
+ dst->minVbvFullness = src->minVbvFullness;
+ dst->maxVbvFullness = src->maxVbvFullness;
dst->rc.cuTree = src->rc.cuTree;
dst->rc.rfConstantMax = src->rc.rfConstantMax;
dst->rc.rfConstantMin = src->rc.rfConstantMin;
diff --git a/source/encoder/ratecontrol.cpp b/source/encoder/ratecontrol.cpp
index 82d7c4f2a..0e0845a85 100644
--- a/source/encoder/ratecontrol.cpp
+++ b/source/encoder/ratecontrol.cpp
@@ -2370,7 +2370,7 @@ double RateControl::clipQscale(Frame* curFrame,
RateControlEntry* rce, double q)
{
finalDur = x265_clip3(0.4, 1.0, totalDuration);
}
- targetFill = X265_MIN(m_bufferFill + totalDuration *
m_vbvMaxRate * 0.5, m_bufferSize * (1 - 0.5 * finalDur));
+ targetFill = X265_MIN(m_bufferFill + totalDuration *
m_vbvMaxRate * 0.5, m_bufferSize * ((m_param->minVbvFullness / 100) *
finalDur));
if (bufferFillCur < targetFill)
{
q *= 1.01;
@@ -2378,7 +2378,7 @@ double RateControl::clipQscale(Frame* curFrame,
RateControlEntry* rce, double q)
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);
+ targetFill = x265_clip3(m_bufferSize *
((m_param->maxVbvFullness / 100) * finalDur), m_bufferSize, m_bufferFill -
totalDuration * m_vbvMaxRate * 0.5);
if (m_isCbr && bufferFillCur > targetFill &&
!m_isSceneTransition)
{
q /= 1.01;
diff --git a/source/x265.h b/source/x265.h
index 0ffa600b0..46024db37 100644
--- a/source/x265.h
+++ b/source/x265.h
@@ -1920,6 +1920,14 @@ typedef struct x265_param
/* Maxrate that could be signaled to the decoder. Default 0. API only.
*/
int decoderVbvMaxRate;
+
+ /* Minimum VBV fullness to be maintained. Default 50. Keep the buffer
+ * at least 50% full */
+ double minVbvFullness;
+
+ /* Maximum VBV fullness to be maintained. Default 80. Keep the buffer
+ * at max 80% full */
+ double maxVbvFullness;
} x265_param;
/* x265_param_alloc:
diff --git a/source/x265cli.h b/source/x265cli.h
index 311f06935..b7bdd0c2d 100644
--- a/source/x265cli.h
+++ b/source/x265cli.h
@@ -374,6 +374,8 @@ static const struct option long_options[] =
{ "no-cll", no_argument, NULL, 0 },
{ "hme-range", required_argument, NULL, 0 },
{ "abr-ladder", required_argument, NULL, 0 },
+ { "min-vbv-fullness", required_argument, NULL, 0 },
+ { "max-vbv-fullness", required_argument, NULL, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
--
--
Regards,
*Aruna Matheswaran,*
Video Codec Engineer,
Media & AI analytics BU,
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20200901/03536aea/attachment-0001.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: x265_patch.diff
Type: application/octet-stream
Size: 8216 bytes
Desc: not available
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20200901/03536aea/attachment-0001.obj>
More information about the x265-devel
mailing list