[x265] [PATCH 1/3] Remove existing histogram based scene change algorithm

Snehaa Giridharan snehaa at multicorewareinc.com
Wed Nov 2 10:53:15 UTC 2022


>From baf4c4530eb9e1fdd85a05159c2b9587cb971bd7 Mon Sep 17 00:00:00 2001
From: ashok2022 <ashok at multicorewareinc.com>
Date: Fri, 21 Oct 2022 20:31:57 +0530
Subject: [PATCH] Remove existing histogram based scene change algorithm

Signed-off-by: Snehaa Giridharan <snehaa at multicorewareinc.com>
---
 doc/reST/cli.rst                |  20 +-
 source/common/common.h          |   2 -
 source/common/frame.cpp         |   2 -
 source/common/lowres.cpp        |   6 +-
 source/common/lowres.h          |   9 +-
 source/common/param.cpp         |  33 +--
 source/encoder/encoder.cpp      | 405 +-------------------------------
 source/encoder/encoder.h        |  18 --
 source/encoder/frameencoder.cpp |   2 +-
 source/encoder/slicetype.cpp    |  97 ++------
 source/encoder/slicetype.h      |   3 +-
 source/x265.h                   |  10 -
 source/x265cli.cpp              |   1 -
 source/x265cli.h                |   3 -
 14 files changed, 34 insertions(+), 577 deletions(-)

diff --git a/doc/reST/cli.rst b/doc/reST/cli.rst
index 9fa12fa92..2437a09da 100755
--- a/doc/reST/cli.rst
+++ b/doc/reST/cli.rst
@@ -1474,24 +1474,10 @@ 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.
- 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.
+ Scenecuts detected based on histogram, intensity and variance of the
picture.
+ :option:`--hist-scenecut` enables or :option:`--no-hist-scenecut`
disables scenecut detection based on
+ histogram.

-.. option:: --hist-threshold <0.0..1.0>
-
- This value represents the threshold for normalized SAD of edge histograms
used in scenecut detection.
- This requires :option:`--hist-scenecut` to be enabled. For example, a
value of 0.2 indicates that a frame with normalized SAD value
- 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.
diff --git a/source/common/common.h b/source/common/common.h
index fad2229e7..7212f3496 100644
--- a/source/common/common.h
+++ b/source/common/common.h
@@ -130,7 +130,6 @@ typedef uint64_t sum2_t;
 typedef uint64_t pixel4;
 typedef int64_t  ssum2_t;
 #define SHIFT_TO_BITPLANE 9
-#define HISTOGRAM_BINS 1024
 #define BRIGHTNESS_THRESHOLD 120 // The threshold above which a pixel is
bright
 #else
 typedef uint8_t  pixel;
@@ -139,7 +138,6 @@ typedef uint32_t sum2_t;
 typedef uint32_t pixel4;
 typedef int32_t  ssum2_t; // Signed sum
 #define SHIFT_TO_BITPLANE 7
-#define HISTOGRAM_BINS 256
 #define BRIGHTNESS_THRESHOLD 30 // The threshold above which a pixel is
bright
 #endif // if HIGH_BIT_DEPTH

diff --git a/source/common/frame.cpp b/source/common/frame.cpp
index e1bdc39b6..f51270bf0 100644
--- a/source/common/frame.cpp
+++ b/source/common/frame.cpp
@@ -181,8 +181,6 @@ fail:
 bool Frame::createSubSample()
 {

-    //m_param = param;
-
     m_fencPicSubsampled2 = new PicYuv;
     m_fencPicSubsampled4 = new PicYuv;

diff --git a/source/common/lowres.cpp b/source/common/lowres.cpp
index 5e7718e7e..56b98b364 100644
--- a/source/common/lowres.cpp
+++ b/source/common/lowres.cpp
@@ -238,7 +238,7 @@ void Lowres::destroy()
     X265_FREE(edgeInclined);
     X265_FREE(qpAqMotionOffset);
     X265_FREE(blockVariance);
-    X265_FREE(lowresEdgePlane);
+
     if (maxAQDepth > 0)
     {
         for (uint32_t d = 0; d < 4; d++)
@@ -270,10 +270,6 @@ void Lowres::init(PicYuv *origPic, int poc)
     indB = 0;
     memset(costEst, -1, sizeof(costEst));
     memset(weightedCostDelta, 0, sizeof(weightedCostDelta));
-    interPCostPercDiff = 0.0;
-    intraCostPercDiff = 0.0;
-    m_bIsMaxThres = false;
-    m_bIsHardScenecut = false;

     if (qpAqOffset && invQscaleFactor)
         memset(costEstAq, -1, sizeof(costEstAq));
diff --git a/source/common/lowres.h b/source/common/lowres.h
index 03d713edb..8adb93a81 100644
--- a/source/common/lowres.h
+++ b/source/common/lowres.h
@@ -217,13 +217,13 @@ struct Lowres : public ReferencePlanes
     double*   qpAqOffset;      // AQ QP offset values for each 16x16 CU
     double*   qpCuTreeOffset;  // cuTree QP offset values for each 16x16 CU
     double*   qpAqMotionOffset;
-    int*      invQscaleFactor; // qScale values for qp Aq Offsets
+    int*      invQscaleFactor;    // qScale values for qp Aq Offsets
     int*      invQscaleFactor8x8; // temporary buffer for qg-size 8
     uint32_t* blockVariance;
     uint64_t  wp_ssd[3];       // This is different than SSDY, this is
sum(pixel^2) - sum(pixel)^2 for entire frame
     uint64_t  wp_sum[3];
     double    frameVariance;
-    int* edgeInclined;
+    int*      edgeInclined;


     /* cutree intermediate data */
@@ -237,11 +237,6 @@ struct Lowres : public ReferencePlanes
     uint16_t* propagateCost;
     double    weightedCostDelta[X265_BFRAME_MAX + 2];
     ReferencePlanes weightedRef[X265_BFRAME_MAX + 2];
-    /* For hist-based scenecut */
-    bool   m_bIsMaxThres;
-    double interPCostPercDiff;
-    double intraCostPercDiff;
-    bool   m_bIsHardScenecut;

     bool create(x265_param* param, PicYuv *origPic, uint32_t qgSize);
     void destroy();
diff --git a/source/common/param.cpp b/source/common/param.cpp
index 00fe84900..5de4361af 100755
--- a/source/common/param.cpp
+++ b/source/common/param.cpp
@@ -170,9 +170,7 @@ void x265_param_default(x265_param* param)
     param->bFrameAdaptive = X265_B_ADAPT_TRELLIS;
     param->bBPyramid = 1;
     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;
@@ -609,7 +607,6 @@ int x265_param_default_preset(x265_param* param, const
char* preset, const char*
             param->lookaheadDepth = 0;
             param->scenecutThreshold = 0;
             param->bHistBasedSceneCut = 0;
-            param->bEnableTradScdInHscd = 1;
             param->rc.cuTree = 0;
             param->frameNumThreads = 1;
         }
@@ -964,8 +961,6 @@ int x265_param_parse(x265_param* p, const char* name,
const char* value)
        {
            bError = false;
            p->scenecutThreshold = atoi(value);
-           p->bHistBasedSceneCut = 0;
-           p->bEnableTradScdInHscd = 1;
        }
     }
     OPT("temporal-layers") p->bEnableTemporalSubLayers = atobool(value);
@@ -1233,22 +1228,7 @@ int x265_param_parse(x265_param* p, const char*
name, const char* value)
         OPT("opt-ref-list-length-pps") p->bOptRefListLengthPPS =
atobool(value);
         OPT("multi-pass-opt-rps") p->bMultiPassOptRPS = atobool(value);
         OPT("scenecut-bias") p->scenecutBias = atof(value);
-        OPT("hist-scenecut")
-        {
-            p->bHistBasedSceneCut = atobool(value);
-            if (bError)
-            {
-                bError = false;
-                p->bHistBasedSceneCut = 0;
-            }
-            if (p->bHistBasedSceneCut)
-            {
-                bError = false;
-                p->scenecutThreshold = 0;
-            }
-        }
-        OPT("hist-threshold") p->edgeTransitionThreshold = atof(value);
-        OPT("traditional-scenecut") p->bEnableTradScdInHscd =
atobool(value);
+        OPT("hist-scenecut") p->bHistBasedSceneCut = 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);
@@ -1786,8 +1766,6 @@ int x265_check_params(x265_param* param)
           "scenecutThreshold must be greater than 0");
     CHECK(param->scenecutBias < 0 || 100 < param->scenecutBias,
             "scenecut-bias must be between 0 and 100");
