[x265] [PATCH] cli: Enable/Disable param tuning during violation of level constraints

Aruna Matheswaran aruna at multicorewareinc.com
Fri Feb 7 18:07:16 CET 2020


# HG changeset patch
# User Aruna Matheswaran <aruna at multicorewareinc.com>
# Date 1581085293 -19800
#      Fri Feb 07 19:51:33 2020 +0530
# Branch Release_3.3
# Node ID 303f0c4847832c6aad959d5e7c66db539375009f
# Parent  3d2d020d2027910c080ed6d22332bcd46b39d89e
cli: Enable/Disable param tuning during violation of level constraints.

diff -r 3d2d020d2027 -r 303f0c484783 doc/reST/cli.rst
--- a/doc/reST/cli.rst	Thu Feb 06 09:44:50 2020 +0530
+++ b/doc/reST/cli.rst	Fri Feb 07 19:51:33 2020 +0530
@@ -629,6 +629,14 @@
 	and level **5.0** is specified as "5.0" or "50".
 
 	Annex A levels: 1, 2, 2.1, 3, 3.1, 4, 4.1, 5, 5.1, 5.2, 6, 6.1, 6.2, 8.5
+	
+.. option:: --force-level, --no-force-level
+
+	Instruct the encoder to not adjust the codec configurations to meet the
+	level constraints. If enabled, the library will error out in the event of
+	violation of level constraints.
+
+	Default disabled.
 
 .. option:: --high-tier, --no-high-tier
 
diff -r 3d2d020d2027 -r 303f0c484783 source/CMakeLists.txt
--- a/source/CMakeLists.txt	Thu Feb 06 09:44:50 2020 +0530
+++ b/source/CMakeLists.txt	Fri Feb 07 19:51:33 2020 +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 188)
+set(X265_BUILD 189)
 configure_file("${PROJECT_SOURCE_DIR}/x265.def.in"
                "${PROJECT_BINARY_DIR}/x265.def")
 configure_file("${PROJECT_SOURCE_DIR}/x265_config.h.in"
diff -r 3d2d020d2027 -r 303f0c484783 source/common/param.cpp
--- a/source/common/param.cpp	Thu Feb 06 09:44:50 2020 +0530
+++ b/source/common/param.cpp	Fri Feb 07 19:51:33 2020 +0530
@@ -138,6 +138,7 @@
     param->sourceBitDepth = 8;
     param->internalCsp = X265_CSP_I420;
     param->levelIdc = 0; //Auto-detect level
+    param->bForceLevel = 0;
     param->uhdBluray = 0;
     param->bHighTier = 1; //Allow high tier by default
     param->interlaceMode = 0;
@@ -1369,6 +1370,7 @@
             sscanf(value, "%d,%d,%d", &p->hmeRange[0], &p->hmeRange[1], &p->hmeRange[2]);
             p->bEnableHME = true;
         }
+        OPT("force-level") p->bForceLevel = atobool(value);
         else
             return X265_PARAM_BAD_NAME;
     }
@@ -1996,6 +1998,7 @@
     if (p->chunkEnd)
         s += sprintf(s, " chunk-end=%d", p->chunkEnd);
     s += sprintf(s, " level-idc=%d", p->levelIdc);
+    BOOL(p->bForceLevel, " force-level");
     s += sprintf(s, " high-tier=%d", p->bHighTier);
     s += sprintf(s, " uhd-bd=%d", p->uhdBluray);
     s += sprintf(s, " ref=%d", p->maxNumReferences);
@@ -2305,6 +2308,7 @@
     dst->interlaceMode = src->interlaceMode;
     dst->totalFrames = src->totalFrames;
     dst->levelIdc = src->levelIdc;
+    dst->bForceLevel = src->bForceLevel;
     dst->bHighTier = src->bHighTier;
     dst->uhdBluray = src->uhdBluray;
     dst->maxNumReferences = src->maxNumReferences;
diff -r 3d2d020d2027 -r 303f0c484783 source/encoder/level.cpp
--- a/source/encoder/level.cpp	Thu Feb 06 09:44:50 2020 +0530
+++ b/source/encoder/level.cpp	Fri Feb 07 19:51:33 2020 +0530
@@ -283,8 +283,8 @@
 
 /* enforce a maximum decoder level requirement, in other words assure that a
  * decoder of the specified level may decode the video about to be created.
- * Lower parameters where necessary to ensure the video will be decodable by a
- * decoder meeting this level of requirement.  Some parameters (resolution and
+ * If force-level is OFF, lower parameters where necessary to ensure the video will be
+ * decodable by a decoder meeting this level of requirement.  Some parameters (resolution and
  * frame rate) are non-negotiable and thus this function may fail. In those
  * circumstances it will be quite noisy */
 bool enforceLevel(x265_param& param, VPS& vps)
@@ -334,24 +334,55 @@
      * within the max limits of that level (high tier if allowed, main otherwise)
      */
 
-    if ((uint32_t)param.rc.vbvMaxBitrate > (allowHighTier ? l.maxBitrateHigh : l.maxBitrateMain))
+    uint32_t maxBRLimit = allowHighTier ? l.maxBitrateHigh : l.maxBitrateMain;
+    uint32_t maxCPBSize = allowHighTier ? l.maxCpbSizeHigh : l.maxCpbSizeMain;
+
+    if ((uint32_t)param.rc.vbvMaxBitrate > maxBRLimit)
     {
-        param.rc.vbvMaxBitrate = allowHighTier ? l.maxBitrateHigh : l.maxBitrateMain;
-        x265_log(&param, X265_LOG_WARNING, "lowering VBV max bitrate to %dKbps\n", param.rc.vbvMaxBitrate);
+        if (!param.bForceLevel)
+        {
+            param.rc.vbvMaxBitrate = allowHighTier ? l.maxBitrateHigh : l.maxBitrateMain;
+            x265_log(&param, X265_LOG_WARNING, "lowering VBV max bitrate to %dKbps\n", param.rc.vbvMaxBitrate);
+        }
+        else
+        {
+            x265_log(&param, X265_LOG_ERROR, "Specified vbv-maxrate (%d) exceeds the limit (%u) allowed in level %d\n",
+                                              param.rc.vbvMaxBitrate, maxBRLimit, param.levelIdc);
+            return false;
+        }
     }
-    if ((uint32_t)param.rc.vbvBufferSize > (allowHighTier ? l.maxCpbSizeHigh : l.maxCpbSizeMain))
+
+    if ((uint32_t)param.rc.vbvBufferSize > maxCPBSize)
     {
-        param.rc.vbvBufferSize = allowHighTier ? l.maxCpbSizeHigh : l.maxCpbSizeMain;
-        x265_log(&param, X265_LOG_WARNING, "lowering VBV buffer size to %dKb\n", param.rc.vbvBufferSize);
+        if (!param.bForceLevel)
+        {
+            param.rc.vbvBufferSize = allowHighTier ? l.maxCpbSizeHigh : l.maxCpbSizeMain;
+            x265_log(&param, X265_LOG_WARNING, "lowering VBV buffer size to %dKb\n", param.rc.vbvBufferSize);
+        }
+        else
+        {
+            x265_log(&param, X265_LOG_ERROR, "Specified vbv-bufsize (%d) exceeds the limit (%u) allowed in level %d\n",
+                                              param.rc.vbvBufferSize, maxCPBSize, param.levelIdc);
+            return false;
+        }
     }
 
     switch (param.rc.rateControlMode)
     {
     case X265_RC_ABR:
-        if ((uint32_t)param.rc.bitrate > (allowHighTier ? l.maxBitrateHigh : l.maxBitrateMain))
+        if ((uint32_t)param.rc.bitrate > maxBRLimit)
         {
-            param.rc.bitrate =  allowHighTier ? l.maxBitrateHigh : l.maxBitrateMain;
-            x265_log(&param, X265_LOG_WARNING, "lowering target bitrate to High tier limit of %dKbps\n", param.rc.bitrate);
+            if (!param.bForceLevel)
+            {
+                param.rc.bitrate = maxBRLimit;
+                x265_log(&param, X265_LOG_WARNING, "lowering target bitrate to High tier limit of %dKbps\n", param.rc.bitrate);
+            }
+            else
+            {
+                x265_log(&param, X265_LOG_ERROR, "Specified bitrate (%d) exceeds the max-rate limit (%u) allowed in level %d\n",
+                                                  param.rc.bitrate, maxBRLimit, param.levelIdc);
+                return false;
+            }
         }
         break;
 
@@ -360,16 +391,21 @@
         return false;
 
     case X265_RC_CRF:
-        if (!param.rc.vbvBufferSize || !param.rc.vbvMaxBitrate)
+        if ((!param.rc.vbvBufferSize || !param.rc.vbvMaxBitrate) && !param.bForceLevel)
         {
             if (!param.rc.vbvMaxBitrate)
-                param.rc.vbvMaxBitrate = allowHighTier ? l.maxBitrateHigh : l.maxBitrateMain;
+                param.rc.vbvMaxBitrate = maxBRLimit;
             if (!param.rc.vbvBufferSize)
-                param.rc.vbvBufferSize = allowHighTier ? l.maxCpbSizeHigh : l.maxCpbSizeMain;
+                param.rc.vbvBufferSize = maxCPBSize;
             x265_log(&param, X265_LOG_WARNING, "Specifying a decoder level with constant rate factor rate-control requires\n");
             x265_log(&param, X265_LOG_WARNING, "enabling VBV with vbv-bufsize=%dkb vbv-maxrate=%dkbps. VBV outputs are non-deterministic!\n",
                      param.rc.vbvBufferSize, param.rc.vbvMaxBitrate);
         }
+        else
+        {
+            x265_log(&param, X265_LOG_ERROR, "Specifying a decoder level with constant rate factor rate-control requires enabling VBV constraints\n");
+            return false;
+        }
         break;
 
     default:
@@ -391,6 +427,14 @@
     }
 
     int savedRefCount = param.maxNumReferences;
