[x265] [PATCH 1 of 2] rc: separate frame bits predictor objects for BRef and B frames

Aarthi Priya Thirumalai aarthi at multicorewareinc.com
Thu Apr 9 11:59:21 CEST 2015


# HG changeset patch
# User Aarthi Thirumalai
# Date 1428573257 -19800
#      Thu Apr 09 15:24:17 2015 +0530
# Node ID c87e15a9a353bc13036bb33a4a1932ebdb7dfb1a
# Parent  4d3bfacc276362175f5f0b4a5844ec640c8871f0
rc: add helper function to decide the VBV predictor type for each frame

diff -r 4d3bfacc2763 -r c87e15a9a353 source/encoder/ratecontrol.cpp
--- a/source/encoder/ratecontrol.cpp Mon Mar 16 12:05:38 2015 +0530
+++ b/source/encoder/ratecontrol.cpp Thu Apr 09 15:24:17 2015 +0530
@@ -952,7 +952,7 @@
     rce->sliceType = m_sliceType;
     if (!m_2pass)
         rce->keptAsRef = IS_REFERENCED(curFrame);
-    m_predType = m_sliceType == B_SLICE && rce->keptAsRef ? 3 :
m_sliceType;
+    m_predType = getPredictorType(curFrame->m_lowres.sliceType,
m_sliceType);
     rce->poc = m_curSlice->m_poc;
     if (m_param->rc.bStatRead)
     {
@@ -1113,6 +1113,14 @@
         m_accumPQp += m_qp;
 }

+int RateControl::getPredictorType(int lowresSliceType, int sliceType)
+{
+    /* Use a different predictor for B Ref and B frames for vbv frame size
predictions */
+    if (lowresSliceType == X265_TYPE_BREF)
+        return 3;
+    return sliceType;
+}
+
 double RateControl::getDiffLimitedQScale(RateControlEntry *rce, double q)
 {
     // force I/B quants as a function of P quants
@@ -1734,7 +1742,7 @@
                         bufferFillCur += wantedFrameSize;
                     int64_t satd = curFrame->m_lowres.plannedSatd[j] >>
(X265_DEPTH - 8);
                     type = IS_X265_TYPE_I(type) ? I_SLICE :
IS_X265_TYPE_B(type) ? B_SLICE : P_SLICE;
-                    int predType = curFrame->m_lowres.plannedType[j] ==
X265_TYPE_BREF ? 3 : type;
+                    int predType =
getPredictorType(curFrame->m_lowres.plannedType[j], type);
                     curBits = predictSize(&m_pred[predType], frameQ[type],
(double)satd);
                     bufferFillCur -= curBits;
                 }
diff -r 4d3bfacc2763 -r c87e15a9a353 source/encoder/ratecontrol.h
--- a/source/encoder/ratecontrol.h Mon Mar 16 12:05:38 2015 +0530
+++ b/source/encoder/ratecontrol.h Thu Apr 09 15:24:17 2015 +0530
@@ -264,7 +264,7 @@
     double rateEstimateQscale(Frame* pic, RateControlEntry *rce); // main
logic for calculating QP based on ABR
     double tuneAbrQScaleFromFeedback(double qScale);
     void   accumPQpUpdate();
-
+    int    getPredictorType(int lowresSliceType, int sliceType);
     void   updateVbv(int64_t bits, RateControlEntry* rce);
     void   updatePredictor(Predictor *p, double q, double var, double
bits);
     double clipQscale(Frame* pic, RateControlEntry* rce, double q);


On Thu, Apr 9, 2015 at 12:08 AM, Steve Borho <steve at borho.org> wrote:

> On 04/08, aarthi at multicorewareinc.com wrote:
> > # HG changeset patch
> > # User Aarthi Thirumalai
> > # Date 1427820381 -19800
> > #      Tue Mar 31 22:16:21 2015 +0530
> > # Node ID 6f159ec858f4eec484d722916c41911e3e4540f9
> > # Parent  3e416dec8024b8339b18568cf65e48eb3448bed1
> > rc: separate frame bits predictor objects for BRef and B frames
> >
> > improves frame size prediction for BRef frames in VBV.
>
> this probably deserves a follow up commit introducing an inline helper
> method that maps from Slice* to predictor type, so we can be sure the
> logic stays consistent going forward and is self-documenting
>
> > diff -r 3e416dec8024 -r 6f159ec858f4 source/encoder/ratecontrol.cpp
> > --- a/source/encoder/ratecontrol.cpp  Tue Apr 07 16:00:39 2015 -0500
> > +++ b/source/encoder/ratecontrol.cpp  Tue Mar 31 22:16:21 2015 +0530
> > @@ -370,7 +370,7 @@
> >      m_accumPQp = (m_param->rc.rateControlMode == X265_RC_CRF ?
> CRF_INIT_QP : ABR_INIT_QP_MIN) * m_accumPNorm;
> >
> >      /* Frame Predictors and Row predictors used in vbv */
> > -    for (int i = 0; i < 5; i++)
> > +    for (int i = 0; i < 4; i++)
> >      {
> >          m_pred[i].coeff = 1.5;
> >          m_pred[i].count = 1.0;
> > @@ -945,6 +945,9 @@
> >      m_curSlice = curEncData.m_slice;
> >      m_sliceType = m_curSlice->m_sliceType;
> >      rce->sliceType = m_sliceType;
> > +    if (!m_2pass)
> > +        rce->keptAsRef = IS_REFERENCED(curFrame);
> > +    m_predType = m_sliceType == B_SLICE && rce->keptAsRef ? 3 :
> m_sliceType;
> >      rce->poc = m_curSlice->m_poc;
> >      if (m_param->rc.bStatRead)
> >      {
> > @@ -1074,7 +1077,7 @@
> >              m_lastQScaleFor[m_sliceType] = x265_qp2qScale(rce->qpaRc);
> >              if (rce->poc == 0)
> >                   m_lastQScaleFor[P_SLICE] =
> m_lastQScaleFor[m_sliceType] * fabs(m_param->rc.ipFactor);
> > -            rce->frameSizePlanned = predictSize(&m_pred[m_sliceType],
> m_qp, (double)m_currentSatd);
> > +            rce->frameSizePlanned = predictSize(&m_pred[m_predType],
> m_qp, (double)m_currentSatd);
> >          }
> >      }
> >      m_framesDone++;
> > @@ -1397,10 +1400,10 @@
> >                  qScale = clipQscale(curFrame, rce, qScale);
> >                  /* clip qp to permissible range after vbv-lookahead
> estimation to avoid possible
> >                   * mispredictions by initial frame size predictors */
> > -                if (m_pred[m_sliceType].count == 1)
> > +                if (m_pred[m_predType].count == 1)
> >                      qScale = x265_clip3(lmin, lmax, qScale);
> >                  m_lastQScaleFor[m_sliceType] = qScale;
> > -                rce->frameSizePlanned =
> predictSize(&m_pred[m_sliceType], qScale, (double)m_currentSatd);
> > +                rce->frameSizePlanned =
> predictSize(&m_pred[m_predType], qScale, (double)m_currentSatd);
> >              }
> >              else
> >                  rce->frameSizePlanned = qScale2bits(rce, qScale);
> > @@ -1544,7 +1547,7 @@
> >              q = clipQscale(curFrame, rce, q);
> >              /*  clip qp to permissible range after vbv-lookahead
> estimation to avoid possible
> >               * mispredictions by initial frame size predictors */
> > -            if (!m_2pass && m_isVbv && m_pred[m_sliceType].count == 1)
> > +            if (!m_2pass && m_isVbv && m_pred[m_predType].count == 1)
> >                  q = x265_clip3(lqmin, lqmax, q);
> >          }
> >          m_lastQScaleFor[m_sliceType] = q;
> > @@ -1554,7 +1557,7 @@
> >          if (m_2pass && m_isVbv)
> >              rce->frameSizePlanned = qScale2bits(rce, q);
> >          else
> > -            rce->frameSizePlanned = predictSize(&m_pred[m_sliceType],
> q, (double)m_currentSatd);
> > +            rce->frameSizePlanned = predictSize(&m_pred[m_predType], q,
> (double)m_currentSatd);
> >
> >          /* Always use up the whole VBV in this case. */
> >          if (m_singleFrameVbv)
> > @@ -1707,7 +1710,7 @@
> >              {
> >                  double frameQ[3];
> >                  double curBits;
> > -                curBits = predictSize(&m_pred[m_sliceType], q,
> (double)m_currentSatd);
> > +                curBits = predictSize(&m_pred[m_predType], q,
> (double)m_currentSatd);
> >                  double bufferFillCur = m_bufferFill - curBits;
> >                  double targetFill;
> >                  double totalDuration = m_frameDuration;
> > @@ -1726,7 +1729,8 @@
> >                          bufferFillCur += wantedFrameSize;
> >                      int64_t satd = curFrame->m_lowres.plannedSatd[j] >>
> (X265_DEPTH - 8);
> >                      type = IS_X265_TYPE_I(type) ? I_SLICE :
> IS_X265_TYPE_B(type) ? B_SLICE : P_SLICE;
> > -                    curBits = predictSize(&m_pred[type], frameQ[type],
> (double)satd);
> > +                    int predType = curFrame->m_lowres.plannedType[j] ==
> X265_TYPE_BREF ? 3 : type;
> > +                    curBits = predictSize(&m_pred[predType],
> frameQ[type], (double)satd);
> >                      bufferFillCur -= curBits;
> >                  }
> >
> > @@ -1766,7 +1770,7 @@
> >              }
> >              // Now a hard threshold to make sure the frame fits in VBV.
> >              // This one is mostly for I-frames.
> > -            double bits = predictSize(&m_pred[m_sliceType], q,
> (double)m_currentSatd);
> > +            double bits = predictSize(&m_pred[m_predType], q,
> (double)m_currentSatd);
> >
> >              // For small VBVs, allow the frame to use up the entire VBV.
> >              double maxFillFactor;
> > @@ -1783,14 +1787,14 @@
> >                  bits *= qf;
> >                  if (bits < m_bufferRate / minFillFactor)
> >                      q *= bits * minFillFactor / m_bufferRate;
> > -                bits = predictSize(&m_pred[m_sliceType], q,
> (double)m_currentSatd);
> > +                bits = predictSize(&m_pred[m_predType], q,
> (double)m_currentSatd);
> >              }
> >
> >              q = X265_MAX(q0, q);
> >          }
> >
> >          /* Apply MinCR restrictions */
> > -        double pbits = predictSize(&m_pred[m_sliceType], q,
> (double)m_currentSatd);
> > +        double pbits = predictSize(&m_pred[m_predType], q,
> (double)m_currentSatd);
> >          if (pbits > rce->frameSizeMaximum)
> >              q *= pbits / rce->frameSizeMaximum;
> >
> > @@ -2099,8 +2103,10 @@
> >
> >  void RateControl::updateVbv(int64_t bits, RateControlEntry* rce)
> >  {
> > +    int predType = rce->sliceType;
> > +    predType = rce->sliceType == B_SLICE && rce->keptAsRef ? 3 :
> predType;
> >      if (rce->lastSatd >= m_ncu)
> > -        updatePredictor(&m_pred[rce->sliceType],
> x265_qp2qScale(rce->qpaRc), (double)rce->lastSatd, (double)bits);
> > +        updatePredictor(&m_pred[predType], x265_qp2qScale(rce->qpaRc),
> (double)rce->lastSatd, (double)bits);
> >      if (!m_isVbv)
> >          return;
> >
> > diff -r 3e416dec8024 -r 6f159ec858f4 source/encoder/ratecontrol.h
> > --- a/source/encoder/ratecontrol.h    Tue Apr 07 16:00:39 2015 -0500
> > +++ b/source/encoder/ratecontrol.h    Tue Mar 31 22:16:21 2015 +0530
> > @@ -157,10 +157,9 @@
> >      double m_rateFactorMaxIncrement; /* Don't allow RF above (CRF +
> this value). */
> >      double m_rateFactorMaxDecrement; /* don't allow RF below (this
> value). */
> >
> > -    Predictor m_pred[5];
> > -    Predictor m_predBfromP;
> > -
> > +    Predictor m_pred[4];       /* Slice predictors to preidct bits for
> each Slice type - I,P,Bref and B */
> >      int64_t m_leadingNoBSatd;
> > +    int     m_predType;       /* Type of slice predictors to be used -
> depends on the slice type */
> >      double  m_ipOffset;
> >      double  m_pbOffset;
> >      int64_t m_bframeBits;
> > _______________________________________________
> > x265-devel mailing list
> > x265-devel at videolan.org
> > https://mailman.videolan.org/listinfo/x265-devel
>
> --
> Steve Borho
> _______________________________________________
> 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/20150409/3007c324/attachment-0001.html>


More information about the x265-devel mailing list