-    CHECK(param->edgeTransitionThreshold < 0.0 || 1.0 <
param->edgeTransitionThreshold,
-            "hist-threshold must be between 0.0 and 1.0");
     CHECK(param->radl < 0 || param->radl > param->bframes,
           "radl must be between 0 and bframes");
     CHECK(param->rdPenalty < 0 || param->rdPenalty > 2,
@@ -2001,8 +1979,8 @@ void x265_print_params(x265_param* param)
         x265_log(param, X265_LOG_INFO, "Keyframe min / max / scenecut /
bias  : %d / %d / %d / %.2lf \n",
                  param->keyframeMin, param->keyframeMax,
param->scenecutThreshold, param->scenecutBias * 100);
     else if (param->bHistBasedSceneCut && param->keyframeMax != INT_MAX)
-        x265_log(param, X265_LOG_INFO, "Keyframe min / max / scenecut /
edge threshold  : %d / %d / %d / %.2lf\n",
-                 param->keyframeMin, param->keyframeMax,
param->bHistBasedSceneCut, param->edgeTransitionThreshold);
+        x265_log(param, X265_LOG_INFO, "Keyframe min / max / scenecut  :
%d / %d / %d / %.2lf\n",
+                 param->keyframeMin, param->keyframeMax,
param->bHistBasedSceneCut);
     else if (param->keyframeMax == INT_MAX)
         x265_log(param, X265_LOG_INFO, "Keyframe min / max / scenecut
 : disabled\n");

@@ -2179,8 +2157,6 @@ char *x265_param2string(x265_param* p, int padx, int
pady)
     s += sprintf(s, " lookahead-slices=%d", p->lookaheadSlices);
     s += sprintf(s, " scenecut=%d", p->scenecutThreshold);
     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");
@@ -2334,7 +2310,6 @@ char *x265_param2string(x265_param* p, int padx, int
pady)
     BOOL(p->bOptRefListLengthPPS, "opt-ref-list-length-pps");
     BOOL(p->bMultiPassOptRPS, "multi-pass-opt-rps");
     s += sprintf(s, " scenecut-bias=%.2f", p->scenecutBias);
-    s += sprintf(s, " hist-threshold=%.2f", p->edgeTransitionThreshold);
     BOOL(p->bOptCUDeltaQP, "opt-cu-delta-qp");
     BOOL(p->bAQMotion, "aq-motion");
     BOOL(p->rc.frameSegment, "sbrc");
@@ -2500,7 +2475,6 @@ void x265_copy_params(x265_param* dst, x265_param*
src)
     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;
@@ -2671,7 +2645,6 @@ void x265_copy_params(x265_param* dst, x265_param*
src)
     dst->bOptRefListLengthPPS = src->bOptRefListLengthPPS;
     dst->bMultiPassOptRPS = src->bMultiPassOptRPS;
     dst->scenecutBias = src->scenecutBias;
-    dst->edgeTransitionThreshold = src->edgeTransitionThreshold;
     dst->gopLookahead = src->lookaheadDepth;
     dst->bOptCUDeltaQP = src->bOptCUDeltaQP;
     dst->analysisMultiPassDistortion = src->analysisMultiPassDistortion;
diff --git a/source/encoder/encoder.cpp b/source/encoder/encoder.cpp
index c24507e5a..0fea6553c 100644
--- a/source/encoder/encoder.cpp
+++ b/source/encoder/encoder.cpp
@@ -168,11 +168,6 @@ Encoder::Encoder()
     m_prevTonemapPayload.payload = NULL;
     m_startPoint = 0;
     m_saveCTUSize = 0;
-    m_edgePic = NULL;
-    m_edgeHistThreshold = 0;
-    m_chromaHistThreshold = 0.0;
-    m_scaledEdgeThreshold = 0.0;
-    m_scaledChromaThreshold = 0.0;
     m_zoneIndex = 0;
     m_origPicBuffer = 0;
 }
@@ -251,34 +246,6 @@ void Encoder::create()
         }
     }

-    if (m_param->bHistBasedSceneCut)
-    {
-        uint32_t planeSize = (m_param->sourceWidth >>
x265_cli_csps[p->internalCsp].width[0]) * (m_param->sourceHeight >>
x265_cli_csps[m_param->internalCsp].height[0]);
-        uint32_t pixelbytes = m_param->internalBitDepth > 8 ? 2 : 1;
-        m_edgePic = X265_MALLOC(pixel, planeSize * pixelbytes);
-        m_edgeHistThreshold = m_param->edgeTransitionThreshold;
-        m_chromaHistThreshold = x265_min(m_edgeHistThreshold * 10.0,
MAX_SCENECUT_THRESHOLD);
-        m_scaledEdgeThreshold = x265_min(m_edgeHistThreshold *
SCENECUT_STRENGTH_FACTOR, MAX_SCENECUT_THRESHOLD);
-        m_scaledChromaThreshold = x265_min(m_chromaHistThreshold *
SCENECUT_STRENGTH_FACTOR, MAX_SCENECUT_THRESHOLD);
-        if (m_param->sourceBitDepth != m_param->internalBitDepth)
-        {
-            int size = m_param->sourceWidth * m_param->sourceHeight;
-            int hshift = CHROMA_H_SHIFT(m_param->internalCsp);
-            int vshift = CHROMA_V_SHIFT(m_param->internalCsp);
-            int widthC = m_param->sourceWidth >> hshift;
-            int heightC = m_param->sourceHeight >> vshift;
-
-            m_inputPic[0] = X265_MALLOC(pixel, size);
-            if (m_param->internalCsp != X265_CSP_I400)
-            {
-                for (int j = 1; j < 3; j++)
-                {
-                    m_inputPic[j] = X265_MALLOC(pixel, widthC * heightC);
-                }
-            }
-        }
-    }
-
     // Do not allow WPP if only one row or fewer than 3 columns, it is
pointless and unstable
     if (rows == 1 || cols < 3)
     {
@@ -927,26 +894,6 @@ void Encoder::destroy()
         }
     }

