Skip to content

Commit

Permalink
add new AQ mode (#17)
Browse files Browse the repository at this point in the history
add new AQ mode

This just adds AQ mode 3's dark bias to AQ mode 4. Because of normal AQ
strength values for mode 4 not really working well with the dark bias,
an additional bias-strength parameter has been added.
  • Loading branch information
noizuy authored and DJATOM committed Sep 2, 2024
1 parent 07556a3 commit 3f2eb5a
Show file tree
Hide file tree
Showing 8 changed files with 42 additions and 12 deletions.
10 changes: 9 additions & 1 deletion doc/reST/cli.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1724,7 +1724,7 @@ Quality, rate control and rate distortion options
ignored. Slower presets will generally achieve better compression
efficiency (and generate smaller bitstreams). Default disabled.

.. option:: --aq-mode <0|1|2|3|4>
.. option:: --aq-mode <0|1|2|3|4|5>

Adaptive Quantization operating mode. Raise or lower per-block
quantization based on complexity analysis of the source image. The
Expand All @@ -1737,6 +1737,7 @@ Quality, rate control and rate distortion options
2. AQ enabled with auto-variance **(default)**
3. AQ enabled with auto-variance and bias to dark scenes. This is recommended for 8-bit encodes or low-bitrate 10-bit encodes, to prevent color banding/blocking.
4. AQ enabled with auto-variance and edge information.
5. AQ enabled with auto-variance, edge information, and bias to dark scenes.

.. option:: --aq-strength <float>

Expand All @@ -1748,6 +1749,13 @@ Quality, rate control and rate distortion options
Default 1.0.
**Range of values:** 0.0 to 3.0

.. option:: --aq-bias-strength <float>

Adjust the strength of dark scene bias in AQ modes 3 and 5. Setting this
to 0 will disable the dark scene bias, meaning modes will be equivalent to
their unbiased counterparts (2 and 4).
Default 1.0.

.. option:: --sbrc, --no-sbrc

To enable and disable segment-based rate control. SBRC controls the overflow with
Expand Down
4 changes: 2 additions & 2 deletions source/common/frame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ bool Frame::create(x265_param *param, float* quantOffsets)
CHECKED_MALLOC_ZERO(m_classifyCount, uint32_t, size);
}

if (param->rc.aqMode == X265_AQ_EDGE || (param->rc.zonefileCount && param->rc.aqMode != 0))
if (param->rc.aqMode == X265_AQ_EDGE || param->rc.aqMode == X265_AQ_EDGE_BIASED || (param->rc.zonefileCount && param->rc.aqMode != 0))
{
uint32_t numCuInWidth = (param->sourceWidth + param->maxCUSize - 1) / param->maxCUSize;
uint32_t numCuInHeight = (param->sourceHeight + param->maxCUSize - 1) / param->maxCUSize;
Expand Down Expand Up @@ -388,7 +388,7 @@ void Frame::destroy()
X265_FREE_ZERO(m_classifyCount);
}

