[x265] Fwd: [PATCH] encoding only the focused frames in the crf 2 pass

Dakshinya T R S dakshinya at multicorewareinc.com
Mon Sep 27 12:04:27 UTC 2021


---------- Forwarded message ---------
From: Liwei Wang <liwei at multicorewareinc.com>
Date: Sun, Sep 26, 2021 at 11:44 AM
Subject: Re: [x265] [PATCH] encoding only the focused frames in the crf 2
pass
To: Dakshinya T R S <dakshinya at multicorewareinc.com>
Cc: Mahesh Pittala <mahesh at multicorewareinc.com>


On Fri, Sep 24, 2021 at 1:34 PM Dakshinya T R S <
dakshinya at multicorewareinc.com> wrote:

> From d4ac086b18c41e6d146cd70524c581138b1186ec Mon Sep 17 00:00:00 2001
> From: lwWang <liwei at multicorewareinc.com>
> Date: Wed, 15 Sep 2021 10:39:51 +0800
> Subject: [PATCH 1/2] encoding only the focused frames in the crf 2 pass
>
> ---
>  source/common/frame.h          |   1 +
>  source/common/framedata.cpp    |   2 +-
>  source/common/param.cpp        |   1 +
>  source/encoder/encoder.cpp     |   1 +
>  source/encoder/ratecontrol.cpp | 240 ++++++++++++++++++---------------
>  source/encoder/ratecontrol.h   |   3 +
>  source/x265.h                  |   3 +
>  7 files changed, 138 insertions(+), 113 deletions(-)
>
> diff --git a/source/common/frame.h b/source/common/frame.h
> index dc5bbacf7..ac1185e81 100644
> --- a/source/common/frame.h
> +++ b/source/common/frame.h
> @@ -70,6 +70,7 @@ struct RcStats
>      double   count[4];
>      double   offset[4];
>      double   bufferFillFinal;
> +    int64_t  currentSatd;
>  };
>
>  class Frame
> diff --git a/source/common/framedata.cpp b/source/common/framedata.cpp
> index c77b017a8..70af8a248 100644
> --- a/source/common/framedata.cpp
> +++ b/source/common/framedata.cpp
> @@ -62,7 +62,7 @@ bool FrameData::create(const x265_param& param, const
> SPS& sps, int csp)
>      }
>      else
>          return false;
> -    CHECKED_MALLOC_ZERO(m_cuStat, RCStatCU, sps.numCUsInFrame);
> +    CHECKED_MALLOC_ZERO(m_cuStat, RCStatCU, sps.numCUsInFrame + 1);
>
[AM] What is the significance of this additional memory?
*[LW] to fix the random crush issue(heap corruption)*