-    if (m_param->bHistBasedSceneCut)
-    {
-        if (m_edgePic != NULL)
-        {
-            X265_FREE_ZERO(m_edgePic);
-        }
-
-        if (m_param->sourceBitDepth != m_param->internalBitDepth)
-        {
-            X265_FREE_ZERO(m_inputPic[0]);
-            if (m_param->internalCsp != X265_CSP_I400)
-            {
-                for (int i = 1; i < 3; i++)
-                {
-                    X265_FREE_ZERO(m_inputPic[i]);
-                }
-            }
-        }
-    }
-
     for (int i = 0; i < m_param->frameNumThreads; i++)
     {
         if (m_frameEncoder[i])
@@ -1414,217 +1361,6 @@ void Encoder::copyPicture(x265_picture *dest, const
x265_picture *src)
     dest->planes[2] = (char*)dest->planes[1] + src->stride[1] *
(src->height >> x265_cli_csps[src->colorSpace].height[1]);
 }

-bool Encoder::computeHistograms(x265_picture *pic)
-{
-    pixel *src = NULL, *planeV = NULL, *planeU = NULL;
-    uint32_t widthC, heightC;
-    int hshift, vshift;
-
-    hshift = CHROMA_H_SHIFT(pic->colorSpace);
-    vshift = CHROMA_V_SHIFT(pic->colorSpace);
-    widthC = pic->width >> hshift;
-    heightC = pic->height >> vshift;
-
-    if (pic->bitDepth == X265_DEPTH)
-    {
-        src = (pixel*)pic->planes[0];
-        if (m_param->internalCsp != X265_CSP_I400)
-        {
-            planeU = (pixel*)pic->planes[1];
-            planeV = (pixel*)pic->planes[2];
-        }
-    }
-    else if (pic->bitDepth == 8 && X265_DEPTH > 8)
-    {
-        int shift = (X265_DEPTH - 8);
-        uint8_t *yChar, *uChar, *vChar;
-
-        yChar = (uint8_t*)pic->planes[0];
-        primitives.planecopy_cp(yChar, pic->stride[0] / sizeof(*yChar),
m_inputPic[0], pic->stride[0] / sizeof(*yChar), pic->width, pic->height,
shift);
-        src = m_inputPic[0];
-        if (m_param->internalCsp != X265_CSP_I400)
-        {
-            uChar = (uint8_t*)pic->planes[1];
-            vChar = (uint8_t*)pic->planes[2];
-            primitives.planecopy_cp(uChar, pic->stride[1] /
sizeof(*uChar), m_inputPic[1], pic->stride[1] / sizeof(*uChar), widthC,
heightC, shift);
-            primitives.planecopy_cp(vChar, pic->stride[2] /
sizeof(*vChar), m_inputPic[2], pic->stride[2] / sizeof(*vChar), widthC,
heightC, shift);
-            planeU = m_inputPic[1];
-            planeV = m_inputPic[2];
-        }
-    }
-    else
-    {
-        uint16_t *yShort, *uShort, *vShort;
-        /* mask off bits that are supposed to be zero */
-        uint16_t mask = (1 << X265_DEPTH) - 1;
-        int shift = abs(pic->bitDepth - X265_DEPTH);
-
-        yShort = (uint16_t*)pic->planes[0];
-        uShort = (uint16_t*)pic->planes[1];
-        vShort = (uint16_t*)pic->planes[2];
-
-        if (pic->bitDepth > X265_DEPTH)
-        {
-            /* shift right and mask pixels to final size */
-            primitives.planecopy_sp(yShort, pic->stride[0] /
sizeof(*yShort), m_inputPic[0], pic->stride[0] / sizeof(*yShort),
pic->width, pic->height, shift, mask);
-            if (m_param->internalCsp != X265_CSP_I400)
-            {
-                primitives.planecopy_sp(uShort, pic->stride[1] /
sizeof(*uShort), m_inputPic[1], pic->stride[1] / sizeof(*uShort), widthC,
heightC, shift, mask);
-                primitives.planecopy_sp(vShort, pic->stride[2] /
sizeof(*vShort), m_inputPic[2], pic->stride[2] / sizeof(*vShort), widthC,
heightC, shift, mask);
-            }
-        }
-        else /* Case for (pic.bitDepth < X265_DEPTH) */
-        {
-            /* shift left and mask pixels to final size */
-            primitives.planecopy_sp_shl(yShort, pic->stride[0] /
sizeof(*yShort), m_inputPic[0], pic->stride[0] / sizeof(*yShort),
pic->width, pic->height, shift, mask);
-            if (m_param->internalCsp != X265_CSP_I400)
-            {
-                primitives.planecopy_sp_shl(uShort, pic->stride[1] /
sizeof(*uShort), m_inputPic[1], pic->stride[1] / sizeof(*uShort), widthC,
heightC, shift, mask);
-                primitives.planecopy_sp_shl(vShort, pic->stride[2] /
sizeof(*vShort), m_inputPic[2], pic->stride[2] / sizeof(*vShort), widthC,
heightC, shift, mask);
-            }
-        }
-
-        src = m_inputPic[0];
-        planeU = m_inputPic[1];
-        planeV = m_inputPic[2];
-    }
-
-    size_t bufSize = sizeof(pixel) * m_planeSizes[0];
-    memset(m_edgePic, 0, bufSize);
-
-    if (!computeEdge(m_edgePic, src, NULL, pic->width, pic->height,
pic->width, false, 1))
-    {
-        x265_log(m_param, X265_LOG_ERROR, "Failed to compute edge!");
-        return false;
-    }
-
-    pixel pixelVal;
-    int32_t *edgeHist = m_curEdgeHist;
-    memset(edgeHist, 0, EDGE_BINS * sizeof(int32_t));
-    for (uint32_t i = 0; i < m_planeSizes[0]; i++)
-    {
-        if (m_edgePic[i])
-            edgeHist[1]++;
-        else
-            edgeHist[0]++;
-    }
-
-    /* Y Histogram Calculation */
-    int32_t *yHist = m_curYUVHist[0];
-    memset(yHist, 0, HISTOGRAM_BINS * sizeof(int32_t));
-    for (uint32_t i = 0; i < m_planeSizes[0]; i++)
-    {
-        pixelVal = src[i];
-        yHist[pixelVal]++;
-    }
-
-    if (pic->colorSpace != X265_CSP_I400)
-    {
-        /* U Histogram Calculation */
-        int32_t *uHist = m_curYUVHist[1];
-        memset(uHist, 0, sizeof(m_curYUVHist[1]));
-        for (uint32_t i = 0; i < m_planeSizes[1]; i++)
-        {
-            pixelVal = planeU[i];
-            uHist[pixelVal]++;
-        }
-
-        /* V Histogram Calculation */
-        pixelVal = 0;
-        int32_t *vHist = m_curYUVHist[2];
-        memset(vHist, 0, sizeof(m_curYUVHist[2]));
-        for (uint32_t i = 0; i < m_planeSizes[2]; i++)
-        {
-            pixelVal = planeV[i];
-            vHist[pixelVal]++;
-        }
-    }
-    return true;
-}
-
-void Encoder::computeHistogramSAD(double *normalizedMaxUVSad, double
*normalizedEdgeSad, int curPoc)
-{
-
-    if (curPoc == 0)
-    {   /* first frame is scenecut by default no sad computation for the
same. */
-        *normalizedMaxUVSad = 0.0;
-        *normalizedEdgeSad = 0.0;
-    }
-    else
-    {
-        /* compute sum of absolute differences of histogram bins of chroma
and luma edge response between the current and prev pictures. */
-        int32_t edgeHistSad = 0;
-        int32_t uHistSad = 0;
-        int32_t vHistSad = 0;
-        double normalizedUSad = 0.0;
-        double normalizedVSad = 0.0;
-
-        for (int j = 0; j < HISTOGRAM_BINS; j++)
-        {
-            if (j < 2)
-            {
-                edgeHistSad += abs(m_curEdgeHist[j] - m_prevEdgeHist[j]);
-            }
-            uHistSad += abs(m_curYUVHist[1][j] - m_prevYUVHist[1][j]);
-            vHistSad += abs(m_curYUVHist[2][j] - m_prevYUVHist[2][j]);
-        }
-        *normalizedEdgeSad = normalizeRange(edgeHistSad, 0, 2 *
m_planeSizes[0], 0.0, 1.0);
-        normalizedUSad = normalizeRange(uHistSad, 0, 2 * m_planeSizes[1],
0.0, 1.0);
-        normalizedVSad = normalizeRange(vHistSad, 0, 2 * m_planeSizes[2],
0.0, 1.0);
-        *normalizedMaxUVSad = x265_max(normalizedUSad, normalizedVSad);
-    }
-
-    /* store histograms of previous frame for reference */
-    memcpy(m_prevEdgeHist, m_curEdgeHist, sizeof(m_curEdgeHist));
-    memcpy(m_prevYUVHist, m_curYUVHist, sizeof(m_curYUVHist));
-}
-
-double Encoder::normalizeRange(int32_t value, int32_t minValue, int32_t
maxValue, double rangeStart, double rangeEnd)
-{
-    return (double)(value - minValue) * (rangeEnd - rangeStart) /
(maxValue - minValue) + rangeStart;
-}
-
-void Encoder::findSceneCuts(x265_picture *pic, bool& bDup, double
maxUVSad, double edgeSad, bool& isMaxThres, bool& isHardSC)
-{
-    double minEdgeT = m_edgeHistThreshold * MIN_EDGE_FACTOR;
-    double minChromaT = minEdgeT * SCENECUT_CHROMA_FACTOR;
-    double maxEdgeT = m_edgeHistThreshold * MAX_EDGE_FACTOR;
-    double maxChromaT = maxEdgeT * SCENECUT_CHROMA_FACTOR;
-    pic->frameData.bScenecut = false;
-
-    if (pic->poc == 0)
-    {
-        /* for first frame */
-        pic->frameData.bScenecut = false;
-        bDup = false;
-    }
-    else
-    {
-        if (edgeSad == 0.0 && maxUVSad == 0.0)
-        {
-            bDup = true;
-        }
-        else if (edgeSad < minEdgeT && maxUVSad < minChromaT)
-        {
-            pic->frameData.bScenecut = false;
-        }
-        else if (edgeSad > maxEdgeT && maxUVSad > maxChromaT)
-        {
-            pic->frameData.bScenecut = true;
-            isMaxThres = true;
-            isHardSC = true;
-        }
-        else if (edgeSad > m_scaledEdgeThreshold || maxUVSad >=
m_scaledChromaThreshold
-                 || (edgeSad > m_edgeHistThreshold && maxUVSad >=
m_chromaHistThreshold))
-        {
-            pic->frameData.bScenecut = true;
-            bDup = false;
-            if (edgeSad > m_scaledEdgeThreshold || maxUVSad >=
m_scaledChromaThreshold)
-                isHardSC = true;
-        }
-    }
-}
-
 bool Encoder::isFilterThisframe(uint8_t sliceTypeConfig, int curSliceType)
 {
     uint8_t newSliceType = 0;
@@ -1737,10 +1473,7 @@ int Encoder::encode(const x265_picture* pic_in,
x265_picture* pic_out)
     const x265_picture* inputPic = NULL;
     static int written = 0, read = 0;
     bool dontRead = false;
-    bool bdropFrame = false;
     bool dropflag = false;
-    bool isMaxThres = false;
-    bool isHardSC = false;

     if (m_exportedPic)
     {
@@ -1758,25 +1491,6 @@ int Encoder::encode(const x265_picture* pic_in,
x265_picture* pic_out)

     if ((pic_in && (!m_param->chunkEnd || (m_encodedFrameNum <
m_param->chunkEnd))) || (m_param->bEnableFrameDuplication && !pic_in &&
(read < written)))
     {
-        if (m_param->bHistBasedSceneCut && pic_in)
-        {
-            x265_picture *pic = (x265_picture *) pic_in;
-
-            if (pic->poc == 0)
-            {
-                /* for entire encode compute the chroma plane sizes only
once */
-                for (int i = 0; i <
x265_cli_csps[m_param->internalCsp].planes; i++)
-                    m_planeSizes[i] = (pic->width >>
x265_cli_csps[m_param->internalCsp].width[i]) * (pic->height >>
x265_cli_csps[m_param->internalCsp].height[i]);
-            }
-
-            if (computeHistograms(pic))
-            {
-                double maxUVSad = 0.0, edgeSad = 0.0;
-                computeHistogramSAD(&maxUVSad, &edgeSad, pic_in->poc);
-                findSceneCuts(pic, bdropFrame, maxUVSad, edgeSad,
isMaxThres, isHardSC);
-            }
-        }
-
         if ((m_param->bEnableFrameDuplication && !pic_in && (read <
written)))
             dontRead = true;
         else
@@ -1820,20 +1534,7 @@ int Encoder::encode(const x265_picture* pic_in,
x265_picture* pic_out)
                     written++;
                 }

-                if (m_param->bEnableFrameDuplication &&
m_param->bHistBasedSceneCut)
-                {
-                    if (!bdropFrame &&
m_dupBuffer[1]->dupPic->frameData.bScenecut == false)
-                    {
-                        psnrWeight = ComputePSNR(m_dupBuffer[0]->dupPic,
m_dupBuffer[1]->dupPic, m_param);
-                        if (psnrWeight >= m_param->dupThreshold)
-                            dropflag = true;
-                    }
-                    else
-                    {
-                        dropflag = true;
-                    }
-                }
-                else if (m_param->bEnableFrameDuplication)
+                if (m_param->bEnableFrameDuplication)
                 {
                     psnrWeight = ComputePSNR(m_dupBuffer[0]->dupPic,
m_dupBuffer[1]->dupPic, m_param);
                     if (psnrWeight >= m_param->dupThreshold)
@@ -1916,12 +1617,6 @@ int Encoder::encode(const x265_picture* pic_in,
x265_picture* pic_out)
                         }
                     }
                 }
