[x265] [PATCH 2 of 2] vbv: bug fixes - move row Predictors, frameSizeEstimated to Frame Encoder scope

aarthi at multicorewareinc.com aarthi at multicorewareinc.com
Mon Mar 10 20:36:36 CET 2014


# HG changeset patch
# User Aarthi Thirumalai
# Date 1394480150 -19800
#      Tue Mar 11 01:05:50 2014 +0530
# Node ID f103a68c678c88c9072f6ea286582ec9427a2241
# Parent  489ec5db168c83c61836b77503eb9280fd5b5164
vbv: bug fixes - move row Predictors, frameSizeEstimated to Frame Encoder scope.

Improves quality and controls buffer underflow when Frame parallelism is enabled.

diff -r 489ec5db168c -r f103a68c678c source/encoder/encoder.cpp
--- a/source/encoder/encoder.cpp	Tue Mar 11 00:17:53 2014 +0530
+++ b/source/encoder/encoder.cpp	Tue Mar 11 01:05:50 2014 +0530
@@ -216,7 +216,12 @@
         FrameEncoder *encoder = &m_frameEncoder[encIdx];
         double bits;
         bits = encoder->m_rce.frameSizePlanned;
-        bits = X265_MAX(bits, m_rateControl->frameSizeEstimated);
+         if (!encoder->m_rce.isActive)
+        {
+            encIdx = (encIdx + 1) % param->frameNumThreads;
+            continue;
+        }
+        bits = X265_MAX(bits,encoder->m_rce.frameSizeEstimated);
         rc->bufferFill -= bits;
         rc->bufferFill = X265_MAX(rc->bufferFill, 0);
         rc->bufferFill += encoder->m_rce.bufferRate;
diff -r 489ec5db168c -r f103a68c678c source/encoder/ratecontrol.cpp
--- a/source/encoder/ratecontrol.cpp	Tue Mar 11 00:17:53 2014 +0530
+++ b/source/encoder/ratecontrol.cpp	Tue Mar 11 01:05:50 2014 +0530
@@ -252,7 +252,6 @@
     lastNonBPictType = I_SLICE;
     isAbrReset = false;
     lastAbrResetPoc = -1;
-    frameSizeEstimated = 0;
     // vbv initialization
     param->rc.vbvBufferSize = Clip3(0, 2000000, param->rc.vbvBufferSize);
     param->rc.vbvMaxBitrate = Clip3(0, 2000000, param->rc.vbvMaxBitrate);
@@ -374,13 +373,7 @@
         pred[i].decay = 0.5;
         pred[i].offset = 0.0;
     }
-    for (int i = 0; i < 4; i++)
-    {
-        rowPreds[i].coeff = 0.25;
-        rowPreds[i].count = 1.0;
-        rowPreds[i].decay = 0.5;
-        rowPreds[i].offset = 0.0;
-    }
+   
     predBfromP = pred[0];
 }
 
@@ -390,7 +383,7 @@
     curSlice = pic->getSlice();
     sliceType = curSlice->getSliceType();
     rce->sliceType = sliceType;
-
+    rce->isActive = true;
     if (sliceType == B_SLICE)
         rce->bframes = bframes;
     else
@@ -401,8 +394,21 @@
     rce->poc = curSlice->getPOC();
     if (isVbv)
     {
-        rowPred[0] = &rowPreds[sliceType];
-        rowPred[1] = &rowPreds[3];
+        if (rce->rowPreds[0][0].count == 0)
+        {
+             for (int i = 0; i < 3; i++)
+             {
+                 for(int j = 0; j < 2; j++)
+                {
+                    rce->rowPreds[i][j].coeff = 0.25;
+                    rce->rowPreds[i][j].count = 1.0;
+                    rce->rowPreds[i][j].decay = 0.5;
+                    rce->rowPreds[i][j].offset = 0.0;
+                }
+             }
+        }
+        rce->rowPred[0] = &rce->rowPreds[sliceType][0];
+        rce->rowPred[1] = &rce->rowPreds[sliceType][1];
         updateVbvPlan(enc);
         rce->bufferFill = bufferFill;
     }
@@ -497,7 +503,7 @@
         qpNoVbv = q;
         double qScale = qp2qScale(qpNoVbv);
         rce->frameSizePlanned = predictSize(&predBfromP, qScale, (double)leadingNoBSatd);
-        frameSizeEstimated = rce->frameSizePlanned;
+        rce->frameSizeEstimated = rce->frameSizePlanned;
         return qScale;
     }
     else
