Skip to content

Instantly share code, notes, and snippets.

@noizuy
Last active October 21, 2022 15:05
Show Gist options
  • Save noizuy/909ceff9230a24e54073837aaa09e9f7 to your computer and use it in GitHub Desktop.
Save noizuy/909ceff9230a24e54073837aaa09e9f7 to your computer and use it in GitHub Desktop.
At high resolutions, AQ modes 4 & 5 show a significant speed reduction. This option (--aq-fast-edge) allows the user to omit the 5x5 Gaussian blur applied before edge detection is performed, slightly improving encode speed. Goes on top of the AQ mode 5 patch.
From 534154762b267f7a8e16620b530de2b18026c5e3 Mon Sep 17 00:00:00 2001
From: noizuy <85082087+noizuy@users.noreply.github.com>
Date: Mon, 26 Sep 2022 12:46:29 +0200
Subject: [PATCH] add AQ fast edge option At high resolutions, AQ modes 4 & 5
show a significant speed reduction. This option allows the user to omit the
5x5 Gaussian blur applied before edge detection is performed, slightly
improving encode speed.
---
doc/reST/cli.rst | 4 +++
source/common/param.cpp | 5 ++++
source/encoder/slicetype.cpp | 51 +++++++++++++++++++-----------------
source/x265.h | 3 +++
source/x265cli.cpp | 1 +
source/x265cli.h | 1 +
6 files changed, 41 insertions(+), 24 deletions(-)
diff --git a/doc/reST/cli.rst b/doc/reST/cli.rst
index 23f2d4a83..ab399cd18 100755
--- a/doc/reST/cli.rst
+++ b/doc/reST/cli.rst
@@ -1774,6 +1774,10 @@ Quality, rate control and rate distortion options
their unbiased counterparts (2 and 4).
Default 1.0.
+.. option:: --aq-fast-edge
+
+ Disable Gaussian blur in AQ modes 4 & 5 for minor speed improvements.
+
.. option:: --hevc-aq
Enable adaptive quantization
diff --git a/source/common/param.cpp b/source/common/param.cpp
index b58c84aeb..70af0d9ac 100755
--- a/source/common/param.cpp
+++ b/source/common/param.cpp
@@ -273,6 +273,7 @@ void x265_param_default(x265_param* param)
param->rc.qgSize = 32;
param->rc.aqStrength = 1.0;
param->rc.aqBiasStrength = 1.0;
+ param->rc.aqFastEdge = 0;
param->rc.qpAdaptationRange = 1.0;
param->rc.cuTree = 1;
param->rc.rfConstantMax = 0;
@@ -750,6 +751,7 @@ int x265_zone_param_parse(x265_param* p, const char* name, const char* value)
OPT("aq-mode") p->rc.aqMode = atoi(value);
OPT("aq-strength") p->rc.aqStrength = atof(value);
OPT("aq-bias-strength") p->rc.aqBiasStrength = atof(value);
+ OPT("aq-fast-edge") p->rc.aqFastEdge = atobool(value);
OPT("nr-intra") p->noiseReductionIntra = atoi(value);
OPT("nr-inter") p->noiseReductionInter = atoi(value);
OPT("limit-modes") p->limitModes = atobool(value);
@@ -1446,6 +1448,7 @@ int x265_param_parse(x265_param* p, const char* name, const char* value)
OPT("min-vbv-fullness") p->minVbvFullness = atof(value);
OPT("max-vbv-fullness") p->maxVbvFullness = atof(value);
OPT("aq-bias-strength") p->rc.aqBiasStrength = atof(value);
+ OPT("aq-fast-edge") p->rc.aqFastEdge = atobool(value);
else
return X265_PARAM_BAD_NAME;
}
@@ -2243,6 +2246,7 @@ char *x265_param2string(x265_param* p, int padx, int pady)
s += sprintf(s, " aq-mode=%d", p->rc.aqMode);
s += sprintf(s, " aq-strength=%.2f", p->rc.aqStrength);
s += sprintf(s, " aq-bias-strength=%.2f", p->rc.aqBiasStrength);
+ BOOL(p->rc.aqFastEdge, "aq-fast-edge");
BOOL(p->rc.cuTree, "cutree");
s += sprintf(s, " zone-count=%d", p->rc.zoneCount);
if (p->rc.zoneCount)
@@ -2532,6 +2536,7 @@ void x265_copy_params(x265_param* dst, x265_param* src)
dst->rc.aqMode = src->rc.aqMode;
dst->rc.aqStrength = src->rc.aqStrength;
dst->rc.aqBiasStrength = src->rc.aqBiasStrength;
+ dst->rc.aqFastEdge = src->rc.aqFastEdge;
dst->rc.vbvBufferSize = src->rc.vbvBufferSize;
dst->rc.vbvMaxBitrate = src->rc.vbvMaxBitrate;
diff --git a/source/encoder/slicetype.cpp b/source/encoder/slicetype.cpp
index ccb44d9e8..3572db8e1 100644
--- a/source/encoder/slicetype.cpp
+++ b/source/encoder/slicetype.cpp
@@ -104,7 +104,7 @@ bool computeEdge(pixel* edgePic, pixel* refPic, pixel* edgeTheta, intptr_t strid
float gradientMagnitude = 0;
pixel blackPixel = 0;
- //Applying Sobel filter expect for border pixels
+ //Applying Sobel filter except for border pixels
height = height - startIndex;
width = width - startIndex;
for (int rowNum = startIndex; rowNum < height; rowNum++)
@@ -180,32 +180,35 @@ void edgeFilter(Frame *curFrame, x265_param* param)
edgePic = curFrame->m_edgePic + curFrame->m_fencPic->m_lumaMarginY * stride + curFrame->m_fencPic->m_lumaMarginX;
pixel pixelValue = 0;
- for (int rowNum = 0; rowNum < height; rowNum++)
+ if (!param->rc.aqFastEdge)
{
- for (int colNum = 0; colNum < width; colNum++)
+ for (int rowNum = 0; rowNum < height; rowNum++)
{
- if ((rowNum >= 2) && (colNum >= 2) && (rowNum != height - 2) && (colNum != width - 2)) //Ignoring the border pixels of the picture
+ for (int colNum = 0; colNum < width; colNum++)
{
- /* 5x5 Gaussian filter
- [2 4 5 4 2]
- 1 [4 9 12 9 4]
- --- [5 12 15 12 5]
- 159 [4 9 12 9 4]
- [2 4 5 4 2]*/
-
- const intptr_t rowOne = (rowNum - 2)*stride, colOne = colNum - 2;
- const intptr_t rowTwo = (rowNum - 1)*stride, colTwo = colNum - 1;
- const intptr_t rowThree = rowNum * stride, colThree = colNum;
- const intptr_t rowFour = (rowNum + 1)*stride, colFour = colNum + 1;
- const intptr_t rowFive = (rowNum + 2)*stride, colFive = colNum + 2;
- const intptr_t index = (rowNum*stride) + colNum;
-
- pixelValue = ((2 * src[rowOne + colOne] + 4 * src[rowOne + colTwo] + 5 * src[rowOne + colThree] + 4 * src[rowOne + colFour] + 2 * src[rowOne + colFive] +
- 4 * src[rowTwo + colOne] + 9 * src[rowTwo + colTwo] + 12 * src[rowTwo + colThree] + 9 * src[rowTwo + colFour] + 4 * src[rowTwo + colFive] +
- 5 * src[rowThree + colOne] + 12 * src[rowThree + colTwo] + 15 * src[rowThree + colThree] + 12 * src[rowThree + colFour] + 5 * src[rowThree + colFive] +
- 4 * src[rowFour + colOne] + 9 * src[rowFour + colTwo] + 12 * src[rowFour + colThree] + 9 * src[rowFour + colFour] + 4 * src[rowFour + colFive] +
- 2 * src[rowFive + colOne] + 4 * src[rowFive + colTwo] + 5 * src[rowFive + colThree] + 4 * src[rowFive + colFour] + 2 * src[rowFive + colFive]) / 159);
- refPic[index] = pixelValue;
+ if ((rowNum >= 2) && (colNum >= 2) && (rowNum != height - 2) && (colNum != width - 2)) //Ignoring the border pixels of the picture
+ {
+ /* 5x5 Gaussian filter
+ [2 4 5 4 2]
+ 1 [4 9 12 9 4]
+ --- [5 12 15 12 5]
+ 159 [4 9 12 9 4]
+ [2 4 5 4 2]*/
+
+ const intptr_t rowOne = (rowNum - 2)*stride, colOne = colNum - 2;
+ const intptr_t rowTwo = (rowNum - 1)*stride, colTwo = colNum - 1;
+ const intptr_t rowThree = rowNum * stride, colThree = colNum;
+ const intptr_t rowFour = (rowNum + 1)*stride, colFour = colNum + 1;
+ const intptr_t rowFive = (rowNum + 2)*stride, colFive = colNum + 2;
+ const intptr_t index = (rowNum*stride) + colNum;
+
+ pixelValue = ((2 * src[rowOne + colOne] + 4 * src[rowOne + colTwo] + 5 * src[rowOne + colThree] + 4 * src[rowOne + colFour] + 2 * src[rowOne + colFive] +
+ 4 * src[rowTwo + colOne] + 9 * src[rowTwo + colTwo] + 12 * src[rowTwo + colThree] + 9 * src[rowTwo + colFour] + 4 * src[rowTwo + colFive] +
+ 5 * src[rowThree + colOne] + 12 * src[rowThree + colTwo] + 15 * src[rowThree + colThree] + 12 * src[rowThree + colFour] + 5 * src[rowThree + colFive] +
+ 4 * src[rowFour + colOne] + 9 * src[rowFour + colTwo] + 12 * src[rowFour + colThree] + 9 * src[rowFour + colFour] + 4 * src[rowFour + colFive] +
+ 2 * src[rowFive + colOne] + 4 * src[rowFive + colTwo] + 5 * src[rowFive + colThree] + 4 * src[rowFive + colFour] + 2 * src[rowFive + colFive]) / 159);
+ refPic[index] = pixelValue;
+ }
}
}
}
diff --git a/source/x265.h b/source/x265.h
index 1b59bb2da..463d37090 100644
--- a/source/x265.h
+++ b/source/x265.h
@@ -1409,6 +1409,9 @@ typedef struct x265_param
/* Sets the bias towards dark scenes in AQ modes 3 and 5. */
double aqBiasStrength;
+ /* Disable Gaussian blur in AQ modes 4 & 5. */
+ int aqFastEdge;
+
/* Delta QP range by QP adaptation based on a psycho-visual model.
* Acceptable values between 1.0 to 6.0 */
double qpAdaptationRange;
diff --git a/source/x265cli.cpp b/source/x265cli.cpp
index eb27c1e9f..37d81f049 100755
--- a/source/x265cli.cpp
+++ b/source/x265cli.cpp
@@ -283,6 +283,7 @@ namespace X265_NS {
H0(" --[no-]hevc-aq Mode for HEVC Adaptive Quantization. Default %s\n", OPT(param->rc.hevcAq));
H0(" --aq-strength <float> Reduces blocking and blurring in flat and textured areas (0 to 3.0). Default %.2f\n", param->rc.aqStrength);
H0(" --aq-bias-strength <float> Sets the bias to dark strength in AQ modes 3 and 5. Default %.2f\n", param->rc.aqBiasStrength);
+ H0(" --aq-fast-edge Disables Gaussian blur in AQ modes 4 & 5 edge detection. Default disabled\n", param->rc.aqFastEdge);
H0(" --qp-adaptation-range <float> Delta QP range by QP adaptation based on a psycho-visual model (1.0 to 6.0). Default %.2f\n", param->rc.qpAdaptationRange);
H0(" --[no-]aq-motion Block level QP adaptation based on the relative motion between the block and the frame. Default %s\n", OPT(param->bAQMotion));
H0(" --qg-size <int> Specifies the size of the quantization group (64, 32, 16, 8). Default %d\n", param->rc.qgSize);
diff --git a/source/x265cli.h b/source/x265cli.h
index d45bbbddc..97d31adcc 100644
--- a/source/x265cli.h
+++ b/source/x265cli.h
@@ -185,6 +185,7 @@ static const struct option long_options[] =
{ "aq-mode", required_argument, NULL, 0 },
{ "aq-strength", required_argument, NULL, 0 },
{ "aq-bias-strength", required_argument, NULL, 0 },
+ { "aq-fast-edge", no_argument, NULL, 0 },
{ "rc-grain", no_argument, NULL, 0 },
{ "no-rc-grain", no_argument, NULL, 0 },
{ "ipratio", required_argument, NULL, 0 },
--
2.37.3
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment