Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add new AQ mode #17

Merged
merged 2 commits into from
Feb 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion doc/reST/cli.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1740,7 +1740,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 @@ -1755,6 +1755,7 @@ Quality, rate control and rate distortion options
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 @@ -1766,6 +1767,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:: --hevc-aq

Enable adaptive quantization
Expand Down
4 changes: 2 additions & 2 deletions source/common/frame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,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 @@ -277,7 +277,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 @@ -272,6 +272,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 @@ -748,6 +749,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 @@ -1050,6 +1052,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 @@ -1690,7 +1693,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 @@ -2239,6 +2242,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 @@ -2527,6 +2531,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 @@ -450,7 +450,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->bHistBasedSceneCut && 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->m_fencPic->m_picHeight;
int width = m_frame->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 @@ -516,17 +516,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->bHistBasedSceneCut && param->recursionSkipMode == EDGE_BASED_RSKIP)
if ((param->rc.aqMode == X265_AQ_EDGE || param->rc.aqMode == X265_AQ_EDGE_BIASED) && !param->bHistBasedSceneCut && 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 @@ -535,7 +535,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 @@ -565,7 +565,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 @@ -594,6 +594,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 @@ -581,6 +581,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 @@ -1405,6 +1406,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 @@ -279,9 +279,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));
H0(" --qg-size <int> Specifies the size of the quantization group (64, 32, 16, 8). Default %d\n", param->rc.qgSize);
Expand Down Expand Up @@ -1111,4 +1112,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 },
{ "rc-grain", no_argument, NULL, 0 },
{ "no-rc-grain", no_argument, NULL, 0 },
{ "ipratio", required_argument, NULL, 0 },
Expand Down