-                if (m_param->recursionSkipMode == EDGE_BASED_RSKIP &&
m_param->bHistBasedSceneCut)
-                {
-                    pixel* src = m_edgePic;
-                    primitives.planecopy_pp_shr(src,
inFrame->m_fencPic->m_picWidth, inFrame->m_edgeBitPic,
inFrame->m_fencPic->m_stride,
-                        inFrame->m_fencPic->m_picWidth,
inFrame->m_fencPic->m_picHeight, 0);
-                }
             }
             else
             {
@@ -1950,13 +1645,6 @@ int Encoder::encode(const x265_picture* pic_in,
x265_picture* pic_out)
         inFrame->m_poc       = ++m_pocLast;
         inFrame->m_userData  = inputPic->userData;
         inFrame->m_pts       = inputPic->pts;
-        if (m_param->bHistBasedSceneCut)
-        {
-            inFrame->m_lowres.bScenecut = (inputPic->frameData.bScenecut
== 1) ? true : false;
-            inFrame->m_lowres.m_bIsMaxThres = isMaxThres;
-            if (m_param->radl && m_param->keyframeMax !=
m_param->keyframeMin)
-                inFrame->m_lowres.m_bIsHardScenecut = isHardSC;
-        }

         if ((m_param->bEnableSceneCutAwareQp & BACKWARD) &&
m_param->rc.bStatRead)
         {
@@ -1974,16 +1662,7 @@ int Encoder::encode(const x265_picture* pic_in,
x265_picture* pic_out)
                 }
             }
         }
