[x265] [PATCH 1/3] Remove existing histogram based scene change algorithm
Snehaa Giridharan
snehaa at multicorewareinc.com
Wed Nov 2 08:17:04 UTC 2022
>From f95697a7dac4f59581ec1fe0bbb2e7ff32722889 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
---
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.34.1.windows.1
*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/fef97a63/attachment-0001.htm>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: release_scene_cut_patch_01.diff
Type: application/octet-stream
Size: 52042 bytes
Desc: not available
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20221102/fef97a63/attachment-0001.obj>
More information about the x265-devel
mailing list