[x265] [PATCH] rc: fix cost issues in predicting row size during mid frame vbv encodes

aarthi at multicorewareinc.com aarthi at multicorewareinc.com
Mon Apr 27 06:52:01 CEST 2015


# HG changeset patch
# User Aarthi Thirumalai
# Date 1429617548 -19800
#      Tue Apr 21 17:29:08 2015 +0530
# Node ID c68d582086a3a5c91c71c5e3ae3ffbf179a038b1
# Parent  4a7176bab7423d831675f0419b6470668bdbd919
rc: fix cost issues in predicting row size during mid frame vbv encodes.

diff -r 4a7176bab742 -r c68d582086a3 source/common/framedata.h
--- a/source/common/framedata.h	Fri Apr 24 16:07:42 2015 -0500
+++ b/source/common/framedata.h	Tue Apr 21 17:29:08 2015 +0530
@@ -74,6 +74,7 @@
         uint32_t numEncodedCUs; /* ctuAddr of last encoded CTU in row */
         uint32_t encodedBits;   /* sum of 'totalBits' of encoded CTUs */
         uint32_t satdForVbv;    /* sum of lowres (estimated) costs for entire row */
+        uint32_t intraSatdForVbv; /* sum of lowres (estimated) intra costs for entire row */
         uint32_t diagSatd;
         uint32_t diagIntraSatd;
         double   diagQp;
diff -r 4a7176bab742 -r c68d582086a3 source/encoder/ratecontrol.cpp
--- a/source/encoder/ratecontrol.cpp	Fri Apr 24 16:07:42 2015 -0500
+++ b/source/encoder/ratecontrol.cpp	Tue Apr 21 17:29:08 2015 +0530
@@ -1395,6 +1395,7 @@
             q += m_pbOffset;
 
         double qScale = x265_qp2qScale(q);
+        rce->qpNoVbv = q;
         double lmin = 0, lmax = 0;
         if (m_isVbv)
         {
@@ -1407,7 +1408,6 @@
                     qScale = x265_clip3(lmin, lmax, qScale);
                 q = x265_qScale2qp(qScale);
             }
-            rce->qpNoVbv = q;
             if (!m_2pass)
             {
                 qScale = clipQscale(curFrame, rce, qScale);
@@ -1858,18 +1858,26 @@
         if (satdCostForPendingCus  > 0)
         {
             double pred_s = predictSize(rce->rowPred[0], qScale, satdCostForPendingCus);
-            uint32_t refRowSatdCost = 0, refRowBits = 0, intraCost = 0;
+            uint32_t refRowSatdCost = 0, refRowBits = 0, intraCostForPendingCus = 0;
             double refQScale = 0;
 
             if (picType != I_SLICE)
             {
                 FrameData& refEncData = *refFrame->m_encData;
                 uint32_t endCuAddr = maxCols * (row + 1);
-                for (uint32_t cuAddr = curEncData.m_rowStat[row].numEncodedCUs + 1; cuAddr < endCuAddr; cuAddr++)
+                uint32_t startCuAddr = curEncData.m_rowStat[row].numEncodedCUs;
+                if (startCuAddr)
                 {
-                    refRowSatdCost += refEncData.m_cuStat[cuAddr].vbvCost;
-                    refRowBits += refEncData.m_cuStat[cuAddr].totalBits;
-                    intraCost += curEncData.m_cuStat[cuAddr].intraVbvCost;
+                    for (uint32_t cuAddr = startCuAddr + 1 ; cuAddr < endCuAddr; cuAddr++)
+                    {
+                        refRowSatdCost += refEncData.m_cuStat[cuAddr].vbvCost;
+                        refRowBits += refEncData.m_cuStat[cuAddr].totalBits;
+                    }
+                }
+                else
+                {
+                    refRowBits = refEncData.m_rowStat[row].encodedBits;
+                    refRowSatdCost = refEncData.m_rowStat[row].satdForVbv;
                 }
 
                 refRowSatdCost >>= X265_DEPTH - 8;
@@ -1879,7 +1887,7 @@
             if (picType == I_SLICE || qScale >= refQScale)
             {
                 if (picType == P_SLICE 
-                    && !refFrame 
+                    && refFrame 
                     && refFrame->m_encData->m_slice->m_sliceType == picType
                     && refQScale > 0
                     && refRowSatdCost > 0)
@@ -1895,8 +1903,9 @@
             }
             else if (picType == P_SLICE)
             {
+                intraCostForPendingCus = curEncData.m_rowStat[row].intraSatdForVbv - curEncData.m_rowStat[row].diagIntraSatd;
                 /* Our QP is lower than the reference! */
-                double pred_intra = predictSize(rce->rowPred[1], qScale, intraCost);
+                double pred_intra = predictSize(rce->rowPred[1], qScale, intraCostForPendingCus);
                 /* Sum: better to overestimate than underestimate by using only one of the two predictors. */
                 totalSatdBits += (int32_t)(pred_intra + pred_s);
             }
diff -r 4a7176bab742 -r c68d582086a3 source/encoder/slicetype.cpp
--- a/source/encoder/slicetype.cpp	Fri Apr 24 16:07:42 2015 -0500
+++ b/source/encoder/slicetype.cpp	Tue Apr 21 17:29:08 2015 +0530
@@ -739,7 +739,7 @@
     {
         /* aggregate lowres row satds to CTU resolution */
         curFrame->m_lowres.lowresCostForRc = curFrame->m_lowres.lowresCosts[b - p0][p1 - b];
-        uint32_t lowresRow = 0, lowresCol = 0, lowresCuIdx = 0, sum = 0;
+        uint32_t lowresRow = 0, lowresCol = 0, lowresCuIdx = 0, sum = 0, intraSum = 0;
         uint32_t scale = m_param->maxCUSize / (2 * X265_LOWRES_CU_SIZE);
         uint32_t numCuInHeight = (m_param->sourceHeight + g_maxCUSize - 1) / g_maxCUSize;
         uint32_t widthInLowresCu = (uint32_t)m_8x8Width, heightInLowresCu = (uint32_t)m_8x8Height;
@@ -753,7 +753,7 @@
             lowresRow = row * scale;
             for (uint32_t cnt = 0; cnt < scale && lowresRow < heightInLowresCu; lowresRow++, cnt++)
             {
-                sum = 0;
+                sum = 0; intraSum = 0;
                 lowresCuIdx = lowresRow * widthInLowresCu;
                 for (lowresCol = 0; lowresCol < widthInLowresCu; lowresCol++, lowresCuIdx++)
                 {
@@ -766,8 +766,10 @@
                     }
                     curFrame->m_lowres.lowresCostForRc[lowresCuIdx] = lowresCuCost;
                     sum += lowresCuCost;
+                    intraSum += curFrame->m_lowres.intraCost[lowresCuIdx];
                 }
                 curFrame->m_encData->m_rowStat[row].satdForVbv += sum;
+                curFrame->m_encData->m_rowStat[row].intraSatdForVbv += intraSum;
             }
         }
     }


More information about the x265-devel mailing list