[x265] [PATCH] api: introduce performance presets

Steve Borho steve at borho.org
Thu Oct 31 00:36:05 CET 2013


# HG changeset patch
# User Steve Borho <steve at borho.org>
# Date 1383176153 18000
#      Wed Oct 30 18:35:53 2013 -0500
# Node ID 2e8e2f6d941bc4c1aa5fbf05da62c5620ae299bd
# Parent  7f68debc632bc8887aea8101859a734b0c52d2cf
api: introduce performance presets

diff -r 7f68debc632b -r 2e8e2f6d941b source/CMakeLists.txt
--- a/source/CMakeLists.txt	Wed Oct 30 20:23:37 2013 +0530
+++ b/source/CMakeLists.txt	Wed Oct 30 18:35:53 2013 -0500
@@ -12,7 +12,7 @@
 include(CheckFunctionExists)
 
 # X265_BUILD must be incremented each time the public API is changed
-set(X265_BUILD 2)
+set(X265_BUILD 3)
 configure_file("${PROJECT_SOURCE_DIR}/x265.def.in"
                "${PROJECT_BINARY_DIR}/x265.def")
 configure_file("${PROJECT_SOURCE_DIR}/x265_config.h.in"
diff -r 7f68debc632b -r 2e8e2f6d941b source/common/common.cpp
--- a/source/common/common.cpp	Wed Oct 30 20:23:37 2013 +0530
+++ b/source/common/common.cpp	Wed Oct 30 18:35:53 2013 -0500
@@ -238,6 +238,170 @@
     return 0;
 }
 
