[x265] [PATCH] stats: report counts of each CU partition per frame in log-level 4

Divya Manivannan divya at multicorewareinc.com
Wed May 27 14:53:25 CEST 2015


# HG changeset patch
# User Divya Manivannan <divya at multicorewareinc.com>
# Date 1432729899 -19800
#      Wed May 27 18:01:39 2015 +0530
# Node ID 49f81cae5865c3ec6f7bdf212ca1657a596bb728
# Parent  c33107628ce48eb4df9039b3620e00ed4bfb36cc
stats: report counts of each CU partition per frame in log-level 4

diff -r c33107628ce4 -r 49f81cae5865 source/encoder/encoder.cpp
--- a/source/encoder/encoder.cpp	Wed May 27 15:37:17 2015 +0530
+++ b/source/encoder/encoder.cpp	Wed May 27 18:01:39 2015 +0530
@@ -249,6 +249,7 @@
                     fprintf(m_csvfpt, ", DecideWait (ms), Row0Wait (ms), Wall time (ms), Ref Wait Wall (ms), Total CTU time (ms), Stall Time (ms), Avg WPP, Row Blocks");
                     if (m_param->logLevel >= X265_LOG_DEBUG)
                     {
+                        fprintf(m_csvfpt, ", 64x64 CU (%%), 32x32 CU (%%), 16x16 CU (%%), 8x8 CU (%%), 4x4 CU (%%)");
                         if (m_param->decodedPictureHashSEI && m_param->logLevel >= X265_LOG_FULL)
                         {
                             if (m_param->decodedPictureHashSEI == 1)
@@ -1295,6 +1296,12 @@
 
         if (m_param->logLevel >= X265_LOG_DEBUG)
         {
+            fprintf(m_csvfpt, ", %5.2lf (Intra: %5.2lf  Inter: %5.2lf  Skip: %5.2lf)", curEncoder->m_frameStats.percentTotalCu[0], curEncoder->m_frameStats.percentIntraCu[0], curEncoder->m_frameStats.percentInterCu[0], curEncoder->m_frameStats.percentSkipCu[0]);
+            fprintf(m_csvfpt, ", %5.2lf (Intra: %5.2lf  Inter: %5.2lf  Skip: %5.2lf)", curEncoder->m_frameStats.percentTotalCu[1], curEncoder->m_frameStats.percentIntraCu[1], curEncoder->m_frameStats.percentInterCu[1], curEncoder->m_frameStats.percentSkipCu[1]);
+            fprintf(m_csvfpt, ", %5.2lf (Intra: %5.2lf  Inter: %5.2lf  Skip: %5.2lf)", curEncoder->m_frameStats.percentTotalCu[2], curEncoder->m_frameStats.percentIntraCu[2], curEncoder->m_frameStats.percentInterCu[2], curEncoder->m_frameStats.percentSkipCu[2]);
+            fprintf(m_csvfpt, ", %5.2lf (Intra: %5.2lf  Inter: %5.2lf  Skip: %5.2lf)", curEncoder->m_frameStats.percentTotalCu[3], curEncoder->m_frameStats.percentIntraCu[3], curEncoder->m_frameStats.percentInterCu[3], curEncoder->m_frameStats.percentSkipCu[3]);
+            fprintf(m_csvfpt, ", %5.2lf", curEncoder->m_frameStats.percentIntraNxN);
+
             if (m_param->decodedPictureHashSEI && m_param->logLevel >= X265_LOG_FULL)
             {
                 const char* digestStr = NULL;
diff -r c33107628ce4 -r 49f81cae5865 source/encoder/frameencoder.cpp
--- a/source/encoder/frameencoder.cpp	Wed May 27 15:37:17 2015 +0530
+++ b/source/encoder/frameencoder.cpp	Wed May 27 18:01:39 2015 +0530
@@ -552,7 +552,7 @@
         }
     }
 
-    if (m_param->rc.bStatWrite)
+    if (m_param->rc.bStatWrite || m_param->logLevel >= X265_LOG_DEBUG)
     {
         int totalI = 0, totalP = 0, totalSkip = 0;
 
@@ -562,14 +562,32 @@
             m_frameStats.mvBits    += m_rows[i].rowStats.mvBits;
             m_frameStats.coeffBits += m_rows[i].rowStats.coeffBits;
             m_frameStats.miscBits  += m_rows[i].rowStats.miscBits;
+            m_frameStats.cntIntraNxN += m_rows[i].rowStats.cntIntraNxN;
+            m_frameStats.totalCu += m_rows[i].rowStats.totalCu;
             totalI                 += m_rows[i].rowStats.iCuCnt;
             totalP                 += m_rows[i].rowStats.pCuCnt;
             totalSkip              += m_rows[i].rowStats.skipCuCnt;
+
+            for (uint32_t depth = 0; depth <= g_maxCUDepth; depth++)
+            {
+                m_frameStats.cntInter[depth] += m_rows[i].rowStats.cntInter[depth];
+                m_frameStats.cntIntra[depth] += m_rows[i].rowStats.cntIntra[depth];
+                m_frameStats.cntSkipCu[depth] += m_rows[i].rowStats.cntSkipCu[depth];
+                m_frameStats.cntTotalCu[depth] += m_rows[i].rowStats.cntTotalCu[depth];
+            }
         }
         int totalCuCount = totalI + totalP + totalSkip;
         m_frameStats.percentIntra = (double)totalI / totalCuCount;
         m_frameStats.percentInter = (double)totalP / totalCuCount;
         m_frameStats.percentSkip  = (double)totalSkip / totalCuCount;
+        m_frameStats.percentIntraNxN = (double)(m_frameStats.cntIntraNxN * 100) / m_frameStats.totalCu;
+        for (uint32_t depth = 0; depth <= g_maxCUDepth; depth++)
+        {
+            m_frameStats.percentIntraCu[depth] = (double)(m_frameStats.cntIntra[depth] * 100) / m_frameStats.totalCu;
+            m_frameStats.percentInterCu[depth] = (double)(m_frameStats.cntInter[depth] * 100) / m_frameStats.totalCu;
+            m_frameStats.percentSkipCu[depth] = (double)(m_frameStats.cntSkipCu[depth] * 100) / m_frameStats.totalCu;
+            m_frameStats.percentTotalCu[depth] = (double)(m_frameStats.cntTotalCu[depth] * 100) / m_frameStats.totalCu;
+        }
     }
 
     m_bs.resetBits();
@@ -826,12 +844,10 @@
     const uint32_t lineStartCUAddr = row * numCols;
     bool bIsVbv = m_param->rc.vbvBufferSize > 0 && m_param->rc.vbvMaxBitrate > 0;
 
-    /* These store the count of inter, intra and skip cus within quad tree structure of each CTU */
-    uint32_t qTreeInterCnt[NUM_CU_DEPTH];
+    /* This store the count of intra cus within quad tree structure of each CTU */
     uint32_t qTreeIntraCnt[NUM_CU_DEPTH];
-    uint32_t qTreeSkipCnt[NUM_CU_DEPTH];
     for (uint32_t depth = 0; depth <= g_maxCUDepth; depth++)
-        qTreeIntraCnt[depth] = qTreeInterCnt[depth] = qTreeSkipCnt[depth] = 0;
+        qTreeIntraCnt[depth] = 0;
 
     while (curRow.completed < numCols)
     {
@@ -904,28 +920,35 @@
         // Completed CU processing
         curRow.completed++;
 
-        if (m_param->rc.bStatWrite)
-            curEncData.m_rowStat[row].sumQpAq += collectCTUStatistics(*ctu, qTreeInterCnt, qTreeIntraCnt, qTreeSkipCnt);
+        StatisticLog cuLog;
+        if (m_param->rc.bStatWrite || m_param->logLevel >= X265_LOG_DEBUG)
+            curEncData.m_rowStat[row].sumQpAq += collectCTUStatistics(*ctu, qTreeIntraCnt, &cuLog);
         else if (m_param->rc.aqMode)
             curEncData.m_rowStat[row].sumQpAq += calcCTUQP(*ctu);
 
         // copy no. of intra, inter Cu cnt per row into frame stats for 2 pass
-        if (m_param->rc.bStatWrite)
+        if (m_param->rc.bStatWrite || m_param->logLevel >= X265_LOG_DEBUG)
         {
             curRow.rowStats.mvBits += best.mvBits;
             curRow.rowStats.coeffBits += best.coeffBits;
             curRow.rowStats.miscBits += best.totalBits - (best.mvBits + best.coeffBits);
+            curRow.rowStats.cntIntraNxN += cuLog.cntIntraNxN;
+            curRow.rowStats.totalCu += cuLog.totalCu;
 
             for (uint32_t depth = 0; depth <= g_maxCUDepth; depth++)
             {
                 /* 1 << shift == number of 8x8 blocks at current depth */
                 int shift = 2 * (g_maxCUDepth - depth);
                 curRow.rowStats.iCuCnt += qTreeIntraCnt[depth] << shift;
-                curRow.rowStats.pCuCnt += qTreeInterCnt[depth] << shift;
-                curRow.rowStats.skipCuCnt += qTreeSkipCnt[depth] << shift;
+                curRow.rowStats.pCuCnt += (int)(cuLog.cntInter[depth] << shift);
+                curRow.rowStats.skipCuCnt += (int)(cuLog.cntSkipCu[depth] << shift);
+                curRow.rowStats.cntInter[depth] += cuLog.cntInter[depth];
+                curRow.rowStats.cntIntra[depth] += cuLog.cntIntra[depth];
+                curRow.rowStats.cntSkipCu[depth] += cuLog.cntSkipCu[depth];
+                curRow.rowStats.cntTotalCu[depth] += cuLog.cntTotalCu[depth];
 
                 // clear the row cu data from thread local object
-                qTreeIntraCnt[depth] = qTreeInterCnt[depth] = qTreeSkipCnt[depth] = 0;
+                qTreeIntraCnt[depth] = 0;
             }
         }
 
@@ -1103,9 +1126,8 @@
 }
 
 /* collect statistics about CU coding decisions, return total QP */
-int FrameEncoder::collectCTUStatistics(const CUData& ctu, uint32_t* qtreeInterCnt, uint32_t* qtreeIntraCnt, uint32_t* qtreeSkipCnt)
+int FrameEncoder::collectCTUStatistics(const CUData& ctu, uint32_t* qtreeIntraCnt, StatisticLog* log)
 {
-    StatisticLog* log = &m_sliceTypeLog[ctu.m_slice->m_sliceType];
     int totQP = 0;
 
     if (ctu.m_slice->m_sliceType == I_SLICE)
@@ -1116,6 +1138,7 @@
             depth = ctu.m_cuDepth[absPartIdx];
 
             log->totalCu++;
+            log->cntTotalCu[depth]++;
             log->cntIntra[depth]++;
             qtreeIntraCnt[depth]++;
             totQP += ctu.m_qp[absPartIdx] * (ctu.m_numPartitions >> (depth * 2));
@@ -1123,6 +1146,7 @@
             if (ctu.m_predMode[absPartIdx] == MODE_NONE)
             {
                 log->totalCu--;
+                log->cntTotalCu[depth]--;
                 log->cntIntra[depth]--;
                 qtreeIntraCnt[depth]--;
             }
@@ -1132,6 +1156,7 @@
                 X265_CHECK(ctu.m_log2CUSize[absPartIdx] == 3 && ctu.m_slice->m_sps->quadtreeTULog2MinSize < 3, "Intra NxN found at improbable depth\n");
                 log->cntIntraNxN++;
                 log->cntIntra[depth]--;
+                log->cntTotalCu[depth]--;
             }
             else if (ctu.m_lumaIntraDir[absPartIdx] > 1)
                 log->cuIntraDistribution[depth][ANGULAR_MODE_ID]++;
@@ -1156,15 +1181,10 @@
                 log->cntTotalCu[depth]--;
             }
             else if (ctu.isSkipped(absPartIdx))
