changeset 12733:e31211b2f00c draft default tip master

Disable fall-back on traditional scenecut algorithm with --hist-scenecut
author Praveen Karadugattu <praveenkumar@multicorewareinc.com>
date Sun, 20 Jun 2021 21:20:50 +0530
parents e7d0e439852a
children
files doc/reST/cli.rst source/CMakeLists.txt source/common/param.cpp source/encoder/encoder.cpp source/encoder/slicetype.cpp source/test/regression-tests.txt source/x265.h source/x265cli.h
diffstat 8 files changed, 47 insertions(+-), 15 deletions(-) [+]
line wrap: on
line diff
--- a/doc/reST/cli.rst	Tue May 25 12:20:03 2021 +0530
+++ b/doc/reST/cli.rst	Sun Jun 20 21:20:50 2021 +0530
@@ -1470,7 +1470,8 @@ Slice decision options
 .. option:: --hist-scenecut, --no-hist-scenecut
 
 	Indicates that scenecuts need to be detected using luma edge and chroma histograms.
-	:option:`--hist-scenecut` enables scenecut detection using the histograms and disables the default scene cut algorithm.
+	:option:`--hist-scenecut` enables scenecut detection using the histograms.
+	It also uses the intra and inter cost info to arrive at a scenecut decision from the default scenecut method.
 	:option:`--no-hist-scenecut` disables histogram based scenecut algorithm.
 	
 .. option:: --hist-threshold <0.0..1.0>
@@ -1480,7 +1481,12 @@ Slice decision options
 	greater than 0.2 against the previous frame as scenecut. 
 	Increasing the threshold reduces the number of scenecuts detected.
 	Default 0.03.
-	
+
+.. option:: --traditional-scenecut, --no-traditional-scenecut
+
+	Enable traditional scenecut detection using intra and inter cost when :option:`--hist-scenecut` is used.
+	Default enabled.
+
 .. option:: --radl <integer>
 	
 	Number of RADL pictures allowed infront of IDR. Requires closed gop interval.
--- a/source/CMakeLists.txt	Tue May 25 12:20:03 2021 +0530
+++ b/source/CMakeLists.txt	Sun Jun 20 21:20:50 2021 +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 200)
+set(X265_BUILD 201)
 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	Tue May 25 12:20:03 2021 +0530
+++ b/source/common/param.cpp	Sun Jun 20 21:20:50 2021 +0530
@@ -172,6 +172,7 @@ void x265_param_default(x265_param* para
     param->scenecutThreshold = 40; /* Magic number pulled in from x264 */
     param->edgeTransitionThreshold = 0.03;
     param->bHistBasedSceneCut = 0;
+    param->bEnableTradScdInHscd = 1;
     param->lookaheadSlices = 8;
     param->lookaheadThreads = 0;
     param->scenecutBias = 5.0;
@@ -598,6 +599,7 @@ int x265_param_default_preset(x265_param
             param->lookaheadDepth = 0;
             param->scenecutThreshold = 0;
             param->bHistBasedSceneCut = 0;
+            param->bEnableTradScdInHscd = 1;
             param->rc.cuTree = 0;
             param->frameNumThreads = 1;
         }
@@ -953,6 +955,7 @@ int x265_param_parse(x265_param* p, cons
            bError = false;
            p->scenecutThreshold = atoi(value);
            p->bHistBasedSceneCut = 0;
+           p->bEnableTradScdInHscd = 1;
        }
     }
     OPT("temporal-layers") p->bEnableTemporalSubLayers = atobool(value);
@@ -1234,6 +1237,7 @@ int x265_param_parse(x265_param* p, cons
             }
         }
         OPT("hist-threshold") p->edgeTransitionThreshold = atof(value);
+        OPT("traditional-scenecut") p->bEnableTradScdInHscd = atobool(value);
         OPT("rskip-edge-threshold") p->edgeVarThreshold = atoi(value)/100.0f;
         OPT("lookahead-threads") p->lookaheadThreads = atoi(value);
         OPT("opt-cu-delta-qp") p->bOptCUDeltaQP = atobool(value);
