[x265] [PATCH] Disable fall-back on traditional scenecut algorithm with --hist-scenecut
Pooja Venkatesan
pooja at multicorewareinc.com
Thu Jun 24 08:47:48 UTC 2021
>From f6c1b86d99ab3a0dd57204f930e526a07e28fed7 Mon Sep 17 00:00:00 2001
From: Praveen Karadugattu <praveenkumar at multicorewareinc.com>
Date: Sun, 20 Jun 2021 21:20:50 +0530
Subject: [PATCH] Disable fall-back on traditional scenecut algorithm with
--hist-scenecut
---
doc/reST/cli.rst | 9 +++++++--
source/CMakeLists.txt | 2 +-
source/common/param.cpp | 8 +++++++-
source/encoder/encoder.cpp | 17 ++++++++++++-----
source/encoder/slicetype.cpp | 15 ++++++++++-----
source/test/regression-tests.txt | 1 +
source/x265.h | 4 ++++
source/x265cli.h | 1 +
8 files changed, 43 insertions(+), 14 deletions(-)
diff --git a/doc/reST/cli.rst b/doc/reST/cli.rst
index 4154221af..280b734b3 100755
--- a/doc/reST/cli.rst
+++ b/doc/reST/cli.rst
@@ -1470,7 +1470,8 @@ Slice decision options
.. option:: --hist-scenecut, --no-hist-scenecut
Indicates that scenecuts need to be detected using luma edge and chroma
histograms.
- :option:`--hist-scenecut` enables scenecut detection using the histograms
and disables the default scene cut algorithm.
+ :option:`--hist-scenecut` enables scenecut detection using the histograms.
+ It also uses the intra and inter cost info to arrive at a scenecut
decision from the default scenecut method.
:option:`--no-hist-scenecut` disables histogram based scenecut algorithm.
.. option:: --hist-threshold <0.0..1.0>
@@ -1480,7 +1481,11 @@ Slice decision options
greater than 0.2 against the previous frame as scenecut.
Increasing the threshold reduces the number of scenecuts detected.
Default 0.03.
-
+
+.. option:: --disable-traditional-scenecut
+
+ Indicates that the usage of traditional scenecut detection using intra
and inter cost should be disabled when :option:`--hist-scenecut` is used.
+
.. option:: --radl <integer>
Number of RADL pictures allowed infront of IDR. Requires closed gop
interval.
diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt
index b4e57b592..f4a9cb793 100755
--- a/source/CMakeLists.txt
+++ b/source/CMakeLists.txt
@@ -29,7 +29,7 @@ option(NATIVE_BUILD "Target the build CPU" OFF)
option(STATIC_LINK_CRT "Statically link C runtime for release builds" OFF)
mark_as_advanced(FPROFILE_USE FPROFILE_GENERATE NATIVE_BUILD)
# X265_BUILD must be incremented each time the public API is changed
-set(X265_BUILD 200)
+set(X265_BUILD 201)
configure_file("${PROJECT_SOURCE_DIR}/x265.def.in"
"${PROJECT_BINARY_DIR}/x265.def")
configure_file("${PROJECT_SOURCE_DIR}/x265_config.h.in"
diff --git a/source/common/param.cpp b/source/common/param.cpp
index 8a27aaef3..3b84415c3 100755
--- a/source/common/param.cpp
+++ b/source/common/param.cpp
@@ -172,6 +172,7 @@ void x265_param_default(x265_param* param)
param->scenecutThreshold = 40; /* Magic number pulled in from x264 */
param->edgeTransitionThreshold = 0.03;
param->bHistBasedSceneCut = 0;
+ param->bDisableTradScdInHscd = 0;
param->lookaheadSlices = 8;
param->lookaheadThreads = 0;
param->scenecutBias = 5.0;
@@ -598,6 +599,7 @@ int x265_param_default_preset(x265_param* param, const
char* preset, const char*
param->lookaheadDepth = 0;
param->scenecutThreshold = 0;
param->bHistBasedSceneCut = 0;
+ param->bDisableTradScdInHscd = 0;
param->rc.cuTree = 0;
param->frameNumThreads = 1;
}
@@ -953,6 +955,7 @@ int x265_param_parse(x265_param* p, const char* name,
const char* value)
bError = false;
p->scenecutThreshold = atoi(value);
p->bHistBasedSceneCut = 0;
+ p->bDisableTradScdInHscd = 0;
}
}
OPT("temporal-layers") p->bEnableTemporalSubLayers = atobool(value);
@@ -1234,6 +1237,7 @@ int x265_param_parse(x265_param* p, const char* name,
const char* value)
}
}
OPT("hist-threshold") p->edgeTransitionThreshold = atof(value);
+ OPT("disable-traditional-scenecut") p->bDisableTradScdInHscd =
atobool(value);
OPT("rskip-edge-threshold") p->edgeVarThreshold =
atoi(value)/100.0f;
OPT("lookahead-threads") p->lookaheadThreads = atoi(value);
OPT("opt-cu-delta-qp") p->bOptCUDeltaQP = atobool(value);
@@ -2151,7 +2155,8 @@ char *x265_param2string(x265_param* p, int padx, int
pady)
s += sprintf(s, " rc-lookahead=%d", p->lookaheadDepth);
s += sprintf(s, " lookahead-slices=%d", p->lookaheadSlices);
s += sprintf(s, " scenecut=%d", p->scenecutThreshold);
- s += sprintf(s, " hist-scenecut=%d", p->bHistBasedSceneCut);
+ BOOL(p->bHistBasedSceneCut, "hist-scenecut");
+ BOOL(p->bDisableTradScdInHscd, "disable-traditional-scenecut");
s += sprintf(s, " radl=%d", p->radl);
BOOL(p->bEnableHRDConcatFlag, "splice");
BOOL(p->bIntraRefresh, "intra-refresh");
@@ -2467,6 +2472,7 @@ void x265_copy_params(x265_param* dst, x265_param*
src)
dst->lookaheadThreads = src->lookaheadThreads;
dst->scenecutThreshold = src->scenecutThreshold;
dst->bHistBasedSceneCut = src->bHistBasedSceneCut;
+ dst->bDisableTradScdInHscd = src->bDisableTradScdInHscd;
dst->bIntraRefresh = src->bIntraRefresh;
dst->maxCUSize = src->maxCUSize;
dst->minCUSize = src->minCUSize;
diff --git a/source/encoder/encoder.cpp b/source/encoder/encoder.cpp
index c1e1cb46d..dfb872889 100644
--- a/source/encoder/encoder.cpp
+++ b/source/encoder/encoder.cpp
@@ -3680,6 +3680,7 @@ void Encoder::configure(x265_param *p)
p->keyframeMax = INT_MAX;
p->scenecutThreshold = 0;
p->bHistBasedSceneCut = 0;
+ p->bDisableTradScdInHscd = 0;
}
else if (p->keyframeMax <= 1)
{
@@ -3694,6 +3695,7 @@ void Encoder::configure(x265_param *p)
p->bframes = 0;
p->scenecutThreshold = 0;
p->bHistBasedSceneCut = 0;
+ p->bDisableTradScdInHscd = 0;
p->bFrameAdaptive = 0;
p->rc.cuTree = 0;
p->bEnableWeightedPred = 0;
@@ -4421,12 +4423,17 @@ void Encoder::configure(x265_param *p)
m_param->searchRange = m_param->hmeRange[2];
}
- if (p->bHistBasedSceneCut && !p->edgeTransitionThreshold)
- {
- p->edgeTransitionThreshold = 0.03;
- x265_log(p, X265_LOG_WARNING, "using default threshold %.2lf for
scene cut detection\n", p->edgeTransitionThreshold);
- }
+ if (p->bHistBasedSceneCut && !p->edgeTransitionThreshold)
+ {
+ p->edgeTransitionThreshold = 0.03;
+ x265_log(p, X265_LOG_WARNING, "using default threshold %.2lf for
scene cut detection.\n", p->edgeTransitionThreshold);
+ }
+ if (!p->bHistBasedSceneCut && p->bDisableTradScdInHscd)
+ {
+ p->bDisableTradScdInHscd = 0;
+ x265_log(p, X265_LOG_WARNING, "option
--disable-traditional-scenecut requires --hist-scenecut to be enabled.\n");
+ }
}
void Encoder::readAnalysisFile(x265_analysis_data* analysis, int curPoc,
const x265_picture* picIn, int paramBytes)
diff --git a/source/encoder/slicetype.cpp b/source/encoder/slicetype.cpp
index 0adb0d0db..ace3b5469 100644
--- a/source/encoder/slicetype.cpp
+++ b/source/encoder/slicetype.cpp
@@ -2014,7 +2014,7 @@ void Lookahead::slicetypeAnalyse(Lowres **frames,
bool bKeyframe)
bool isScenecut = false;
/* Temporal computations for scenecut detection */
- if (m_param->bHistBasedSceneCut)
+ if (m_param->bHistBasedSceneCut && !m_param->bDisableTradScdInHscd)
{
for (int i = numFrames - 1; i > 0; i--)
{
@@ -2047,8 +2047,10 @@ void Lookahead::slicetypeAnalyse(Lowres **frames,
bool bKeyframe)
}
/* When scenecut threshold is set, use scenecut detection for I frame
placements */
- if (!m_param->bHistBasedSceneCut || (m_param->bHistBasedSceneCut &&
frames[1]->bScenecut))
+ if (!m_param->bHistBasedSceneCut || (m_param->bHistBasedSceneCut &&
!m_param->bDisableTradScdInHscd && frames[1]->bScenecut))
isScenecut = scenecut(frames, 0, 1, true, origNumFrames);
+ else if (m_param->bHistBasedSceneCut && frames[1]->bScenecut)
+ isScenecut = true;
if (isScenecut && (m_param->bHistBasedSceneCut ||
m_param->scenecutThreshold))
{
@@ -2061,14 +2063,17 @@ void Lookahead::slicetypeAnalyse(Lowres **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 && frames[i + 1]->bScenecut))
+ if (!m_param->bHistBasedSceneCut ||
(m_param->bHistBasedSceneCut && !m_param->bDisableTradScdInHscd && frames[i
+ 1]->bScenecut))
scenecut(frames, i, i + 1, true, origNumFrames);
for (int j = i + 1; j <= X265_MIN(i + m_param->bframes + 1,
origNumFrames); j++)
{
- if (frames[j]->bScenecut && scenecutInternal(frames, j -
1, j, true))
+ if (frames[j]->bScenecut)
{
- m_extendGopBoundary = true;
+ if (!m_param->bDisableTradScdInHscd)
+ m_extendGopBoundary = scenecutInternal(frames, j -
1, j, true);
+ else
+ m_extendGopBoundary = true;
break;
}
}
diff --git a/source/test/regression-tests.txt
b/source/test/regression-tests.txt
index 971c854df..828157cab 100644
--- a/source/test/regression-tests.txt
+++ b/source/test/regression-tests.txt
@@ -160,6 +160,7 @@ Traffic_4096x2048_30p.y4m, --preset medium --frame-dup
--dup-threshold 60 --hrd
Kimono1_1920x1080_24_400.yuv,--preset superfast --qp 28 --zones 0,139,q=32
sintel_trailer_2k_1920x1080_24.yuv, --preset medium --hist-scenecut
--hist-threshold 0.02 --frame-dup --dup-threshold 60 --hrd --bitrate 10000
--vbv-bufsize 15000 --vbv-maxrate 12000
sintel_trailer_2k_1920x1080_24.yuv, --preset medium --hist-scenecut
--hist-threshold 0.02
+sintel_trailer_2k_1920x1080_24.yuv, --preset medium --hist-scenecut
--hist-threshold 0.02 --disable-traditional-scenecut
sintel_trailer_2k_1920x1080_24.yuv, --preset ultrafast --hist-scenecut
--hist-threshold 0.02
crowd_run_1920x1080_50.yuv, --preset faster --ctu 32 --rskip 2
--rskip-edge-threshold 5
crowd_run_1920x1080_50.yuv, --preset fast --ctu 64 --rskip 2
--rskip-edge-threshold 5 --aq-mode 4
diff --git a/source/x265.h b/source/x265.h
index 324f3163f..3a65fdda6 100644
--- a/source/x265.h
+++ b/source/x265.h
@@ -1963,6 +1963,10 @@ typedef struct x265_param
/* Flag indicating whether the encoder should emit an End of Sequence
* NAL at the end of every Coded Video Sequence. Default false */
int bEnableEndOfSequence;
+
+ /* Flag to turn off traditional scenecut detection in histogram based
scenecut detection so that
+ * only spatial properties are used for scenecut detection. Default
false */
+ int bDisableTradScdInHscd;
} x265_param;
/* x265_param_alloc:
diff --git a/source/x265cli.h b/source/x265cli.h
index 46a2b68ae..86136fbfb 100644
--- a/source/x265cli.h
+++ b/source/x265cli.h
@@ -144,6 +144,7 @@ static const struct option long_options[] =
{ "hist-scenecut", no_argument, NULL, 0},
{ "no-hist-scenecut", no_argument, NULL, 0},
{ "hist-threshold", required_argument, NULL, 0},
+ { "disable-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.24.0.windows.2
Regards,
*Pooja Venkatesan*,
Video Codec Engineer,
Media & AI analytics BU
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20210624/e898490c/attachment-0001.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: disable-trad-scenecutHSCD.diff
Type: application/octet-stream
Size: 11603 bytes
Desc: not available
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20210624/e898490c/attachment-0001.obj>
More information about the x265-devel
mailing list