<div dir="ltr">Thanks - nice work. Why is it necessary to turn on regular aq for this? Regular aq penalises blocks with high variance, while aq-motion penalises blocks with high MVs. Can we not use aq-motion without basic aq? </div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Dec 28, 2016 at 6:38 PM, <span dir="ltr"><<a href="mailto:gopi.satykrishna@multicorewareinc.com" target="_blank">gopi.satykrishna@multicorewareinc.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"># HG changeset patch<br>
# User Gopi Satykrishna Akisetty <<a href="mailto:gopi.satykrishna@multicorewareinc.com">gopi.satykrishna@<wbr>multicorewareinc.com</a>><br>
# Date 1482137927 -19800<br>
# Mon Dec 19 14:28:47 2016 +0530<br>
# Node ID 93fd14d86372368f7120e8999b9eb4<wbr>5247f849fd<br>
# Parent af10eaeb36cd22c7ad20ed2dafeac6<wbr>f8e388ed9d<br>
AQMotion: Add aq offsets based the relative motion of each CU<br>
<br>
diff -r af10eaeb36cd -r 93fd14d86372 doc/reST/cli.rst<br>
--- a/doc/reST/cli.rst Wed Dec 28 10:17:08 2016 +0530<br>
+++ b/doc/reST/cli.rst Mon Dec 19 14:28:47 2016 +0530<br>
@@ -1382,6 +1382,14 @@<br>
Default 1.0.<br>
**Range of values:** 0.0 to 3.0<br>
<br>
+.. option:: --[no-]aq-motion<br>
+<br>
+ Adjust the AQ offsets based on the relative motion of each block with<br>
+ respect to the motion of the frame. The more the relative motion of the block,<br>
+ the more quantization is used. Default disabled.<br>
+<br>
+ Requires AQ Mode to be on.<br>
+<br>
.. option:: --qg-size <64|32|16|8><br>
<br>
Enable adaptive quantization for sub-CTUs. This parameter specifies<br>
diff -r af10eaeb36cd -r 93fd14d86372 source/CMakeLists.txt<br>
--- a/source/CMakeLists.txt Wed Dec 28 10:17:08 2016 +0530<br>
+++ b/source/CMakeLists.txt Mon Dec 19 14:28:47 2016 +0530<br>
@@ -29,7 +29,7 @@<br>
option(STATIC_LINK_CRT "Statically link C runtime for release builds" OFF)<br>
mark_as_advanced(FPROFILE_USE FPROFILE_GENERATE NATIVE_BUILD)<br>
# X265_BUILD must be incremented each time the public API is changed<br>
-set(X265_BUILD 105)<br>
+set(X265_BUILD 106)<br>
configure_file("${PROJECT_<wbr>SOURCE_DIR}/<a href="http://x265.def.in" rel="noreferrer" target="_blank">x265.def.in</a>"<br>
"${PROJECT_BINARY_DIR}/x265.<wbr>def")<br>
configure_file("${PROJECT_<wbr>SOURCE_DIR}/<a href="http://x265_config.h.in" rel="noreferrer" target="_blank">x265_config.h.in</a>"<br>
diff -r af10eaeb36cd -r 93fd14d86372 source/common/lowres.cpp<br>
--- a/source/common/lowres.cpp Wed Dec 28 10:17:08 2016 +0530<br>
+++ b/source/common/lowres.cpp Mon Dec 19 14:28:47 2016 +0530<br>
@@ -56,6 +56,7 @@<br>
if (bAQEnabled)<br>
{<br>
CHECKED_MALLOC_ZERO(<wbr>qpAqOffset, double, cuCountFullRes);<br>
+ CHECKED_MALLOC_ZERO(<wbr>qpAqMotionOffset, double, cuCountFullRes);<br>
CHECKED_MALLOC_ZERO(<wbr>invQscaleFactor, int, cuCountFullRes);<br>
CHECKED_MALLOC_ZERO(<wbr>qpCuTreeOffset, double, cuCountFullRes);<br>
CHECKED_MALLOC_ZERO(<wbr>blockVariance, uint32_t, cuCountFullRes);<br>
@@ -124,8 +125,8 @@<br>
X265_FREE(lowresMvCosts[0][i])<wbr>;<br>
X265_FREE(lowresMvCosts[1][i])<wbr>;<br>
}<br>
-<br>
X265_FREE(qpAqOffset);<br>
+ X265_FREE(qpAqMotionOffset);<br>
X265_FREE(invQscaleFactor);<br>
X265_FREE(qpCuTreeOffset);<br>
X265_FREE(propagateCost);<br>
diff -r af10eaeb36cd -r 93fd14d86372 source/common/lowres.h<br>
--- a/source/common/lowres.h Wed Dec 28 10:17:08 2016 +0530<br>
+++ b/source/common/lowres.h Mon Dec 19 14:28:47 2016 +0530<br>
@@ -144,6 +144,7 @@<br>
/* rate control / adaptive quant data */<br>
double* qpAqOffset; // AQ QP offset values for each 16x16 CU<br>
double* qpCuTreeOffset; // cuTree QP offset values for each 16x16 CU<br>
+ double* qpAqMotionOffset;<br>
int* invQscaleFactor; // qScale values for qp Aq Offsets<br>
int* invQscaleFactor8x8; // temporary buffer for qg-size 8<br>
uint32_t* blockVariance;<br>
diff -r af10eaeb36cd -r 93fd14d86372 source/common/param.cpp<br>
--- a/source/common/param.cpp Wed Dec 28 10:17:08 2016 +0530<br>
+++ b/source/common/param.cpp Mon Dec 19 14:28:47 2016 +0530<br>
@@ -266,6 +266,7 @@<br>
param->bOptQpPPS = 1;<br>
param->bOptRefListLengthPPS = 1;<br>
param->bOptCUDeltaQP = 0;<br>
+ param->bAQMotion = 0;<br>
<br>
}<br>
<br>
@@ -926,6 +927,7 @@<br>
OPT("opt-cu-delta-qp") p->bOptCUDeltaQP = atobool(value);<br>
OPT("multi-pass-opt-analysis") p->analysisMultiPassRefine = atobool(value);<br>
OPT("multi-pass-opt-<wbr>distortion") p->analysisMultiPassDistortion = atobool(value);<br>
+ OPT("aq-motion") p->bAQMotion = atobool(value);<br>
else<br>
return X265_PARAM_BAD_NAME;<br>
}<br>
@@ -1621,6 +1623,7 @@<br>
BOOL(p->bMultiPassOptRPS, "multi-pass-opt-rps");<br>
s += sprintf(s, " scenecut-bias=%.2f", p->scenecutBias);<br>
BOOL(p->bOptCUDeltaQP, "opt-cu-delta-qp");<br>
+ BOOL(p->bAQMotion, "aq-motion");<br>
#undef BOOL<br>
return buf;<br>
}<br>
diff -r af10eaeb36cd -r 93fd14d86372 source/encoder/encoder.cpp<br>
--- a/source/encoder/encoder.cpp Wed Dec 28 10:17:08 2016 +0530<br>
+++ b/source/encoder/encoder.cpp Mon Dec 19 14:28:47 2016 +0530<br>
@@ -2132,6 +2132,12 @@<br>
x265_log(p, X265_LOG_WARNING, "--opt-cu-delta-qp disabled, requires RD level > 4\n");<br>
}<br>
<br>
+ if (p->bAQMotion && !p->rc.aqMode)<br>
+ {<br>
+ p->bAQMotion = false;<br>
+ x265_log(p, X265_LOG_WARNING, "--aq-motion disabled, requires aq mode to be on\n");<br>
+ }<br>
+<br>
if (p->limitTU && p->tuQTMaxInterDepth < 2)<br>
{<br>
p->limitTU = 0;<br>
diff -r af10eaeb36cd -r 93fd14d86372 source/encoder/slicetype.cpp<br>
--- a/source/encoder/slicetype.cpp Wed Dec 28 10:17:08 2016 +0530<br>
+++ b/source/encoder/slicetype.cpp Mon Dec 19 14:28:47 2016 +0530<br>
@@ -1495,6 +1495,8 @@<br>
<br>
resetStart = bKeyframe ? 1 : 2;<br>
}<br>
+ if (m_param->bAQMotion)<br>
+ aqMotion(frames, bKeyframe);<br>
<br>
if (m_param->rc.cuTree)<br>
cuTree(frames, X265_MIN(numFrames, m_param->keyframeMax), bKeyframe);<br>
@@ -1724,6 +1726,88 @@<br>
<br>
return cost;<br>
}<br>
+void Lookahead::aqMotion(Lowres **frames, bool bIntra)<br>
+{<br>
+ if (!bIntra)<br>
+ {<br>
+ int curnonb = 0, lastnonb = 1;<br>
+ int bframes = 0, i = 1;<br>
+ while (frames[lastnonb]->sliceType != X265_TYPE_P)<br>
+ lastnonb++;<br>
+ bframes = lastnonb - 1;<br>
+ if (m_param->bBPyramid && bframes > 1)<br>
+ {<br>
+ int middle = (bframes + 1) / 2;<br>
+ for (i = 1; i < lastnonb; i++)<br>
+ {<br>
+ int p0 = i > middle ? middle : curnonb;<br>
+ int p1 = i < middle ? middle : lastnonb;<br>
+ if (i != middle)<br>
+ calcMotionAdaptiveQuantFrame(<wbr>frames, p0, p1, i);<br>
+ }<br>
+ calcMotionAdaptiveQuantFrame(<wbr>frames, curnonb, lastnonb, middle);<br>
+ }<br>
+ else<br>
+ for (i = 1; i < lastnonb; i++)<br>
+ calcMotionAdaptiveQuantFrame(<wbr>frames, curnonb, lastnonb, i);<br>
+ calcMotionAdaptiveQuantFrame(<wbr>frames, curnonb, lastnonb, lastnonb);<br>
+ }<br>
+}<br>
+<br>
+void Lookahead::<wbr>calcMotionAdaptiveQuantFrame(<wbr>Lowres **frames, int p0, int p1, int b)<br>
+{<br>
+ int listDist[2] = { b - p0 - 1, p1 - b - 1 };<br>
+ int32_t strideInCU = m_8x8Width;<br>
+ double qp_adj = 0, avg_adj = 0, avg_adj_pow2 = 0, sd;<br>
+ for (uint16_t blocky = 0; blocky < m_8x8Height; blocky++)<br>
+ {<br>
+ int cuIndex = blocky * strideInCU;<br>
+ for (uint16_t blockx = 0; blockx < m_8x8Width; blockx++, cuIndex++)<br>
+ {<br>
+ int32_t lists_used = frames[b]->lowresCosts[b - p0][p1 - b][cuIndex] >> LOWRES_COST_SHIFT;<br>
+ double displacement = 0;<br>
+ for (uint16_t list = 0; list < 2; list++)<br>
+ {<br>
+ if ((lists_used >> list) & 1)<br>
+ {<br>
+ MV *mvs = frames[b]->lowresMvs[list][<wbr>listDist[list]];<br>
+ int32_t x = mvs[cuIndex].x;<br>
+ int32_t y = mvs[cuIndex].y;<br>
+ displacement += sqrt(pow(abs(x), 2) + pow(abs(y), 2));<br>
+ }<br>
+ else<br>
+ displacement += 0.0;<br>
+ }<br>
+ if (lists_used == 3)<br>
+ displacement = displacement / 2;<br>
+ qp_adj = pow(displacement, 0.1);<br>
+ frames[b]->qpAqMotionOffset[<wbr>cuIndex] = qp_adj;<br>
+ avg_adj += qp_adj;<br>
+ avg_adj_pow2 += qp_adj * qp_adj;<br>
+ }<br>
+ }<br>
+ avg_adj /= m_cuCount;<br>
+ avg_adj_pow2 /= m_cuCount;<br>
+ sd = sqrt((avg_adj_pow2 - (avg_adj * avg_adj)));<br>
+ if (sd > 0)<br>
+ {<br>
+ for (uint16_t blocky = 0; blocky < m_8x8Height; blocky++)<br>
+ {<br>
+ int cuIndex = blocky * strideInCU;<br>
+ for (uint16_t blockx = 0; blockx < m_8x8Width; blockx++, cuIndex++)<br>
+ {<br>
+ qp_adj = frames[b]->qpAqMotionOffset[<wbr>cuIndex];<br>
+ qp_adj = (qp_adj - avg_adj) / sd;<br>
+ if (qp_adj > 1)<br>
+ {<br>
+ frames[b]->qpAqOffset[cuIndex] += qp_adj;<br>
+ frames[b]->qpCuTreeOffset[<wbr>cuIndex] += qp_adj;<br>
+ frames[b]->invQscaleFactor[<wbr>cuIndex] += x265_exp2fix8(qp_adj);<br>
+ }<br>
+ }<br>
+ }<br>
+ }<br>
+}<br>
<br>
void Lookahead::cuTree(Lowres **frames, int numframes, bool bIntra)<br>
{<br>
diff -r af10eaeb36cd -r 93fd14d86372 source/encoder/slicetype.h<br>
--- a/source/encoder/slicetype.h Wed Dec 28 10:17:08 2016 +0530<br>
+++ b/source/encoder/slicetype.h Mon Dec 19 14:28:47 2016 +0530<br>
@@ -165,7 +165,8 @@<br>
int64_t slicetypePathCost(Lowres **frames, char *path, int64_t threshold);<br>
int64_t vbvFrameCost(Lowres **frames, int p0, int p1, int b);<br>
void vbvLookahead(Lowres **frames, int numFrames, int keyframes);<br>
-<br>
+ void aqMotion(Lowres **frames, bool bintra);<br>
+ void calcMotionAdaptiveQuantFrame(<wbr>Lowres **frames, int p0, int p1, int b);<br>
/* called by slicetypeAnalyse() to effect cuTree adjustments to adaptive<br>
* quant offsets */<br>
void cuTree(Lowres **frames, int numframes, bool bintra);<br>
diff -r af10eaeb36cd -r 93fd14d86372 source/test/regression-tests.<wbr>txt<br>
--- a/source/test/regression-<wbr>tests.txt Wed Dec 28 10:17:08 2016 +0530<br>
+++ b/source/test/regression-<wbr>tests.txt Mon Dec 19 14:28:47 2016 +0530<br>
@@ -43,6 +43,7 @@<br>
CrowdRun_1920x1080_50_10bit_<wbr>444.yuv,--preset veryfast --temporal-layers --repeat-headers --limit-refs 2<br>
CrowdRun_1920x1080_50_10bit_<wbr>444.yuv,--preset medium --dither --keyint -1 --rdoq-level 1 --limit-modes<br>
CrowdRun_1920x1080_50_10bit_<wbr>444.yuv,--preset veryslow --tskip --tskip-fast --no-scenecut --limit-tu 1<br>
+CrowdRun_1920x1080_50_10bit_<wbr>444.yuv,--preset veryslow --aq-mode 3 --aq-strength 1.5 --aq-motion --bitrate 5000<br>
DucksAndLegs_1920x1080_60_<wbr>10bit_422.yuv,--preset superfast --weightp --qg-size 16<br>
DucksAndLegs_1920x1080_60_<wbr>10bit_422.yuv,--preset medium --tune psnr --bframes 16 --limit-modes<br>
DucksAndLegs_1920x1080_60_<wbr>10bit_422.yuv,--preset slow --temporal-layers --no-psy-rd --qg-size 32 --limit-refs 0 --cu-lossless<br>
diff -r af10eaeb36cd -r 93fd14d86372 source/x265.h<br>
--- a/source/x265.h Wed Dec 28 10:17:08 2016 +0530<br>
+++ b/source/x265.h Mon Dec 19 14:28:47 2016 +0530<br>
@@ -1360,6 +1360,9 @@<br>
<br>
/* Refine analysis in multipass ratecontrol based on distortion data stored */<br>
int analysisMultiPassDistortion;<br>
+<br>
+ /* Adaptive Quantization based on relative motion */<br>
+ int bAQMotion;<br>
} x265_param;<br>
<br>
/* x265_param_alloc:<br>
diff -r af10eaeb36cd -r 93fd14d86372 source/x265cli.h<br>
--- a/source/x265cli.h Wed Dec 28 10:17:08 2016 +0530<br>
+++ b/source/x265cli.h Mon Dec 19 14:28:47 2016 +0530<br>
@@ -256,6 +256,8 @@<br>
{ "analyze-src-pics", no_argument, NULL, 0 },<br>
{ "no-analyze-src-pics", no_argument, NULL, 0 },<br>
{ "slices", required_argument, NULL, 0 },<br>
+ { "aq-motion", no_argument, NULL, 0 },<br>
+ { "no-aq-motion", no_argument, NULL, 0 },<br>
{ 0, 0, 0, 0 },<br>
{ 0, 0, 0, 0 },<br>
{ 0, 0, 0, 0 },<br>
@@ -414,6 +416,7 @@<br>
H0(" --analysis-file <filename> Specify file name used for either dumping or reading analysis data.\n");<br>
H0(" --aq-mode <integer> Mode for Adaptive Quantization - 0:none 1:uniform AQ 2:auto variance 3:auto variance with bias to dark scenes. Default %d\n", param->rc.aqMode);<br>
H0(" --aq-strength <float> Reduces blocking and blurring in flat and textured areas (0 to 3.0). Default %.2f\n", param->rc.aqStrength);<br>
+ H0(" --[no-]aq-motion Adaptive Quantization based on the relative motion of each CU w.r.t., frame. Default %s\n", OPT(param->bOptCUDeltaQP));<br>
H0(" --qg-size <int> Specifies the size of the quantization group (64, 32, 16, 8). Default %d\n", param->rc.qgSize);<br>
H0(" --[no-]cutree Enable cutree for Adaptive Quantization. Default %s\n", OPT(param->rc.cuTree));<br>
H0(" --[no-]rc-grain Enable ratecontrol mode to handle grains specifically. turned on with tune grain. Default %s\n", OPT(param->rc.bEnableGrain));<br>
______________________________<wbr>_________________<br>
x265-devel mailing list<br>
<a href="mailto:x265-devel@videolan.org">x265-devel@videolan.org</a><br>
<a href="https://mailman.videolan.org/listinfo/x265-devel" rel="noreferrer" target="_blank">https://mailman.videolan.org/<wbr>listinfo/x265-devel</a><br>
</blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature" data-smartmail="gmail_signature">Deepthi</div>
</div>