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

Steve Borho steve at borho.org
Wed May 27 18:22:19 CEST 2015


On 05/27, Divya Manivannan wrote:
> # 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]);

This doesn't look very parseable for a spreadsheet.

> +            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
> _______________________________________________
> x265-devel mailing list
> x265-devel at videolan.org
> https://mailman.videolan.org/listinfo/x265-devel

-- 
Steve Borho


More information about the x265-devel mailing list