<div dir="ltr"><div># HG changeset patch</div><div># User Aarthi Thirumalai</div><div># Date 1428573257 -19800</div><div>#      Thu Apr 09 15:24:17 2015 +0530</div><div># Node ID c87e15a9a353bc13036bb33a4a1932ebdb7dfb1a</div><div># Parent  4d3bfacc276362175f5f0b4a5844ec640c8871f0</div><div>rc: add helper function to decide the VBV predictor type for each frame</div><div><br></div><div>diff -r 4d3bfacc2763 -r c87e15a9a353 source/encoder/ratecontrol.cpp</div><div>--- a/source/encoder/ratecontrol.cpp<span class="" style="white-space:pre">     </span>Mon Mar 16 12:05:38 2015 +0530</div><div>+++ b/source/encoder/ratecontrol.cpp<span class="" style="white-space:pre"> </span>Thu Apr 09 15:24:17 2015 +0530</div><div>@@ -952,7 +952,7 @@</div><div>     rce->sliceType = m_sliceType;</div><div>     if (!m_2pass)</div><div>         rce->keptAsRef = IS_REFERENCED(curFrame);</div><div>-    m_predType = m_sliceType == B_SLICE && rce->keptAsRef ? 3 : m_sliceType;</div><div>+    m_predType = getPredictorType(curFrame->m_lowres.sliceType, m_sliceType);</div><div>     rce->poc = m_curSlice->m_poc;</div><div>     if (m_param->rc.bStatRead)</div><div>     {</div><div>@@ -1113,6 +1113,14 @@</div><div>         m_accumPQp += m_qp;</div><div> }</div><div> </div><div>+int RateControl::getPredictorType(int lowresSliceType, int sliceType)</div><div>+{</div><div>+    /* Use a different predictor for B Ref and B frames for vbv frame size predictions */</div><div>+    if (lowresSliceType == X265_TYPE_BREF)</div><div>+        return 3;</div><div>+    return sliceType;</div><div>+}</div><div>+</div><div> double RateControl::getDiffLimitedQScale(RateControlEntry *rce, double q)</div><div> {</div><div>     // force I/B quants as a function of P quants</div><div>@@ -1734,7 +1742,7 @@</div><div>                         bufferFillCur += wantedFrameSize;</div><div>                     int64_t satd = curFrame->m_lowres.plannedSatd[j] >> (X265_DEPTH - 8);</div><div>                     type = IS_X265_TYPE_I(type) ? I_SLICE : IS_X265_TYPE_B(type) ? B_SLICE : P_SLICE;</div><div>-                    int predType = curFrame->m_lowres.plannedType[j] == X265_TYPE_BREF ? 3 : type;</div><div>+                    int predType = getPredictorType(curFrame->m_lowres.plannedType[j], type);</div><div>                     curBits = predictSize(&m_pred[predType], frameQ[type], (double)satd);</div><div>                     bufferFillCur -= curBits;</div><div>                 }</div><div>diff -r 4d3bfacc2763 -r c87e15a9a353 source/encoder/ratecontrol.h</div><div>--- a/source/encoder/ratecontrol.h<span class="" style="white-space:pre">        </span>Mon Mar 16 12:05:38 2015 +0530</div><div>+++ b/source/encoder/ratecontrol.h<span class="" style="white-space:pre">   </span>Thu Apr 09 15:24:17 2015 +0530</div><div>@@ -264,7 +264,7 @@</div><div>     double rateEstimateQscale(Frame* pic, RateControlEntry *rce); // main logic for calculating QP based on ABR</div><div>     double tuneAbrQScaleFromFeedback(double qScale);</div><div>     void   accumPQpUpdate();</div><div>-</div><div>+    int    getPredictorType(int lowresSliceType, int sliceType);</div><div>     void   updateVbv(int64_t bits, RateControlEntry* rce);</div><div>     void   updatePredictor(Predictor *p, double q, double var, double bits);</div><div>     double clipQscale(Frame* pic, RateControlEntry* rce, double q);</div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Apr 9, 2015 at 12:08 AM, Steve Borho <span dir="ltr"><<a href="mailto:steve@borho.org" target="_blank">steve@borho.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">On 04/08, <a href="mailto:aarthi@multicorewareinc.com">aarthi@multicorewareinc.com</a> wrote:<br>
> # HG changeset patch<br>
> # User Aarthi Thirumalai<br>
> # Date 1427820381 -19800<br>
> #      Tue Mar 31 22:16:21 2015 +0530<br>
> # Node ID 6f159ec858f4eec484d722916c41911e3e4540f9<br>
> # Parent  3e416dec8024b8339b18568cf65e48eb3448bed1<br>
> rc: separate frame bits predictor objects for BRef and B frames<br>
><br>
> improves frame size prediction for BRef frames in VBV.<br>
<br>
</span>this probably deserves a follow up commit introducing an inline helper<br>
method that maps from Slice* to predictor type, so we can be sure the<br>
logic stays consistent going forward and is self-documenting<br>
<div><div class="h5"><br>
> diff -r 3e416dec8024 -r 6f159ec858f4 source/encoder/ratecontrol.cpp<br>
> --- a/source/encoder/ratecontrol.cpp  Tue Apr 07 16:00:39 2015 -0500<br>
> +++ b/source/encoder/ratecontrol.cpp  Tue Mar 31 22:16:21 2015 +0530<br>
> @@ -370,7 +370,7 @@<br>
>      m_accumPQp = (m_param->rc.rateControlMode == X265_RC_CRF ? CRF_INIT_QP : ABR_INIT_QP_MIN) * m_accumPNorm;<br>
><br>
>      /* Frame Predictors and Row predictors used in vbv */<br>
> -    for (int i = 0; i < 5; i++)<br>
> +    for (int i = 0; i < 4; i++)<br>
>      {<br>
>          m_pred[i].coeff = 1.5;<br>
>          m_pred[i].count = 1.0;<br>
> @@ -945,6 +945,9 @@<br>
>      m_curSlice = curEncData.m_slice;<br>
>      m_sliceType = m_curSlice->m_sliceType;<br>
>      rce->sliceType = m_sliceType;<br>
> +    if (!m_2pass)<br>
> +        rce->keptAsRef = IS_REFERENCED(curFrame);<br>
> +    m_predType = m_sliceType == B_SLICE && rce->keptAsRef ? 3 : m_sliceType;<br>
>      rce->poc = m_curSlice->m_poc;<br>
>      if (m_param->rc.bStatRead)<br>
>      {<br>
> @@ -1074,7 +1077,7 @@<br>
>              m_lastQScaleFor[m_sliceType] = x265_qp2qScale(rce->qpaRc);<br>
>              if (rce->poc == 0)<br>
>                   m_lastQScaleFor[P_SLICE] = m_lastQScaleFor[m_sliceType] * fabs(m_param->rc.ipFactor);<br>
> -            rce->frameSizePlanned = predictSize(&m_pred[m_sliceType], m_qp, (double)m_currentSatd);<br>
> +            rce->frameSizePlanned = predictSize(&m_pred[m_predType], m_qp, (double)m_currentSatd);<br>
>          }<br>
>      }<br>
>      m_framesDone++;<br>
> @@ -1397,10 +1400,10 @@<br>
>                  qScale = clipQscale(curFrame, rce, qScale);<br>
>                  /* clip qp to permissible range after vbv-lookahead estimation to avoid possible<br>
>                   * mispredictions by initial frame size predictors */<br>
> -                if (m_pred[m_sliceType].count == 1)<br>
> +                if (m_pred[m_predType].count == 1)<br>
>                      qScale = x265_clip3(lmin, lmax, qScale);<br>
>                  m_lastQScaleFor[m_sliceType] = qScale;<br>
> -                rce->frameSizePlanned = predictSize(&m_pred[m_sliceType], qScale, (double)m_currentSatd);<br>
> +                rce->frameSizePlanned = predictSize(&m_pred[m_predType], qScale, (double)m_currentSatd);<br>
>              }<br>
>              else<br>
>                  rce->frameSizePlanned = qScale2bits(rce, qScale);<br>
> @@ -1544,7 +1547,7 @@<br>
>              q = clipQscale(curFrame, rce, q);<br>
>              /*  clip qp to permissible range after vbv-lookahead estimation to avoid possible<br>
>               * mispredictions by initial frame size predictors */<br>
> -            if (!m_2pass && m_isVbv && m_pred[m_sliceType].count == 1)<br>
> +            if (!m_2pass && m_isVbv && m_pred[m_predType].count == 1)<br>
>                  q = x265_clip3(lqmin, lqmax, q);<br>
>          }<br>
>          m_lastQScaleFor[m_sliceType] = q;<br>
> @@ -1554,7 +1557,7 @@<br>
>          if (m_2pass && m_isVbv)<br>
>              rce->frameSizePlanned = qScale2bits(rce, q);<br>
>          else<br>
> -            rce->frameSizePlanned = predictSize(&m_pred[m_sliceType], q, (double)m_currentSatd);<br>
> +            rce->frameSizePlanned = predictSize(&m_pred[m_predType], q, (double)m_currentSatd);<br>
><br>
>          /* Always use up the whole VBV in this case. */<br>
>          if (m_singleFrameVbv)<br>
> @@ -1707,7 +1710,7 @@<br>
>              {<br>
>                  double frameQ[3];<br>
>                  double curBits;<br>
> -                curBits = predictSize(&m_pred[m_sliceType], q, (double)m_currentSatd);<br>
> +                curBits = predictSize(&m_pred[m_predType], q, (double)m_currentSatd);<br>
>                  double bufferFillCur = m_bufferFill - curBits;<br>
>                  double targetFill;<br>
>                  double totalDuration = m_frameDuration;<br>
> @@ -1726,7 +1729,8 @@<br>
>                          bufferFillCur += wantedFrameSize;<br>
>                      int64_t satd = curFrame->m_lowres.plannedSatd[j] >> (X265_DEPTH - 8);<br>
>                      type = IS_X265_TYPE_I(type) ? I_SLICE : IS_X265_TYPE_B(type) ? B_SLICE : P_SLICE;<br>
> -                    curBits = predictSize(&m_pred[type], frameQ[type], (double)satd);<br>
> +                    int predType = curFrame->m_lowres.plannedType[j] == X265_TYPE_BREF ? 3 : type;<br>
> +                    curBits = predictSize(&m_pred[predType], frameQ[type], (double)satd);<br>
>                      bufferFillCur -= curBits;<br>
>                  }<br>
><br>
> @@ -1766,7 +1770,7 @@<br>
>              }<br>
>              // Now a hard threshold to make sure the frame fits in VBV.<br>
>              // This one is mostly for I-frames.<br>
> -            double bits = predictSize(&m_pred[m_sliceType], q, (double)m_currentSatd);<br>
> +            double bits = predictSize(&m_pred[m_predType], q, (double)m_currentSatd);<br>
><br>
>              // For small VBVs, allow the frame to use up the entire VBV.<br>
>              double maxFillFactor;<br>
> @@ -1783,14 +1787,14 @@<br>
>                  bits *= qf;<br>
>                  if (bits < m_bufferRate / minFillFactor)<br>
>                      q *= bits * minFillFactor / m_bufferRate;<br>
> -                bits = predictSize(&m_pred[m_sliceType], q, (double)m_currentSatd);<br>
> +                bits = predictSize(&m_pred[m_predType], q, (double)m_currentSatd);<br>
>              }<br>
><br>
>              q = X265_MAX(q0, q);<br>
>          }<br>
><br>
>          /* Apply MinCR restrictions */<br>
> -        double pbits = predictSize(&m_pred[m_sliceType], q, (double)m_currentSatd);<br>
> +        double pbits = predictSize(&m_pred[m_predType], q, (double)m_currentSatd);<br>
>          if (pbits > rce->frameSizeMaximum)<br>
>              q *= pbits / rce->frameSizeMaximum;<br>
><br>
> @@ -2099,8 +2103,10 @@<br>
><br>
>  void RateControl::updateVbv(int64_t bits, RateControlEntry* rce)<br>
>  {<br>
> +    int predType = rce->sliceType;<br>
> +    predType = rce->sliceType == B_SLICE && rce->keptAsRef ? 3 : predType;<br>
>      if (rce->lastSatd >= m_ncu)<br>
> -        updatePredictor(&m_pred[rce->sliceType], x265_qp2qScale(rce->qpaRc), (double)rce->lastSatd, (double)bits);<br>
> +        updatePredictor(&m_pred[predType], x265_qp2qScale(rce->qpaRc), (double)rce->lastSatd, (double)bits);<br>
>      if (!m_isVbv)<br>
>          return;<br>
><br>
> diff -r 3e416dec8024 -r 6f159ec858f4 source/encoder/ratecontrol.h<br>
> --- a/source/encoder/ratecontrol.h    Tue Apr 07 16:00:39 2015 -0500<br>
> +++ b/source/encoder/ratecontrol.h    Tue Mar 31 22:16:21 2015 +0530<br>
> @@ -157,10 +157,9 @@<br>
>      double m_rateFactorMaxIncrement; /* Don't allow RF above (CRF + this value). */<br>
>      double m_rateFactorMaxDecrement; /* don't allow RF below (this value). */<br>
><br>
> -    Predictor m_pred[5];<br>
> -    Predictor m_predBfromP;<br>
> -<br>
> +    Predictor m_pred[4];       /* Slice predictors to preidct bits for each Slice type - I,P,Bref and B */<br>
>      int64_t m_leadingNoBSatd;<br>
> +    int     m_predType;       /* Type of slice predictors to be used - depends on the slice type */<br>
>      double  m_ipOffset;<br>
>      double  m_pbOffset;<br>
>      int64_t m_bframeBits;<br>
</div></div>> _______________________________________________<br>
> x265-devel mailing list<br>
> <a href="mailto:x265-devel@videolan.org">x265-devel@videolan.org</a><br>
> <a href="https://mailman.videolan.org/listinfo/x265-devel" target="_blank">https://mailman.videolan.org/listinfo/x265-devel</a><br>
<span class="HOEnZb"><font color="#888888"><br>
--<br>
Steve Borho<br>
_______________________________________________<br>
x265-devel mailing list<br>
<a href="mailto:x265-devel@videolan.org">x265-devel@videolan.org</a><br>
<a href="https://mailman.videolan.org/listinfo/x265-devel" target="_blank">https://mailman.videolan.org/listinfo/x265-devel</a><br>
</font></span></blockquote></div><br></div>