[x265] [PATCH 6 of 6] vbv: integrate row level vbv ratecontrol at each major row diagonal

aarthi at multicorewareinc.com aarthi at multicorewareinc.com
Thu Feb 20 14:25:48 CET 2014


# HG changeset patch
# User Aarthi Thirumalai
# Date 1392901254 -19800
#      Thu Feb 20 18:30:54 2014 +0530
# Node ID 650d5f835e417f45bd8a9f86465ca1909eaa9526
# Parent  49b90667f050a7dd9c28b5017f389f5c29a1c191
vbv: integrate row level vbv ratecontrol at each major row diagonal.

diff -r 49b90667f050 -r 650d5f835e41 source/encoder/frameencoder.cpp
--- a/source/encoder/frameencoder.cpp	Thu Feb 20 18:23:48 2014 +0530
+++ b/source/encoder/frameencoder.cpp	Thu Feb 20 18:30:54 2014 +0530
@@ -1057,6 +1057,7 @@
     CTURow& codeRow = m_rows[m_cfg->param.bEnableWavefront ? row : 0];
     const uint32_t numCols = m_pic->getPicSym()->getFrameWidthInCU();
     const uint32_t lineStartCUAddr = row * numCols;
+    double qpBase = m_pic->m_avgQpRc;
     for (uint32_t col = curRow.m_completed; col < numCols; col++)
     {
         const uint32_t cuAddr = lineStartCUAddr + col;
@@ -1067,24 +1068,42 @@
         codeRow.m_entropyCoder.resetEntropy();
 
         TEncSbac *bufSbac = (m_cfg->param.bEnableWavefront && col == 0 && row > 0) ? &m_rows[row - 1].m_bufferSbacCoder : NULL;
-        if (m_cfg->param.rc.aqMode)
+
+        if ((uint32_t)row >= col && (row !=0))
+            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))
         {
-            int qp = calcQpForCu(m_pic, cuAddr);
+            int qp = calcQpForCu(m_pic, cuAddr , qpBase);
             setLambda(qp, row);
-            if (qp > MAX_QP)
-                qp = MAX_QP;
-            cu->setQP(0, (char)qp);
+            qp = X265_MIN(qp, MAX_QP);
+            cu->setQP(0,char(qp));
+            cu->m_baseQp = qpBase;
         }
         codeRow.processCU(cu, m_pic->getSlice(), bufSbac, m_cfg->param.bEnableWavefront && col == 1);
 
-        // TODO: Keep atomic running totals for rate control?
-        // cu->m_totalBits;
-        // cu->m_totalCost;
-        // cu->m_totalDistortion;
+        if (m_cfg->param.rc.vbvBufferSize && m_cfg->param.rc.vbvMaxBitrate)
+        {
+            // Update encoded bits, satdCost, baseQP for each CU
+            m_pic->m_rowDiagSatd[row] += m_pic->m_cuCostsForVbv[cuAddr];
+            m_pic->m_rowEncodedBits[row] += cu->m_totalBits;
+            m_pic->m_numEncodedCusPerRow[row] = cuAddr;
+            m_pic->m_qpaAq[row] += cu->getQP(0);
+            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 = Clip3((double)MIN_QP, (double)MAX_MAX_QP, qpBase);
+            }
+        }
 
         // Completed CU processing
         m_rows[row].m_completed++;
-
         if (m_rows[row].m_completed >= 2 && row < m_numRows - 1)
         {
             ScopedLock below(m_rows[row + 1].m_lock);
@@ -1128,34 +1147,43 @@
     curRow.m_busy = false;
 }
 
