[x265] [PATCH] AQ/VBV: separate VBV cost accumulation from QP averaging for AQ

deepthi at multicorewareinc.com deepthi at multicorewareinc.com
Sun Apr 5 18:55:17 CEST 2015


# HG changeset patch
# User Deepthi Nandakumar <deepthi at multicorewareinc.com>
# Date 1428252902 -19800
#      Sun Apr 05 22:25:02 2015 +0530
# Node ID 9c48cb93a0b0dcc67697257fd227edda8e690c60
# Parent  d6e059bd8a9cd0cb9aad7444b1a141a59ac01193
AQ/VBV: separate VBV cost accumulation from QP averaging for AQ

diff -r d6e059bd8a9c -r 9c48cb93a0b0 source/encoder/analysis.cpp
--- a/source/encoder/analysis.cpp	Mon Mar 23 14:23:42 2015 +0530
+++ b/source/encoder/analysis.cpp	Sun Apr 05 22:25:02 2015 +0530
@@ -129,7 +129,7 @@
 {
     m_slice = ctu.m_slice;
     m_frame = &frame;
-
+    FrameData& curEncData = *m_frame->m_encData;
 #if _DEBUG || CHECKED_BUILD
     for (uint32_t i = 0; i <= g_maxCUDepth; i++)
         for (uint32_t j = 0; j < MAX_PRED_TYPES; j++)
@@ -159,6 +159,7 @@
         }
         this->setQP(*m_slice, m_qp[0][0]);
         m_qp[0][0] = x265_clip3(QP_MIN, QP_MAX_SPEC, m_qp[0][0]);
+        curEncData.m_rowStat[ctu.m_cuAddr % m_slice->m_sps->numCuInWidth].sumQpAq += m_qp[0][0];
         ctu.setQPSubParts((int8_t)m_qp[0][0], 0, 0);
     }
     else
diff -r d6e059bd8a9c -r 9c48cb93a0b0 source/encoder/frameencoder.cpp
--- a/source/encoder/frameencoder.cpp	Mon Mar 23 14:23:42 2015 +0530
+++ b/source/encoder/frameencoder.cpp	Sun Apr 05 22:25:02 2015 +0530
@@ -849,14 +849,9 @@
         else
             curEncData.m_cuStat[cuAddr].baseQp = curEncData.m_avgQpRc;
 
-        if (m_param->rc.aqMode || bIsVbv)
-        {
-            int qp = calcQpForCu(cuAddr, curEncData.m_cuStat[cuAddr].baseQp);
-            qp = x265_clip3(QP_MIN, QP_MAX_SPEC, qp);
-            curEncData.m_rowStat[row].sumQpAq += qp;
-        }
-        else
-            tld.analysis.setQP(*slice, slice->m_sliceQp);
+        if (bIsVbv)
+            accumVBVCosts(cuAddr);
+
 
         if (m_param->bEnableWavefront && !col && row)
         {
@@ -1196,53 +1191,31 @@
     }
 }
 
-int FrameEncoder::calcQpForCu(uint32_t ctuAddr, double baseQp)
+void FrameEncoder::accumVBVCosts(uint32_t ctuAddr)
 {
     x265_emms();
-    double qp = baseQp;
 
     FrameData& curEncData = *m_frame->m_encData;
-    /* clear cuCostsForVbv from when vbv row reset was triggered */
-    bool bIsVbv = m_param->rc.vbvBufferSize > 0 && m_param->rc.vbvMaxBitrate > 0;
-    if (bIsVbv)
-    {
-        curEncData.m_cuStat[ctuAddr].vbvCost = 0;
-        curEncData.m_cuStat[ctuAddr].intraVbvCost = 0;
-    }
 
-    /* Derive qpOffet for each CU by averaging offsets for all 16x16 blocks in the cu. */
-    double qp_offset = 0;
+    curEncData.m_cuStat[ctuAddr].vbvCost = 0;
+    curEncData.m_cuStat[ctuAddr].intraVbvCost = 0;
+
     uint32_t maxBlockCols = (m_frame->m_fencPic->m_picWidth + (16 - 1)) / 16;
     uint32_t maxBlockRows = (m_frame->m_fencPic->m_picHeight + (16 - 1)) / 16;
     uint32_t noOfBlocks = g_maxCUSize / 16;
     uint32_t block_y = (ctuAddr / curEncData.m_slice->m_sps->numCuInWidth) * noOfBlocks;
     uint32_t block_x = (ctuAddr * noOfBlocks) - block_y * curEncData.m_slice->m_sps->numCuInWidth;
 
-    /* Use cuTree offsets if cuTree enabled and frame is referenced, else use AQ offsets */
-    bool isReferenced = IS_REFERENCED(m_frame);
-    double *qpoffs = (isReferenced && m_param->rc.cuTree) ? m_frame->m_lowres.qpCuTreeOffset : m_frame->m_lowres.qpAqOffset;
-
-    uint32_t cnt = 0, idx = 0;
+    uint32_t idx = 0;
     for (uint32_t h = 0; h < noOfBlocks && block_y < maxBlockRows; h++, block_y++)
     {
         for (uint32_t w = 0; w < noOfBlocks && (block_x + w) < maxBlockCols; w++)
         {
             idx = block_x + w + (block_y * maxBlockCols);
-            if (m_param->rc.aqMode)
-                qp_offset += qpoffs[idx];
-            if (bIsVbv)
-            {
-                curEncData.m_cuStat[ctuAddr].vbvCost += m_frame->m_lowres.lowresCostForRc[idx] & LOWRES_COST_MASK;
-                curEncData.m_cuStat[ctuAddr].intraVbvCost += m_frame->m_lowres.intraCost[idx];
-            }
-            cnt++;
+            curEncData.m_cuStat[ctuAddr].vbvCost += m_frame->m_lowres.lowresCostForRc[idx] & LOWRES_COST_MASK;
+            curEncData.m_cuStat[ctuAddr].intraVbvCost += m_frame->m_lowres.intraCost[idx];
         }
     }
-
-    qp_offset /= cnt;
-    qp += qp_offset;
-
-    return x265_clip3(QP_MIN, QP_MAX_MAX, (int)(qp + 0.5));
 }
 
 Frame *FrameEncoder::getEncodedPicture(NALList& output)
diff -r d6e059bd8a9c -r 9c48cb93a0b0 source/encoder/frameencoder.h
--- a/source/encoder/frameencoder.h	Mon Mar 23 14:23:42 2015 +0530
+++ b/source/encoder/frameencoder.h	Sun Apr 05 22:25:02 2015 +0530
@@ -226,7 +226,7 @@
     void encodeSlice();
 
     void threadMain();
-    int  calcQpForCu(uint32_t cuAddr, double baseQp);
+    void  accumVBVCosts(uint32_t cuAddr);
     void collectCTUStatistics(CUData& ctu);
     void noiseReductionUpdate();
 


More information about the x265-devel mailing list