>      CHECKED_MALLOC(m_rowStat, RCStatRow, sps.numCuInHeight);
>      reinit(sps);
>
> diff --git a/source/common/param.cpp b/source/common/param.cpp
> index 6751e0aa7..2c1583d93 100755
> --- a/source/common/param.cpp
> +++ b/source/common/param.cpp
> @@ -282,6 +282,7 @@ void x265_param_default(x265_param* param)
>      param->rc.bStatRead = 0;
>      param->rc.bStatWrite = 0;
>      param->rc.statFileName = NULL;
> +    param->rc.bEncFocusedFramesOnly = 0;
>      param->rc.complexityBlur = 20;
>      param->rc.qblur = 0.5;
>      param->rc.zoneCount = 0;
> diff --git a/source/encoder/encoder.cpp b/source/encoder/encoder.cpp
> index dee8fd85d..cc014a740 100644
> --- a/source/encoder/encoder.cpp
> +++ b/source/encoder/encoder.cpp
> @@ -2249,6 +2249,7 @@ int Encoder::encode(const x265_picture* pic_in,
> x265_picture* pic_out)
>                  outFrame->m_rcData->iCuCount =
> outFrame->m_encData->m_frameStats.percent8x8Intra * m_rateControl->m_ncu;
>                  outFrame->m_rcData->pCuCount =
> outFrame->m_encData->m_frameStats.percent8x8Inter * m_rateControl->m_ncu;
>                  outFrame->m_rcData->skipCuCount =
> outFrame->m_encData->m_frameStats.percent8x8Skip  * m_rateControl->m_ncu;
> +                outFrame->m_rcData->currentSatd =
> curEncoder->m_rce.coeffBits;
>              }
>
>              /* Allow this frame to be recycled if no frame encoders are
> using it for reference */
> diff --git a/source/encoder/ratecontrol.cpp
> b/source/encoder/ratecontrol.cpp
> index a4756de39..2c211022d 100644
> --- a/source/encoder/ratecontrol.cpp
> +++ b/source/encoder/ratecontrol.cpp
> @@ -1002,123 +1002,106 @@ bool RateControl::initPass2()
>      uint64_t allAvailableBits = uint64_t(m_param->rc.bitrate * 1000. *
> m_numEntries * m_frameDuration);
>      int startIndex, framesCount, endIndex;
>      int fps = X265_MIN(m_param->keyframeMax, (int)(m_fps + 0.5));
> +    int distance = fps << 1;
> +    distance = distance > m_param->keyframeMax ? (m_param->keyframeMax <<
> 1) : m_param->keyframeMax;
>      startIndex = endIndex = framesCount = 0;
> -    int diffQp = 0;
>      double targetBits = 0;
>      double expectedBits = 0;
> -    for (startIndex = m_start, endIndex = m_start; endIndex <
> m_numEntries; endIndex++)
> +    double targetBits2 = 0;
> +    double expectedBits2 = 0;
> +    double cpxSum = 0;
> +    double cpxSum2 = 0;
> +
> +    if (m_param->rc.rateControlMode == X265_RC_ABR)
>      {
> -        allConstBits += m_rce2Pass[endIndex].miscBits;
> -        allCodedBits += m_rce2Pass[endIndex].coeffBits +
> m_rce2Pass[endIndex].mvBits;
> -        if (m_param->rc.rateControlMode == X265_RC_CRF)
> +        for (startIndex = m_start, endIndex = m_start; endIndex <
> m_numEntries; endIndex++)
>          {
> -            framesCount = endIndex - startIndex + 1;
> -            diffQp += int (m_rce2Pass[endIndex].qpaRc -
> m_rce2Pass[endIndex].qpNoVbv);
> -            if (framesCount > fps)
> -                diffQp -= int (m_rce2Pass[endIndex - fps].qpaRc -
> m_rce2Pass[endIndex - fps].qpNoVbv);
> -            if (framesCount >= fps)
> -            {
> -                if (diffQp >= 1)
> -                {
> -                    if (!m_isQpModified && endIndex > fps)
> -                    {
> -                        double factor = 2;
> -                        double step = 0;
> -                        if (endIndex + fps >= m_numEntries)
> -                        {
> -                            m_start = endIndex - (endIndex % fps);
> -                            return true;
> -                        }
> -                        for (int start = endIndex + 1; start <= endIndex
> + fps && start < m_numEntries; start++)
> -                        {
> -                            RateControlEntry *rce = &m_rce2Pass[start];
> -                            targetBits += qScale2bits(rce,
> x265_qp2qScale(rce->qpNoVbv));
> -                            expectedBits += qScale2bits(rce, rce->qScale);
> -                        }
> -                        if (expectedBits < 0.95 * targetBits)
> -                        {
> -                            m_isQpModified = true;
> -                            m_isGopReEncoded = true;
> -                            while (endIndex + fps < m_numEntries)
> -                            {
> -                                step = pow(2, factor / 6.0);
> -                                expectedBits = 0;
> -                                for (int start = endIndex + 1; start <=
> endIndex + fps; start++)
> -                                {
> -                                    RateControlEntry *rce =
> &m_rce2Pass[start];
> -                                    rce->newQScale = rce->qScale / step;
> -                                    X265_CHECK(rce->newQScale >= 0, "new
> Qscale is negative\n");
> -                                    expectedBits += qScale2bits(rce,
> rce->newQScale);
> -                                    rce->newQp =
> x265_qScale2qp(rce->newQScale);
> -                                }
> -                                if (expectedBits >= targetBits && step >
> 1)
> -                                    factor *= 0.90;
> -                                else
> -                                    break;
> -                            }
> -
> -                            if (m_isVbv && endIndex + fps < m_numEntries)
> -                                if (!vbv2Pass((uint64_t)targetBits,
> endIndex + fps, endIndex + 1))
> -                                    return false;
> -
> -                            targetBits = 0;
> -                            expectedBits = 0;
> -
> -                            for (int start = endIndex - fps + 1; start <=
> endIndex; start++)
> -                            {
> -                                RateControlEntry *rce =
> &m_rce2Pass[start];
> -                                targetBits += qScale2bits(rce,
> x265_qp2qScale(rce->qpNoVbv));
> -                            }
> -                            while (1)
> -                            {
> -                                step = pow(2, factor / 6.0);
> -                                expectedBits = 0;
> -                                for (int start = endIndex - fps + 1;
> start <= endIndex; start++)
> -                                {
> -                                    RateControlEntry *rce =
> &m_rce2Pass[start];
> -                                    rce->newQScale = rce->qScale * step;
> -                                    X265_CHECK(rce->newQScale >= 0, "new
> Qscale is negative\n");
> -                                    expectedBits += qScale2bits(rce,
> rce->newQScale);
> -                                    rce->newQp =
> x265_qScale2qp(rce->newQScale);
> -                                }
> -                                if (expectedBits > targetBits && step > 1)
> -                                    factor *= 1.1;
> -                                else
> -                                     break;
> -                            }
> -                            if (m_isVbv)
> -                                if (!vbv2Pass((uint64_t)targetBits,
> endIndex, endIndex - fps + 1))
> -                                    return false;
> -                            diffQp = 0;
> -                            m_reencode = endIndex - fps + 1;
> -                            endIndex = endIndex + fps;
> -                            startIndex = endIndex + 1;
> -                            m_start = startIndex;
> -                            targetBits = expectedBits = 0;
> -                        }
> -                        else
> -                            targetBits = expectedBits = 0;
> -                    }
> -                }
> -                else
> -                    m_isQpModified = false;
> -            }
> +            allConstBits += m_rce2Pass[endIndex].miscBits;
> +            allCodedBits += m_rce2Pass[endIndex].coeffBits +
> m_rce2Pass[endIndex].mvBits;
>          }
> -    }
>
> -    if (m_param->rc.rateControlMode == X265_RC_ABR)
> -    {
>          if (allAvailableBits < allConstBits)
>          {
>              x265_log(m_param, X265_LOG_ERROR, "requested bitrate is too
> low. estimated minimum is %d kbps\n",
> -                     (int)(allConstBits * m_fps / framesCount * 1000.));
> +                (int)(allConstBits * m_fps / framesCount * 1000.));
>              return false;
>          }
>          if (!analyseABR2Pass(allAvailableBits))
>              return false;
> +
> +        return true;
> +    }
> +
> +    if (m_param->rc.rateControlMode != X265_RC_CRF)
> +    {
>
[AM] This condition will never hit. Please clarify why this is required.
*[LW] Yeah, you're right. It will never hit. I will remove this
check.Thanks*

> +        return true;
>      }
>

> -    m_start = X265_MAX(m_start, endIndex - fps);
> +    if (m_isQpModified)
> +    {
>
[AM] This condition will always hit. Please clarify why this check is
required.
*[LW] m_isQpModified may be false.  And in the uhdkit, the cappedvbr would
modify its value.*
[AM] Please include a conformance check in Encoder::configure() to disable
m_param->rc.bEncFocusedFramesOnly if either bStatRead or CRF is disabled.
[*LW] OK. I will add it. By the way, **bEncFocusedFramesOnly has been set
to be false by default in the x265_param_default()*
[AM] Update X265_BUILD, add help document, and add an entry for the new
param in info SEI.
Is this a param?API only option? If so, clarify that in the document. Else,
add a test CLI.
*[LW] OK. However, **bEncFocusedFramesOnly would only be used together with
cappedvbr in uhdkit. It could not be used alone in x25. So maybe it is
better to move it from the x265_param to the encoder or rateontrol?*

>          /* temporally blur quants */
>          double    qblur;
>

On Fri, Sep 24, 2021 at 5:02 PM Dakshinya T R S <
dakshinya at multicorewareinc.com> wrote:

>
>
> ---------- Forwarded message ---------
> From: Aruna Matheswaran <aruna at multicorewareinc.com>
> Date: Fri, Sep 24, 2021 at 2:26 PM
> Subject: Re: [x265] [PATCH] encoding only the focused frames in the crf 2
> pass
> To: Development for x265 <x265-devel at videolan.org>
>
>
>
>
> On Fri, Sep 24, 2021 at 1:34 PM Dakshinya T R S <
> dakshinya at multicorewareinc.com> wrote:
>
>> From d4ac086b18c41e6d146cd70524c581138b1186ec Mon Sep 17 00:00:00 2001
>> From: lwWang <liwei at multicorewareinc.com>
>> Date: Wed, 15 Sep 2021 10:39:51 +0800
>> Subject: [PATCH 1/2] encoding only the focused frames in the crf 2 pass
>>
>> ---
>>  source/common/frame.h          |   1 +
>>  source/common/framedata.cpp    |   2 +-
>>  source/common/param.cpp        |   1 +
>>  source/encoder/encoder.cpp     |   1 +
>>  source/encoder/ratecontrol.cpp | 240 ++++++++++++++++++---------------
>>  source/encoder/ratecontrol.h   |   3 +
>>  source/x265.h                  |   3 +
>>  7 files changed, 138 insertions(+), 113 deletions(-)
>>
>> diff --git a/source/common/frame.h b/source/common/frame.h
>> index dc5bbacf7..ac1185e81 100644
>> --- a/source/common/frame.h
>> +++ b/source/common/frame.h
>> @@ -70,6 +70,7 @@ struct RcStats
>>      double   count[4];
>>      double   offset[4];
>>      double   bufferFillFinal;
>> +    int64_t  currentSatd;
>>  };
>>
>>  class Frame
>> diff --git a/source/common/framedata.cpp b/source/common/framedata.cpp
>> index c77b017a8..70af8a248 100644
>> --- a/source/common/framedata.cpp
>> +++ b/source/common/framedata.cpp
>> @@ -62,7 +62,7 @@ bool FrameData::create(const x265_param& param, const
>> SPS& sps, int csp)
>>      }
>>      else
>>          return false;
>> -    CHECKED_MALLOC_ZERO(m_cuStat, RCStatCU, sps.numCUsInFrame);
>> +    CHECKED_MALLOC_ZERO(m_cuStat, RCStatCU, sps.numCUsInFrame + 1);
>>
> [AM] What is the significance of this additional memory?
>
>>      CHECKED_MALLOC(m_rowStat, RCStatRow, sps.numCuInHeight);
>>      reinit(sps);
>>
>> diff --git a/source/common/param.cpp b/source/common/param.cpp
>> index 6751e0aa7..2c1583d93 100755
>> --- a/source/common/param.cpp
>> +++ b/source/common/param.cpp
>> @@ -282,6 +282,7 @@ void x265_param_default(x265_param* param)
>>      param->rc.bStatRead = 0;
>>      param->rc.bStatWrite = 0;
>>      param->rc.statFileName = NULL;
>> +    param->rc.bEncFocusedFramesOnly = 0;
>>      param->rc.complexityBlur = 20;
>>      param->rc.qblur = 0.5;
>>      param->rc.zoneCount = 0;
>> diff --git a/source/encoder/encoder.cpp b/source/encoder/encoder.cpp
>> index dee8fd85d..cc014a740 100644
>> --- a/source/encoder/encoder.cpp
>> +++ b/source/encoder/encoder.cpp
>> @@ -2249,6 +2249,7 @@ int Encoder::encode(const x265_picture* pic_in,
>> x265_picture* pic_out)
>>                  outFrame->m_rcData->iCuCount =
>> outFrame->m_encData->m_frameStats.percent8x8Intra * m_rateControl->m_ncu;
>>                  outFrame->m_rcData->pCuCount =
>> outFrame->m_encData->m_frameStats.percent8x8Inter * m_rateControl->m_ncu;
>>                  outFrame->m_rcData->skipCuCount =
>> outFrame->m_encData->m_frameStats.percent8x8Skip  * m_rateControl->m_ncu;
>> +                outFrame->m_rcData->currentSatd =
>> curEncoder->m_rce.coeffBits;
>>              }
>>
>>              /* Allow this frame to be recycled if no frame encoders are
>> using it for reference */
>> diff --git a/source/encoder/ratecontrol.cpp
>> b/source/encoder/ratecontrol.cpp
>> index a4756de39..2c211022d 100644
>> --- a/source/encoder/ratecontrol.cpp
>> +++ b/source/encoder/ratecontrol.cpp
>> @@ -1002,123 +1002,106 @@ bool RateControl::initPass2()
>>      uint64_t allAvailableBits = uint64_t(m_param->rc.bitrate * 1000. *
>> m_numEntries * m_frameDuration);
>>      int startIndex, framesCount, endIndex;
>>      int fps = X265_MIN(m_param->keyframeMax, (int)(m_fps + 0.5));
>> +    int distance = fps << 1;
>> +    distance = distance > m_param->keyframeMax ? (m_param->keyframeMax
>> << 1) : m_param->keyframeMax;
>>      startIndex = endIndex = framesCount = 0;
>> -    int diffQp = 0;
>>      double targetBits = 0;
>>      double expectedBits = 0;
>> -    for (startIndex = m_start, endIndex = m_start; endIndex <
>> m_numEntries; endIndex++)
>> +    double targetBits2 = 0;
>> +    double expectedBits2 = 0;
>> +    double cpxSum = 0;
>> +    double cpxSum2 = 0;
>> +
>> +    if (m_param->rc.rateControlMode == X265_RC_ABR)
>>      {
>> -        allConstBits += m_rce2Pass[endIndex].miscBits;
>> -        allCodedBits += m_rce2Pass[endIndex].coeffBits +
>> m_rce2Pass[endIndex].mvBits;
>> -        if (m_param->rc.rateControlMode == X265_RC_CRF)
>> +        for (startIndex = m_start, endIndex = m_start; endIndex <
>> m_numEntries; endIndex++)
>>          {
>> -            framesCount = endIndex - startIndex + 1;
>> -            diffQp += int (m_rce2Pass[endIndex].qpaRc -
>> m_rce2Pass[endIndex].qpNoVbv);
>> -            if (framesCount > fps)
>> -                diffQp -= int (m_rce2Pass[endIndex - fps].qpaRc -
>> m_rce2Pass[endIndex - fps].qpNoVbv);
>> -            if (framesCount >= fps)
>> -            {
>> -                if (diffQp >= 1)
>> -                {
>> -                    if (!m_isQpModified && endIndex > fps)
>> -                    {
>> -                        double factor = 2;
>> -                        double step = 0;
>> -                        if (endIndex + fps >= m_numEntries)
>> -                        {
>> -                            m_start = endIndex - (endIndex % fps);
>> -                            return true;
>> -                        }
>> -                        for (int start = endIndex + 1; start <= endIndex
>> + fps && start < m_numEntries; start++)
>> -                        {
>> -                            RateControlEntry *rce = &m_rce2Pass[start];
>> -                            targetBits += qScale2bits(rce,
>> x265_qp2qScale(rce->qpNoVbv));
>> -                            expectedBits += qScale2bits(rce,
>> rce->qScale);
>> -                        }
>> -                        if (expectedBits < 0.95 * targetBits)
>> -                        {
>> -                            m_isQpModified = true;
>> -                            m_isGopReEncoded = true;
>> -                            while (endIndex + fps < m_numEntries)
>> -                            {
>> -                                step = pow(2, factor / 6.0);
>> -                                expectedBits = 0;
>> -                                for (int start = endIndex + 1; start <=
>> endIndex + fps; start++)
>> -                                {
>> -                                    RateControlEntry *rce =
>> &m_rce2Pass[start];
>> -                                    rce->newQScale = rce->qScale / step;
>> -                                    X265_CHECK(rce->newQScale >= 0, "new
>> Qscale is negative\n");
>> -                                    expectedBits += qScale2bits(rce,
>> rce->newQScale);
>> -                                    rce->newQp =
>> x265_qScale2qp(rce->newQScale);
>> -                                }
>> -                                if (expectedBits >= targetBits && step >
>> 1)
>> -                                    factor *= 0.90;
>> -                                else
>> -                                    break;
>> -                            }
>> -
>> -                            if (m_isVbv && endIndex + fps < m_numEntries)
>> -                                if (!vbv2Pass((uint64_t)targetBits,
>> endIndex + fps, endIndex + 1))
>> -                                    return false;
>> -
>> -                            targetBits = 0;
>> -                            expectedBits = 0;
>> -
>> -                            for (int start = endIndex - fps + 1; start
>> <= endIndex; start++)
>> -                            {
>> -                                RateControlEntry *rce =
>> &m_rce2Pass[start];
>> -                                targetBits += qScale2bits(rce,
>> x265_qp2qScale(rce->qpNoVbv));
>> -                            }
>> -                            while (1)
>> -                            {
>> -                                step = pow(2, factor / 6.0);
>> -                                expectedBits = 0;
>> -                                for (int start = endIndex - fps + 1;
>> start <= endIndex; start++)
>> -                                {
>> -                                    RateControlEntry *rce =
>> &m_rce2Pass[start];
>> -                                    rce->newQScale = rce->qScale * step;
>> -                                    X265_CHECK(rce->newQScale >= 0, "new
>> Qscale is negative\n");
>> -                                    expectedBits += qScale2bits(rce,
>> rce->newQScale);
>> -                                    rce->newQp =
>> x265_qScale2qp(rce->newQScale);
>> -                                }
>> -                                if (expectedBits > targetBits && step >
>> 1)
>> -                                    factor *= 1.1;
>> -                                else
>> -                                     break;
>> -                            }
>> -                            if (m_isVbv)
>> -                                if (!vbv2Pass((uint64_t)targetBits,
>> endIndex, endIndex - fps + 1))
>> -                                    return false;
>> -                            diffQp = 0;
>> -                            m_reencode = endIndex - fps + 1;
>> -                            endIndex = endIndex + fps;
>> -                            startIndex = endIndex + 1;
>> -                            m_start = startIndex;
>> -                            targetBits = expectedBits = 0;
>> -                        }
>> -                        else
>> -                            targetBits = expectedBits = 0;
>> -                    }
>> -                }
>> -                else
>> -                    m_isQpModified = false;
>> -            }
>> +            allConstBits += m_rce2Pass[endIndex].miscBits;
>> +            allCodedBits += m_rce2Pass[endIndex].coeffBits +
>> m_rce2Pass[endIndex].mvBits;
>>          }
>> -    }
>>
>> -    if (m_param->rc.rateControlMode == X265_RC_ABR)
>> -    {
>>          if (allAvailableBits < allConstBits)
>>          {
>>              x265_log(m_param, X265_LOG_ERROR, "requested bitrate is too
>> low. estimated minimum is %d kbps\n",
>> -                     (int)(allConstBits * m_fps / framesCount * 1000.));
>> +                (int)(allConstBits * m_fps / framesCount * 1000.));
>>              return false;
>>          }
>>          if (!analyseABR2Pass(allAvailableBits))
>>              return false;
>> +
>> +        return true;
>> +    }
>> +
>> +    if (m_param->rc.rateControlMode != X265_RC_CRF)
>> +    {
>>
> [AM] This condition will never hit. Please clarify why this is required.
>
>> +        return true;
>>      }
>>
>
>> -    m_start = X265_MAX(m_start, endIndex - fps);
>> +    if (m_isQpModified)
>> +    {
>>
> [AM] This condition will always hit. Please clarify why this check is
> required.
>
>> +        return true;
>> +    }
>> +
>> +    if (m_start + (fps << 1) > m_numEntries)
>> +    {
>> +        return true;
>> +    }
>> +
>> +    for (startIndex = m_start, endIndex = m_numEntries - 1; startIndex <
>> endIndex; startIndex++, endIndex--)
>> +    {
>> +        cpxSum += m_rce2Pass[startIndex].qScale /
>> m_rce2Pass[startIndex].coeffBits;
>> +        cpxSum2 += m_rce2Pass[endIndex].qScale /
>> m_rce2Pass[endIndex].coeffBits;
>> +
>> +        RateControlEntry *rce = &m_rce2Pass[startIndex];
>> +        targetBits += qScale2bits(rce, x265_qp2qScale(rce->qpNoVbv));
>> +        expectedBits += qScale2bits(rce, rce->qScale);
>> +
>> +        rce = &m_rce2Pass[endIndex];
>> +        targetBits2 += qScale2bits(rce, x265_qp2qScale(rce->qpNoVbv));
>> +        expectedBits2 += qScale2bits(rce, rce->qScale);
>> +    }
>> +
>> +    if (expectedBits < 0.95 * targetBits || expectedBits2 < 0.95 *
>> targetBits2)
>> +    {
>> +        if (cpxSum / cpxSum2 < 0.95 || cpxSum2 / cpxSum < 0.95)
>> +        {
>> +            m_isQpModified = true;
>> +            m_isGopReEncoded = true;
>> +
>> +            m_shortTermCplxSum = 0;
>> +            m_shortTermCplxCount = 0;
>> +            m_framesDone = m_start;
>> +
>> +            for (startIndex = m_start; startIndex < m_numEntries;
>> startIndex++)
>> +            {
>> +                m_shortTermCplxSum *= 0.5;
>> +                m_shortTermCplxCount *= 0.5;
>> +                m_shortTermCplxSum += m_rce2Pass[startIndex].currentSatd
>> / (CLIP_DURATION(m_frameDuration) / BASE_FRAME_DURATION);
>> +                m_shortTermCplxCount++;
>> +            }
>> +
>> +            m_bufferFill = m_rce2Pass[m_start - 1].bufferFill;
>> +            m_bufferFillFinal = m_rce2Pass[m_start - 1].bufferFillFinal;
>> +            m_bufferFillActual = m_rce2Pass[m_start -
>> 1].bufferFillActual;
>> +
>> +            m_reencode = m_start;
>> +            m_start = m_numEntries;
>> +        }
>> +        else
>> +        {
>> +
>> +            m_isQpModified = false;
>> +            m_isGopReEncoded = false;
>> +        }
>> +    }
>> +    else
>> +    {
>> +
>> +        m_isQpModified = false;
>> +        m_isGopReEncoded = false;
>> +    }
>> +
>> +    m_start = X265_MAX(m_start, m_numEntries - distance +
>> m_param->keyframeMax);
>>
>>      return true;
>>  }
>> @@ -1391,15 +1374,47 @@ int RateControl::rateControlStart(Frame*
>> curFrame, RateControlEntry* rce, Encode
>>              rce->frameSizeMaximum *= m_param->maxAUSizeFactor;
>>          }
>>      }
>> +
>> +    ///< regenerate the qp
>>      if (!m_isAbr && m_2pass && m_param->rc.rateControlMode ==
>> X265_RC_CRF)
>>      {
>> -        rce->qpPrev = x265_qScale2qp(rce->qScale);
>> -        rce->qScale = rce->newQScale;
>> -        rce->qpaRc = curEncData.m_avgQpRc = curEncData.m_avgQpAq =
>> x265_qScale2qp(rce->newQScale);
>> -        m_qp = int(rce->qpaRc + 0.5);
>> -        rce->frameSizePlanned = qScale2bits(rce, rce->qScale);
>> -        m_framesDone++;
>> -        return m_qp;
>> +        if (!m_param->rc.bEncFocusedFramesOnly)
>> +        {
>> +            rce->qpPrev = x265_qScale2qp(rce->qScale);
>> +            rce->qScale = rce->newQScale;
>> +            rce->qpaRc = curEncData.m_avgQpRc = curEncData.m_avgQpAq =
>> x265_qScale2qp(rce->newQScale);
>> +            m_qp = int(rce->qpaRc + 0.5);
>> +            rce->frameSizePlanned = qScale2bits(rce, rce->qScale);
>> +            m_framesDone++;
>> +            return m_qp;
>> +        }
>> +        else
>> +        {
>> +            int index = m_encOrder[rce->poc];
>> +            index++;
>> +            double totalDuration = m_frameDuration;
>> +            for (int j = 0; totalDuration < 1.0 && index < m_numEntries;
>> j++)
>> +            {
>> +                switch (m_rce2Pass[index].sliceType)
>> +                {
>> +                case B_SLICE:
>> +                    curFrame->m_lowres.plannedType[j] =
>> m_rce2Pass[index].keptAsRef ? X265_TYPE_BREF : X265_TYPE_B;
>> +                    break;
>> +                case P_SLICE:
>> +                    curFrame->m_lowres.plannedType[j] = X265_TYPE_P;
>> +                    break;
>> +                case I_SLICE:
>> +                    curFrame->m_lowres.plannedType[j] =
>> m_param->bOpenGOP ? X265_TYPE_I : X265_TYPE_IDR;
>> +                    break;
>> +                default:
>> +                    break;
>> +                }
>> +
>> +                curFrame->m_lowres.plannedSatd[j] =
>> m_rce2Pass[index].currentSatd;
>> +                totalDuration += m_frameDuration;
>> +                index++;
>> +            }
>> +        }
>>      }
>>
>>      if (m_isAbr || m_2pass) // ABR,CRF
>> @@ -1890,7 +1905,7 @@ double RateControl::rateEstimateQscale(Frame*
>> curFrame, RateControlEntry *rce)
>>                  qScale = x265_clip3(lqmin, lqmax, qScale);
>>              }
>>
>> -            if (!m_2pass || m_param->bliveVBV2pass)
>> +            if (!m_2pass || m_param->bliveVBV2pass || (m_2pass &&
>> m_param->rc.rateControlMode == X265_RC_CRF &&
>> m_param->rc.bEncFocusedFramesOnly))
>>              {
>>                  /* clip qp to permissible range after vbv-lookahead
>> estimation to avoid possible
>>                   * mispredictions by initial frame size predictors */
>> @@ -1927,7 +1942,7 @@ double RateControl::rateEstimateQscale(Frame*
>> curFrame, RateControlEntry *rce)
>>      else
>>      {
>>          double abrBuffer = 2 * m_rateTolerance * m_bitrate;
>> -        if (m_2pass)
>> +        if (m_2pass && (m_param->rc.rateControlMode != X265_RC_CRF ||
>> !m_param->rc.bEncFocusedFramesOnly))
>>          {
>>
> [AM] Please include a conformance check in Encoder::configure() to disable
> m_param->rc.bEncFocusedFramesOnly if either bStatRead or CRF is disabled.
>
>>              double lmin = m_lmin[m_sliceType];
>>              double lmax = m_lmax[m_sliceType];
>> @@ -2828,7 +2843,7 @@ int RateControl::rateControlEnd(Frame* curFrame,
>> int64_t bits, RateControlEntry*
>>
>>      if (m_param->rc.aqMode || m_isVbv || m_param->bAQMotion ||
>> bEnableDistOffset)
>>      {
>> -        if (m_isVbv && !(m_2pass && m_param->rc.rateControlMode ==
>> X265_RC_CRF))
>> +        if (m_isVbv && !(m_2pass && m_param->rc.rateControlMode ==
>> X265_RC_CRF && !m_param->rc.bEncFocusedFramesOnly))
>>          {
>>              double avgQpRc = 0;
>>              /* determine avg QP decided by VBV rate control */
>> @@ -2862,8 +2877,9 @@ int RateControl::rateControlEnd(Frame* curFrame,
>> int64_t bits, RateControlEntry*
>>      if (m_param->rc.rateControlMode == X265_RC_CRF)
>>      {
>>          double crfVal, qpRef = curEncData.m_avgQpRc;
>> +
>>          bool is2passCrfChange = false;
>> -        if (m_2pass)
>> +        if (m_2pass && !m_param->rc.bEncFocusedFramesOnly)
>>          {
>>              if (fabs(curEncData.m_avgQpRc - rce->qpPrev) > 0.1)
>>              {
>> diff --git a/source/encoder/ratecontrol.h b/source/encoder/ratecontrol.h
>> index 996465eeb..204bd71e1 100644
>> --- a/source/encoder/ratecontrol.h
>> +++ b/source/encoder/ratecontrol.h
>> @@ -73,6 +73,7 @@ struct RateControlEntry
>>      Predictor  rowPreds[3][2];
>>      Predictor* rowPred[2];
>>
>> +    int64_t currentSatd;
>>      int64_t lastSatd;      /* Contains the picture cost of the previous
>> frame, required for resetAbr and VBV */
>>      int64_t leadingNoBSatd;
>>      int64_t rowTotalBits;  /* update cplxrsum and totalbits at the end
>> of 2 rows */
>> @@ -87,6 +88,8 @@ struct RateControlEntry
>>      double  rowCplxrSum;
>>      double  qpNoVbv;
>>      double  bufferFill;
>> +    double  bufferFillFinal;
>> +    double  bufferFillActual;
>>      double  targetFill;
>>      bool    vbvEndAdj;
>>      double  frameDuration;
>> diff --git a/source/x265.h b/source/x265.h
>> index 3f3133536..6bb893c98 100644
>> --- a/source/x265.h
>> +++ b/source/x265.h
>> @@ -1443,6 +1443,9 @@ typedef struct x265_param
>>           * encoder will default to using x265_2pass.log */
>>          const char* statFileName;
>>
>> +        /* if only the focused frames would be re-encode or not */
>> +        int       bEncFocusedFramesOnly;
>> +
>>
> [AM] Update X265_BUILD, add help document, and add an entry for the new
> param in info SEI.
> Is this a param?API only option? If so, clarify that in the document.
> Else, add a test CLI.
>
>>          /* temporally blur quants */
>>          double    qblur;
>>
>> --
>> 2.22.0.windows.1
>>
>> _______________________________________________
>> x265-devel mailing list
>> x265-devel at videolan.org
>> https://mailman.videolan.org/listinfo/x265-devel
>>
>
>
> --
> Regards,
> *Aruna Matheswaran,*
> Video Codec Engineer,
> Media & AI analytics BU,
>
>
>
> _______________________________________________
> 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/20210927/27ab5d4c/attachment-0001.html>


More information about the x265-devel mailing list