[x265] [PATCH] AQMotion: Add aq offsets based the relative motion of each CU
Deepthi Nandakumar
deepthipnandakumar at gmail.com
Thu Jan 5 11:46:40 CET 2017
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?
On Wed, Dec 28, 2016 at 6:38 PM, <gopi.satykrishna at multicorewareinc.com>
wrote:
> # HG changeset patch
> # User Gopi Satykrishna Akisetty <gopi.satykrishna at multicorewareinc.com>
> # Date 1482137927 -19800
> # Mon Dec 19 14:28:47 2016 +0530
> # Node ID 93fd14d86372368f7120e8999b9eb45247f849fd
> # Parent af10eaeb36cd22c7ad20ed2dafeac6f8e388ed9d
> AQMotion: Add aq offsets based the relative motion of each CU
>
> diff -r af10eaeb36cd -r 93fd14d86372 doc/reST/cli.rst
> --- a/doc/reST/cli.rst Wed Dec 28 10:17:08 2016 +0530
> +++ b/doc/reST/cli.rst Mon Dec 19 14:28:47 2016 +0530
> @@ -1382,6 +1382,14 @@
> Default 1.0.
> **Range of values:** 0.0 to 3.0
>
> +.. option:: --[no-]aq-motion
> +
> + Adjust the AQ offsets based on the relative motion of each block
> with
> + respect to the motion of the frame. The more the relative motion
> of the block,
> + the more quantization is used. Default disabled.
> +
> + Requires AQ Mode to be on.
> +
> .. option:: --qg-size <64|32|16|8>
>
> Enable adaptive quantization for sub-CTUs. This parameter specifies
> diff -r af10eaeb36cd -r 93fd14d86372 source/CMakeLists.txt
> --- a/source/CMakeLists.txt Wed Dec 28 10:17:08 2016 +0530
> +++ b/source/CMakeLists.txt Mon Dec 19 14:28:47 2016 +0530
> @@ -29,7 +29,7 @@
> 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 105)
> +set(X265_BUILD 106)
> configure_file("${PROJECT_SOURCE_DIR}/x265.def.in"
> "${PROJECT_BINARY_DIR}/x265.def")
> configure_file("${PROJECT_SOURCE_DIR}/x265_config.h.in"
> diff -r af10eaeb36cd -r 93fd14d86372 source/common/lowres.cpp
> --- a/source/common/lowres.cpp Wed Dec 28 10:17:08 2016 +0530
> +++ b/source/common/lowres.cpp Mon Dec 19 14:28:47 2016 +0530
> @@ -56,6 +56,7 @@
> if (bAQEnabled)
> {
> CHECKED_MALLOC_ZERO(qpAqOffset, double, cuCountFullRes);
> + CHECKED_MALLOC_ZERO(qpAqMotionOffset, double, cuCountFullRes);
> CHECKED_MALLOC_ZERO(invQscaleFactor, int, cuCountFullRes);
> CHECKED_MALLOC_ZERO(qpCuTreeOffset, double, cuCountFullRes);
> CHECKED_MALLOC_ZERO(blockVariance, uint32_t, cuCountFullRes);
> @@ -124,8 +125,8 @@
> X265_FREE(lowresMvCosts[0][i]);
> X265_FREE(lowresMvCosts[1][i]);
> }
> -
> X265_FREE(qpAqOffset);
> + X265_FREE(qpAqMotionOffset);
> X265_FREE(invQscaleFactor);
> X265_FREE(qpCuTreeOffset);
> X265_FREE(propagateCost);
> diff -r af10eaeb36cd -r 93fd14d86372 source/common/lowres.h
> --- a/source/common/lowres.h Wed Dec 28 10:17:08 2016 +0530
> +++ b/source/common/lowres.h Mon Dec 19 14:28:47 2016 +0530
> @@ -144,6 +144,7 @@
> /* rate control / adaptive quant data */
> double* qpAqOffset; // AQ QP offset values for each 16x16 CU
> double* qpCuTreeOffset; // cuTree QP offset values for each 16x16
> CU
> + double* qpAqMotionOffset;
> int* invQscaleFactor; // qScale values for qp Aq Offsets
> int* invQscaleFactor8x8; // temporary buffer for qg-size 8
> uint32_t* blockVariance;
> diff -r af10eaeb36cd -r 93fd14d86372 source/common/param.cpp
> --- a/source/common/param.cpp Wed Dec 28 10:17:08 2016 +0530
> +++ b/source/common/param.cpp Mon Dec 19 14:28:47 2016 +0530
> @@ -266,6 +266,7 @@
> param->bOptQpPPS = 1;
> param->bOptRefListLengthPPS = 1;
> param->bOptCUDeltaQP = 0;
> + param->bAQMotion = 0;
>
> }
>
> @@ -926,6 +927,7 @@
> OPT("opt-cu-delta-qp") p->bOptCUDeltaQP = atobool(value);
> OPT("multi-pass-opt-analysis") p->analysisMultiPassRefine =
> atobool(value);
> OPT("multi-pass-opt-distortion") p->analysisMultiPassDistortion
> = atobool(value);
> + OPT("aq-motion") p->bAQMotion = atobool(value);
> else
> return X265_PARAM_BAD_NAME;
> }
> @@ -1621,6 +1623,7 @@
> BOOL(p->bMultiPassOptRPS, "multi-pass-opt-rps");
> s += sprintf(s, " scenecut-bias=%.2f", p->scenecutBias);
> BOOL(p->bOptCUDeltaQP, "opt-cu-delta-qp");
> + BOOL(p->bAQMotion, "aq-motion");
> #undef BOOL
> return buf;
> }
> diff -r af10eaeb36cd -r 93fd14d86372 source/encoder/encoder.cpp
> --- a/source/encoder/encoder.cpp Wed Dec 28 10:17:08 2016 +0530
> +++ b/source/encoder/encoder.cpp Mon Dec 19 14:28:47 2016 +0530
> @@ -2132,6 +2132,12 @@
> x265_log(p, X265_LOG_WARNING, "--opt-cu-delta-qp disabled,
> requires RD level > 4\n");
> }
>
> + if (p->bAQMotion && !p->rc.aqMode)
> + {
> + p->bAQMotion = false;
> + x265_log(p, X265_LOG_WARNING, "--aq-motion disabled, requires aq
> mode to be on\n");
> + }
> +
> if (p->limitTU && p->tuQTMaxInterDepth < 2)
> {
> p->limitTU = 0;
> diff -r af10eaeb36cd -r 93fd14d86372 source/encoder/slicetype.cpp
> --- a/source/encoder/slicetype.cpp Wed Dec 28 10:17:08 2016 +0530
> +++ b/source/encoder/slicetype.cpp Mon Dec 19 14:28:47 2016 +0530
> @@ -1495,6 +1495,8 @@
>
> resetStart = bKeyframe ? 1 : 2;
> }
> + if (m_param->bAQMotion)
> + aqMotion(frames, bKeyframe);
>
> if (m_param->rc.cuTree)
> cuTree(frames, X265_MIN(numFrames, m_param->keyframeMax),
> bKeyframe);
> @@ -1724,6 +1726,88 @@
>
> return cost;
> }
> +void Lookahead::aqMotion(Lowres **frames, bool bIntra)
> +{
> + if (!bIntra)
> + {
> + int curnonb = 0, lastnonb = 1;
> + int bframes = 0, i = 1;
> + while (frames[lastnonb]->sliceType != X265_TYPE_P)
> + lastnonb++;
> + bframes = lastnonb - 1;
> + if (m_param->bBPyramid && bframes > 1)
> + {
> + int middle = (bframes + 1) / 2;
> + for (i = 1; i < lastnonb; i++)
> + {
> + int p0 = i > middle ? middle : curnonb;
> + int p1 = i < middle ? middle : lastnonb;
> + if (i != middle)
> + calcMotionAdaptiveQuantFrame(frames, p0, p1, i);
> + }
> + calcMotionAdaptiveQuantFrame(frames, curnonb, lastnonb,
> middle);
> + }
> + else
> + for (i = 1; i < lastnonb; i++)
> + calcMotionAdaptiveQuantFrame(frames, curnonb, lastnonb,
> i);
> + calcMotionAdaptiveQuantFrame(frames, curnonb, lastnonb,
> lastnonb);
> + }
> +}
> +
> +void Lookahead::calcMotionAdaptiveQuantFrame(Lowres **frames, int p0,
> int p1, int b)
> +{
> + int listDist[2] = { b - p0 - 1, p1 - b - 1 };
> + int32_t strideInCU = m_8x8Width;
> + double qp_adj = 0, avg_adj = 0, avg_adj_pow2 = 0, sd;
> + for (uint16_t blocky = 0; blocky < m_8x8Height; blocky++)
> + {
> + int cuIndex = blocky * strideInCU;
> + for (uint16_t blockx = 0; blockx < m_8x8Width; blockx++,
> cuIndex++)
> + {
> + int32_t lists_used = frames[b]->lowresCosts[b - p0][p1 -
> b][cuIndex] >> LOWRES_COST_SHIFT;
> + double displacement = 0;
> + for (uint16_t list = 0; list < 2; list++)
> + {
> + if ((lists_used >> list) & 1)
> + {
> + MV *mvs = frames[b]->lowresMvs[list][listDist[list]];
> + int32_t x = mvs[cuIndex].x;
> + int32_t y = mvs[cuIndex].y;
> + displacement += sqrt(pow(abs(x), 2) + pow(abs(y), 2));
> + }
> + else
> + displacement += 0.0;
> + }
> + if (lists_used == 3)
> + displacement = displacement / 2;
> + qp_adj = pow(displacement, 0.1);
> + frames[b]->qpAqMotionOffset[cuIndex] = qp_adj;
> + avg_adj += qp_adj;
> + avg_adj_pow2 += qp_adj * qp_adj;
> + }
> + }
> + avg_adj /= m_cuCount;
> + avg_adj_pow2 /= m_cuCount;
> + sd = sqrt((avg_adj_pow2 - (avg_adj * avg_adj)));
> + if (sd > 0)
> + {
> + for (uint16_t blocky = 0; blocky < m_8x8Height; blocky++)
> + {
> + int cuIndex = blocky * strideInCU;
> + for (uint16_t blockx = 0; blockx < m_8x8Width; blockx++,
> cuIndex++)
> + {
> + qp_adj = frames[b]->qpAqMotionOffset[cuIndex];
> + qp_adj = (qp_adj - avg_adj) / sd;
> + if (qp_adj > 1)
> + {
> + frames[b]->qpAqOffset[cuIndex] += qp_adj;
> + frames[b]->qpCuTreeOffset[cuIndex] += qp_adj;
> + frames[b]->invQscaleFactor[cuIndex] +=
> x265_exp2fix8(qp_adj);
> + }
> + }
> + }
> + }
> +}
>
> void Lookahead::cuTree(Lowres **frames, int numframes, bool bIntra)
> {
> diff -r af10eaeb36cd -r 93fd14d86372 source/encoder/slicetype.h
> --- a/source/encoder/slicetype.h Wed Dec 28 10:17:08 2016 +0530
> +++ b/source/encoder/slicetype.h Mon Dec 19 14:28:47 2016 +0530
> @@ -165,7 +165,8 @@
> int64_t slicetypePathCost(Lowres **frames, char *path, int64_t
> threshold);
> int64_t vbvFrameCost(Lowres **frames, int p0, int p1, int b);
> void vbvLookahead(Lowres **frames, int numFrames, int keyframes);
> -
> + void aqMotion(Lowres **frames, bool bintra);
> + void calcMotionAdaptiveQuantFrame(Lowres **frames, int p0, int
> p1, int b);
> /* called by slicetypeAnalyse() to effect cuTree adjustments to
> adaptive
> * quant offsets */
> void cuTree(Lowres **frames, int numframes, bool bintra);
> diff -r af10eaeb36cd -r 93fd14d86372 source/test/regression-tests.txt
> --- a/source/test/regression-tests.txt Wed Dec 28 10:17:08 2016 +0530
> +++ b/source/test/regression-tests.txt Mon Dec 19 14:28:47 2016 +0530
> @@ -43,6 +43,7 @@
> CrowdRun_1920x1080_50_10bit_444.yuv,--preset veryfast --temporal-layers
> --repeat-headers --limit-refs 2
> CrowdRun_1920x1080_50_10bit_444.yuv,--preset medium --dither --keyint -1
> --rdoq-level 1 --limit-modes
> CrowdRun_1920x1080_50_10bit_444.yuv,--preset veryslow --tskip
> --tskip-fast --no-scenecut --limit-tu 1
> +CrowdRun_1920x1080_50_10bit_444.yuv,--preset veryslow --aq-mode 3
> --aq-strength 1.5 --aq-motion --bitrate 5000
> DucksAndLegs_1920x1080_60_10bit_422.yuv,--preset superfast --weightp
> --qg-size 16
> DucksAndLegs_1920x1080_60_10bit_422.yuv,--preset medium --tune psnr
> --bframes 16 --limit-modes
> DucksAndLegs_1920x1080_60_10bit_422.yuv,--preset slow --temporal-layers
> --no-psy-rd --qg-size 32 --limit-refs 0 --cu-lossless
> diff -r af10eaeb36cd -r 93fd14d86372 source/x265.h
> --- a/source/x265.h Wed Dec 28 10:17:08 2016 +0530
> +++ b/source/x265.h Mon Dec 19 14:28:47 2016 +0530
> @@ -1360,6 +1360,9 @@
>
> /* Refine analysis in multipass ratecontrol based on distortion data
> stored */
> int analysisMultiPassDistortion;
> +
> + /* Adaptive Quantization based on relative motion */
> + int bAQMotion;
> } x265_param;
>
> /* x265_param_alloc:
> diff -r af10eaeb36cd -r 93fd14d86372 source/x265cli.h
> --- a/source/x265cli.h Wed Dec 28 10:17:08 2016 +0530
> +++ b/source/x265cli.h Mon Dec 19 14:28:47 2016 +0530
> @@ -256,6 +256,8 @@
> { "analyze-src-pics", no_argument, NULL, 0 },
> { "no-analyze-src-pics", no_argument, NULL, 0 },
> { "slices", required_argument, NULL, 0 },
> + { "aq-motion", no_argument, NULL, 0 },
> + { "no-aq-motion", no_argument, NULL, 0 },
> { 0, 0, 0, 0 },
> { 0, 0, 0, 0 },
> { 0, 0, 0, 0 },
> @@ -414,6 +416,7 @@
> H0(" --analysis-file <filename> Specify file name used for
> either dumping or reading analysis data.\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. Default %d\n", param->rc.aqMode);
> H0(" --aq-strength <float> Reduces blocking and blurring in
> flat and textured areas (0 to 3.0). Default %.2f\n", param->rc.aqStrength);
> + H0(" --[no-]aq-motion Adaptive Quantization based on
> the relative motion of each CU w.r.t., frame. Default %s\n",
> OPT(param->bOptCUDeltaQP));
> H0(" --qg-size <int> Specifies the size of the
> quantization group (64, 32, 16, 8). Default %d\n", param->rc.qgSize);
> H0(" --[no-]cutree Enable cutree for Adaptive
> Quantization. Default %s\n", OPT(param->rc.cuTree));
> H0(" --[no-]rc-grain Enable ratecontrol mode to
> handle grains specifically. turned on with tune grain. Default %s\n",
> OPT(param->rc.bEnableGrain));
> _______________________________________________
> x265-devel mailing list
> x265-devel at videolan.org
> https://mailman.videolan.org/listinfo/x265-devel
>
--
Deepthi
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20170105/b95b8752/attachment-0001.html>
More information about the x265-devel
mailing list