# HG changeset patch # User Pooja Venkatesan <[email protected]> # 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 <[email protected]> wrote: > # HG changeset patch > # User Pooja Venkatesan <[email protected]> > # 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 > [email protected] > https://mailman.videolan.org/listinfo/x265-devel >
_______________________________________________ x265-devel mailing list [email protected] https://mailman.videolan.org/listinfo/x265-devel