if (m_param->rc.aqMode == X265_AQ_EDGE || (m_param->rc.zonefileCount && m_param->rc.aqMode != 0))
if (m_param->rc.aqMode == X265_AQ_EDGE || m_param->rc.aqMode == X265_AQ_EDGE_BIASED || (m_param->rc.zonefileCount && m_param->rc.aqMode != 0))
{
X265_FREE(m_edgePic);
X265_FREE(m_gaussianPic);
Expand Down
7 changes: 6 additions & 1 deletion source/common/param.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,7 @@ void x265_param_default(x265_param* param)
param->rc.hevcAq = 0;
param->rc.qgSize = 32;
param->rc.aqStrength = 1.0;
param->rc.aqBiasStrength = 1.0;
param->rc.qpAdaptationRange = 1.0;
param->rc.cuTree = 1;
param->rc.rfConstantMax = 0;
Expand Down Expand Up @@ -829,6 +830,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("nr-intra") p->noiseReductionIntra = atoi(value);
OPT("nr-inter") p->noiseReductionInter = atoi(value);
OPT("limit-modes") p->limitModes = atobool(value);
Expand Down Expand Up @@ -1130,6 +1132,7 @@ int x265_param_parse(x265_param* p, const char* name, const char* value)
OPT("qblur") p->rc.qblur = atof(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("vbv-maxrate") p->rc.vbvMaxBitrate = atoi(value);
OPT("vbv-bufsize") p->rc.vbvBufferSize = atoi(value);
OPT("vbv-init") p->rc.vbvBufferInit = atof(value);
Expand Down Expand Up @@ -1728,7 +1731,7 @@ int x265_check_params(x265_param* param)
"Lookahead depth must be less than 256");
CHECK(param->lookaheadSlices > 16 || param->lookaheadSlices < 0,
"Lookahead slices must between 0 and 16");
CHECK(param->rc.aqMode < X265_AQ_NONE || X265_AQ_EDGE < param->rc.aqMode,
CHECK(param->rc.aqMode < X265_AQ_NONE || X265_AQ_EDGE_BIASED < param->rc.aqMode,
"Aq-Mode is out of range");
CHECK(param->rc.aqStrength < 0 || param->rc.aqStrength > 3,
"Aq-Strength is out of range");
Expand Down Expand Up @@ -2310,6 +2313,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.cuTree, "cutree");
s += sprintf(s, " zone-count=%d", p->rc.zoneCount);
if (p->rc.zoneCount)
Expand Down Expand Up @@ -2760,6 +2764,7 @@ void x265_copy_params(x265_param* dst, x265_param* src)
dst->rc.qpStep = src->rc.qpStep;
dst->rc.aqMode = src->rc.aqMode;
dst->rc.aqStrength = src->rc.aqStrength;
dst->rc.aqBiasStrength = src->rc.aqBiasStrength;
dst->rc.vbvBufferSize = src->rc.vbvBufferSize;
dst->rc.vbvMaxBitrate = src->rc.vbvMaxBitrate;

Expand Down
2 changes: 1 addition & 1 deletion source/encoder/frameencoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -484,7 +484,7 @@ void FrameEncoder::compressFrame(int layer)
memset(&(m_frame[layer]->m_encData->m_frameStats), 0, sizeof(m_frame[layer]->m_encData->m_frameStats));
m_sLayerId = layer;

if (m_param->rc.aqMode != X265_AQ_EDGE && m_param->recursionSkipMode == EDGE_BASED_RSKIP)
if (m_param->rc.aqMode != X265_AQ_EDGE_BIASED && m_param->rc.aqMode != X265_AQ_EDGE && m_param->recursionSkipMode == EDGE_BASED_RSKIP)
{
int height = m_frame[layer]->m_fencPic->m_picHeight;
int width = m_frame[layer]->m_fencPic->m_picWidth;
Expand Down
21 changes: 16 additions & 5 deletions source/encoder/slicetype.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -524,17 +524,17 @@ void LookaheadTLD::calcAdaptiveQuantFrame(Frame *curFrame, x265_param* param)
double bias_strength = 0.f;
double strength = 0.f;

if (param->rc.aqMode == X265_AQ_EDGE)
if (param->rc.aqMode == X265_AQ_EDGE || param->rc.aqMode == X265_AQ_EDGE_BIASED)
edgeFilter(curFrame, param);

if (param->rc.aqMode == X265_AQ_EDGE && param->recursionSkipMode == EDGE_BASED_RSKIP)
if ((param->rc.aqMode == X265_AQ_EDGE || param->rc.aqMode == X265_AQ_EDGE_BIASED) && 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,
curFrame->m_fencPic->m_stride, curFrame->m_fencPic->m_picWidth, curFrame->m_fencPic->m_picHeight, SHIFT_TO_BITPLANE);
}

if (param->rc.aqMode == X265_AQ_AUTO_VARIANCE || param->rc.aqMode == X265_AQ_AUTO_VARIANCE_BIASED || param->rc.aqMode == X265_AQ_EDGE)
if (param->rc.aqMode == X265_AQ_AUTO_VARIANCE || param->rc.aqMode == X265_AQ_AUTO_VARIANCE_BIASED || param->rc.aqMode == X265_AQ_EDGE || param->rc.aqMode == X265_AQ_EDGE_BIASED)
{
double bit_depth_correction = 1.f / (1 << (2 * (X265_DEPTH - 8)));
for (int blockY = 0; blockY < maxRow; blockY += loopIncr)
Expand All @@ -543,7 +543,7 @@ void LookaheadTLD::calcAdaptiveQuantFrame(Frame *curFrame, x265_param* param)
{
uint32_t energy, edgeDensity, avgAngle;
energy = acEnergyCu(curFrame, blockX, blockY, param->internalCsp, param->rc.qgSize);
if (param->rc.aqMode == X265_AQ_EDGE)
if (param->rc.aqMode == X265_AQ_EDGE || param->rc.aqMode == X265_AQ_EDGE_BIASED)
{
edgeDensity = edgeDensityCu(curFrame, avgAngle, blockX, blockY, param->rc.qgSize);
if (edgeDensity)
Expand Down Expand Up @@ -573,7 +573,7 @@ void LookaheadTLD::calcAdaptiveQuantFrame(Frame *curFrame, x265_param* param)
avg_adj_pow2 /= blockCount;
strength = param->rc.aqStrength * avg_adj;
avg_adj = avg_adj - 0.5f * (avg_adj_pow2 - modeTwoConst) / avg_adj;
bias_strength = param->rc.aqStrength;
bias_strength = param->rc.aqBiasStrength * param->rc.aqStrength;
}
else
strength = param->rc.aqStrength * 1.0397f;
Expand Down Expand Up @@ -602,6 +602,17 @@ void LookaheadTLD::calcAdaptiveQuantFrame(Frame *curFrame, x265_param* param)
else
qp_adj = strength * (qp_adj - avg_adj);
}
else if (param->rc.aqMode == X265_AQ_EDGE_BIASED)
{
inclinedEdge = curFrame->m_lowres.edgeInclined[blockXY];
qp_adj = curFrame->m_lowres.qpCuTreeOffset[blockXY];
double dark_bias = bias_strength * (1.f - modeTwoConst / (qp_adj * qp_adj)) / 10.f;
if(inclinedEdge && (qp_adj - avg_adj > 0))
qp_adj = ((strength + AQ_EDGE_BIAS) * (qp_adj - avg_adj));
else
qp_adj = strength * (qp_adj - avg_adj);
qp_adj += dark_bias;
}
else
{
uint32_t energy = acEnergyCu(curFrame, blockX, blockY, param->internalCsp, param->rc.qgSize);
Expand Down
4 changes: 4 additions & 0 deletions source/x265.h
Original file line number Diff line number Diff line change
Expand Up @@ -594,6 +594,7 @@ typedef enum
#define X265_AQ_AUTO_VARIANCE 2
#define X265_AQ_AUTO_VARIANCE_BIASED 3
#define X265_AQ_EDGE 4
#define X265_AQ_EDGE_BIASED 5
#define x265_ADAPT_RD_STRENGTH 4
#define X265_REFINE_INTER_LEVELS 3
/* NOTE! For this release only X265_CSP_I420 and X265_CSP_I444 are supported */
Expand Down Expand Up @@ -1730,6 +1731,9 @@ typedef struct x265_param
* AQ is enabled. Default value: 1.0. Acceptable values between 0.0 and 3.0 */
double aqStrength;

/* Sets the bias towards dark scenes in AQ modes 3 and 5. */
double aqBiasStrength;

/* Delta QP range by QP adaptation based on a psycho-visual model.
* Acceptable values between 1.0 to 6.0 */
double qpAdaptationRange;
Expand Down
5 changes: 3 additions & 2 deletions source/x265cli.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -280,9 +280,10 @@ namespace X265_NS {
" - 0 : Disabled.\n"
" - 1 : Store/Load ctu distortion to/from the file specified in analysis-save/load.\n"
" Default 0 - Disabled\n");
H0(" --aq-mode <integer> Mode for Adaptive Quantization - 0:none 1:uniform AQ 2:auto variance 3:auto variance with bias to dark scenes 4:auto variance with edge information. Default %d\n", param->rc.aqMode);
H0(" --aq-mode <integer> Mode for Adaptive Quantization - 0:none 1:uniform AQ 2:auto variance 3:auto variance with bias to dark scenes 4:auto variance with edge information 5:auto variance with edge information and bias to dark scenes. Default %d\n", param->rc.aqMode);
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(" --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));
H1(" --[no-]sbrc Enables the segment based rate control. Default %s\n", OPT(param->bEnableSBRC));
Expand Down Expand Up @@ -1486,4 +1487,4 @@ namespace X265_NS {

#ifdef __cplusplus
}
#endif
#endif
1 change: 1 addition & 0 deletions source/x265cli.h
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ static const struct option long_options[] =
{ "qp", required_argument, NULL, 'q' },
{ "aq-mode", required_argument, NULL, 0 },
{ "aq-strength", required_argument, NULL, 0 },
{ "aq-bias-strength", required_argument, NULL, 0 },
{ "sbrc", no_argument, NULL, 0 },
{ "no-sbrc", no_argument, NULL, 0 },
{ "rc-grain", no_argument, NULL, 0 },
Expand Down

0 comments on commit 3f2eb5a

Please sign in to comment.