@@ -616,7 +622,7 @@
         {
             // Reset ABR if prev frames are blank to prevent further sudden overflows/ high bit rate spikes.
             double underflow = 1.0 + (totalBits - wantedBitsWindow) / abrBuffer;
-            if (underflow < 1 && !isFrameDone)
+            if (underflow < 0.9 && !isFrameDone)
             {
                 reInit();
                 shortTermCplxSum = rce->lastSatd / (CLIP_DURATION(frameDuration) / BASE_FRAME_DURATION);
@@ -765,7 +771,7 @@
     return Clip3(lmin1, lmax1, q);
 }
 
-double RateControl::predictRowsSizeSum(TComPic* pic, double qpVbv, int32_t & encodedBitsSoFar)
+double RateControl::predictRowsSizeSum(TComPic* pic, RateControlEntry* rce, double qpVbv, int32_t & encodedBitsSoFar)
 {
     uint32_t rowSatdCostSoFar = 0, totalSatdBits = 0;
 
@@ -781,7 +787,7 @@
         uint32_t satdCostForPendingCus = pic->m_rowSatdForVbv[row] - rowSatdCostSoFar;
         if (satdCostForPendingCus  > 0)
         {
-            double pred_s = predictSize(rowPred[0], qScale, satdCostForPendingCus);
+            double pred_s = predictSize(rce->rowPred[0], qScale, satdCostForPendingCus);
             uint32_t refRowSatdCost = 0, refRowBits = 0, intraCost = 0;
             double refQScale = 0;
 
@@ -818,7 +824,7 @@
             else
             {
                 /* Our QP is lower than the reference! */
-                double pred_intra = predictSize(rowPred[1], qScale, intraCost);
+                double pred_intra = predictSize(rce->rowPred[1], qScale, intraCost);
                 /* Sum: better to overestimate than underestimate by using only one of the two predictors. */
                 totalSatdBits += int32_t(pred_intra + pred_s);
             }
@@ -841,16 +847,16 @@
         rowSatdCost += pic->m_rowDiagSatd[0];
         encodedBits += pic->m_rowEncodedBits[0];
     }
-    updatePredictor(rowPred[0], qScaleVbv, rowSatdCost, encodedBits);
+    updatePredictor(rce->rowPred[0], qScaleVbv, rowSatdCost, encodedBits);
     if (pic->getSlice()->getSliceType() == P_SLICE)
     {
         TComPic* refSlice = pic->getSlice()->getRefPic(REF_PIC_LIST_0, 0);
         if (qpVbv < refSlice->m_rowDiagQp[row])
         {
             if (row == 1)
-                updatePredictor(rowPred[1], qScaleVbv, pic->m_rowDiagIntraSatd[row] + pic->m_rowDiagIntraSatd[0], pic->m_rowEncodedBits[row] + pic->m_rowEncodedBits[0]);
+                updatePredictor(rce->rowPred[1], qScaleVbv, pic->m_rowDiagIntraSatd[row] + pic->m_rowDiagIntraSatd[0], pic->m_rowEncodedBits[row] + pic->m_rowEncodedBits[0]);
             else
-                updatePredictor(rowPred[1], qScaleVbv, pic->m_rowDiagIntraSatd[row], pic->m_rowEncodedBits[row]);
+                updatePredictor(rce->rowPred[1], qScaleVbv, pic->m_rowDiagIntraSatd[row], pic->m_rowEncodedBits[row]);
         }
     }
 
@@ -880,7 +886,7 @@
         /* More threads means we have to be more cautious in letting ratecontrol use up extra bits. */
         double rcTol = bufferLeftPlanned / param->frameNumThreads * param->rc.rateTolerance;
         int32_t encodedBitsSoFar = 0;
-        double accFrameBits = predictRowsSizeSum(pic, qpVbv, encodedBitsSoFar);
+        double accFrameBits = predictRowsSizeSum(pic, rce, qpVbv, encodedBitsSoFar);
 
         /* * 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
@@ -900,7 +906,7 @@
                    (accFrameBits > rce->frameSizePlanned && qpVbv < rce->qpNoVbv)))
         {
             qpVbv += stepSize;
-            accFrameBits = predictRowsSizeSum(pic, qpVbv, encodedBitsSoFar);
+            accFrameBits = predictRowsSizeSum(pic, rce, qpVbv, encodedBitsSoFar);
         }
 
         while (qpVbv > qpMin
@@ -909,7 +915,7 @@
                    || accFrameBits < (rce->bufferFill - bufferSize + bufferRate) * 1.1))
         {
             qpVbv -= stepSize;
-            accFrameBits = predictRowsSizeSum(pic, qpVbv, encodedBitsSoFar);
+            accFrameBits = predictRowsSizeSum(pic, rce, qpVbv, encodedBitsSoFar);
         }
 
         /* avoid VBV underflow */
@@ -917,10 +923,10 @@
                && (rce->bufferFill - accFrameBits < bufferRate * maxFrameError))
         {
             qpVbv += stepSize;
-            accFrameBits = predictRowsSizeSum(pic, qpVbv, encodedBitsSoFar);
+            accFrameBits = predictRowsSizeSum(pic, rce, qpVbv, encodedBitsSoFar);
         }
 
-        frameSizeEstimated = accFrameBits;
+        rce->frameSizeEstimated = accFrameBits;
 
         /* If the current row was large enough to cause a large QP jump, try re-encoding it. */
         if (qpVbv > qpMax && prevRowQp < qpMax && canReencodeRow)
@@ -933,11 +939,11 @@
     else
     {
         int32_t encodedBitsSoFar = 0;
-        frameSizeEstimated = predictRowsSizeSum(pic, qpVbv, encodedBitsSoFar);
+        rce->frameSizeEstimated = predictRowsSizeSum(pic, rce, qpVbv, encodedBitsSoFar);
 
         /* Last-ditch attempt: if the last row of the frame underflowed the VBV,
          * try again. */
-        if ((frameSizeEstimated > (rce->bufferFill - bufferRate * maxFrameError) &&
+        if ((rce->frameSizeEstimated > (rce->bufferFill - bufferRate * maxFrameError) &&
              qpVbv < qpMax && canReencodeRow))
         {
             qpVbv = qpMax;
@@ -1069,6 +1075,7 @@
             }
         }
         updateVbv(bits, rce);
+        rce->isActive = false;
     }
     return 0;
 }
diff -r 489ec5db168c -r f103a68c678c source/encoder/ratecontrol.h
--- a/source/encoder/ratecontrol.h	Tue Mar 11 00:17:53 2014 +0530
+++ b/source/encoder/ratecontrol.h	Tue Mar 11 01:05:50 2014 +0530
@@ -43,6 +43,14 @@
 
 #define CLIP_DURATION(f) Clip3(MIN_FRAME_DURATION, MAX_FRAME_DURATION, f)
 
+struct Predictor
+{
+    double coeff;
+    double count;
+    double decay;
+    double offset;
+};
+
 struct RateControlEntry
 {
     int64_t texBits;  /* Required in 2-pass rate control */
@@ -57,19 +65,15 @@
     double blurredComplexity;
     double qpaRc;
     double qRceq;
-    double frameSizePlanned;
+    double frameSizePlanned;  /* frame Size decided by RateCotrol before encoding the frame */
     double bufferRate;
     double movingAvgSum;
     double qpNoVbv;
     double bufferFill;
-};
-
-struct Predictor
-{
-    double coeff;
-    double count;
-    double decay;
-    double offset;
+    Predictor rowPreds[3][2];
+    Predictor* rowPred[2];
+    double frameSizeEstimated;  /* hold frameSize, updated from cu level vbv rc */
+    bool isActive;
 };
 
 struct RateControl
@@ -96,8 +100,6 @@
     bool isVbv;
     Predictor pred[5];
     Predictor predBfromP;
-    Predictor rowPreds[4];
-    Predictor *rowPred[2];
     int bframes;
     int bframeBits;
     bool isAbrReset;
@@ -123,7 +125,6 @@
     int framesDone;           /* framesDone keeps track of # of frames passed through RateCotrol already */
     double qCompress;
     double qpNoVbv;             /* QP for the current frame if 1-pass VBV was disabled. */
-    double frameSizeEstimated;  /* hold synched frameSize, updated from cu level vbv rc */
     RateControl(Encoder * _cfg);
 
     // to be called for each frame to process RateControl and set QP
@@ -146,7 +147,7 @@
     void updateVbvPlan(Encoder* enc);
     double predictSize(Predictor *p, double q, double var);
     void checkAndResetABR(RateControlEntry* rce, bool isFrameDone);
-    double predictRowsSizeSum(TComPic* pic, double qpm, int32_t& encodedBits);
+    double predictRowsSizeSum(TComPic* pic, RateControlEntry* rce, double qpm, int32_t& encodedBits);
 };
 }
 #endif // ifndef X265_RATECONTROL_H


More information about the x265-devel mailing list