[x265] [PATCH] Extend gop boundary by doing gop lookahead

Ashok Kumar Mishra ashok at multicorewareinc.com
Fri Dec 1 16:20:47 CET 2017


Thanks, Pushed.

On Fri, Dec 1, 2017 at 10:47 AM, Aruna Matheswaran <
aruna at multicorewareinc.com> wrote:

> I have resent the patch after fixing a warning.
> Thanks,
> Aruna
>
> On Fri, Dec 1, 2017 at 10:46 AM, <aruna at multicorewareinc.com> wrote:
>
>> # HG changeset patch
>> # User Aruna Matheswaran <aruna at multicorewareinc.com>
>> # Date 1511241504 -19800
>> #      Tue Nov 21 10:48:24 2017 +0530
>> # Node ID 805ac1fd3e058a590ffc65126c884ceea0473b38
>> # Parent  b1dfa312234ed72c3541831a15f307feaf79484d
>> Extend gop boundary by doing gop lookahead
>>
>> diff -r b1dfa312234e -r 805ac1fd3e05 doc/reST/cli.rst
>> --- a/doc/reST/cli.rst  Thu Nov 30 10:06:49 2017 +0530
>> +++ b/doc/reST/cli.rst  Tue Nov 21 10:48:24 2017 +0530
>> @@ -1374,6 +1374,17 @@
>>
>>         **Range of values:** Between the maximum consecutive bframe count
>> (:option:`--bframes`) and 250
>>
>> +.. option:: --gop-lookahead <integer>
>> +
>> +        Number of frames for GOP boundary decision lookahead. If a
>> scenecut frame is found
>> +        within this from the gop boundary set by `--keyint`, the GOP
>> will be extented until such a point,
>> +        otherwise the GOP will be terminated as set by `--keyint`.
>> Default 0.
>> +
>> +        **Range of values:** Between 0 and (`--rc-lookahead` - mini-GOP
>> length)
>> +
>> +        It is recommended to have `--gop-lookahaed` less than
>> `--min-keyint` as scenecuts beyond
>> +        `--min-keyint` are already being coded as keyframes.
>> +
>>  .. option:: --lookahead-slices <0..16>
>>
>>         Use multiple worker threads to measure the estimated cost of each
>> frame
>> diff -r b1dfa312234e -r 805ac1fd3e05 source/CMakeLists.txt
>> --- a/source/CMakeLists.txt     Thu Nov 30 10:06:49 2017 +0530
>> +++ b/source/CMakeLists.txt     Tue Nov 21 10:48:24 2017 +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 146)
>> +set(X265_BUILD 147)
>>  configure_file("${PROJECT_SOURCE_DIR}/x265.def.in"
>>                 "${PROJECT_BINARY_DIR}/x265.def")
>>  configure_file("${PROJECT_SOURCE_DIR}/x265_config.h.in"
>> diff -r b1dfa312234e -r 805ac1fd3e05 source/common/param.cpp
>> --- a/source/common/param.cpp   Thu Nov 30 10:06:49 2017 +0530
>> +++ b/source/common/param.cpp   Tue Nov 21 10:48:24 2017 +0530
>> @@ -144,6 +144,7 @@
>>      /* Coding Structure */
>>      param->keyframeMin = 0;
>>      param->keyframeMax = 250;
>> +    param->gopLookahead = 0;
>>      param->bOpenGOP = 1;
>>      param->bframes = 4;
>>      param->lookaheadDepth = 20;
>> @@ -1004,6 +1005,7 @@
>>                  bError = true;
>>              }
>>           }
>> +        OPT("gop-lookahead") p->gopLookahead = atoi(value);
>>          else
>>              return X265_PARAM_BAD_NAME;
>>      }
>> @@ -1314,6 +1316,8 @@
>>            "Valid penalty for 32x32 intra TU in non-I slices. 0:disabled
>> 1:RD-penalty 2:maximum");
>>      CHECK(param->keyframeMax < -1,
>>            "Invalid max IDR period in frames. value should be greater
>> than -1");
>> +    CHECK(param->gopLookahead < -1,
>> +          "GOP lookahead must be greater than -1");
>>      CHECK(param->decodedPictureHashSEI < 0 ||
>> param->decodedPictureHashSEI > 3,
>>            "Invalid hash option. Decoded Picture Hash SEI 0: disabled, 1:
>> MD5, 2: CRC, 3: Checksum");
>>      CHECK(param->rc.vbvBufferSize < 0,
>> @@ -1561,6 +1565,7 @@
>>      BOOL(p->bOpenGOP, "open-gop");
>>      s += sprintf(s, " min-keyint=%d", p->keyframeMin);
>>      s += sprintf(s, " keyint=%d", p->keyframeMax);
>> +    s += sprintf(s, " gop-lookahead=%d", p->gopLookahead);
>>      s += sprintf(s, " bframes=%d", p->bframes);
>>      s += sprintf(s, " b-adapt=%d", p->bFrameAdaptive);
>>      BOOL(p->bBPyramid, "b-pyramid");
>> diff -r b1dfa312234e -r 805ac1fd3e05 source/encoder/slicetype.cpp
>> --- a/source/encoder/slicetype.cpp      Thu Nov 30 10:06:49 2017 +0530
>> +++ b/source/encoder/slicetype.cpp      Tue Nov 21 10:48:24 2017 +0530
>> @@ -589,6 +589,7 @@
>>      m_outputSignalRequired = false;
>>      m_isActive = true;
>>      m_inputCount = 0;
>> +    m_extendGopBoundary = false;
>>
>>      m_8x8Height = ((m_param->sourceHeight / 2) + X265_LOWRES_CU_SIZE -
>> 1) >> X265_LOWRES_CU_BITS;
>>      m_8x8Width = ((m_param->sourceWidth / 2) + X265_LOWRES_CU_SIZE - 1)
>> >> X265_LOWRES_CU_BITS;
>> @@ -647,6 +648,11 @@
>>          m_numCoopSlices = 1;
>>      }
>>
>> +    if (param->gopLookahead && (param->gopLookahead >
>> (param->lookaheadDepth - param->bframes - 2)))
>> +    {
>> +        param->gopLookahead = X265_MAX(0, param->lookaheadDepth -
>> param->bframes - 2);
>> +        x265_log(param, X265_LOG_WARNING, "Gop-lookahead cannot be
>> greater than (rc-lookahead - length of the mini-gop); Clipping
>> gop-lookahead to %d\n", param->gopLookahead);
>> +    }
>>  #if DETAILED_CU_STATS
>>      m_slicetypeDecideElapsedTime = 0;
>>      m_preLookaheadElapsedTime = 0;
>> @@ -1086,7 +1092,8 @@
>>              x265_log(m_param, X265_LOG_WARNING, "B-ref at frame %d
>> incompatible with B-pyramid and %d reference frames\n",
>>                       frm.sliceType, m_param->maxNumReferences);
>>          }
>> -        if ((!m_param->bIntraRefresh || frm.frameNum == 0) &&
>> frm.frameNum - m_lastKeyframe >= m_param->keyframeMax)
>> +        if ((!m_param->bIntraRefresh || frm.frameNum == 0) &&
>> frm.frameNum - m_lastKeyframe >= m_param->keyframeMax &&
>> +            (!m_extendGopBoundary || frm.frameNum - m_lastKeyframe >=
>> m_param->keyframeMax + m_param->gopLookahead))
>>          {
>>              if (frm.sliceType == X265_TYPE_AUTO || frm.sliceType ==
>> X265_TYPE_I)
>>                  frm.sliceType = m_param->bOpenGOP && m_lastKeyframe >= 0
>> ? X265_TYPE_I : X265_TYPE_IDR;
>> @@ -1379,8 +1386,13 @@
>>      }
>>
>>      frames[framecnt + 1] = NULL;
>> +    int keyFrameLimit = m_param->keyframeMax + m_lastKeyframe -
>> frames[0]->frameNum - 1;
>> +    if (m_param->gopLookahead && keyFrameLimit <= m_param->bframes + 1)
>> +        keyintLimit = keyFrameLimit + m_param->gopLookahead;
>> +    else
>> +        keyintLimit = keyFrameLimit;
>>
>> -    keyintLimit = m_param->keyframeMax - frames[0]->frameNum +
>> m_lastKeyframe - 1;
>> +
>>      origNumFrames = numFrames = m_param->bIntraRefresh ? framecnt :
>> X265_MIN(framecnt, keyintLimit);
>>
>>      if (bIsVbvLookahead)
>> @@ -1473,6 +1485,26 @@
>>          return;
>>      }
>>
>> +    if (m_param->gopLookahead && (keyFrameLimit >= 0) && (keyFrameLimit
>> <= m_param->bframes + 1))
>> +    {
>> +        bool sceneTransition = m_isSceneTransition;
>> +        m_extendGopBoundary = false;
>> +        for (int i = m_param->bframes + 1; i < origNumFrames; i +=
>> m_param->bframes + 1)
>> +        {
>> +            scenecut(frames, i, i + 1, true, origNumFrames);
>> +            for (int j = i + 1; j <= X265_MIN(i + m_param->bframes + 1,
>> origNumFrames); j++)
>> +            {
>> +                if (frames[j]->bScenecut && scenecutInternal(frames, j -
>> 1, j, true) )
>> +                {
>> +                    m_extendGopBoundary = true;
>> +                    break;
>> +                }
>> +            }
>> +            if (m_extendGopBoundary)
>> +                break;
>> +        }
>> +        m_isSceneTransition = sceneTransition;
>> +    }
>>      if (m_param->bframes)
>>      {
>>          if (m_param->bFrameAdaptive == X265_B_ADAPT_TRELLIS)
>> @@ -1579,6 +1611,9 @@
>>      if (m_param->rc.cuTree)
>>          cuTree(frames, X265_MIN(numFrames, m_param->keyframeMax),
>> bKeyframe);
>>
>> +    if (m_param->gopLookahead && (keyFrameLimit >= 0) && (keyFrameLimit
>> <= m_param->bframes + 1) && !m_extendGopBoundary)
>> +        keyintLimit = keyFrameLimit;
>> +
>>      if (!m_param->bIntraRefresh)
>>          for (int j = keyintLimit + 1; j <= numFrames; j +=
>> m_param->keyframeMax)
>>          {
>> @@ -1589,7 +1624,8 @@
>>      if (bIsVbvLookahead)
>>          vbvLookahead(frames, numFrames, bKeyframe);
>>
>> -     int maxp1 = X265_MIN(m_param->bframes + 1, origNumFrames);
>> +    int maxp1 = X265_MIN(m_param->bframes + 1, origNumFrames);
>> +
>>      /* Restore frame types for all frames that haven't actually been
>> decided yet. */
>>      for (int j = resetStart; j <= numFrames; j++)
>>      {
>> @@ -1613,8 +1649,8 @@
>>          bool fluctuate = false;
>>          bool noScenecuts = false;
>>          int64_t avgSatdCost = 0;
>> -        if (frames[0]->costEst[1][0] > -1)
>> -            avgSatdCost = frames[0]->costEst[1][0];
>> +        if (frames[p0]->costEst[p1 - p0][0] > -1)
>> +            avgSatdCost = frames[p0]->costEst[p1 - p0][0];
>>          int cnt = 1;
>>          /* Where A and B are scenes: AAAAAABBBAAAAAA
>>           * If BBB is shorter than (maxp1-p0), it is detected as a flash
>> @@ -1703,7 +1739,7 @@
>>
>>      int64_t icost = frame->costEst[0][0];
>>      int64_t pcost = frame->costEst[p1 - p0][0];
>> -    int gopSize = frame->frameNum - m_lastKeyframe;
>> +    int gopSize = (frame->frameNum - m_lastKeyframe) %
>> m_param->keyframeMax;
>>      float threshMax = (float)(m_param->scenecutThreshold / 100.0);
>>
>>      /* magic numbers pulled out of thin air */
>> diff -r b1dfa312234e -r 805ac1fd3e05 source/encoder/slicetype.h
>> --- a/source/encoder/slicetype.h        Thu Nov 30 10:06:49 2017 +0530
>> +++ b/source/encoder/slicetype.h        Tue Nov 21 10:48:24 2017 +0530
>> @@ -132,6 +132,7 @@
>>      bool          m_filled;
>>      bool          m_isSceneTransition;
>>      int           m_numPools;
>> +    bool          m_extendGopBoundary;
>>      Lookahead(x265_param *param, ThreadPool *pool);
>>  #if DETAILED_CU_STATS
>>      int64_t       m_slicetypeDecideElapsedTime;
>> diff -r b1dfa312234e -r 805ac1fd3e05 source/test/regression-tests.txt
>> --- a/source/test/regression-tests.txt  Thu Nov 30 10:06:49 2017 +0530
>> +++ b/source/test/regression-tests.txt  Tue Nov 21 10:48:24 2017 +0530
>> @@ -150,6 +150,7 @@
>>  Kimono1_1920x1080_24_400.yuv,--preset medium --rdoq-level 0
>> --limit-refs 3 --slices 2
>>  Kimono1_1920x1080_24_400.yuv,--preset veryslow --crf 4 --cu-lossless
>> --slices 2 --limit-refs 3 --limit-modes
>>  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 20
>>
>>  # Main12 intraCost overflow bug test
>>  720p50_parkrun_ter.y4m,--preset medium
>> diff -r b1dfa312234e -r 805ac1fd3e05 source/x265.h
>> --- a/source/x265.h     Thu Nov 30 10:06:49 2017 +0530
>> +++ b/source/x265.h     Tue Nov 21 10:48:24 2017 +0530
>> @@ -1535,6 +1535,11 @@
>>
>>      /* Allow the encoder to have a copy of the planes of x265_picture in
>> Frame */
>>      int       bCopyPicToFrame;
>> +
>> +    /*Number of frames for GOP boundary decision lookahead.If a scenecut
>> frame is found
>> +    * within this from the gop boundary set by keyint, the GOP will be
>> extented until such a point,
>> +    * otherwise the GOP will be terminated as set by keyint*/
>> +    int       gopLookahead;
>>  } x265_param;
>>
>>  /* x265_param_alloc:
>> diff -r b1dfa312234e -r 805ac1fd3e05 source/x265cli.h
>> --- a/source/x265cli.h  Thu Nov 30 10:06:49 2017 +0530
>> +++ b/source/x265cli.h  Tue Nov 21 10:48:24 2017 +0530
>> @@ -119,6 +119,7 @@
>>      { "open-gop",             no_argument, NULL, 0 },
>>      { "keyint",         required_argument, NULL, 'I' },
>>      { "min-keyint",     required_argument, NULL, 'i' },
>> +    { "gop-lookahead",  required_argument, NULL, 0 },
>>      { "scenecut",       required_argument, NULL, 0 },
>>      { "no-scenecut",          no_argument, NULL, 0 },
>>      { "scenecut-bias",  required_argument, NULL, 0 },
>> @@ -418,6 +419,7 @@
>>      H0("   --[no-]open-gop               Enable open-GOP, allows I
>> slices to be non-IDR. Default %s\n", OPT(param->bOpenGOP));
>>      H0("-I/--keyint <integer>            Max IDR period in frames. -1
>> for infinite-gop. Default %d\n", param->keyframeMax);
>>      H0("-i/--min-keyint <integer>        Scenecuts closer together than
>> this are coded as I, not IDR. Default: auto\n");
>> +    H0("   --gop-lookahead <integer>     Extends gop boundary if a
>> scenecut is found within this from keyint boundary. Default 0\n");
>>      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);
>>
>
>
> _______________________________________________
> 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/20171201/67ba4aed/attachment-0001.html>


More information about the x265-devel mailing list