+extern "C"
+int x265_param_default_preset(x265_param *param, const char *preset, const char *tune)
+{
+    x265_param_default(param);
+
+    if (preset)
+    {
+        char *end;
+        int i = strtol(preset, &end, 10);
+        if (*end == 0 && i >= 0 && i < sizeof(x265_preset_names)/sizeof(*x265_preset_names)-1)
+            preset = x265_preset_names[i];
+
+        if (!strcmp(preset, "ultrafast"))
+        {
+            param->maxCUSize = 32;
+            param->bFrameAdaptive = 0;
+            param->bframes = 4;
+            param->tuQTMaxInterDepth = 1;
+            param->tuQTMaxIntraDepth = 1;
+            param->rdLevel = 0;
+            param->subpelRefine = 0;
+            param->maxNumMergeCand = 1;
+            param->searchMethod = 0;
+            param->bEnableAMP = 0;
+            param->bEnableRectInter = 0;
+            param->bEnableTransformSkip = 0;
+            param->bEnableEarlySkip = 1;
+            param->bEnableCbfFastMode = 1;
+            param->bEnableLoopFilter = 0;
+            param->bEnableSAO = 0;
+            param->bEnableSignHiding = 0;
+            param->bEnableWeightedPred = 0;
+        }
+        else if (!strcmp(preset, "superfast"))
+        {
+            param->maxCUSize = 32;
+            param->bFrameAdaptive = 0;
+            param->bframes = 4;
+            param->tuQTMaxInterDepth = 1;
+            param->tuQTMaxIntraDepth = 1;
+            param->rdLevel = 0;
+            param->subpelRefine = 1;
+            param->maxNumMergeCand = 1;
+            param->searchMethod = 1;
+            param->bEnableAMP = 0;
+            param->bEnableRectInter = 0;
+            param->bEnableTransformSkip = 0;
+            param->bEnableEarlySkip = 1;
+            param->bEnableCbfFastMode = 1;
+            param->bEnableSignHiding = 0;
+            param->bEnableWeightedPred = 0;
+        }
+        else if (!strcmp(preset, "veryfast"))
+        {
+            param->bFrameAdaptive = 0;
+            param->bframes = 4;
+            param->tuQTMaxInterDepth = 1;
+            param->tuQTMaxIntraDepth = 1;
+            param->rdLevel = 0;
+            param->subpelRefine = 1;
+            param->searchMethod = 1;
+            param->maxNumMergeCand = 2;
+            param->bEnableAMP = 0;
+            param->bEnableRectInter = 0;
+            param->bEnableTransformSkip = 0;
+            param->bEnableEarlySkip = 1;
+            param->bEnableCbfFastMode = 1;
+        }
+        else if (!strcmp(preset, "faster"))
+        {
+            param->bFrameAdaptive = 0;
+            param->bframes = 4;
+            param->tuQTMaxInterDepth = 1;
+            param->tuQTMaxIntraDepth = 1;
+            param->rdLevel = 0;
+            param->subpelRefine = 1;
+            param->searchMethod = 1;
+            param->maxNumMergeCand = 2;
+            param->bEnableAMP = 0;
+            param->bEnableRectInter = 0;
+            param->bEnableTransformSkip = 0;
+            param->bEnableEarlySkip = 1;
+        }
+        else if (!strcmp(preset, "fast"))
+        {
+            param->tuQTMaxInterDepth = 1;
+            param->tuQTMaxIntraDepth = 1;
+            param->rdLevel = 0;
+            param->subpelRefine = 1;
+            param->searchMethod = 1;
+            param->maxNumMergeCand = 2;
+            param->bEnableAMP = 0;
+            param->bEnableRectInter = 0;
+            param->bEnableTransformSkip = 0;
+        }
+        else if (!strcmp(preset, "medium"))
+        {
+            param->tuQTMaxInterDepth = 1;
+            param->tuQTMaxIntraDepth = 1;
+            param->rdLevel = 2;
+            param->maxNumMergeCand = 3;
+            param->bEnableAMP = 0;
+            param->bEnableRectInter = 0;
+            param->bEnableTransformSkip = 0;
+        }
+        else if (!strcmp(preset, "slow"))
+        {
+            param->bFrameAdaptive = 2;
+            param->bframes = 4;
+            param->tuQTMaxInterDepth = 1;
+            param->tuQTMaxIntraDepth = 1;
+            param->rdLevel = 2;
+            param->maxNumMergeCand = 3;
+            param->bEnableTransformSkip = 0;
+        }
+        else if (!strcmp(preset, "slower"))
+        {
+            param->bFrameAdaptive = 2;
+            param->lookaheadDepth = 20;
+            param->bframes = 5;
+            param->tuQTMaxInterDepth = 2;
+            param->tuQTMaxIntraDepth = 2;
+            param->rdLevel = 2;
+            param->maxNumMergeCand = 4;
+            param->bEnableTransformSkip = 0;
+            param->maxNumReferences = 3;
+        }
+        else if (!strcmp(preset, "veryslow"))
+        {
+            param->bFrameAdaptive = 2;
+            param->lookaheadDepth = 30;
+            param->bframes = 9;
+            param->maxNumMergeCand = 5;
+            param->maxNumReferences = 5;
+        }
+        else if (!strcmp(preset, "placebo"))
+        {
+            param->bFrameAdaptive = 2;
+            param->bframes = 16;
+            param->maxNumMergeCand = 5;
+            param->maxNumReferences = 16;
+            param->searchRange = 124;
+            param->lookaheadDepth = 60;
+        }
+        else
+            return -1;
+    }
+    if (tune)
+    {
+        if (!strcmp(tune, "psnr"))
+        {
+            // nop; currently the default
+        }
+        else if (!strcmp(tune, "ssim"))
+        {
+            // not yet supported
+        }
+        else
+            return -1;
+    }
+
+    return 0;
+}
+
 static inline int _confirm(x265_param *param, bool bflag, const char* message)
 {
     if (!bflag)
diff -r 7f68debc632b -r 2e8e2f6d941b source/x265.cpp
--- a/source/x265.cpp	Wed Oct 30 20:23:37 2013 +0530
+++ b/source/x265.cpp	Wed Oct 30 18:35:53 2013 -0500
@@ -59,7 +59,7 @@
 
 using namespace x265;
 
-static const char short_options[] = "o:f:F:r:i:b:s:q:m:hwV";
+static const char short_options[] = "o:p:f:F:r:i:b:s:t:q:m:hwV";
 static const struct option long_options[] =
 {
 #if HIGH_BIT_DEPTH
@@ -68,6 +68,8 @@
     { "help",                 no_argument, NULL, 'h' },
     { "cpuid",          required_argument, NULL, 0 },
     { "threads",        required_argument, NULL, 0 },
+    { "preset",         required_argument, NULL, 'p' },
+    { "tune",           required_argument, NULL, 't' },
     { "frame-threads",  required_argument, NULL, 'F' },
     { "log",            required_argument, NULL, 0 },
     { "csv",            required_argument, NULL, 0 },
@@ -248,6 +250,7 @@
     x265_param_default(param);
     printVersion(param);
     uint32_t inputBitDepth = 8, outputBitDepth = param->internalBitDepth;
+
 #define H0 printf
 #define OPT(value) (value ? "enabled" : "disabled")
     H0("\nSyntax: x265 [options] infile [-o] outfile\n");
@@ -258,6 +261,8 @@
     H0("-V/--version                     Show version info and exit\n");
     H0("   --cpuid                       Limit SIMD capability bitmap 0:auto 1:None. Default:0\n");
     H0("   --threads                     Number of threads for thread pool (0: detect CPU core count, default)\n");
+    H0("-p/--preset                      ultrafast, veryfast, faster, fast, medium, slow, slower, veryslow, or placebo\n");
+    H0("-t/--tune                        \n");
     H0("-F/--frame-threads               Number of concurrently encoded frames. Default %d\n", param->frameNumThreads);
     H0("   --log                         Logging level 0:ERROR 1:WARNING 2:INFO 3:DEBUG -1:NONE. Default %d\n", param->logLevel);
     H0("   --csv                         Comma separated log file, log level >= 3 frame log, else one line per run\n");
@@ -337,8 +342,25 @@
     const char *reconfn = NULL;
     const char *bitstreamfn = NULL;
     const char *inputRes = NULL;
+    const char *preset = "medium";
+    const char *tune = "psnr";
 
-    x265_param_default(param);
+    /* Presets are applied before all other options. */
+    for (optind = 0;; )
+    {
+        int c = getopt_long(argc, argv, short_options, long_options, NULL);
+        if (c == -1)
+            break;
+        if (c == 'p')
+            preset = optarg;
+        if (c == 't')
+            tune = optarg;
+        else if (c == '?')
+            return true;
+    }
+
+    if (x265_param_default_preset(param, preset, tune) < 0 )
+        return true;
 
     for (optind = 0;; )
     {
@@ -390,6 +412,7 @@
         if (0);
             OPT("cpuid") cpuid = atoi(optarg);
             OPT("frames") this->framesToBeEncoded = (uint32_t)atoi(optarg);
+            OPT("preset") preset = optarg;
             OPT("no-progress") this->bProgress = false;
             OPT("frame-skip") this->frameSkip = (uint32_t)atoi(optarg);
             OPT("output") bitstreamfn = optarg;
diff -r 7f68debc632b -r 2e8e2f6d941b source/x265.def.in
--- a/source/x265.def.in	Wed Oct 30 20:23:37 2013 +0530
+++ b/source/x265.def.in	Wed Oct 30 18:35:53 2013 -0500
@@ -2,6 +2,7 @@
 x265_encoder_open_${X265_BUILD}
 x265_setup_primitives
 x265_param_default
+x265_param_default_preset
 x265_param_parse
 x265_picture_init
 x265_param_apply_profile
diff -r 7f68debc632b -r 2e8e2f6d941b source/x265.h
--- a/source/x265.h	Wed Oct 30 20:23:37 2013 +0530
+++ b/source/x265.h	Wed Oct 30 18:35:53 2013 -0500
@@ -356,11 +356,6 @@
 #define X265_PARAM_BAD_VALUE (-2)
 int x265_param_parse(x265_param *p, const char *name, const char *value);
 
-/***
- * Initialize an x265_picture_t structure to default values
- */
-void x265_picture_init(x265_param *param, x265_picture *pic);
-
 /* x265_param_apply_profile:
  *      Applies the restrictions of the given profile. (one of below) */
 static const char * const x265_profile_names[] = { "main", "main10", "mainstillpicture", 0 };
@@ -369,6 +364,34 @@
  *      returns 0 on success, negative on failure (e.g. invalid profile name). */
 int x265_param_apply_profile(x265_param *, const char *profile);
 
+/* x265_param_default_preset:
+ *      The same as x265_param_default, but also use the passed preset and tune
+ *      to modify the default settings.
+ *      (either can be NULL, which implies no preset or no tune, respectively)
+ *
+ *      Currently available presets are, ordered from fastest to slowest: */
+static const char * const x265_preset_names[] = { "ultrafast", "superfast", "veryfast", "faster", "fast", "medium", "slow", "slower", "veryslow", "placebo", 0 };
+
+/*      The presets can also be indexed numerically, as in:
+ *      x265_param_default_preset( &param, "3", ... )
+ *      with ultrafast mapping to "0" and placebo mapping to "9".  This mapping may
+ *      of course change if new presets are added in between, but will always be
+ *      ordered from fastest to slowest.
+ *
+ *      Warning: the speed of these presets scales dramatically.  Ultrafast is a full
+ *      100 times faster than placebo!
+ *
+ *      Currently available tunings are: */
+static const char * const x265_tune_names[] = { "psnr", "ssim", 0 };
+
+/*      returns 0 on success, negative on failure (e.g. invalid preset/tune name). */
+int x265_param_default_preset(x265_param *, const char *preset, const char *tune);
+
+/***
+ * Initialize an x265_picture structure to default values
+ */
+void x265_picture_init(x265_param *param, x265_picture *pic);
+
 /* x265_max_bit_depth:
  *      Specifies the maximum number of bits per pixel that x265 can input. This
  *      is also the max bit depth that x265 encodes in.  When x265_max_bit_depth
-------------- next part --------------
A non-text attachment was scrubbed...
Name: x265.patch
Type: text/x-patch
Size: 12341 bytes
Desc: not available
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20131030/7c173e75/attachment-0001.bin>


More information about the x265-devel mailing list