[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