-        if (m_param->bHistBasedSceneCut && m_param->analysisSave)
-        {
-            memcpy(inFrame->m_analysisData.edgeHist, m_curEdgeHist,
EDGE_BINS * sizeof(int32_t));
-            memcpy(inFrame->m_analysisData.yuvHist[0], m_curYUVHist[0],
HISTOGRAM_BINS *sizeof(int32_t));
-            if (inputPic->colorSpace != X265_CSP_I400)
-            {
-                memcpy(inFrame->m_analysisData.yuvHist[1],
m_curYUVHist[1], HISTOGRAM_BINS * sizeof(int32_t));
-                memcpy(inFrame->m_analysisData.yuvHist[2],
m_curYUVHist[2], HISTOGRAM_BINS * sizeof(int32_t));
-            }
-        }
+
         inFrame->m_forceqp   = inputPic->forceqp;
         inFrame->m_param     = (m_reconfigure || m_reconfigureRc) ?
m_latestParam : m_param;
         inFrame->m_picStruct = inputPic->picStruct;
@@ -2242,16 +1921,6 @@ int Encoder::encode(const x265_picture* pic_in,
x265_picture* pic_out)
                     pic_out->analysisData.poc = pic_out->poc;
                     pic_out->analysisData.sliceType = pic_out->sliceType;
                     pic_out->analysisData.bScenecut =
outFrame->m_lowres.bScenecut;
-                    if (m_param->bHistBasedSceneCut)
-                    {
-                        memcpy(pic_out->analysisData.edgeHist,
outFrame->m_analysisData.edgeHist, EDGE_BINS * sizeof(int32_t));
-                        memcpy(pic_out->analysisData.yuvHist[0],
outFrame->m_analysisData.yuvHist[0], HISTOGRAM_BINS * sizeof(int32_t));
-                        if (pic_out->colorSpace != X265_CSP_I400)
-                        {
-                            memcpy(pic_out->analysisData.yuvHist[1],
outFrame->m_analysisData.yuvHist[1], HISTOGRAM_BINS * sizeof(int32_t));
-                            memcpy(pic_out->analysisData.yuvHist[2],
outFrame->m_analysisData.yuvHist[2], HISTOGRAM_BINS * sizeof(int32_t));
-                        }
-                    }
                     pic_out->analysisData.satdCost  =
outFrame->m_lowres.satdCost;
                     pic_out->analysisData.numCUsInFrame =
outFrame->m_analysisData.numCUsInFrame;
                     pic_out->analysisData.numPartitions =
outFrame->m_analysisData.numPartitions;
@@ -2736,7 +2405,7 @@ int Encoder::encode(const x265_picture* pic_in,
x265_picture* pic_out)
                 for (int i = 0; i < frameEnc->m_mcstf->m_numRef; i++)
                 {
                     TemporalFilterRefPicInfo *ref =
&curEncoder->m_mcstfRefList[i];
-                    ref->slicetype =
m_lookahead->FindSliceType(frameEnc->m_poc + ref->origOffset);
+                    ref->slicetype =
m_lookahead->findSliceType(frameEnc->m_poc + ref->origOffset);
                     Frame* dpbframePtr =
m_dpb->m_picList.getPOC(frameEnc->m_poc + ref->origOffset);
                     if (dpbframePtr != NULL)
                     {
@@ -3031,18 +2700,7 @@ void Encoder::printSummary()
             (float)100.0 * m_numLumaWPBiFrames / m_analyzeB.m_numPics,
             (float)100.0 * m_numChromaWPBiFrames / m_analyzeB.m_numPics);
     }
-    int pWithB = 0;
-    for (int i = 0; i <= m_param->bframes; i++)
-        pWithB += m_lookahead->m_histogram[i];

-    if (pWithB)
-    {
-        int p = 0;
-        for (int i = 0; i <= m_param->bframes; i++)
-            p += sprintf(buffer + p, "%.1f%% ", 100. *
m_lookahead->m_histogram[i] / pWithB);
-
-        x265_log(m_param, X265_LOG_INFO, "consecutive B-frames: %s\n",
buffer);
-    }
     if (m_param->bLossless)
     {
         float frameSize = (float)(m_param->sourceWidth -
m_sps.conformanceWindow.rightOffset) *
@@ -3949,7 +3607,6 @@ void Encoder::configure(x265_param *p)
         p->keyframeMax = INT_MAX;
         p->scenecutThreshold = 0;
         p->bHistBasedSceneCut = 0;
-        p->bEnableTradScdInHscd = 1;
     }
     else if (p->keyframeMax <= 1)
     {
@@ -3964,7 +3621,6 @@ 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;
@@ -4701,18 +4357,6 @@ void Encoder::configure(x265_param *p)
         if (m_param->searchRange != m_param->hmeRange[2])
             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->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)