@@ -2151,7 +2155,9 @@ char *x265_param2string(x265_param* p, i
     s += sprintf(s, " rc-lookahead=%d", p->lookaheadDepth);
     s += sprintf(s, " lookahead-slices=%d", p->lookaheadSlices);
     s += sprintf(s, " scenecut=%d", p->scenecutThreshold);
-    s += sprintf(s, " hist-scenecut=%d", p->bHistBasedSceneCut);
+    BOOL(p->bHistBasedSceneCut, "hist-scenecut");
+    if (p->bHistBasedSceneCut)
+        BOOL(p->bEnableTradScdInHscd, "traditional-scenecut");
     s += sprintf(s, " radl=%d", p->radl);
     BOOL(p->bEnableHRDConcatFlag, "splice");
     BOOL(p->bIntraRefresh, "intra-refresh");
@@ -2467,6 +2473,7 @@ void x265_copy_params(x265_param* dst, x
     dst->lookaheadThreads = src->lookaheadThreads;
     dst->scenecutThreshold = src->scenecutThreshold;
     dst->bHistBasedSceneCut = src->bHistBasedSceneCut;
+    dst->bEnableTradScdInHscd = src->bEnableTradScdInHscd;
     dst->bIntraRefresh = src->bIntraRefresh;
     dst->maxCUSize = src->maxCUSize;
     dst->minCUSize = src->minCUSize;
--- a/source/encoder/encoder.cpp	Tue May 25 12:20:03 2021 +0530
+++ b/source/encoder/encoder.cpp	Sun Jun 20 21:20:50 2021 +0530
@@ -3680,6 +3680,7 @@ void Encoder::configure(x265_param *p)
         p->keyframeMax = INT_MAX;
         p->scenecutThreshold = 0;
         p->bHistBasedSceneCut = 0;
+        p->bEnableTradScdInHscd = 1;
     }
     else if (p->keyframeMax <= 1)
     {
@@ -3694,6 +3695,7 @@ void Encoder::configure(x265_param *p)
         p->bframes = 0;
         p->scenecutThreshold = 0;
         p->bHistBasedSceneCut = 0;
+        p->bEnableTradScdInHscd = 1;
         p->bFrameAdaptive = 0;
         p->rc.cuTree = 0;
         p->bEnableWeightedPred = 0;
@@ -4421,12 +4423,17 @@ void Encoder::configure(x265_param *p)
             m_param->searchRange = m_param->hmeRange[2];
     }
 
-   if (p->bHistBasedSceneCut && !p->edgeTransitionThreshold)
-   {
-       p->edgeTransitionThreshold = 0.03;
-       x265_log(p, X265_LOG_WARNING, "using  default threshold %.2lf for scene cut detection\n", p->edgeTransitionThreshold);
-   }
-
+    if (p->bHistBasedSceneCut && !p->edgeTransitionThreshold)
+    {
+        p->edgeTransitionThreshold = 0.03;
+        x265_log(p, X265_LOG_WARNING, "using  default threshold %.2lf for scene cut detection.\n", p->edgeTransitionThreshold);
+    }
+
+    if (!p->bHistBasedSceneCut && !p->bEnableTradScdInHscd)
+    {
+        p->bEnableTradScdInHscd = 1;
+        x265_log(p, X265_LOG_WARNING, "option --no-traditional-scenecut requires --hist-scenecut to be enabled.\n");
+    }
 }
 
 void Encoder::readAnalysisFile(x265_analysis_data* analysis, int curPoc, const x265_picture* picIn, int paramBytes)
--- a/source/encoder/slicetype.cpp	Tue May 25 12:20:03 2021 +0530
+++ b/source/encoder/slicetype.cpp	Sun Jun 20 21:20:50 2021 +0530
@@ -2014,7 +2014,7 @@ void Lookahead::slicetypeAnalyse(Lowres 
     bool isScenecut = false;
 
     /* Temporal computations for scenecut detection */
-    if (m_param->bHistBasedSceneCut)
+    if (m_param->bHistBasedSceneCut && m_param->bEnableTradScdInHscd)
     {
         for (int i = numFrames - 1; i > 0; i--)
         {
@@ -2047,8 +2047,10 @@ void Lookahead::slicetypeAnalyse(Lowres 
     }
 
     /* When scenecut threshold is set, use scenecut detection for I frame placements */
-    if (!m_param->bHistBasedSceneCut || (m_param->bHistBasedSceneCut && frames[1]->bScenecut))
+    if (!m_param->bHistBasedSceneCut || (m_param->bHistBasedSceneCut && m_param->bEnableTradScdInHscd && frames[1]->bScenecut))
         isScenecut = scenecut(frames, 0, 1, true, origNumFrames);
+    else if (m_param->bHistBasedSceneCut && frames[1]->bScenecut)
+        isScenecut = true;
 
     if (isScenecut && (m_param->bHistBasedSceneCut || m_param->scenecutThreshold))
     {
@@ -2061,14 +2063,17 @@ void Lookahead::slicetypeAnalyse(Lowres 
         m_extendGopBoundary = false;
         for (int i = m_param->bframes + 1; i < origNumFrames; i += m_param->bframes + 1)
         {
-            if (!m_param->bHistBasedSceneCut || (m_param->bHistBasedSceneCut && frames[i + 1]->bScenecut))
+            if (!m_param->bHistBasedSceneCut || (m_param->bHistBasedSceneCut && m_param->bEnableTradScdInHscd && frames[i + 1]->bScenecut))
                 scenecut(frames, i, i + 1, true, origNumFrames);
 
             for (int j = i + 1; j <= X265_MIN(i + m_param->bframes + 1, origNumFrames); j++)
             {
-                if (frames[j]->bScenecut && scenecutInternal(frames, j - 1, j, true))
+                if (frames[j]->bScenecut)
                 {
-                    m_extendGopBoundary = true;
+                    if (m_param->bEnableTradScdInHscd)
+                        m_extendGopBoundary = scenecutInternal(frames, j - 1, j, true);
+                    else
+                        m_extendGopBoundary = true;
                     break;
                 }
             }
--- a/source/test/regression-tests.txt	Tue May 25 12:20:03 2021 +0530
+++ b/source/test/regression-tests.txt	Sun Jun 20 21:20:50 2021 +0530
@@ -160,6 +160,7 @@ Traffic_4096x2048_30p.y4m, --preset medi
 Kimono1_1920x1080_24_400.yuv,--preset superfast --qp 28 --zones 0,139,q=32
 sintel_trailer_2k_1920x1080_24.yuv, --preset medium --hist-scenecut --hist-threshold 0.02 --frame-dup --dup-threshold 60 --hrd --bitrate 10000 --vbv-bufsize 15000 --vbv-maxrate 12000
 sintel_trailer_2k_1920x1080_24.yuv, --preset medium --hist-scenecut --hist-threshold 0.02
+sintel_trailer_2k_1920x1080_24.yuv, --preset medium --hist-scenecut --hist-threshold 0.02 --no-traditional-scenecut
 sintel_trailer_2k_1920x1080_24.yuv, --preset ultrafast --hist-scenecut --hist-threshold 0.02
 crowd_run_1920x1080_50.yuv, --preset faster --ctu 32 --rskip 2 --rskip-edge-threshold 5
 crowd_run_1920x1080_50.yuv, --preset fast --ctu 64 --rskip 2 --rskip-edge-threshold 5 --aq-mode 4
--- a/source/x265.h	Tue May 25 12:20:03 2021 +0530
+++ b/source/x265.h	Sun Jun 20 21:20:50 2021 +0530
@@ -1963,6 +1963,10 @@ typedef struct x265_param
     /* Flag indicating whether the encoder should emit an End of Sequence
      * NAL at the end of every Coded Video Sequence. Default false */
     int      bEnableEndOfSequence;
+
+    /* Flag to turn on/off traditional scenecut detection in histogram based scenecut detection.
+     * When false, only spatial properties are used for scenecut detection. Default true */
+    int      bEnableTradScdInHscd;
 } x265_param;
 
 /* x265_param_alloc:
--- a/source/x265cli.h	Tue May 25 12:20:03 2021 +0530
+++ b/source/x265cli.h	Sun Jun 20 21:20:50 2021 +0530
@@ -144,6 +144,8 @@ static const struct option long_options[
     { "hist-scenecut",        no_argument, NULL, 0},
     { "no-hist-scenecut",     no_argument, NULL, 0},
     { "hist-threshold", required_argument, NULL, 0},
+    { "traditional-scenecut", no_argument, NULL, 0},
+    { "no-traditional-scenecut", no_argument, NULL, 0},
     { "fades",                no_argument, NULL, 0 },
     { "no-fades",             no_argument, NULL, 0 },
     { "scenecut-aware-qp", required_argument, NULL, 0 },