[x265] [PATCH] Add vbv-end tolerance check

Alex Giladi alex.giladi at gmail.com
Mon Jun 11 19:26:25 CEST 2018


This may still break HRD compliance -- imagine you have a large amount of
chunks (hundreds or thousands per movie) which you encode in parallel.
Under VBV-based (VBV or VBV+CRF) rate control you try running as close to
the buffer capacity as you can. If uncoordinated overshoot of e.g. 4% in
buffer fulness occurs sufficiently frequently, chunks towards the end may
overflow as we developed a drift between the real CPB fulness and the CPB
fulness assumed by x265 encoding a chunk.

Hence this patch breaks HRD compatibility for parallel encoding of any
sufficiently complex long-form content. To make things more interesting,
this breakage is not deterministic.

You can allow fullness which is less than vbv-end. This would mean that
towards the end of the movie you may be under-utilizing the CPB, but you
will not generate incompliant streams.

On Mon, Jun 11, 2018 at 1:24 AM, Aruna Matheswaran <
aruna at multicorewareinc.com> wrote:

>
>
> On Mon, Jun 11, 2018 at 3:34 AM, Alex Giladi <alex.giladi at gmail.com>
> wrote:
>
>> Does this "5% tolerance" imply that CPB fullness as defined by vbv-end
>> can be exceeded by 5%?
>>
>
> yes, the CPB fullness can vary by +/- 5 % from the value defined by
> vbv-end.
>
>>
>> On Fri, Jun 8, 2018 at 6:39 AM, <aruna at multicorewareinc.com> wrote:
>>
>>> # HG changeset patch
>>> # User Aruna Matheswaran <aruna at multicorewareinc.com>
>>> # Date 1523005500 -19800
>>> #      Fri Apr 06 14:35:00 2018 +0530
>>> # Node ID ed853c4af6710a991d0cdf4bf68e00fe32edaacb
>>> # Parent  182914e1d201395d152e310db7f5cf29ab3c787e
>>> Add vbv-end tolerance check
>>>
>>> This will attempt to keep the desired fraction of the target buffer (
>>> specified
>>> by vbv-end ) empty within a defined error margin of 5%.
>>>
>>> diff -r 182914e1d201 -r ed853c4af671 source/encoder/ratecontrol.cpp
>>> --- a/source/encoder/ratecontrol.cpp    Wed Mar 14 12:30:28 2018 +0530
>>> +++ b/source/encoder/ratecontrol.cpp    Fri Apr 06 14:35:00 2018 +0530
>>> @@ -1282,6 +1282,12 @@
>>>          m_predictedBits = m_totalBits;
>>>          updateVbvPlan(enc);
>>>          rce->bufferFill = m_bufferFill;
>>> +        rce->vbvEndAdj = false;
>>> +        if (m_param->vbvBufferEnd && rce->encodeOrder >=
>>> m_param->vbvEndFrameAdjust * m_param->totalFrames)
>>> +        {
>>> +            rce->vbvEndAdj = true;
>>> +            rce->targetFill = 0;
>>> +        }
>>>
>>>          int mincr = enc->m_vps.ptl.minCrForLevel;
>>>          /* Profiles above Main10 don't require maxAU size check, so
>>> just set the maximum to a large value. */
>>> @@ -2173,12 +2179,12 @@
>>>                      curBits = predictSize(&m_pred[predType],
>>> frameQ[type], (double)satd);
>>>                      bufferFillCur -= curBits;
>>>                  }
>>> -                if (m_param->vbvBufferEnd && rce->encodeOrder >=
>>> m_param->vbvEndFrameAdjust * m_param->totalFrames)
>>> +                if (rce->vbvEndAdj)
>>>                  {
>>>                      bool loopBreak = false;
>>>                      double bufferDiff = m_param->vbvBufferEnd -
>>> (m_bufferFill / m_bufferSize);
>>> -                    targetFill = m_bufferFill + m_bufferSize *
>>> (bufferDiff / (m_param->totalFrames - rce->encodeOrder));
>>> -                    if (bufferFillCur < targetFill)
>>> +                    rce->targetFill = m_bufferFill + m_bufferSize *
>>> (bufferDiff / (m_param->totalFrames - rce->encodeOrder));
>>> +                    if (bufferFillCur < rce->targetFill)
>>>                      {
>>>                          q *= 1.01;
>>>                          loopTerminate |= 1;
>>> @@ -2421,6 +2427,7 @@
>>>          double rcTol = bufferLeftPlanned / m_param->frameNumThreads *
>>> m_rateTolerance;
>>>          int32_t encodedBitsSoFar = 0;
>>>          double accFrameBits = predictRowsSizeSum(curFrame, rce, qpVbv,
>>> encodedBitsSoFar);
>>> +        double vbvEndBias = 0.95;
>>>
>>>          /* * Don't increase the row QPs until a sufficent amount of the
>>> bits of
>>>           * the frame have been processed, in case a flat area at the
>>> top of the
>>> @@ -2442,7 +2449,8 @@
>>>          while (qpVbv < qpMax
>>>                 && (((accFrameBits > rce->frameSizePlanned + rcTol) ||
>>>                     (rce->bufferFill - accFrameBits < bufferLeftPlanned
>>> * 0.5) ||
>>> -                   (accFrameBits > rce->frameSizePlanned && qpVbv <
>>> rce->qpNoVbv))
>>> +                   (accFrameBits > rce->frameSizePlanned && qpVbv <
>>> rce->qpNoVbv) ||
>>> +                   (rce->vbvEndAdj && ((rce->bufferFill - accFrameBits)
>>> < (rce->targetFill * vbvEndBias))))
>>>                     && (!m_param->rc.bStrictCbr ? 1 : abrOvershoot >
>>> 0.1)))
>>>          {
>>>              qpVbv += stepSize;
>>> @@ -2453,7 +2461,8 @@
>>>          while (qpVbv > qpMin
>>>                 && (qpVbv > curEncData.m_rowStat[0].rowQp ||
>>> m_singleFrameVbv)
>>>                 && (((accFrameBits < rce->frameSizePlanned * 0.8f &&
>>> qpVbv <= prevRowQp)
>>> -                   || accFrameBits < (rce->bufferFill - m_bufferSize +
>>> m_bufferRate) * 1.1)
>>> +                   || accFrameBits < (rce->bufferFill - m_bufferSize +
>>> m_bufferRate) * 1.1
>>> +                   || (rce->vbvEndAdj && ((rce->bufferFill -
>>> accFrameBits) > (rce->targetFill * vbvEndBias))))
>>>                     && (!m_param->rc.bStrictCbr ? 1 : abrOvershoot < 0)))
>>>          {
>>>              qpVbv -= stepSize;
>>> diff -r 182914e1d201 -r ed853c4af671 source/encoder/ratecontrol.h
>>> --- a/source/encoder/ratecontrol.h      Wed Mar 14 12:30:28 2018 +0530
>>> +++ b/source/encoder/ratecontrol.h      Fri Apr 06 14:35:00 2018 +0530
>>> @@ -82,6 +82,8 @@
>>>      double  rowCplxrSum;
>>>      double  qpNoVbv;
>>>      double  bufferFill;
>>> +    double  targetFill;
>>> +    bool    vbvEndAdj;
>>>      double  frameDuration;
>>>      double  clippedDuration;
>>>      double  frameSizeEstimated; /* hold frameSize, updated from cu
>>> level vbv rc */
>>>
>>> _______________________________________________
>>> x265-devel mailing list
>>> x265-devel at videolan.org
>>> https://mailman.videolan.org/listinfo/x265-devel
>>>
>>>
>>
>> _______________________________________________
>> x265-devel mailing list
>> x265-devel at videolan.org
>> https://mailman.videolan.org/listinfo/x265-devel
>>
>>
>
> _______________________________________________
> 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/20180611/245c178e/attachment.html>


More information about the x265-devel mailing list