changeset 12696:49a6e30c692e

Introduce CLI/param options to control min and max VBV fullness Signed-off-by: Aruna <aruna@multicorewareinc.com>
author Aruna <aruna@multicorewareinc.com>
date Mon, 14 Sep 2020 21:18:35 +0530
parents f34b58f2f3de
children 772b3229d157
files doc/reST/cli.rst source/CMakeLists.txt source/common/param.cpp source/encoder/ratecontrol.cpp source/x265.h source/x265cli.cpp source/x265cli.h
diffstat 7 files changed, 49 insertions(+-), 9 deletions(-) [+]
line wrap: on
line diff
--- a/doc/reST/cli.rst	Wed Sep 09 21:45:55 2020 +0530
+++ b/doc/reST/cli.rst	Mon Sep 14 21:18:35 2020 +0530
@@ -1671,8 +1671,8 @@ Quality, rate control and rate distortio
 
 .. 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,26 @@ Quality, rate control and rate distortio
 .. 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.
+	
+	Decreasing the minimum required fullness shall improve the compression efficiency,
+	but is expected to affect VBV conformance. Experimental option.
+
+.. 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.
+	
+    Increasing the minimum required fullness shall improve the compression efficiency,
+	but is expected to affect VBV conformance. Experimental option.
 
 .. option:: --qp, -q <integer>
 
--- a/source/CMakeLists.txt	Wed Sep 09 21:45:55 2020 +0530
+++ b/source/CMakeLists.txt	Mon Sep 14 21:18:35 2020 +0530
@@ -29,7 +29,7 @@ option(NATIVE_BUILD "Target the build CP
 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 197)
+set(X265_BUILD 198)
 configure_file("${PROJECT_SOURCE_DIR}/x265.def.in"
                "${PROJECT_BINARY_DIR}/x265.def")
 configure_file("${PROJECT_SOURCE_DIR}/x265_config.h.in"
--- a/source/common/param.cpp	Wed Sep 09 21:45:55 2020 +0530
+++ b/source/common/param.cpp	Mon Sep 14 21:18:35 2020 +0530
@@ -255,6 +255,8 @@ void x265_param_default(x265_param* para
     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;
@@ -1377,6 +1379,8 @@ int x265_param_parse(x265_param* p, cons
             p->bEnableHME = true;
         }
         OPT("vbv-live-multi-pass") p->bliveVBV2pass = atobool(value);
+        OPT("min-vbv-fullness") p->minVbvFullness = atof(value);
+        OPT("max-vbv-fullness") p->maxVbvFullness = atof(value);
         else
             return X265_PARAM_BAD_NAME;
     }
@@ -1716,6 +1720,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,
@@ -2142,8 +2150,8 @@ char *x265_param2string(x265_param* p, i
             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)
@@ -2452,6 +2460,8 @@ void x265_copy_params(x265_param* dst, x
     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;
--- a/source/encoder/ratecontrol.cpp	Wed Sep 09 21:45:55 2020 +0530
+++ b/source/encoder/ratecontrol.cpp	Mon Sep 14 21:18:35 2020 +0530
@@ -2380,7 +2380,7 @@ double RateControl::clipQscale(Frame* cu
                     {
                         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;
@@ -2388,7 +2388,8 @@ double RateControl::clipQscale(Frame* cu
                         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 || m_2pass) && bufferFillCur > targetFill && !m_isSceneTransition)
                     {
                         q /= 1.01;
@@ -2405,7 +2406,7 @@ double RateControl::clipQscale(Frame* cu
             /* Fallback to old purely-reactive algorithm: no lookahead. */
             if ((m_sliceType == P_SLICE || m_sliceType == B_SLICE ||
                     (m_sliceType == I_SLICE && m_lastNonBPictType == I_SLICE)) &&
-                m_bufferFill / m_bufferSize < 0.5)
+                m_bufferFill / m_bufferSize < (m_param->minVbvFullness / 100))
             {
                 q /= x265_clip3(0.5, 1.0, 2.0 * m_bufferFill / m_bufferSize);
             }
--- a/source/x265.h	Wed Sep 09 21:45:55 2020 +0530
+++ b/source/x265.h	Mon Sep 14 21:18:35 2020 +0530
@@ -1925,6 +1925,13 @@ typedef struct x265_param
     control 2 pass. Experimental.Default is disabled*/
     int      bliveVBV2pass;
 
+    /* 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:
--- a/source/x265cli.cpp	Wed Sep 09 21:45:55 2020 +0530
+++ b/source/x265cli.cpp	Mon Sep 14 21:18:35 2020 +0530
@@ -212,6 +212,8 @@ namespace X265_NS {
         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)\n");
+        H0("   --min-vbv-fullness <double>   Minimum VBV fullness percentage to be maintained. Default %.2f\n", param->minVbvFullness);
+        H0("   --max-vbv-fullness <double>   Maximum VBV fullness percentage to be maintained. Default %.2f\n", param->maxVbvFullness);
         H0("   --vbv-end-fr-adj <float>      Frame from which qp has to be adjusted to achieve final decode buffer emptiness. Default 0\n");
         H0("   --chunk-start <integer>       First frame of the chunk. Default 0 (disabled)\n");
         H0("   --chunk-end <integer>         Last frame of the chunk. Default 0 (disabled)\n");
--- a/source/x265cli.h	Wed Sep 09 21:45:55 2020 +0530
+++ b/source/x265cli.h	Mon Sep 14 21:18:35 2020 +0530
@@ -376,6 +376,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 },