changeset 12590:a4e060a44839

Add option hme-range to modify search range for HME levels L0, L1 and L2.
author Pooja Venkatesan <pooja@multicorewareinc.com>
date Wed, 11 Sep 2019 15:38:06 +0530
parents f8a38d6ef1eb
children a26521d20827
files doc/reST/cli.rst source/CMakeLists.txt source/common/param.cpp source/encoder/encoder.cpp source/encoder/slicetype.cpp source/x265.h source/x265cli.h
diffstat 7 files changed, 39 insertions(+-), 6 deletions(-) [+]
line wrap: on
line diff
--- a/doc/reST/cli.rst	Thu Nov 28 18:37:53 2019 +0530
+++ b/doc/reST/cli.rst	Wed Sep 11 15:38:06 2019 +0530
@@ -1290,6 +1290,12 @@ Temporal / motion search options
        which will apply to all levels. Default is hex,umh,umh for 
        levels 0,1,2 respectively.
 
+.. option:: --hme-range <integer>,<integer>,<integer>
+
+	Search range for HME level 0, 1 and 2.
+	The Search Range for each HME level must be between 0 and 32768(excluding).
+	Default search range is 16,32,48 for level 0,1,2 respectively.
+
 Spatial/intra options
 =====================
 
--- a/source/CMakeLists.txt	Thu Nov 28 18:37:53 2019 +0530
+++ b/source/CMakeLists.txt	Wed Sep 11 15:38:06 2019 +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 183)
+set(X265_BUILD 184)
 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	Thu Nov 28 18:37:53 2019 +0530
+++ b/source/common/param.cpp	Wed Sep 11 15:38:06 2019 +0530
@@ -210,6 +210,9 @@ void x265_param_default(x265_param* para
     param->bEnableHME = 0;
     param->hmeSearchMethod[0] = X265_HEX_SEARCH;
     param->hmeSearchMethod[1] = param->hmeSearchMethod[2] = X265_UMH_SEARCH;
+    param->hmeRange[0] = 16;
+    param->hmeRange[1] = 32;
+    param->hmeRange[2] = 48;
     param->bSourceReferenceEstimation = 0;
     param->limitTU = 0;
     param->dynamicRd = 0;
@@ -1344,6 +1347,11 @@ int x265_param_parse(x265_param* p, cons
             }
             p->bEnableHME = true;
         }
+        OPT("hme-range")
+        {
+            sscanf(value, "%d,%d,%d", &p->hmeRange[0], &p->hmeRange[1], &p->hmeRange[2]);
+            p->bEnableHME = true;
+        }
         else
             return X265_PARAM_BAD_NAME;
     }
@@ -1734,6 +1742,9 @@ int x265_check_params(x265_param* param)
         "Invalid scenecut Window duration. Value must be between 0 and 1000(inclusive)");
     CHECK(param->maxQpDelta < 0 || param->maxQpDelta > 10,
         "Invalid maxQpDelta value. Value must be between 0 and 10 (inclusive)");
+    for(int level = 0; level < 3; level++)
+        CHECK(param->hmeRange[level] < 0 || param->hmeRange[level] >= 32768,
+            "Search Range for HME levels must be between 0 and 32768");
 #if !X86_64
     CHECK(param->searchMethod == X265_SEA && (param->sourceWidth > 840 || param->sourceHeight > 480),
         "SEA motion search does not support resolutions greater than 480p in 32 bit build");
@@ -2019,7 +2030,10 @@ char *x265_param2string(x265_param* p, i
         s += sprintf(s, " dup-threshold=%d", p->dupThreshold);
     BOOL(p->bEnableHME, "hme");
     if (p->bEnableHME)
+    {
         s += sprintf(s, " Level 0,1,2=%d,%d,%d", p->hmeSearchMethod[0], p->hmeSearchMethod[1], p->hmeSearchMethod[2]);
+        s += sprintf(s, " merange L0,L1,L2=%d,%d,%d", p->hmeRange[0], p->hmeRange[1], p->hmeRange[2]);
+    }
     BOOL(p->bEnableWeightedPred, "weightp");
     BOOL(p->bEnableWeightedBiPred, "weightb");
     BOOL(p->bSourceReferenceEstimation, "analyze-src-pics");
@@ -2320,7 +2334,10 @@ void x265_copy_params(x265_param* dst, x
     if (src->bEnableHME)
     {
         for (int level = 0; level < 3; level++)
+        {
             dst->hmeSearchMethod[level] = src->hmeSearchMethod[level];
+            dst->hmeRange[level] = src->hmeRange[level];
+        }
     }
     dst->bEnableWeightedBiPred = src->bEnableWeightedBiPred;
     dst->bEnableWeightedPred = src->bEnableWeightedPred;
--- a/source/encoder/encoder.cpp	Thu Nov 28 18:37:53 2019 +0530
+++ b/source/encoder/encoder.cpp	Wed Sep 11 15:38:06 2019 +0530
@@ -4079,10 +4079,14 @@ void Encoder::configure(x265_param *p)
             x265_log(p, X265_LOG_WARNING, "Source height < 540p is too low for HME. Disabling HME.\n");
             p->bEnableHME = 0;
         }
-        if (m_param->bEnableHME && m_param->searchMethod != m_param->hmeSearchMethod[2])
-        {
+    }
+
+    if (m_param->bEnableHME)
+    {
+        if (m_param->searchMethod != m_param->hmeSearchMethod[2])
             m_param->searchMethod = m_param->hmeSearchMethod[2];
-        }
+        if (m_param->searchRange != m_param->hmeRange[2])
+            m_param->searchRange = m_param->hmeRange[2];
     }
 
    if (p->bHistBasedSceneCut && !p->edgeTransitionThreshold)
