[x265] [PATCH] api: Add option "--fades" to detect and handle fade-in regions
Dinesh Kumar Reddy
dinesh at multicorewareinc.com
Tue May 21 11:06:46 CEST 2019
# HG changeset patch
# User Pooja Venkatesan <pooja at multicorewareinc.com>
# Date 1555911695 -19800
# Mon Apr 22 11:11:35 2019 +0530
# Node ID eb2ecf2d2f7289398bd8c82658752ae75efdf985
# Parent 39b35ea862834f05e7437e1670e55de595c8f875
api: Add option "--fades" to detect and handle fade-in regions
Pushed Patch to x265 default branch.
Thanks & Regards,
Dinesh
On Fri, May 17, 2019 at 2:41 PM <pooja at multicorewareinc.com> wrote:
> # HG changeset patch
> # User Pooja Venkatesan <pooja at multicorewareinc.com>
> # Date 1555911695 -19800
> # Mon Apr 22 11:11:35 2019 +0530
> # Node ID eb2ecf2d2f7289398bd8c82658752ae75efdf985
> # Parent 39b35ea862834f05e7437e1670e55de595c8f875
> api: Add option "--fades" to detect and handle fade-in regions
>
> It does the following:
> Force I-slice and
> Initialize RC history for the brightest frame after fade-in.
>
> diff -r 39b35ea86283 -r eb2ecf2d2f72 doc/reST/cli.rst
> --- a/doc/reST/cli.rst Tue Mar 26 10:31:41 2019 +0530
> +++ b/doc/reST/cli.rst Mon Apr 22 11:11:35 2019 +0530
> @@ -1520,6 +1520,10 @@
> slicetype decision may change with this option.
> 2 - flush the slicetype decided frames only.
>
> +.. option:: --fades, --no-fades
> +
> + Detect and handle fade-in regions. Default disabled.
> +
> Quality, rate control and rate distortion options
> =================================================
>
> diff -r 39b35ea86283 -r eb2ecf2d2f72 source/CMakeLists.txt
> --- a/source/CMakeLists.txt Tue Mar 26 10:31:41 2019 +0530
> +++ b/source/CMakeLists.txt Mon Apr 22 11:11:35 2019 +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 173)
> +set(X265_BUILD 174)
> configure_file("${PROJECT_SOURCE_DIR}/x265.def.in"
> "${PROJECT_BINARY_DIR}/x265.def")
> configure_file("${PROJECT_SOURCE_DIR}/x265_config.h.in"
> diff -r 39b35ea86283 -r eb2ecf2d2f72 source/common/lowres.cpp
> --- a/source/common/lowres.cpp Tue Mar 26 10:31:41 2019 +0530
> +++ b/source/common/lowres.cpp Mon Apr 22 11:11:35 2019 +0530
> @@ -82,7 +82,7 @@
>
> if (origPic->m_param->bAQMotion)
> CHECKED_MALLOC_ZERO(qpAqMotionOffset, double, cuCountFullRes);
> - if (origPic->m_param->bDynamicRefine)
> + if (origPic->m_param->bDynamicRefine ||
> origPic->m_param->bEnableFades)
> CHECKED_MALLOC_ZERO(blockVariance, uint32_t, cuCountFullRes);
>
> if (!!param->rc.hevcAq)
> @@ -217,6 +217,7 @@
> {
> bLastMiniGopBFrame = false;
> bKeyframe = false; // Not a keyframe unless identified by lookahead
> + bIsFadeEnd = false;
> frameNum = poc;
> leadingBframes = 0;
> indB = 0;
> diff -r 39b35ea86283 -r eb2ecf2d2f72 source/common/lowres.h
> --- a/source/common/lowres.h Tue Mar 26 10:31:41 2019 +0530
> +++ b/source/common/lowres.h Mon Apr 22 11:11:35 2019 +0530
> @@ -160,6 +160,7 @@
> bool bScenecut; // Set to false if the frame cannot possibly
> be part of a real scenecut.
> bool bKeyframe;
> bool bLastMiniGopBFrame;
> + bool bIsFadeEnd;
>
> double ipCostRatio;
>
> @@ -195,6 +196,7 @@
> uint32_t* blockVariance;
> uint64_t wp_ssd[3]; // This is different than SSDY, this is
> sum(pixel^2) - sum(pixel)^2 for entire frame
> uint64_t wp_sum[3];
> + double frameVariance;
>
> /* cutree intermediate data */
> PicQPAdaptationLayer* pAQLayer;
> diff -r 39b35ea86283 -r eb2ecf2d2f72 source/common/param.cpp
> --- a/source/common/param.cpp Tue Mar 26 10:31:41 2019 +0530
> +++ b/source/common/param.cpp Mon Apr 22 11:11:35 2019 +0530
> @@ -172,6 +172,7 @@
> param->chunkStart = 0;
> param->chunkEnd = 0;
> param->bEnableHRDConcatFlag = 0;
> + param->bEnableFades = 0;
>
> /* Intra Coding Tools */
> param->bEnableConstrainedIntra = 0;
> @@ -1265,6 +1266,7 @@
> OPT("svt-pred-struct") x265_log(p, X265_LOG_WARNING, "Option %s
> is SVT-HEVC Encoder specific; Disabling it here \n", name);
> OPT("svt-fps-in-vps") x265_log(p, X265_LOG_WARNING, "Option %s is
> SVT-HEVC Encoder specific; Disabling it here \n", name);
> #endif
> + OPT("fades") p->bEnableFades = atobool(value);
> else
> return X265_PARAM_BAD_NAME;
> }
> @@ -2367,6 +2369,7 @@
> dst->bEnableHRDConcatFlag = src->bEnableHRDConcatFlag;
> dst->dolbyProfile = src->dolbyProfile;
> dst->bEnableSvtHevc = src->bEnableSvtHevc;
> + dst->bEnableFades = src->bEnableFades;
>
> #ifdef SVT_HEVC
> memcpy(dst->svtHevcParam, src->svtHevcParam,
> sizeof(EB_H265_ENC_CONFIGURATION));
> diff -r 39b35ea86283 -r eb2ecf2d2f72 source/encoder/ratecontrol.cpp
> --- a/source/encoder/ratecontrol.cpp Tue Mar 26 10:31:41 2019 +0530
> +++ b/source/encoder/ratecontrol.cpp Mon Apr 22 11:11:35 2019 +0530
> @@ -1262,6 +1262,7 @@
> }
> rce->isActive = true;
> rce->scenecut = false;
> + rce->isFadeEnd = curFrame->m_lowres.bIsFadeEnd;
> bool isRefFrameScenecut = m_sliceType!= I_SLICE &&
> m_curSlice->m_refFrameList[0][0]->m_lowres.bScenecut;
> m_isFirstMiniGop = m_sliceType == I_SLICE ? true : m_isFirstMiniGop;
> if (curFrame->m_lowres.bScenecut)
> @@ -1373,6 +1374,8 @@
> m_numBframesInPattern++;
> }
> }
> + if (rce->isFadeEnd)
> + m_isPatternPresent = true;
> }
> /* For a scenecut that occurs within the mini-gop, enable scene
> transition
> * switch until the next mini-gop to ensure a min qp for all the
> frames within
> @@ -2097,7 +2100,7 @@
> double abrBuffer = 2 * m_rateTolerance * m_bitrate;
>
> // Check if current Slice is a scene cut that follows low
> detailed/blank frames
> - if (rce->lastSatd > 4 * rce->movingAvgSum || rce->scenecut)
> + if (rce->lastSatd > 4 * rce->movingAvgSum || rce->scenecut ||
> rce->isFadeEnd)
> {
> if (!m_isAbrReset && rce->movingAvgSum > 0
> && (m_isPatternPresent || !m_param->bframes))
> @@ -2110,7 +2113,7 @@
> shrtTermTotalBitsSum += m_encodedBitsWindow[i];
> double underflow = (shrtTermTotalBitsSum -
> shrtTermWantedBits) / abrBuffer;
> const double epsilon = 0.0001f;
> - if (underflow < epsilon && !isFrameDone)
> + if ((underflow < epsilon || rce->isFadeEnd) && !isFrameDone)
> {
> init(*m_curSlice->m_sps);
> m_shortTermCplxSum = rce->lastSatd /
> (CLIP_DURATION(m_frameDuration) / BASE_FRAME_DURATION);
> diff -r 39b35ea86283 -r eb2ecf2d2f72 source/encoder/ratecontrol.h
> --- a/source/encoder/ratecontrol.h Tue Mar 26 10:31:41 2019 +0530
> +++ b/source/encoder/ratecontrol.h Mon Apr 22 11:11:35 2019 +0530
> @@ -115,6 +115,7 @@
> HRDTiming *hrdTiming;
> int rpsIdx;
> RPS rpsData;
> + bool isFadeEnd;
> };
>
> class RateControl
> diff -r 39b35ea86283 -r eb2ecf2d2f72 source/encoder/slicetype.cpp
> --- a/source/encoder/slicetype.cpp Tue Mar 26 10:31:41 2019 +0530
> +++ b/source/encoder/slicetype.cpp Mon Apr 22 11:11:35 2019 +0530
> @@ -459,17 +459,21 @@
> }
> }
>
> - if (param->bDynamicRefine)
> + if (param->bDynamicRefine || param->bEnableFades)
> {
> - int blockXY = 0;
> + uint64_t blockXY = 0, rowVariance = 0;
> + curFrame->m_lowres.frameVariance = 0;
> for (int blockY = 0; blockY < maxRow; blockY += loopIncr)
> {
> for (int blockX = 0; blockX < maxCol; blockX += loopIncr)
> {
> curFrame->m_lowres.blockVariance[blockXY] =
> acEnergyCu(curFrame, blockX, blockY, param->internalCsp, param->rc.qgSize);
> + rowVariance += curFrame->m_lowres.blockVariance[blockXY];
> blockXY++;
> }
> + curFrame->m_lowres.frameVariance += (rowVariance / maxCol);
> }
> + curFrame->m_lowres.frameVariance /= maxRow;
> }
> }
>
> @@ -757,6 +761,9 @@
> m_8x8Width = ((m_param->sourceWidth / 2) + X265_LOWRES_CU_SIZE - 1)
> >> X265_LOWRES_CU_BITS;
> m_cuCount = m_8x8Width * m_8x8Height;
> m_8x8Blocks = m_8x8Width > 2 && m_8x8Height > 2 ? (m_cuCount + 4 - 2
> * (m_8x8Width + m_8x8Height)) : m_cuCount;
> + m_isFadeIn = false;
> + m_fadeCount = 0;
> + m_fadeStart = -1;
>
> /* Allow the strength to be adjusted via qcompress, since the two
> concepts
> * are very similar. */
> @@ -1179,7 +1186,6 @@
> void Lookahead::slicetypeDecide()
> {
> PreLookaheadGroup pre(*this);
> -
> Lowres* frames[X265_LOOKAHEAD_MAX + X265_BFRAME_MAX + 4];
> Frame* list[X265_BFRAME_MAX + 4];
> memset(frames, 0, sizeof(frames));
> @@ -1224,6 +1230,54 @@
> pre.waitForExit();
> }
>
> + if(m_param->bEnableFades)
> + {
> + int j, endIndex = 0, length = X265_BFRAME_MAX + 4;
> + for (j = 0; j < length; j++)
> + m_frameVariance[j] = -1;
> + for (j = 0; list[j] != NULL; j++)
> + m_frameVariance[list[j]->m_poc % length] =
> list[j]->m_lowres.frameVariance;
> + for (int k = list[0]->m_poc % length; k <= list[j - 1]->m_poc %
> length; k++)
> + {
> + if (m_frameVariance[k] == -1)
> + break;
> + if((k > 0 && m_frameVariance[k] >= m_frameVariance[k - 1]) ||
> + (k == 0 && m_frameVariance[k] >= m_frameVariance[length -
> 1]))
> + {
> + m_isFadeIn = true;
> + if (m_fadeCount == 0 && m_fadeStart == -1)
> + {
> + for(int temp = list[0]->m_poc; temp <= list[j -
> 1]->m_poc; temp++)
> + if (k == temp % length) {
> + m_fadeStart = temp ? temp - 1 : 0;
> + break;
> + }
> + }
> + m_fadeCount = list[endIndex]->m_poc > m_fadeStart ?
> list[endIndex]->m_poc - m_fadeStart : 0;
> + endIndex++;
> + }
> + else
> + {
> + if (m_isFadeIn && m_fadeCount >= m_param->fpsNum /
> m_param->fpsDenom)
> + {
> + for (int temp = 0; list[temp] != NULL; temp++)
> + {
> + if (list[temp]->m_poc == m_fadeStart +
> (int)m_fadeCount)
> + {
> + list[temp]->m_lowres.bIsFadeEnd = true;
> + break;
> + }
> + }
> + }
> + m_isFadeIn = false;
> + m_fadeCount = 0;
> + m_fadeStart = -1;
> + }
> + if (k == length - 1)
> + k = -1;
> + }
> + }
> +
> if (m_lastNonB && !m_param->rc.bStatRead &&
> ((m_param->bFrameAdaptive && m_param->bframes) ||
> m_param->rc.cuTree || m_param->scenecutThreshold ||
> @@ -1283,6 +1337,9 @@
> frm.sliceType = m_param->bOpenGOP && m_lastKeyframe
> >= 0 ? X265_TYPE_I : X265_TYPE_IDR;
> }
> }
> + if (frm.bIsFadeEnd){
> + frm.sliceType = m_param->bOpenGOP && m_lastKeyframe >= 0
> ? X265_TYPE_I : X265_TYPE_IDR;
> + }
> for (int i = 0; i < m_param->rc.zonefileCount; i++)
> {
> int curZoneStart = m_param->rc.zones[i].startFrame;
> diff -r 39b35ea86283 -r eb2ecf2d2f72 source/encoder/slicetype.h
> --- a/source/encoder/slicetype.h Tue Mar 26 10:31:41 2019 +0530
> +++ b/source/encoder/slicetype.h Mon Apr 22 11:11:35 2019 +0530
> @@ -134,6 +134,10 @@
> bool m_isSceneTransition;
> int m_numPools;
> bool m_extendGopBoundary;
> + double m_frameVariance[X265_BFRAME_MAX + 4];
> + bool m_isFadeIn;
> + uint64_t m_fadeCount;
> + int m_fadeStart;
> Lookahead(x265_param *param, ThreadPool *pool);
> #if DETAILED_CU_STATS
> int64_t m_slicetypeDecideElapsedTime;
> diff -r 39b35ea86283 -r eb2ecf2d2f72 source/test/regression-tests.txt
> --- a/source/test/regression-tests.txt Tue Mar 26 10:31:41 2019 +0530
> +++ b/source/test/regression-tests.txt Mon Apr 22 11:11:35 2019 +0530
> @@ -151,6 +151,7 @@
> Kimono1_1920x1080_24_400.yuv,--preset placebo --ctu 32 --max-tu-size 8
> --limit-tu 2
> big_buck_bunny_360p24.y4m, --keyint 60 --min-keyint 40 --gop-lookahead 14
> BasketballDrive_1920x1080_50.y4m, --preset medium --no-open-gop --keyint
> 50 --min-keyint 50 --radl 2 --vbv-maxrate 5000 --vbv-bufsize 5000
> +big_buck_bunny_360p24.y4m, --bitrate 500 --fades
>
> # Main12 intraCost overflow bug test
> 720p50_parkrun_ter.y4m,--preset medium
> diff -r 39b35ea86283 -r eb2ecf2d2f72 source/x265.h
> --- a/source/x265.h Tue Mar 26 10:31:41 2019 +0530
> +++ b/source/x265.h Mon Apr 22 11:11:35 2019 +0530
> @@ -1771,6 +1771,10 @@
>
> /* SVT-HEVC param structure. For internal use when SVT HEVC encoder
> is enabled */
> void* svtHevcParam;
> +
> + /* Detect fade-in regions. Enforces I-slice for the brightest point.
> + Re-init RC history at that point in ABR mode. Default is disabled.
> */
> + int bEnableFades;
> } x265_param;
> /* x265_param_alloc:
> * Allocates an x265_param instance. The returned param structure is not
> diff -r 39b35ea86283 -r eb2ecf2d2f72 source/x265cli.h
> --- a/source/x265cli.h Tue Mar 26 10:31:41 2019 +0530
> +++ b/source/x265cli.h Mon Apr 22 11:11:35 2019 +0530
> @@ -124,6 +124,8 @@
> { "scenecut", required_argument, NULL, 0 },
> { "no-scenecut", no_argument, NULL, 0 },
> { "scenecut-bias", required_argument, NULL, 0 },
> + { "fades", no_argument, NULL, 0 },
> + { "no-fades", no_argument, NULL, 0 },
> { "radl", required_argument, NULL, 0 },
> { "ctu-info", required_argument, NULL, 0 },
> { "intra-refresh", no_argument, NULL, 0 },
> @@ -471,6 +473,7 @@
> H0(" --no-scenecut Disable adaptive I-frame
> decision\n");
> H0(" --scenecut <integer> How aggressively to insert extra
> I-frames. Default %d\n", param->scenecutThreshold);
> H1(" --scenecut-bias <0..100.0> Bias for scenecut detection.
> Default %.2f\n", param->scenecutBias);
> + H0(" --[no-]fades Enable detection and handling of
> fade-in regions. Default %s\n", OPT(param->bEnableFades));
> H0(" --radl <integer> Number of RADL pictures allowed
> in front of IDR. Default %d\n", param->radl);
> H0(" --intra-refresh Use Periodic Intra Refresh
> instead of IDR frames\n");
> H0(" --rc-lookahead <integer> Number of frames for frame-type
> lookahead (determines encoder latency) Default %d\n",
> param->lookaheadDepth);
> _______________________________________________
> x265-devel mailing list
> x265-devel at videolan.org
> https://mailman.videolan.org/listinfo/x265-devel
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20190521/4df2c187/attachment-0001.html>
More information about the x265-devel
mailing list