[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