+
+    if (param.bForceLevel && vps.maxDecPicBuffering > maxDpbSize)
+    {
+        x265_log(&param, X265_LOG_ERROR, "Specified max references (%d) exceeds the limit (%u) allowed in level %d.\n",
+                 vps.maxDecPicBuffering, maxDpbSize, param.levelIdc);
+        return false;
+    }
+
     while (vps.maxDecPicBuffering > maxDpbSize && param.maxNumReferences > 1)
     {
         param.maxNumReferences--;
@@ -402,16 +446,34 @@
     /* For level 5 and higher levels, the value of CtbSizeY shall be equal to 32 or 64 */
     if (param.levelIdc >= 50 && param.maxCUSize < 32)
     {
-        param.maxCUSize = 32;
-        x265_log(&param, X265_LOG_WARNING, "Levels 5.0 and above require a maximum CTU size of at least 32, using --ctu 32\n");
+        if (!param.bForceLevel)
+        {
+            param.maxCUSize = 32;
+            x265_log(&param, X265_LOG_WARNING, "Levels 5.0 and above require a maximum CTU size of at least 32, using --ctu 32\n");
+        }
+        else
+        {
+            x265_log(&param, X265_LOG_ERROR, "Specified maxCUSize (%d) doesn't meet the minimum maxCUSize (32) requirement specified in Level %d\n",
+                param.maxCUSize, param.levelIdc);
+            return false;
+        }
     }
 
     /* The value of NumPocTotalCurr shall be less than or equal to 8 */
     int numPocTotalCurr = param.maxNumReferences + !!param.bframes;
     if (numPocTotalCurr > 8)
     {
-        param.maxNumReferences = 8 - !!param.bframes;
-        x265_log(&param, X265_LOG_WARNING, "Lowering max references to %d to meet numPocTotalCurr requirement\n", param.maxNumReferences);
+        if (!param.bForceLevel)
+        {
+            param.maxNumReferences = 8 - !!param.bframes;
+            x265_log(&param, X265_LOG_WARNING, "Lowering max references to %d to meet numPocTotalCurr requirement\n", param.maxNumReferences);
+        }
+        else
+        {
+            x265_log(&param, X265_LOG_ERROR, "Specified numPocTotalCurr (%d) exceeds the limit (8) allowed in level %d\n",
+                numPocTotalCurr, param.levelIdc);
+            return false;
+        }
     }
 
     return true;
diff -r 3d2d020d2027 -r 303f0c484783 source/x265.h
--- a/source/x265.h	Thu Feb 06 09:44:50 2020 +0530
+++ b/source/x265.h	Fri Feb 07 19:51:33 2020 +0530
@@ -1901,6 +1901,11 @@
     * info is available from the corresponding analysis-save. */
 
     int      confWinBottomOffset;
+
+    /* Instruct the encoder to not adjust the codec configurations to meet the 
+     * level constraints. If enabled, the library will error out in the event of
+     * violation of level constraints. Default disabled.*/
+    int      bForceLevel;
 } x265_param;
 
 /* x265_param_alloc:
diff -r 3d2d020d2027 -r 303f0c484783 source/x265cli.h
--- a/source/x265cli.h	Thu Feb 06 09:44:50 2020 +0530
+++ b/source/x265cli.h	Fri Feb 07 19:51:33 2020 +0530
@@ -358,6 +358,8 @@
     { "cll", no_argument, NULL, 0 },
     { "no-cll", no_argument, NULL, 0 },
     { "hme-range", required_argument, NULL, 0 },
+    { "force-level", no_argument, NULL, 0 },
+    { "no-force-level", no_argument, NULL, 0 },
     { 0, 0, 0, 0 },
     { 0, 0, 0, 0 },
     { 0, 0, 0, 0 },
@@ -424,6 +426,7 @@
     H0("\nProfile, Level, Tier:\n");
     H0("-P/--profile <string>            Enforce an encode profile: main, main10, mainstillpicture\n");
     H0("   --level-idc <integer|float>   Force a minimum required decoder level (as '5.0' or '50')\n");
+    H0("   --[no-]force-level            Instruct the encoder to not adjust the codec configurations to meet the level constraints. Default disabled.\n");
     H0("   --[no-]high-tier              If a decoder level is specified, this modifier selects High tier of that level\n");
     H0("   --uhd-bd                      Enable UHD Bluray compatibility support\n");
     H0("   --[no-]allow-non-conformance  Allow the encoder to generate profile NONE bitstreams. Default %s\n", OPT(param->bAllowNonConformance));
-------------- next part --------------
A non-text attachment was scrubbed...
Name: x265_push.patch
Type: text/x-patch
Size: 12226 bytes
Desc: not available
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20200207/6063ebdc/attachment-0001.bin>


More information about the x265-devel mailing list