-            {
-                log->totalCu--;
                 log->cntSkipCu[depth]++;
-                qtreeSkipCnt[depth]++;
-            }
             else if (ctu.isInter(absPartIdx))
             {
                 log->cntInter[depth]++;
-                qtreeInterCnt[depth]++;
 
                 if (ctu.m_partSize[absPartIdx] < AMP_ID)
                     log->cuInterDistribution[depth][ctu.m_partSize[absPartIdx]]++;
@@ -1181,6 +1201,7 @@
                     X265_CHECK(ctu.m_log2CUSize[absPartIdx] == 3 && ctu.m_slice->m_sps->quadtreeTULog2MinSize < 3, "Intra NxN found at improbable depth\n");
                     log->cntIntraNxN++;
                     log->cntIntra[depth]--;
+                    log->cntTotalCu[depth]--;
                     /* TODO: log intra modes at absPartIdx +0 to +3 */
                 }
                 else if (ctu.m_lumaIntraDir[absPartIdx] > 1)
diff -r c33107628ce4 -r 49f81cae5865 source/encoder/frameencoder.h
--- a/source/encoder/frameencoder.h	Wed May 27 15:37:17 2015 +0530
+++ b/source/encoder/frameencoder.h	Wed May 27 18:01:39 2015 +0530
@@ -156,7 +156,6 @@
     MD5Context               m_state[3];
     uint32_t                 m_crc[3];
     uint32_t                 m_checksum[3];