@@ -4773,16 +4417,6 @@ void Encoder::readAnalysisFile(x265_analysis_data*
analysis, int curPoc, const x
     analysis->frameRecordSize = frameRecordSize;
     X265_FREAD(&analysis->sliceType, sizeof(int), 1, m_analysisFileIn,
&(picData->sliceType));
     X265_FREAD(&analysis->bScenecut, sizeof(int), 1, m_analysisFileIn,
&(picData->bScenecut));
-    if (m_param->bHistBasedSceneCut)
-    {
-        X265_FREAD(&analysis->edgeHist, sizeof(int32_t), EDGE_BINS,
m_analysisFileIn, &m_curEdgeHist);
-        X265_FREAD(&analysis->yuvHist[0], sizeof(int32_t), HISTOGRAM_BINS,
m_analysisFileIn, &m_curYUVHist[0]);
-        if (m_param->internalCsp != X265_CSP_I400)
-        {
-            X265_FREAD(&analysis->yuvHist[1], sizeof(int32_t),
HISTOGRAM_BINS, m_analysisFileIn, &m_curYUVHist[1]);
-            X265_FREAD(&analysis->yuvHist[2], sizeof(int32_t),
HISTOGRAM_BINS, m_analysisFileIn, &m_curYUVHist[2]);
-        }
-    }
     X265_FREAD(&analysis->satdCost, sizeof(int64_t), 1, m_analysisFileIn,
&(picData->satdCost));
     X265_FREAD(&numCUsLoad, sizeof(int), 1, m_analysisFileIn,
&(picData->numCUsInFrame));
     X265_FREAD(&analysis->numPartitions, sizeof(int), 1, m_analysisFileIn,
&(picData->numPartitions));
@@ -5105,16 +4739,6 @@ void Encoder::readAnalysisFile(x265_analysis_data*
analysis, int curPoc, const x
     analysis->frameRecordSize = frameRecordSize;
     X265_FREAD(&analysis->sliceType, sizeof(int), 1, m_analysisFileIn,
&(picData->sliceType));
     X265_FREAD(&analysis->bScenecut, sizeof(int), 1, m_analysisFileIn,
&(picData->bScenecut));
-    if (m_param->bHistBasedSceneCut)
-    {
-        X265_FREAD(&analysis->edgeHist, sizeof(int32_t), EDGE_BINS,
m_analysisFileIn, &m_curEdgeHist);
-        X265_FREAD(&analysis->yuvHist[0], sizeof(int32_t), HISTOGRAM_BINS,
m_analysisFileIn, &m_curYUVHist[0]);
-        if (m_param->internalCsp != X265_CSP_I400)
-        {
-            X265_FREAD(&analysis->yuvHist[1], sizeof(int32_t),
HISTOGRAM_BINS, m_analysisFileIn, &m_curYUVHist[1]);
-            X265_FREAD(&analysis->yuvHist[2], sizeof(int32_t),
HISTOGRAM_BINS, m_analysisFileIn, &m_curYUVHist[2]);
-        }
-    }
     X265_FREAD(&analysis->satdCost, sizeof(int64_t), 1, m_analysisFileIn,
&(picData->satdCost));
     X265_FREAD(&analysis->numCUsInFrame, sizeof(int), 1, m_analysisFileIn,
&(picData->numCUsInFrame));
     X265_FREAD(&analysis->numPartitions, sizeof(int), 1, m_analysisFileIn,
&(picData->numPartitions));
@@ -5731,6 +5355,7 @@ void
Encoder::computeDistortionOffset(x265_analysis_data* analysis)
             distortionData->highDistortionCtuCount++;
     }
 }