-int FrameEncoder::calcQpForCu(TComPic *pic, uint32_t cuAddr)
+int FrameEncoder::calcQpForCu(TComPic *pic, uint32_t cuAddr, double baseQp)
 {
     x265_emms();
-    double qp = pic->getSlice()->m_avgQpRc;
-    if (m_cfg->param.rc.aqMode)
+    double qp = baseQp;
+
+    /* Derive qpOffet for each CU by averaging offsets for all 16x16 blocks in the cu. */
+    double qp_offset = 0;
+    int maxBlockCols = (pic->getPicYuvOrg()->getWidth() + (16 - 1)) / 16;
+    int maxBlockRows = (pic->getPicYuvOrg()->getHeight() + (16 - 1)) / 16;
+    int noOfBlocks = g_maxCUWidth / 16;
+    int block_y = (cuAddr / pic->getPicSym()->getFrameWidthInCU()) * noOfBlocks;
+    int block_x = (cuAddr * noOfBlocks) - block_y * pic->getPicSym()->getFrameWidthInCU();
+
+    double *qpoffs = (pic->getSlice()->isReferenced() && m_cfg->param.rc.cuTree) ? pic->m_lowres.qpOffset : pic->m_lowres.qpAqOffset;
+    int cnt = 0, idx =0;
+    for (int h = 0; h < noOfBlocks && block_y < maxBlockRows; h++, block_y++)
     {
-        /* Derive qpOffet for each CU by averaging offsets for all 16x16 blocks in the cu. */
-        double qp_offset = 0;
-        int maxBlockCols = (pic->getPicYuvOrg()->getWidth() + (16 - 1)) / 16;
-        int maxBlockRows = (pic->getPicYuvOrg()->getHeight() + (16 - 1)) / 16;
-        int noOfBlocks = g_maxCUWidth / 16;
-        int block_y = (cuAddr / pic->getPicSym()->getFrameWidthInCU()) * noOfBlocks;
-        int block_x = (cuAddr * noOfBlocks) - block_y * pic->getPicSym()->getFrameWidthInCU();
+        for (int w = 0; w < noOfBlocks && (block_x + w) < maxBlockCols; w++)
+        {
+            idx = block_x + w + (block_y * maxBlockCols);
+            if (m_cfg->param.rc.aqMode)
+                qp_offset += qpoffs[idx];
 
-        double *qpoffs = (pic->getSlice()->isReferenced() && m_cfg->param.rc.cuTree) ? pic->m_lowres.qpOffset : pic->m_lowres.qpAqOffset;
-        int cnt = 0;
-        for (int h = 0; h < noOfBlocks && block_y < maxBlockRows; h++, block_y++)
-        {
-            for (int w = 0; w < noOfBlocks && (block_x + w) < maxBlockCols; w++)
+            if (m_cfg->param.rc.vbvBufferSize > 0 && m_cfg->param.rc.vbvMaxBitrate > 0)
             {
-                qp_offset += qpoffs[block_x + w + (block_y * maxBlockCols)];
-                cnt++;
+                m_pic->m_cuCostsForVbv[cuAddr] += m_pic->m_lowres.lowresCostForRc[idx];
+                if (!m_cfg->param.rc.cuTree)
+                    m_pic->m_cuCostsForVbv[cuAddr] += m_pic->m_lowres.intraCost[idx];
             }
+            cnt++;
         }
+    }
 
-        qp_offset /= cnt;
-        qp += qp_offset;
-    }
+    qp_offset /= cnt;
+    qp += qp_offset;
+
+
     return Clip3(MIN_QP, MAX_MAX_QP, (int)(qp + 0.5));
 }
 
diff -r 49b90667f050 -r 650d5f835e41 source/encoder/frameencoder.h
--- a/source/encoder/frameencoder.h	Thu Feb 20 18:23:48 2014 +0530
+++ b/source/encoder/frameencoder.h	Thu Feb 20 18:30:54 2014 +0530
@@ -173,7 +173,7 @@
 protected:
 
     void determineSliceBounds();
-    int calcQpForCu(TComPic *pic, uint32_t cuAddr);
+    int calcQpForCu (TComPic *pic, uint32_t cuAddr, double baseQp);
     Encoder*                 m_top;
     TEncCfg*                 m_cfg;
 


More information about the x265-devel mailing list