-    StatisticLog             m_sliceTypeLog[3];     // per-slice type CU statistics
     FrameStats               m_frameStats;          // stats of current frame for multi-pass encodes
 
     volatile int             m_activeWorkerCount;        // count of workers currently encoding or filtering CTUs
@@ -221,7 +220,7 @@
     void encodeSlice();
 
     void threadMain();
-    int  collectCTUStatistics(const CUData& ctu, uint32_t* qtreeInterCnt, uint32_t* qtreeIntraCnt, uint32_t* qtreeSkipCnt);
+    int  collectCTUStatistics(const CUData& ctu, uint32_t* qtreeIntraCnt, StatisticLog* log);
     int  calcCTUQP(const CUData& ctu);
     void noiseReductionUpdate();
 
diff -r c33107628ce4 -r 49f81cae5865 source/encoder/ratecontrol.h
--- a/source/encoder/ratecontrol.h	Wed May 27 15:37:17 2015 +0530
+++ b/source/encoder/ratecontrol.h	Wed May 27 18:01:39 2015 +0530
@@ -61,6 +61,19 @@
     double      percentIntra;
     double      percentInter;
     double      percentSkip;
+
+    uint64_t    cntInter[4];
+    uint64_t    cntIntra[4];
+    uint64_t    cntIntraNxN;
+    uint64_t    cntSkipCu[4];
+    uint64_t    cntTotalCu[4];
+    uint64_t    totalCu;
+
+    double      percentIntraCu[4];
+    double      percentInterCu[4];
+    double      percentSkipCu[4];
+    double      percentIntraNxN;
+    double      percentTotalCu[4];
 };
 
 struct Predictor


More information about the x265-devel mailing list