[x265-commits] [x265] vbv: bug fix in clipQScale

Aarthi at videolan.org Aarthi at videolan.org
Mon Feb 24 22:45:59 CET 2014


details:   http://hg.videolan.org/x265/rev/80caa9f00d7c
branches:  
changeset: 6268:80caa9f00d7c
user:      Aarthi Thirumalai
date:      Sun Feb 23 21:25:22 2014 +0530
description:
vbv: bug fix in clipQScale
Subject: [x265] tcomrom: remove unused  g_sigLastScan8x8 and g_sigLastScanCG32x32 variables

details:   http://hg.videolan.org/x265/rev/57ce7f0f4f4c
branches:  
changeset: 6269:57ce7f0f4f4c
user:      Gopu Govindaswamy
date:      Thu Feb 20 16:01:28 2014 -0800
description:
tcomrom: remove unused  g_sigLastScan8x8 and g_sigLastScanCG32x32 variables
Subject: [x265] rc: bug fix - clip qp before setting into TComPic:m_avgQpRc.

details:   http://hg.videolan.org/x265/rev/acaed9dbaae2
branches:  
changeset: 6270:acaed9dbaae2
user:      Aarthi Thirumalai
date:      Mon Feb 24 23:01:32 2014 +0530
description:
rc: bug fix - clip qp before setting into TComPic:m_avgQpRc.

This fix resolves Encoder crash caused due to invalid qp being used in each
CU.
Subject: [x265] vbv: refactor, implement row wise qp updates only if vbv is enabled.

details:   http://hg.videolan.org/x265/rev/d0aea0cfd263
branches:  
changeset: 6271:d0aea0cfd263
user:      Aarthi Thirumalai
date:      Mon Feb 24 17:50:55 2014 +0530
description:
vbv: refactor, implement row wise qp updates only if vbv is enabled.
Subject: [x265] rc: implement abr reset for single pass ABR + VBV

details:   http://hg.videolan.org/x265/rev/ebaa34c8f651
branches:  
changeset: 6272:ebaa34c8f651
user:      Aarthi Thirumalai
date:      Mon Feb 24 18:55:00 2014 +0530
description:
rc: implement abr reset for single pass ABR + VBV

diffstat:

 source/Lib/TLibCommon/TComRom.cpp |  18 -------
 source/Lib/TLibCommon/TComRom.h   |   9 ---
 source/encoder/frameencoder.cpp   |   7 +-
 source/encoder/ratecontrol.cpp    |  90 +++++++++++++++++++-------------------
 source/encoder/ratecontrol.h      |   3 +-
 5 files changed, 50 insertions(+), 77 deletions(-)

diffs (truncated from 301 to 300 lines):

diff -r d1cd52bb3461 -r ebaa34c8f651 source/Lib/TLibCommon/TComRom.cpp
--- a/source/Lib/TLibCommon/TComRom.cpp	Sat Feb 22 19:00:07 2014 -0600
+++ b/source/Lib/TLibCommon/TComRom.cpp	Mon Feb 24 18:55:00 2014 +0530
@@ -443,24 +443,6 @@ uint64_t g_nSymbolCounter = 0;
 // Scanning order & context model mapping
 // ====================================================================================================================
 
-const uint32_t g_sigLastScan8x8[3][4] =
-{
-    { 0, 2, 1, 3 },
-    { 0, 1, 2, 3 },
-    { 0, 2, 1, 3 }
-};
-const uint32_t g_sigLastScanCG32x32[64] =
-{
-    0,  8,  1, 16,  9,  2, 24, 17,
-    10,  3, 32, 25, 18, 11,  4, 40,
-    33, 26, 19, 12,  5, 48, 41, 34,
-    27, 20, 13,  6, 56, 49, 42, 35,
-    28, 21, 14,  7, 57, 50, 43, 36,
-    29, 22, 15, 58, 51, 44, 37, 30,
-    23, 59, 52, 45, 38, 31, 60, 53,
-    46, 39, 61, 54, 47, 62, 55, 63
-};
-
 const uint32_t g_minInGroup[10] = { 0, 1, 2, 3, 4, 6, 8, 12, 16, 24 };
 const uint32_t g_groupIdx[32]   = { 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9 };
 
