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.satykris...@multicorewareinc.com> wrote: > # HG changeset patch > # User Gopi Satykrishna Akisetty <gopi.satykris...@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@videolan.org > https://mailman.videolan.org/listinfo/x265-devel > -- Deepthi
_______________________________________________ x265-devel mailing list x265-devel@videolan.org https://mailman.videolan.org/listinfo/x265-devel