[x265] [PATCH] Add dynamic rate-control reconfiguration

Aruna Matheswaran aruna at multicorewareinc.com
Thu Apr 6 12:39:59 CEST 2017


On Thu, Apr 6, 2017 at 1:35 PM, Aarthi Priya Thirumalai <
aarthi at multicorewareinc.com> wrote:

>
>
> On Tue, Apr 4, 2017 at 6:34 PM, <aruna at multicorewareinc.com> wrote:
>
>> # HG changeset patch
>> # User Aruna Matheswaran <aruna at multicorewareinc.com>
>> # Date 1487757265 -19800
>> #      Wed Feb 22 15:24:25 2017 +0530
>> # Node ID 576ad673d9b352c45853b7ffeeacce7d23268bb8
>> # Parent  08a05ca9fd16c9f5efb1ce4d8389bda8a63f5f7d
>> Add dynamic rate-control reconfiguration
>>
>> diff -r 08a05ca9fd16 -r 576ad673d9b3 source/common/frame.cpp
>> --- a/source/common/frame.cpp   Mon Mar 27 12:35:20 2017 +0530
>> +++ b/source/common/frame.cpp   Wed Feb 22 15:24:25 2017 +0530
>> @@ -47,6 +47,7 @@
>>      memset(&m_lowres, 0, sizeof(m_lowres));
>>      m_rcData = NULL;
>>      m_encodeStartTime = 0;
>> +    m_reconfigureRc = false;
>>  }
>>
>>  bool Frame::create(x265_param *param, float* quantOffsets)
>> diff -r 08a05ca9fd16 -r 576ad673d9b3 source/common/frame.h
>> --- a/source/common/frame.h     Mon Mar 27 12:35:20 2017 +0530
>> +++ b/source/common/frame.h     Wed Feb 22 15:24:25 2017 +0530
>> @@ -84,6 +84,7 @@
>>      Lowres                 m_lowres;
>>      bool                   m_lowresInit;         // lowres init complete
>> (pre-analysis)
>>      bool                   m_bChromaExtended;    // orig chroma planes
>> motion extended for weight analysis
>> +    bool                   m_reconfigureRc;
>>
>>      float*                 m_quantOffsets;       // points to
>> quantOffsets in x265_picture
>>      x265_sei               m_userSEI;
>> diff -r 08a05ca9fd16 -r 576ad673d9b3 source/encoder/api.cpp
>> --- a/source/encoder/api.cpp    Mon Mar 27 12:35:20 2017 +0530
>> +++ b/source/encoder/api.cpp    Wed Feb 22 15:24:25 2017 +0530
>> @@ -171,7 +171,7 @@
>>
>>      x265_param save;
>>      Encoder* encoder = static_cast<Encoder*>(enc);
>> -    if (encoder->m_reconfigure) /* Reconfigure in progress */
>> +    if (encoder->m_reconfigure || encoder->m_reconfigureRc) /*
>> Reconfigure in progress */
>>          return 1;
>>      memcpy(&save, encoder->m_latestParam, sizeof(x265_param));
>>      int ret = encoder->reconfigureParam(encoder->m_latestParam,
>> param_in);
>> @@ -197,7 +197,22 @@
>>                  return -1;
>>              }
>>          }
>> -        encoder->m_reconfigure = true;
>> +        if (encoder->m_reconfigureRc)
>> +        {
>> +            VPS saveVPS;
>> +            memcpy(&saveVPS.ptl, &encoder->m_vps.ptl,
>> sizeof(saveVPS.ptl));
>> +            determineLevel(*encoder->m_latestParam, encoder->m_vps);
>> +            if (saveVPS.ptl.profileIdc != encoder->m_vps.ptl.profileIdc
>> || saveVPS.ptl.levelIdc != encoder->m_vps.ptl.levelIdc
>> +                || saveVPS.ptl.tierFlag != encoder->m_vps.ptl.tierFlag)
>> +            {
>> +                x265_log(encoder->m_param, X265_LOG_WARNING,
>> "Profile/Level/Tier has changed from %d/%d/%s to %d/%d/%s.Cannot
>> reconfigure rate-control.\n",
>> +                         saveVPS.ptl.profileIdc, saveVPS.ptl.levelIdc,
>> saveVPS.ptl.tierFlag ? "High" : "Main", encoder->m_vps.ptl.profileIdc,
>> +                         encoder->m_vps.ptl.levelIdc,
>> encoder->m_vps.ptl.tierFlag ? "High" : "Main");
>> +                encoder->m_reconfigureRc = false;
>> +            }
>> +        }
>> +        else
>> +            encoder->m_reconfigure = true;
>>
> why set only m_reconfigure as true,  where are you setting m_reconfigureRc
> to true?
>