diff -r d1cd52bb3461 -r ebaa34c8f651 source/Lib/TLibCommon/TComRom.h
--- a/source/Lib/TLibCommon/TComRom.h	Sat Feb 22 19:00:07 2014 -0600
+++ b/source/Lib/TLibCommon/TComRom.h	Mon Feb 24 18:55:00 2014 +0530
@@ -137,15 +137,6 @@ extern const uint32_t g_minInGroup[10];
 extern const uint32_t g_goRiceRange[5];      //!< maximum value coded with Rice codes
 extern const uint32_t g_goRicePrefixLen[5];  //!< prefix length for each maximum value
 
-extern const uint32_t g_sigLastScan8x8[3][4];   //!< coefficient group scan order for 8x8 TUs
-extern const uint32_t g_sigLastScanCG32x32[64];
-
-// ====================================================================================================================
-// ADI table
-// ====================================================================================================================
-
-extern const UChar g_intraModeNumFast[7];
-
 // ====================================================================================================================
 // Bit-depth
 // ====================================================================================================================
diff -r d1cd52bb3461 -r ebaa34c8f651 source/encoder/frameencoder.cpp
--- a/source/encoder/frameencoder.cpp	Sat Feb 22 19:00:07 2014 -0600
+++ b/source/encoder/frameencoder.cpp	Mon Feb 24 18:55:00 2014 +0530
@@ -1058,6 +1058,7 @@ void FrameEncoder::processRowEncoder(int
     const uint32_t numCols = m_pic->getPicSym()->getFrameWidthInCU();
     const uint32_t lineStartCUAddr = row * numCols;
     double qpBase = m_pic->m_avgQpRc;
+    bool isVbv = m_cfg->param.rc.vbvBufferSize > 0 && m_cfg->param.rc.vbvMaxBitrate > 0;
     for (uint32_t col = curRow.m_completed; col < numCols; col++)
     {
         const uint32_t cuAddr = lineStartCUAddr + col;
@@ -1068,10 +1069,10 @@ void FrameEncoder::processRowEncoder(int
         codeRow.m_entropyCoder.resetEntropy();
         TEncSbac *bufSbac = (m_cfg->param.bEnableWavefront && col == 0 && row > 0) ? &m_rows[row - 1].m_bufferSbacCoder : NULL;
 
-        if ((uint32_t)row >= col && (row != 0))
+        if ((uint32_t)row >= col && (row != 0) && isVbv)
             qpBase = m_pic->getCU(cuAddr - numCols + 1)->m_baseQp;
 
-        if (m_cfg->param.rc.aqMode || (m_cfg->param.rc.vbvBufferSize > 0 && m_cfg->param.rc.vbvMaxBitrate > 0))
+        if (m_cfg->param.rc.aqMode || isVbv)
         {
             int qp = calcQpForCu(m_pic, cuAddr, qpBase);
             setLambda(qp, row);
@@ -1080,7 +1081,7 @@ void FrameEncoder::processRowEncoder(int
             cu->m_baseQp = qpBase;
         }
         codeRow.processCU(cu, m_pic->getSlice(), bufSbac, m_cfg->param.bEnableWavefront && col == 1);
-        if (m_cfg->param.rc.vbvBufferSize && m_cfg->param.rc.vbvMaxBitrate)
+        if (isVbv)
         {
             // Update encoded bits, satdCost, baseQP for each CU
             m_pic->m_rowDiagSatd[row] += m_pic->m_cuCostsForVbv[cuAddr];
diff -r d1cd52bb3461 -r ebaa34c8f651 source/encoder/ratecontrol.cpp
--- a/source/encoder/ratecontrol.cpp	Sat Feb 22 19:00:07 2014 -0600
+++ b/source/encoder/ratecontrol.cpp	Mon Feb 24 18:55:00 2014 +0530
@@ -245,15 +245,12 @@ RateControl::RateControl(TEncCfg * _cfg)
     }
 
     isAbr = cfg->param.rc.rateControlMode != X265_RC_CQP; // later add 2pass option
-
     bitrate = cfg->param.rc.bitrate * 1000;
     frameDuration = (double)cfg->param.fpsDenom / cfg->param.fpsNum;
     qp = cfg->param.rc.qp;
     lastRceq = 1; /* handles the cmplxrsum when the previous frame cost is zero */
-    totalBits = 0;
     shortTermCplxSum = 0;
     shortTermCplxCount = 0;
-    framesDone = 0;
     lastNonBPictType = I_SLICE;
     isAbrReset = false;
     lastAbrResetPoc = -1;
@@ -325,43 +322,20 @@ RateControl::RateControl(TEncCfg * _cfg)
             && cfg->param.rc.vbvMaxBitrate <= cfg->param.rc.bitrate;
     }
 
-    for (int i = 0; i < 5; i++)
-    {
-        pred[i].coeff = 2.0;
-        pred[i].count = 1.0;
-        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];
     bframes = cfg->param.bframes;
     bframeBits = 0;
     leadingNoBSatd = 0;
-    accumPNorm = .01;
-    /* estimated ratio that produces a reasonable QP for the first I-frame */
-    cplxrSum = .01 * pow(7.0e5, qCompress) * pow(ncu, 0.5);
-    wantedBitsWindow = bitrate * frameDuration;
-
     if (cfg->param.rc.rateControlMode == X265_RC_ABR)
     {
         /* Adjust the first frame in order to stabilize the quality level compared to the rest */
 #define ABR_INIT_QP_MIN (24 + QP_BD_OFFSET)
 #define ABR_INIT_QP_MAX (34 + QP_BD_OFFSET)
-        accumPQp = (ABR_INIT_QP_MIN)*accumPNorm;
     }
     else if (cfg->param.rc.rateControlMode == X265_RC_CRF)
     {
 #define ABR_INIT_QP ((int)cfg->param.rc.rfConstant + QP_BD_OFFSET)
-        accumPQp = ABR_INIT_QP * accumPNorm;
     }
+    reInit();
 
     ipOffset = 6.0 * X265_LOG2(cfg->param.rc.ipFactor);
     pbOffset = 6.0 * X265_LOG2(cfg->param.rc.pbFactor);
@@ -383,6 +357,36 @@ RateControl::RateControl(TEncCfg * _cfg)
     lstep = pow(2, cfg->param.rc.qpStep / 6.0);
 }
 
+void RateControl::reInit()
+{
+    totalBits = 0;
+    framesDone = 0;
+
+    /* estimated ratio that produces a reasonable QP for the first I-frame */
+    cplxrSum = .01 * pow(7.0e5, qCompress) * pow(ncu, 0.5);
+    wantedBitsWindow = bitrate * frameDuration;
+    accumPNorm = .01;
+    accumPQp = (cfg->param.rc.rateControlMode == X265_RC_CRF ? ABR_INIT_QP : ABR_INIT_QP_MIN) * accumPNorm;
+
+    /* Frame Predictors and Row predictors used in vbv */
+    for (int i = 0; i < 5; i++)
+    {
+        pred[i].coeff = 2.0;
+        pred[i].count = 1.0;
+        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];
+}
+
+
 void RateControl::rateControlStart(TComPic* pic, Lookahead *l, RateControlEntry* rce, Encoder* enc)
 {
     curSlice = pic->getSlice();
@@ -409,7 +413,8 @@ void RateControl::rateControlStart(TComP
         /* Update rce for use in rate control VBV later */
         rce->lastSatd = currentSatd;
         double q = qScale2qp(rateEstimateQscale(pic, rce));
-        qp = Clip3(MIN_QP, MAX_MAX_QP, (int)(q + 0.5));
+        q = Clip3((double)MIN_QP, (double)MAX_MAX_QP, q);
+        qp = int(q + 0.5);
         rce->qpaRc = pic->m_avgQpRc = q;
         /* copy value of lastRceq into thread local rce struct *to be used in RateControlEnd() */
         rce->qRceq = lastRceq;
@@ -464,7 +469,7 @@ double RateControl::rateEstimateQscale(T
         int dt1 = abs(curSlice->getPOC() - nextRefSlice->getPOC());
 
         // Skip taking a reference frame before the Scenecut if ABR has been reset.
-        if (lastAbrResetPoc >= 0 && !isVbv)
+        if (lastAbrResetPoc >= 0)
         {
             if (prevRefSlice->getSliceType() == P_SLICE && prevRefSlice->getPOC() < lastAbrResetPoc)
             {
@@ -530,10 +535,8 @@ double RateControl::rateEstimateQscale(T
         }
         else
         {
-            if (!isVbv)
-            {
-                checkAndResetABR(pic, rce);
-            }
+
+            checkAndResetABR(rce, false);
             q = getQScale(rce, wantedBitsWindow / cplxrSum);
 
             /* ABR code can potentially be counterproductive in CBR, so just
@@ -569,7 +572,7 @@ double RateControl::rateEstimateQscale(T
                 lqmax = qp2qScale(ABR_INIT_QP_MAX) * lstep;
                 q = Clip3(lqmin, lqmax, q);
             }
-            else if (totalBits > 0 || (isVbv && rce->poc > 0))
+            else if (totalBits > 0 || (isVbv && framesDone > 0))
             {
                 lqmin = lastQScaleFor[sliceType] / lstep;
                 lqmax = lastQScaleFor[sliceType] * lstep;
@@ -585,10 +588,10 @@ double RateControl::rateEstimateQscale(T
             if (qCompress != 1 && framesDone == 0)
                 q = qp2qScale(ABR_INIT_QP) / fabs(cfg->param.rc.ipFactor);
         }
-        qpNoVbv = qScale2qp(q);
         double lmin1 = lmin[sliceType];
         double lmax1 = lmax[sliceType];
         q = Clip3(lmin1, lmax1, q);
+        qpNoVbv = qScale2qp(q);
 
         q = clipQscale(pic, q);
 
@@ -603,7 +606,7 @@ double RateControl::rateEstimateQscale(T
     }
 }
 
-void RateControl::checkAndResetABR(TComPic* pic, RateControlEntry* rce)
+void RateControl::checkAndResetABR(RateControlEntry* rce, bool isFrameDone)
 {
     double abrBuffer = 2 * cfg->param.rc.rateTolerance * bitrate;
 
@@ -614,14 +617,9 @@ void RateControl::checkAndResetABR(TComP
         {
             // 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 && pic->m_avgQpRc == 0)
+            if (underflow < 1 && !isFrameDone)
             {
-                totalBits = 0;
-                framesDone = 0;
-                cplxrSum = .01 * pow(7.0e5, qCompress) * pow(ncu, 0.5);
-                wantedBitsWindow = bitrate * frameDuration;
-                accumPNorm = .01;
-                accumPQp = (ABR_INIT_QP_MIN)*accumPNorm;
+                reInit();
                 shortTermCplxSum = rce->lastSatd / (CLIP_DURATION(frameDuration) / BASE_FRAME_DURATION);
                 shortTermCplxCount = 1;
                 isAbrReset = true;
@@ -756,7 +754,7 @@ double RateControl::clipQscale(TComPic* 
             {
                 q *= X265_MAX(pbbits / space, bits / (0.5 * bufferSize));
             }
-            q = X265_MAX(q0 - 5, q);
+            q = X265_MAX(q0 / 2, q);
         }
         if (!vbvMinRate)
             q = X265_MAX(q0, q);
@@ -1009,9 +1007,9 @@ int RateControl::rateControlEnd(TComPic*
 {
     if (isAbr)
     {
-        if (!isVbv && cfg->param.rc.rateControlMode == X265_RC_ABR)
+        if (cfg->param.rc.rateControlMode == X265_RC_ABR)
         {
-            checkAndResetABR(pic, rce);
+            checkAndResetABR(rce, true);
         }
         if (!isAbrReset)
         {
diff -r d1cd52bb3461 -r ebaa34c8f651 source/encoder/ratecontrol.h
--- a/source/encoder/ratecontrol.h	Sat Feb 22 19:00:07 2014 -0600
+++ b/source/encoder/ratecontrol.h	Mon Feb 24 18:55:00 2014 +0530
@@ -134,6 +134,7 @@ struct RateControl
 
 protected:
 
+    void reInit();
     double getQScale(RateControlEntry *rce, double rateFactor);
     double rateEstimateQscale(TComPic* pic, RateControlEntry *rce); // main logic for calculating QP based on ABR
     void accumPQpUpdate();
@@ -144,7 +145,7 @@ protected:
     double clipQscale(TComPic* pic, double q);
     void updateVbvPlan(Encoder* enc);
     double predictSize(Predictor *p, double q, double var);
-    void checkAndResetABR(TComPic* pic, RateControlEntry* rce);
+    void checkAndResetABR(RateControlEntry* rce, bool isFrameDone);
     double predictRowsSizeSum(TComPic* pic, double qpm, int32_t& encodedBits);
 };


More information about the x265-commits mailing list