[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