[x265] [PATCH] vbv: enable row resets during vbv when mid-frame qp adjustemets are too high/low

aarthi at multicorewareinc.com aarthi at multicorewareinc.com
Mon Mar 10 21:22:52 CET 2014


# HG changeset patch
# User Aarthi Thirumalai
# Date 1394482958 -19800
#      Tue Mar 11 01:52:38 2014 +0530
# Node ID 6f43b3b9719208d08801f594c750939a69c8d1b8
# Parent  7f4b871d7a0ce7f8aa90b10518fd7edc5bc95261
vbv: enable row resets during vbv when mid-frame qp adjustemets are too high/low.

diff -r 7f4b871d7a0c -r 6f43b3b97192 source/common/wavefront.cpp
--- a/source/common/wavefront.cpp	Tue Mar 11 01:16:28 2014 +0530
+++ b/source/common/wavefront.cpp	Tue Mar 11 01:52:38 2014 +0530
@@ -32,6 +32,7 @@
 bool WaveFront::init(int numRows)
 {
     m_numRows = numRows;
+    m_bAllRowsStop = false;
 
     if (m_pool)
     {
@@ -117,6 +118,9 @@
 
             CTZ64(id, mask);
 
+            if (m_bAllRowsStop)
+                return false;
+
             uint64_t newval = oldval & ~(1LL << id);
             if (ATOMIC_CAS(&m_internalDependencyBitmap[w], oldval, newval) == oldval)
             {
diff -r 7f4b871d7a0c -r 6f43b3b97192 source/common/wavefront.h
--- a/source/common/wavefront.h	Tue Mar 11 01:16:28 2014 +0530
+++ b/source/common/wavefront.h	Tue Mar 11 01:52:38 2014 +0530
@@ -53,6 +53,8 @@
 
 public:
 
+    bool m_bAllRowsStop;  /*flag used by FrameEncoder to pause scheduler while doing vbv row resets */
+
     WaveFront(ThreadPool *pool)
         : JobProvider(pool)
         , m_internalDependencyBitmap(0)
diff -r 7f4b871d7a0c -r 6f43b3b97192 source/encoder/cturow.h
--- a/source/encoder/cturow.h	Tue Mar 11 01:16:28 2014 +0530
+++ b/source/encoder/cturow.h	Tue Mar 11 01:52:38 2014 +0530
@@ -102,6 +102,9 @@
 
     /* count of completed CUs in this row */
     volatile uint32_t   m_completed;
+
+   /* flag to enable row resets in vbv */
+    bool                   m_isReencode;
 };
 }
 
diff -r 7f4b871d7a0c -r 6f43b3b97192 source/encoder/frameencoder.cpp
--- a/source/encoder/frameencoder.cpp	Tue Mar 11 01:16:28 2014 +0530
+++ b/source/encoder/frameencoder.cpp	Tue Mar 11 01:52:38 2014 +0530
@@ -929,8 +929,11 @@
         m_rows[i].m_rdGoOnBinCodersCABAC.m_fracBits = 0;
         m_rows[i].m_completed = 0;
         m_rows[i].m_busy = false;
+        m_rows[i].m_isReencode = false;
+
+
     }
-
+    m_vbvResetTriggerRow = -1;
     int range = m_cfg->param->searchRange; /* fpel search */
     range    += 1;                        /* diamond search range check lag */
     range    += 2;                        /* subpel refine */
@@ -1059,8 +1062,25 @@
     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;
+
+     //block current row if previous row is getting reencoded or prev row reference cus are not completed.
+     ScopedLock self(curRow.m_lock);
+    if (row > 0 && (m_rows[row - 1].m_isReencode || m_rows[row].m_completed < numCols - 2  && m_rows[row - 1].m_completed < m_rows[row].m_completed + 2))
+    {
+        m_rows[row].m_active = false;
+        m_rows[row].m_busy = false;
+        m_totalTime = m_totalTime + (x265_mdate() - startTime);
+        return;
+    }
     for (uint32_t col = curRow.m_completed; col < numCols; col++)
     {
+        //reset current row data if reencoded is turned on this row
+        if (m_rows[row].m_isReencode == true )
+        {
+            col = 0;
+            m_bAllRowsStop = false;
+            m_rows[row].m_isReencode = false;          
+        }
         const uint32_t cuAddr = lineStartCUAddr + col;
         TComDataCU* cu = m_pic->getCU(cuAddr);
         cu->initCU(m_pic, cuAddr);
@@ -1069,16 +1089,26 @@
         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) && isVbv)
-            qpBase = m_pic->getCU(cuAddr - numCols + 1)->m_baseQp;
+        if(isVbv)
+        {
+            if ((uint32_t)row == 0)
+                m_pic->m_rowDiagQp[row] = m_pic->m_avgQpRc;
+
+            if ((uint32_t)row >= col && (row != 0) && m_vbvResetTriggerRow != row)
+                cu->m_baseQp = m_pic->getCU(cuAddr - numCols + 1)->m_baseQp;
+            else 
+                cu->m_baseQp = m_pic->m_rowDiagQp[row];
+        }
+        else
+            cu->m_baseQp = m_pic->m_avgQpRc;
 
         if (m_cfg->param->rc.aqMode || isVbv)
         {
-            int qp = calcQpForCu(m_pic, cuAddr, qpBase);
+            int qp = calcQpForCu(m_pic, cuAddr, cu->m_baseQp);
             setLambda(qp, row);
             qp = X265_MIN(qp, MAX_QP);
             cu->setQP(0, char(qp));
-            cu->m_baseQp = qpBase;
+
             if (m_cfg->param->rc.aqMode)
                 m_pic->m_qpaAq[row] += qp;
         }