m_reconfigureRc will get set to true inside reconfigureParam().


>          encoder->printReconfigureParams();
>>      }
>>      return ret;
>> diff -r 08a05ca9fd16 -r 576ad673d9b3 source/encoder/encoder.cpp
>> --- a/source/encoder/encoder.cpp        Mon Mar 27 12:35:20 2017 +0530
>> +++ b/source/encoder/encoder.cpp        Wed Feb 22 15:24:25 2017 +0530
>> @@ -56,6 +56,7 @@
>>  {
>>      m_aborted = false;
>>      m_reconfigure = false;
>> +    m_reconfigureRc = false;
>>      m_encodedFrameNum = 0;
>>      m_pocLast = -1;
>>      m_curEncoder = 0;
>> @@ -607,7 +608,7 @@
>>          {
>>              inFrame = new Frame;
>>              inFrame->m_encodeStartTime = x265_mdate();
>> -            x265_param* p = m_reconfigure ? m_latestParam : m_param;
>>
> no need for this change - when reconfigureRc is true, m_reconfigure will
> also be true..so dont need to change these
>

Both m_reconfigure and m_reconfigureRc will not be true at a
time.m_reconfigureRc will be set true when rate-control parameters have to
be reconfigured and it will show effect from the next pic_in. For all other
parameters m_reconfigure will be set true and it will show effect from the
next frame to be encoded.


+            x265_param* p = (m_reconfigure || m_reconfigureRc) ?
>> m_latestParam : m_param;
>>              if (inFrame->create(p, pic_in->quantOffsets))
>>              {
>>                  /* the first PicYuv created is asked to generate the CU
>> and block unit offset
>> @@ -674,7 +675,7 @@
>>          inFrame->m_userData  = pic_in->userData;
>>          inFrame->m_pts       = pic_in->pts;
>>          inFrame->m_forceqp   = pic_in->forceqp;
>> -        inFrame->m_param     = m_reconfigure ? m_latestParam : m_param;
>>
> same as above. for any reconfigure, set m_reconfigure to true,
> additionally, set m_reconfigureRc to true for
> Rate control reconfigure changes. no need for the above change then
>
>> +        inFrame->m_param     = (m_reconfigure || m_reconfigureRc) ?
>> m_latestParam : m_param;
>>
>>          if (pic_in->userSEI.numPayloads)
>>          {
>> @@ -740,6 +741,8 @@
>>              inFrame->m_lowres.bScenecut = !!inFrame->m_analysisData.bSce
>> necut;
>>              inFrame->m_lowres.satdCost = inFrame->m_analysisData.satdCo
>> st;
>>          }
>> +        if (m_reconfigureRc)
>> +            inFrame->m_reconfigureRc = true;
>>
>>          m_lookahead->addPicture(*inFrame, sliceType);
>>          m_numDelayedPic++;
>> @@ -940,6 +943,15 @@
>>                  if (m_param->rc.bStatRead)
>>                      readAnalysis2PassFile(&frameEnc->m_analysis2Pass,
>> frameEnc->m_poc, frameEnc->m_lowres.sliceType);
>>               }
>> +
>> +            if (frameEnc->m_reconfigureRc && m_reconfigureRc)
>> +            {
>> +                memcpy(m_param, m_latestParam, sizeof(x265_param));
>> +                m_rateControl->reconfigureRC();
>> +                m_reconfigureRc = false;
>> +            }
>> +            if (frameEnc->m_reconfigureRc && !m_reconfigureRc)
>> +                frameEnc->m_reconfigureRc = false;
>>              if (curEncoder->m_reconfigure)
>>              {
>>                  /* One round robin cycle of FE reconfigure is complete */
>> @@ -1090,6 +1102,25 @@
>>      encParam->bIntraInBFrames = param->bIntraInBFrames;
>>      if (param->scalingLists && !encParam->scalingLists)
>>          encParam->scalingLists = strdup(param->scalingLists);
>>
> Can you turn vbv off in reconfigure, if it was ON to beign with? need that
> check as well
>

This will check that too. Will include it in the comment.


> +    /* VBV can't be turned ON if it wasn't ON to begin with */
>> +    if (param->rc.vbvMaxBitrate > 0 && param->rc.vbvBufferSize > 0 &&
>> +        encParam->rc.vbvMaxBitrate > 0 && encParam->rc.vbvBufferSize > 0)
>> +    {
>> +        m_reconfigureRc |= encParam->rc.vbvMaxBitrate !=
>> param->rc.vbvMaxBitrate;
>> +        m_reconfigureRc |= encParam->rc.vbvBufferSize !=
>> param->rc.vbvBufferSize;
>> +        if (m_reconfigureRc && m_param->bEmitHRDSEI)
>> +            x265_log(m_param, X265_LOG_WARNING, "VBV parameters cannot
>> be changed when HRD is in use.\n");
>> +        else
>> +        {
>> +            encParam->rc.vbvMaxBitrate = param->rc.vbvMaxBitrate;
>> +            encParam->rc.vbvBufferSize = param->rc.vbvBufferSize;
>
> +        }
>> +    }
>> +    m_reconfigureRc |= encParam->rc.bitrate != param->rc.bitrate;
>> +    encParam->rc.bitrate = param->rc.bitrate;
>> +    m_reconfigureRc |= encParam->rc.rfConstant != param->rc.rfConstant;
>> +    encParam->rc.rfConstant = param->rc.rfConstant;
>> +
>>      /* To add: Loop Filter/deblocking controls, transform skip, signhide
>> require PPS to be resent */
>>      /* To add: SAO, temporal MVP, AMP, TU depths require SPS to be
>> resent, at every CVS boundary */
>>      return x265_check_params(encParam);
>> @@ -3090,7 +3121,7 @@
>>
>>  void Encoder::printReconfigureParams()
>>  {
>> -    if (!m_reconfigure)
>> +    if (!(m_reconfigure || m_reconfigureRc))
>>          return;
>>      x265_param* oldParam = m_param;
>>      x265_param* newParam = m_latestParam;
>> @@ -3112,6 +3143,10 @@
>>      TOOLCMP(oldParam->maxNumMergeCand, newParam->maxNumMergeCand,
>> "max-merge=%d to %d\n");
>>      TOOLCMP(oldParam->bIntraInBFrames, newParam->bIntraInBFrames,
>> "b-intra=%d to %d\n");
>>      TOOLCMP(oldParam->scalingLists, newParam->scalingLists,
>> "scalinglists=%s to %s\n");
>> +    TOOLCMP(oldParam->rc.vbvMaxBitrate, newParam->rc.vbvMaxBitrate,
>> "vbv-maxrate=%d to %d\n");
>> +    TOOLCMP(oldParam->rc.vbvBufferSize, newParam->rc.vbvBufferSize,
>> "vbv-bufsize=%d to %d\n");
>> +    TOOLCMP(oldParam->rc.bitrate, newParam->rc.bitrate, "bitrate=%d to
>> %d\n");
>> +    TOOLCMP(oldParam->rc.rfConstant, newParam->rc.rfConstant, "crf=%f
>> to %f\n");
>>  }
>>
>>  bool Encoder::computeSPSRPSIndex()
>> diff -r 08a05ca9fd16 -r 576ad673d9b3 source/encoder/encoder.h
>> --- a/source/encoder/encoder.h  Mon Mar 27 12:35:20 2017 +0530
>> +++ b/source/encoder/encoder.h  Wed Feb 22 15:24:25 2017 +0530
>> @@ -153,6 +153,7 @@
>>      bool               m_bZeroLatency;     // x265_encoder_encode()
>> returns NALs for the input picture, zero lag
>>      bool               m_aborted;          // fatal error detected
>>      bool               m_reconfigure;      // Encoder reconfigure in
>> progress
>> +    bool               m_reconfigureRc;
>>
>>      /* Begin intra refresh when one not in progress or else begin one as
>> soon as the current
>>       * one is done. Requires bIntraRefresh to be set.*/
>> diff -r 08a05ca9fd16 -r 576ad673d9b3 source/encoder/ratecontrol.cpp
>> --- a/source/encoder/ratecontrol.cpp    Mon Mar 27 12:35:20 2017 +0530
>> +++ b/source/encoder/ratecontrol.cpp    Wed Feb 22 15:24:25 2017 +0530
>> @@ -683,6 +683,56 @@
>>      return true;
>>  }
>>
>> +void RateControl::reconfigureRC()
>> +{
>> +    if (m_isVbv)
>> +    {
>> +        m_param->rc.vbvBufferSize = x265_clip3(0, 2000000,
>> m_param->rc.vbvBufferSize);
>> +        m_param->rc.vbvMaxBitrate = x265_clip3(0, 2000000,
>> m_param->rc.vbvMaxBitrate);
>> +        if (m_param->rc.vbvMaxBitrate < m_param->rc.bitrate &&
>> +            m_param->rc.rateControlMode == X265_RC_ABR)
>> +        {
>> +            x265_log(m_param, X265_LOG_WARNING, "max bitrate less than
>> average bitrate, assuming CBR\n");
>> +            m_param->rc.bitrate = m_param->rc.vbvMaxBitrate;
>> +        }
>> +
>> +        if (m_param->rc.vbvBufferSize < (int)(m_param->rc.vbvMaxBitrate
>> / m_fps))
>> +        {
>> +            m_param->rc.vbvBufferSize = (int)(m_param->rc.vbvMaxBitrate
>> / m_fps);
>> +            x265_log(m_param, X265_LOG_WARNING, "VBV buffer size cannot
>> be smaller than one frame, using %d kbit\n",
>> +                m_param->rc.vbvBufferSize);
>> +        }
>> +        int vbvBufferSize = m_param->rc.vbvBufferSize * 1000;
>> +        int vbvMaxBitrate = m_param->rc.vbvMaxBitrate * 1000;
>> +        m_bufferRate = vbvMaxBitrate / m_fps;
>> +        m_vbvMaxRate = vbvMaxBitrate;
>> +        m_bufferSize = vbvBufferSize;
>> +        m_singleFrameVbv = m_bufferRate * 1.1 > m_bufferSize;
>> +    }
>> +    if (m_param->rc.rateControlMode == X265_RC_CRF)
>> +    {
>> +        #define CRF_INIT_QP (int)m_param->rc.rfConstant
>> +        m_param->rc.bitrate = 0;
>> +        double baseCplx = m_ncu * (m_param->bframes ? 120 : 80);
>> +        double mbtree_offset = m_param->rc.cuTree ? (1.0 -
>> m_param->rc.qCompress) * 13.5 : 0;
>> +        m_rateFactorConstant = pow(baseCplx, 1 - m_qCompress) /
>> +            x265_qp2qScale(m_param->rc.rfConstant + mbtree_offset);
>> +        if (m_param->rc.rfConstantMax)
>> +        {
>> +            m_rateFactorMaxIncrement = m_param->rc.rfConstantMax -
>> m_param->rc.rfConstant;
>> +            if (m_rateFactorMaxIncrement <= 0)
>> +            {
>> +                x265_log(m_param, X265_LOG_WARNING, "CRF max must be
>> greater than CRF\n");
>> +                m_rateFactorMaxIncrement = 0;
>> +            }
>> +        }
>> +        if (m_param->rc.rfConstantMin)
>> +            m_rateFactorMaxDecrement = m_param->rc.rfConstant -
>> m_param->rc.rfConstantMin;
>> +    }
>> +    m_bitrate = m_param->rc.bitrate * 1000;
>> +}
>> +
>> +
>>  void RateControl::initHRD(SPS& sps)
>>  {
>>      int vbvBufferSize = m_param->rc.vbvBufferSize * 1000;
>> diff -r 08a05ca9fd16 -r 576ad673d9b3 source/encoder/ratecontrol.h
>> --- a/source/encoder/ratecontrol.h      Mon Mar 27 12:35:20 2017 +0530
>> +++ b/source/encoder/ratecontrol.h      Wed Feb 22 15:24:25 2017 +0530
>> @@ -234,6 +234,7 @@
>>      RateControl(x265_param& p);
>>      bool init(const SPS& sps);
>>      void initHRD(SPS& sps);
>> +    void reconfigureRC();
>>
>>      void setFinalFrameCount(int count);
>>      void terminate();          /* un-block all waiting functions so
>> encoder may close */
>> _______________________________________________
>> 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/20170406/7835d664/attachment-0001.html>


More information about the x265-devel mailing list