+
 void Encoder::readAnalysisFile(x265_analysis_data* analysis, int curPoc,
int sliceType)
 {

@@ -5880,17 +5505,6 @@ void Encoder::writeAnalysisFile(x265_analysis_data*
analysis, FrameData &curEncD
     /* calculate frameRecordSize */
     analysis->frameRecordSize = sizeof(analysis->frameRecordSize) +
sizeof(depthBytes) + sizeof(analysis->poc) + sizeof(analysis->sliceType) +
                       sizeof(analysis->numCUsInFrame) +
sizeof(analysis->numPartitions) + sizeof(analysis->bScenecut) +
sizeof(analysis->satdCost);
-    if (m_param->bHistBasedSceneCut)
-    {
-        analysis->frameRecordSize += sizeof(analysis->edgeHist);
-        analysis->frameRecordSize += sizeof(int32_t) * HISTOGRAM_BINS;
-        if (m_param->internalCsp != X265_CSP_I400)
-        {
-            analysis->frameRecordSize += sizeof(int32_t) * HISTOGRAM_BINS;
-            analysis->frameRecordSize += sizeof(int32_t) * HISTOGRAM_BINS;
-        }
-    }
-
     if (analysis->sliceType > X265_TYPE_I)
     {
         numDir = (analysis->sliceType == X265_TYPE_P) ? 1 : 2;
@@ -6035,17 +5649,6 @@ void Encoder::writeAnalysisFile(x265_analysis_data*
analysis, FrameData &curEncD
     X265_FWRITE(&analysis->poc, sizeof(int), 1, m_analysisFileOut);
     X265_FWRITE(&analysis->sliceType, sizeof(int), 1, m_analysisFileOut);
     X265_FWRITE(&analysis->bScenecut, sizeof(int), 1, m_analysisFileOut);
-    if (m_param->bHistBasedSceneCut)
-    {
-        X265_FWRITE(&analysis->edgeHist, sizeof(int32_t), EDGE_BINS,
m_analysisFileOut);
-        X265_FWRITE(&analysis->yuvHist[0], sizeof(int32_t),
HISTOGRAM_BINS, m_analysisFileOut);
-        if (m_param->internalCsp != X265_CSP_I400)
-        {
-            X265_FWRITE(&analysis->yuvHist[1], sizeof(int32_t),
HISTOGRAM_BINS, m_analysisFileOut);
-            X265_FWRITE(&analysis->yuvHist[2], sizeof(int32_t),
HISTOGRAM_BINS, m_analysisFileOut);
-        }
-    }
-
     X265_FWRITE(&analysis->satdCost, sizeof(int64_t), 1,
m_analysisFileOut);
     X265_FWRITE(&analysis->numCUsInFrame, sizeof(int), 1,
m_analysisFileOut);
     X265_FWRITE(&analysis->numPartitions, sizeof(int), 1,
m_analysisFileOut);
diff --git a/source/encoder/encoder.h b/source/encoder/encoder.h
index 669154da3..06a01e21c 100644
--- a/source/encoder/encoder.h
+++ b/source/encoder/encoder.h
@@ -257,19 +257,6 @@ public:
     int                m_bToneMap; // Enables tone-mapping
     int                m_enableNal;

-    /* For histogram based scene-cut detection */
-    pixel*             m_edgePic;
-    pixel*             m_inputPic[3];
-    int32_t            m_curYUVHist[3][HISTOGRAM_BINS];
-    int32_t            m_prevYUVHist[3][HISTOGRAM_BINS];
-    int32_t            m_curEdgeHist[2];
-    int32_t            m_prevEdgeHist[2];
-    uint32_t           m_planeSizes[3];
-    double             m_edgeHistThreshold;
-    double             m_chromaHistThreshold;
-    double             m_scaledEdgeThreshold;
-    double             m_scaledChromaThreshold;
-
 #ifdef ENABLE_HDR10_PLUS
     const hdr10plus_api     *m_hdr10plus_api;
     uint8_t                 **m_cim;
@@ -379,11 +366,6 @@ public:

     void copyPicture(x265_picture *dest, const x265_picture *src);

-    bool computeHistograms(x265_picture *pic);
-    void computeHistogramSAD(double *maxUVNormalizedSAD, double
*edgeNormalizedSAD, int curPoc);
-    double normalizeRange(int32_t value, int32_t minValue, int32_t
maxValue, double rangeStart, double rangeEnd);
-    void findSceneCuts(x265_picture *pic, bool& bDup, double
m_maxUVSADVal, double m_edgeSADVal, bool& isMaxThres, bool& isHardSC);
-
     void initRefIdx();
     void analyseRefIdx(int *numRefIdx);
     void updateRefIdx();
diff --git a/source/encoder/frameencoder.cpp
b/source/encoder/frameencoder.cpp
index 6f567b9cf..1ce0d393c 100644
--- a/source/encoder/frameencoder.cpp
+++ b/source/encoder/frameencoder.cpp
@@ -471,7 +471,7 @@ void FrameEncoder::compressFrame()
     m_ssimCnt = 0;
     memset(&(m_frame->m_encData->m_frameStats), 0,
sizeof(m_frame->m_encData->m_frameStats));

-    if (!m_param->bHistBasedSceneCut && m_param->rc.aqMode != X265_AQ_EDGE
&& m_param->recursionSkipMode == EDGE_BASED_RSKIP)
+    if (m_param->rc.aqMode != X265_AQ_EDGE && m_param->recursionSkipMode
== EDGE_BASED_RSKIP)
     {
         int height = m_frame->m_fencPic->m_picHeight;
         int width = m_frame->m_fencPic->m_picWidth;
diff --git a/source/encoder/slicetype.cpp b/source/encoder/slicetype.cpp
index ae908e626..1ff5abcc8 100644
--- a/source/encoder/slicetype.cpp
+++ b/source/encoder/slicetype.cpp
@@ -519,7 +519,7 @@ void LookaheadTLD::calcAdaptiveQuantFrame(Frame
*curFrame, x265_param* param)
                 if (curFrame->m_frameSegment == X265_AQ_EDGE )
                     edgeFilter(curFrame, param);

-                if (curFrame->m_frameSegment == X265_AQ_EDGE  &&
!param->bHistBasedSceneCut && param->recursionSkipMode == EDGE_BASED_RSKIP)
+                if (curFrame->m_frameSegment == X265_AQ_EDGE &&
param->recursionSkipMode == EDGE_BASED_RSKIP)
                 {
                     pixel* src = curFrame->m_edgePic +
curFrame->m_fencPic->m_lumaMarginY * curFrame->m_fencPic->m_stride +
curFrame->m_fencPic->m_lumaMarginX;
                     primitives.planecopy_pp_shr(src,
curFrame->m_fencPic->m_stride, curFrame->m_edgeBitPic,
@@ -1050,7 +1050,6 @@ Lookahead::Lookahead(x265_param *param, ThreadPool*
pool)
     m_countPreLookahead = 0;
 #endif

-    memset(m_histogram, 0, sizeof(m_histogram));
 }

 #if DETAILED_CU_STATS
@@ -1098,6 +1097,7 @@ void Lookahead::stopJobs()
             m_pool[i].stopWorkers();
     }
 }
+
 void Lookahead::destroy()
 {
     // these two queues will be empty unless the encode was aborted
@@ -1571,7 +1571,7 @@ void Lookahead::slicetypeDecide()
          m_param->rc.cuTree || m_param->scenecutThreshold ||
m_param->bHistBasedSceneCut ||
          (m_param->lookaheadDepth && m_param->rc.vbvBufferSize)))
     {
-        if(!m_param->rc.bStatRead)
+        if (!m_param->rc.bStatRead)
             slicetypeAnalyse(frames, false);
         bool bIsVbv = m_param->rc.vbvBufferSize > 0 &&
m_param->rc.vbvMaxBitrate > 0;
         if ((m_param->analysisLoad && m_param->scaleFactor && bIsVbv) ||
m_param->bliveVBV2pass)
@@ -1652,12 +1652,9 @@ void Lookahead::slicetypeDecide()
             }
             if (frm.sliceType == X265_TYPE_IDR && frm.bScenecut &&
isClosedGopRadl)
             {
-                if (!m_param->bHistBasedSceneCut ||
(m_param->bHistBasedSceneCut && frm.m_bIsHardScenecut))
-                {
-                    for (int i = bframes; i < bframes + m_param->radl; i++)
-                        list[i]->m_lowres.sliceType = X265_TYPE_B;
-                    list[(bframes + m_param->radl)]->m_lowres.sliceType =
X265_TYPE_IDR;
-                }
+                for (int i = bframes; i < bframes + m_param->radl; i++)
+                    list[i]->m_lowres.sliceType = X265_TYPE_B;
+                list[(bframes + m_param->radl)]->m_lowres.sliceType =
X265_TYPE_IDR;
             }
             if (frm.sliceType == X265_TYPE_IDR)
             {
@@ -1722,7 +1719,6 @@ void Lookahead::slicetypeDecide()
         list[bframes - 1]->m_lowres.bLastMiniGopBFrame = true;
     list[bframes]->m_lowres.leadingBframes = bframes;
     m_lastNonB = &list[bframes]->m_lowres;
-    m_histogram[bframes]++;

     /* insert a bref into the sequence */
     if (m_param->bBPyramid && bframes > 1 && !brefs)
@@ -2082,46 +2078,10 @@ void Lookahead::slicetypeAnalyse(Lowres **frames,
bool bKeyframe)
     int numAnalyzed = numFrames;
     bool isScenecut = false;

-    /* Temporal computations for scenecut detection */
-    if (m_param->bHistBasedSceneCut && m_param->bEnableTradScdInHscd)
-    {
-        for (int i = numFrames - 1; i > 0; i--)
-        {
-            if (frames[i]->interPCostPercDiff > 0.0)
-                continue;
-            int64_t interCost = frames[i]->costEst[1][0];
-            int64_t intraCost = frames[i]->costEst[0][0];
-            if (interCost < 0 || intraCost < 0)
-                continue;
-            int times = 0;
-            double averagePcost = 0.0, averageIcost = 0.0;
-            for (int j = i - 1; j >= 0 && times < 5; j--, times++)
-            {
-                if (frames[j]->costEst[0][0] > 0 &&
frames[j]->costEst[1][0] > 0)
-                {
-                    averageIcost += frames[j]->costEst[0][0];
-                    averagePcost += frames[j]->costEst[1][0];
-                }
-                else
-                    times--;
-            }
-            if (times)
-            {
-                averageIcost = averageIcost / times;
-                averagePcost = averagePcost / times;
-                frames[i]->interPCostPercDiff = abs(interCost -
averagePcost) / X265_MIN(interCost, averagePcost) * 100;
-                frames[i]->intraCostPercDiff = abs(intraCost -
averageIcost) / X265_MIN(intraCost, averageIcost) * 100;
-            }
-        }
-    }
+    isScenecut = scenecut(frames, 0, 1, true, origNumFrames);

     /* When scenecut threshold is set, use scenecut detection for I frame
placements */
-    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))
+    if (m_param->scenecutThreshold && isScenecut)
     {
         frames[1]->sliceType = X265_TYPE_I;
         return;
@@ -2132,17 +2092,13 @@ void Lookahead::slicetypeAnalyse(Lowres **frames,
bool bKeyframe)
         m_extendGopBoundary = false;
         for (int i = m_param->bframes + 1; i < origNumFrames; i +=
m_param->bframes + 1)
         {
-            if (!m_param->bHistBasedSceneCut ||
(m_param->bHistBasedSceneCut && m_param->bEnableTradScdInHscd && frames[i +
1]->bScenecut))
-                scenecut(frames, i, i + 1, true, origNumFrames);
+            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)
+                if (frames[j]->bScenecut && scenecutInternal(frames, j -
1, j, true))
                 {
-                    if (m_param->bEnableTradScdInHscd)
-                        m_extendGopBoundary = scenecutInternal(frames, j -
1, j, true);
-                    else
-                        m_extendGopBoundary = true;
+                    m_extendGopBoundary = true;
                     break;
                 }
             }
@@ -2249,10 +2205,8 @@ void Lookahead::slicetypeAnalyse(Lowres **frames,
bool bKeyframe)
         {
             for (int j = 1; j < numBFrames + 1; j++)
             {
-                bool isNextScenecut = false;
-                if (!m_param->bHistBasedSceneCut ||
(m_param->bHistBasedSceneCut && frames[j + 1]->bScenecut))
-                    isNextScenecut = scenecut(frames, j, j + 1, false,
origNumFrames);
-                if (isNextScenecut || (bForceRADL && frames[j]->frameNum
== preRADL))
+                if (scenecut(frames, j, j + 1, false, origNumFrames) ||
+                    (bForceRADL && (frames[j]->frameNum == preRADL)))
                 {
                     frames[j]->sliceType = X265_TYPE_P;
                     numAnalyzed = j;
@@ -2318,9 +2272,10 @@ bool Lookahead::scenecut(Lowres **frames, int p0,
int p1, bool bRealScenecut, in
         /* Where A and B are scenes: AAAAAABBBAAAAAA
          * If BBB is shorter than (maxp1-p0), it is detected as a flash
          * and not considered a scenecut. */
+
         for (int cp1 = p1; cp1 <= maxp1; cp1++)
         {
-            if (!scenecutInternal(frames, p0, cp1, false) &&
!m_param->bHistBasedSceneCut)
+            if (!scenecutInternal(frames, p0, cp1, false))
             {
                 /* Any frame in between p0 and cur_p1 cannot be a real
scenecut. */
                 for (int i = cp1; i > p0; i--)
@@ -2329,7 +2284,7 @@ bool Lookahead::scenecut(Lowres **frames, int p0, int
p1, bool bRealScenecut, in
                     noScenecuts = false;
                 }
             }
-            else if ((m_param->bHistBasedSceneCut &&
frames[cp1]->m_bIsMaxThres) || scenecutInternal(frames, cp1 - 1, cp1,
false))
+            else if (scenecutInternal(frames, cp1 - 1, cp1, false))
             {
                 /* If current frame is a Scenecut from p0 frame as well as
Scenecut from
                  * preceeding frame, mark it as a Scenecut */
@@ -2390,9 +2345,6 @@ bool Lookahead::scenecut(Lowres **frames, int p0, int
p1, bool bRealScenecut, in

     if (!frames[p1]->bScenecut)
         return false;
-    /* Check only scene transitions if max threshold */
-    if (m_param->bHistBasedSceneCut && frames[p1]->m_bIsMaxThres)
-        return frames[p1]->bScenecut;

     return scenecutInternal(frames, p0, p1, bRealScenecut);
 }
@@ -2410,19 +2362,8 @@ bool Lookahead::scenecutInternal(Lowres **frames,
int p0, int p1, bool bRealScen
     /* magic numbers pulled out of thin air */
     float threshMin = (float)(threshMax * 0.25);
     double bias = m_param->scenecutBias;
-    if (m_param->bHistBasedSceneCut)
-    {
-        double minT = TEMPORAL_SCENECUT_THRESHOLD * (1 +
m_param->edgeTransitionThreshold);
-        if (frame->interPCostPercDiff > minT || frame->intraCostPercDiff >
minT)
-        {
-            if (bRealScenecut && frame->bScenecut)
-                x265_log(m_param, X265_LOG_DEBUG, "scene cut at %d \n",
frame->frameNum);
-            return frame->bScenecut;
-        }
-        else
-            return false;
-    }
-    else if (bRealScenecut)
+
+    if (bRealScenecut)
     {
         if (m_param->keyframeMin == m_param->keyframeMax)
             threshMin = threshMax;
@@ -2479,7 +2420,7 @@ void Lookahead::slicetypePath(Lowres **frames, int
length, char(*best_paths)[X26
 }

 // Find slicetype of the frame with poc # in lookahead buffer
-int Lookahead::FindSliceType(int poc)
+int Lookahead::findSliceType(int poc)
 {
     int out_slicetype = X265_TYPE_AUTO;
     if (m_filled)
diff --git a/source/encoder/slicetype.h b/source/encoder/slicetype.h
index 52b55a4a8..490e7ba1a 100644
--- a/source/encoder/slicetype.h
+++ b/source/encoder/slicetype.h
@@ -124,7 +124,6 @@ public:

     /* pre-lookahead */
     int           m_fullQueueSize;
-    int           m_histogram[X265_BFRAME_MAX + 1];
     int           m_lastKeyframe;
     int           m_8x8Width;
     int           m_8x8Height;
@@ -174,7 +173,7 @@ public:

     void    getEstimatedPictureCost(Frame *pic);
     void    setLookaheadQueue();
-    int FindSliceType(int poc);
+    int     findSliceType(int poc);

 protected:

diff --git a/source/x265.h b/source/x265.h
index e0be6a25a..4f1c52d56 100644
--- a/source/x265.h
+++ b/source/x265.h
@@ -1895,12 +1895,6 @@ typedef struct x265_param
     /* The offset by which QP is incremented for non-referenced
inter-frames after a scenecut when bEnableSceneCutAwareQp is 1 or 3. */
     double    fwdNonRefQpDelta;

-    /* A genuine threshold used for histogram based scene cut detection.
-     * This threshold determines whether a frame is a scenecut or not
-     * when compared against the edge and chroma histogram sad values.
-     * Default 0.03. Range: Real number in the interval (0,1). */
-    double    edgeTransitionThreshold;
-
     /* Enables histogram based scenecut detection algorithm to detect
scenecuts. Default disabled */
     int       bHistBasedSceneCut;

@@ -1990,10 +1984,6 @@ typedef struct x265_param
      * 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;
-
     /* Film Grain Characteristic file */
     char* filmGrain;

diff --git a/source/x265cli.cpp b/source/x265cli.cpp
index d7e6e95c1..54479ef2f 100755
--- a/source/x265cli.cpp
+++ b/source/x265cli.cpp
@@ -174,7 +174,6 @@ namespace X265_NS {
         H1("   --scenecut-bias <0..100.0>    Bias for scenecut detection.
Default %.2f\n", param->scenecutBias);
         H0("   --hist-scenecut               Enables histogram based
scene-cut detection using histogram based algorithm.\n");
         H0("   --no-hist-scenecut            Disables histogram based
scene-cut detection using histogram based algorithm.\n");
-        H1("   --hist-threshold <0.0..1.0>   Luma Edge histogram's
Normalized SAD threshold for histogram based scenecut detection Default
%.2f\n", param->edgeTransitionThreshold);
         H0("   --[no-]fades                  Enable detection and handling
of fade-in regions. Default %s\n", OPT(param->bEnableFades));
         H1("   --scenecut-aware-qp <0..3>    Enable increasing QP for
frames inside the scenecut window around scenecut. Default %s\n",
OPT(param->bEnableSceneCutAwareQp));
         H1("                                 0 - Disabled\n");
diff --git a/source/x265cli.h b/source/x265cli.h
index 84c3adf25..eea47f168 100644
--- a/source/x265cli.h
+++ b/source/x265cli.h
@@ -143,9 +143,6 @@ static const struct option long_options[] =
     { "scenecut-bias",  required_argument, NULL, 0 },
     { "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 },
-- 
2.37.2.windows.2

*Thanks and Regards,*





*Snehaa.GVideo Codec Engineer,Media & AI analytics
<https://multicorewareinc.com/>*
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20221102/2d3f813f/attachment-0001.htm>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: release_scene_cut_patch_01.diff
Type: application/octet-stream
Size: 52105 bytes
Desc: not available
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20221102/2d3f813f/attachment-0001.obj>


More information about the x265-devel mailing list