--- a/source/encoder/slicetype.cpp	Thu Nov 28 18:37:53 2019 +0530
+++ b/source/encoder/slicetype.cpp	Wed Sep 11 15:38:06 2019 +0530
@@ -3240,12 +3240,13 @@ void CostEstimateGroup::estimateCUCost(L
             }
         }
 
+        int searchRange = m_lookahead.m_param->bEnableHME ? (hme ? m_lookahead.m_param->hmeRange[0] : m_lookahead.m_param->hmeRange[1]) : s_merange;
         /* ME will never return a cost larger than the cost @MVP, so we do not
          * have to check that ME cost is more than the estimated merge cost */
         if(!hme)
-            fencCost = tld.me.motionEstimate(fref, mvmin, mvmax, mvp, 0, NULL, s_merange, *fencMV, m_lookahead.m_param->maxSlices);
+            fencCost = tld.me.motionEstimate(fref, mvmin, mvmax, mvp, 0, NULL, searchRange, *fencMV, m_lookahead.m_param->maxSlices);
         else
-            fencCost = tld.me.motionEstimate(fref, mvmin, mvmax, mvp, 0, NULL, s_merange, *fencMV, m_lookahead.m_param->maxSlices, fref->lowerResPlane[0]);
+            fencCost = tld.me.motionEstimate(fref, mvmin, mvmax, mvp, 0, NULL, searchRange, *fencMV, m_lookahead.m_param->maxSlices, fref->lowerResPlane[0]);
         if (skipCost < 64 && skipCost < fencCost && bBidir)
         {
             fencCost = skipCost;
--- a/source/x265.h	Thu Nov 28 18:37:53 2019 +0530
+++ b/source/x265.h	Wed Sep 11 15:38:06 2019 +0530
@@ -1856,6 +1856,9 @@ typedef struct x265_param
 
     /* Enables histogram based scenecut detection algorithm to detect scenecuts. Default disabled */
     int      bHistBasedSceneCut;
+
+    /* Enable HME search ranges for L0, L1 and L2 respectively. */
+    int       hmeRange[3];
 } x265_param;
 
 /* x265_param_alloc:
--- a/source/x265cli.h	Thu Nov 28 18:37:53 2019 +0530
+++ b/source/x265cli.h	Wed Sep 11 15:38:06 2019 +0530
@@ -351,6 +351,7 @@ static const struct option long_options[
 #endif
     { "cll", no_argument, NULL, 0 },
     { "no-cll", no_argument, NULL, 0 },
+    { "hme-range", required_argument, NULL, 0 },
     { 0, 0, 0, 0 },
     { 0, 0, 0, 0 },
     { 0, 0, 0, 0 },
@@ -479,6 +480,7 @@ static void showHelp(x265_param *param)
     H1("   --[no-]temporal-mvp           Enable temporal MV predictors. Default %s\n", OPT(param->bEnableTemporalMvp));
     H1("   --[no-]hme                    Enable Hierarchical Motion Estimation. Default %s\n", OPT(param->bEnableHME));
     H1("   --hme-search <string>         Motion search-method for HME L0,L1 and L2. Default(L0,L1,L2) is %d,%d,%d\n", param->hmeSearchMethod[0], param->hmeSearchMethod[1], param->hmeSearchMethod[2]);
+    H1("   --hme-range <int>,<int>,<int> Motion search-range for HME L0,L1 and L2. Default(L0,L1,L2) is %d,%d,%d\n", param->hmeRange[0], param->hmeRange[1], param->hmeRange[2]);
     H0("\nSpatial / intra options:\n");
     H0("   --[no-]strong-intra-smoothing Enable strong intra smoothing for 32x32 blocks. Default %s\n", OPT(param->bEnableStrongIntraSmoothing));
     H0("   --[no-]constrained-intra      Constrained intra prediction (use only intra coded reference pixels) Default %s\n", OPT(param->bEnableConstrainedIntra));