@@ -1087,22 +1117,46 @@
         {
             // Update encoded bits, satdCost, baseQP for each CU
             m_pic->m_rowDiagSatd[row] += m_pic->m_cuCostsForVbv[cuAddr];
+            m_pic->m_rowDiagIntraSatd[row] += m_pic->m_intraCuCostsForVbv[cuAddr];
             m_pic->m_rowEncodedBits[row] += cu->m_totalBits;
             m_pic->m_numEncodedCusPerRow[row] = cuAddr;
             m_pic->m_qpaRc[row] += cu->m_baseQp;
 
-            if ((uint32_t)row == col)
-                m_pic->m_rowDiagQp[row] = qpBase;
-
             // If current block is at row diagonal checkpoint, call vbv ratecontrol.
             if ((uint32_t)row == col && row != 0)
             {
-                m_top->m_rateControl->rowDiagonalVbvRateControl(m_pic, row, &m_rce, qpBase);
+                qpBase = cu->m_baseQp;
+                int reEncode =  m_top->m_rateControl->rowDiagonalVbvRateControl(m_pic, row, &m_rce, qpBase);
                 qpBase = Clip3((double)MIN_QP, (double)MAX_MAX_QP, qpBase);
+                m_pic->m_rowDiagQp[row] = qpBase;
+                m_pic->m_rowDiagQScale[row] =  x265_qp2qScale(qpBase);
+                if (reEncode < 0)
+                {
+                   m_bAllRowsStop = true;
+                   m_rows[row].m_completed = 0;
+                   m_rows[row].m_isReencode = true;
+                   m_vbvResetTriggerRow = row;
+                   for (int bottomRows = m_numRows - 1; bottomRows >= row ; bottomRows--)
+                   {
+                       if (bottomRows!=row)
+                       {
+                           //wait for each row to be idle 
+                            while(m_rows[bottomRows].m_active && m_rows[bottomRows].m_busy)
+                                GIVE_UP_TIME();
+                        }
+                        m_rows[bottomRows].m_isReencode = true;
+                        m_rows[bottomRows].m_completed = 0;
+                        m_pic->m_qpaAq[bottomRows] = 0;
+                        m_pic->m_rowEncodedBits[bottomRows] = 0;
+                        m_pic->m_qpaRc[bottomRows] = 0;
+                        m_pic->m_numEncodedCusPerRow[bottomRows] = 0;
+                    }
+				}
             }
         }
         // Completed CU processing
-        m_rows[row].m_completed++;
+        if (!m_rows[row].m_isReencode)
+            m_rows[row].m_completed++;
         if (m_rows[row].m_completed >= 2 && row < m_numRows - 1)
         {
             ScopedLock below(m_rows[row + 1].m_lock);
@@ -1171,6 +1225,7 @@
             if (m_cfg->param->rc.vbvBufferSize > 0 && m_cfg->param->rc.vbvMaxBitrate > 0)
             {
                 m_pic->m_cuCostsForVbv[cuAddr] += m_pic->m_lowres.lowresCostForRc[idx];
+                m_pic->m_intraCuCostsForVbv[cuAddr] += m_pic->m_lowres.intraCost[idx];
             }
             cnt++;
         }
diff -r 7f4b871d7a0c -r 6f43b3b97192 source/encoder/frameencoder.h
--- a/source/encoder/frameencoder.h	Tue Mar 11 01:16:28 2014 +0530
+++ b/source/encoder/frameencoder.h	Tue Mar 11 01:52:38 2014 +0530
@@ -114,6 +114,8 @@
 
     int          m_blockRefPOC;
 
+    int          m_vbvResetTriggerRow;
+
     Event        m_reconRowWait;
 
     TEncEntropy* getEntropyCoder(int row)      { return &this->m_rows[row].m_entropyCoder; }
diff -r 7f4b871d7a0c -r 6f43b3b97192 source/encoder/ratecontrol.cpp
--- a/source/encoder/ratecontrol.cpp	Tue Mar 11 01:16:28 2014 +0530
+++ b/source/encoder/ratecontrol.cpp	Tue Mar 11 01:52:38 2014 +0530
@@ -790,7 +790,7 @@
                     intraCost += pic->m_intraCuCostsForVbv[cuAddr];
                 }
 
-                refQScale = row == maxRows - 1 ? refPic->m_rowDiagQScale[row] : refPic->m_rowDiagQScale[row + 1];
+                refQScale = refPic->m_rowDiagQScale[row];
             }
 
             if (picType == I_SLICE || qScale >= refQScale)
@@ -827,8 +827,6 @@
 {
     double qScaleVbv = x265_qp2qScale(qpVbv);
 
-    pic->m_rowDiagQp[row] = qpVbv;
-    pic->m_rowDiagQScale[row] = qScaleVbv;
     double rowSatdCost = pic->m_rowDiagSatd[row];
     double encodedBits = pic->m_rowEncodedBits[row];
     if (row == 1)


More information about the x265-devel mailing list