[x265] [PATCH] encoder: log the average QP used per frame, per I slices, P, and B slices

Steve Borho steve at borho.org
Tue Feb 25 09:03:24 CET 2014


# HG changeset patch
# User Steve Borho <steve at borho.org>
# Date 1393315391 21600
#      Tue Feb 25 02:03:11 2014 -0600
# Node ID e0adb30ddf6481a3a0785e8dcd9c4a054a2a156e
# Parent  444d7eaf1ec19bcf650daaec0834c9393c6ff45e
encoder: log the average QP used per frame, per I slices, P, and B slices

diff -r 444d7eaf1ec1 -r e0adb30ddf64 source/encoder/encoder.cpp
--- a/source/encoder/encoder.cpp	Tue Feb 25 01:23:16 2014 -0600
+++ b/source/encoder/encoder.cpp	Tue Feb 25 02:03:11 2014 -0600
@@ -228,6 +228,40 @@
     }
 }
 
+#define VERBOSE_RATE 0
+#if VERBOSE_RATE
+static const char* nalUnitTypeToString(NalUnitType type)
+{
+    switch (type)
+    {
+    case NAL_UNIT_CODED_SLICE_TRAIL_R:    return "TRAIL_R";
+    case NAL_UNIT_CODED_SLICE_TRAIL_N:    return "TRAIL_N";
+    case NAL_UNIT_CODED_SLICE_TLA_R:      return "TLA_R";
+    case NAL_UNIT_CODED_SLICE_TSA_N:      return "TSA_N";
+    case NAL_UNIT_CODED_SLICE_STSA_R:     return "STSA_R";
+    case NAL_UNIT_CODED_SLICE_STSA_N:     return "STSA_N";
+    case NAL_UNIT_CODED_SLICE_BLA_W_LP:   return "BLA_W_LP";
+    case NAL_UNIT_CODED_SLICE_BLA_W_RADL: return "BLA_W_RADL";
+    case NAL_UNIT_CODED_SLICE_BLA_N_LP:   return "BLA_N_LP";
+    case NAL_UNIT_CODED_SLICE_IDR_W_RADL: return "IDR_W_RADL";
+    case NAL_UNIT_CODED_SLICE_IDR_N_LP:   return "IDR_N_LP";
+    case NAL_UNIT_CODED_SLICE_CRA:        return "CRA";
+    case NAL_UNIT_CODED_SLICE_RADL_R:     return "RADL_R";
+    case NAL_UNIT_CODED_SLICE_RASL_R:     return "RASL_R";
+    case NAL_UNIT_VPS:                    return "VPS";
+    case NAL_UNIT_SPS:                    return "SPS";
+    case NAL_UNIT_PPS:                    return "PPS";
+    case NAL_UNIT_ACCESS_UNIT_DELIMITER:  return "AUD";
+    case NAL_UNIT_EOS:                    return "EOS";
+    case NAL_UNIT_EOB:                    return "EOB";
+    case NAL_UNIT_FILLER_DATA:            return "FILLER";
+    case NAL_UNIT_PREFIX_SEI:             return "SEI";
+    case NAL_UNIT_SUFFIX_SEI:             return "SEI";
+    default:                              return "UNK";
+    }
+}
+#endif // if VERBOSE_RATE
+
 /**
  \param   flush               force encoder to encode a frame
  \param   pic_in              input original YUV picture or NULL
@@ -362,11 +396,28 @@
         if (out->getSlice()->m_numWPRefs > 0)
             m_numWPFrames++;
 
-        uint64_t bits = calculateHashAndPSNR(out, curEncoder, nalunits);
+        /* calculate the size of the access unit, excluding:
+         *  - any AnnexB contributions (start_code_prefix, zero_byte, etc.,)
+         *  - SEI NAL units
+         */
+        uint32_t numRBSPBytes = 0;
+        for (int count = 0; nalunits[count] != NULL; count++)
+        {
+            uint32_t numRBSPBytes_nal = nalunits[count]->m_packetSize;
+#if VERBOSE_RATE
+            printf("*** %6s numBytesInNALunit: %u\n", nalUnitTypeToString((*it)->m_nalUnitType), numRBSPBytes_nal);
+#endif
+            if (nalunits[count]->m_nalUnitType != NAL_UNIT_PREFIX_SEI && nalunits[count]->m_nalUnitType != NAL_UNIT_SUFFIX_SEI)
+            {
+                numRBSPBytes += numRBSPBytes_nal;
+            }
+        }
+        uint64_t bits = numRBSPBytes * 8;
+        m_rateControl->rateControlEnd(out, bits, &curEncoder->m_rce);
+        finishFrameStats(out, curEncoder, bits);
 
         // Allow this frame to be recycled if no frame encoders are using it for reference
         ATOMIC_DEC(&out->m_countRefEncoders);
-        m_rateControl->rateControlEnd(out, bits, &(curEncoder->m_rce));
         m_dpb->recycleUnreferenced(m_freeList);
         ret = 1;
     }
@@ -423,6 +474,12 @@
     m_globalSsim += ssim;
 }
 
+void EncStats::addQP(double aveQp)
+{
+    m_totalQp += aveQp;
+}
+
+
 char* Encoder::statsString(EncStats& stat, char* buffer)
 {
     double fps = (double)param.fpsNum / param.fpsDenom;
@@ -431,6 +488,7 @@
     int len = sprintf(buffer, "%-6d ", stat.m_numPics);
 
     len += sprintf(buffer + len, "kb/s: %-8.2lf", stat.m_accBits * scale);
+    len += sprintf(buffer + len, " Ave QP: %2.2lf", stat.m_totalQp / (double)stat.m_numPics);
     if (param.bEnablePsnr)
     {
         len += sprintf(buffer + len, " PSNR Mean: Y:%.3lf U:%.3lf V:%.3lf",
@@ -695,41 +753,6 @@
     }
 }
 
-#define VERBOSE_RATE 0
-#if VERBOSE_RATE
-static const char* nalUnitTypeToString(NalUnitType type)
-{
-    switch (type)
-    {
-    case NAL_UNIT_CODED_SLICE_TRAIL_R:    return "TRAIL_R";
-    case NAL_UNIT_CODED_SLICE_TRAIL_N:    return "TRAIL_N";
-    case NAL_UNIT_CODED_SLICE_TLA_R:      return "TLA_R";
-    case NAL_UNIT_CODED_SLICE_TSA_N:      return "TSA_N";
-    case NAL_UNIT_CODED_SLICE_STSA_R:     return "STSA_R";
-    case NAL_UNIT_CODED_SLICE_STSA_N:     return "STSA_N";
-    case NAL_UNIT_CODED_SLICE_BLA_W_LP:   return "BLA_W_LP";
-    case NAL_UNIT_CODED_SLICE_BLA_W_RADL: return "BLA_W_RADL";
-    case NAL_UNIT_CODED_SLICE_BLA_N_LP:   return "BLA_N_LP";
-    case NAL_UNIT_CODED_SLICE_IDR_W_RADL: return "IDR_W_RADL";
-    case NAL_UNIT_CODED_SLICE_IDR_N_LP:   return "IDR_N_LP";
-    case NAL_UNIT_CODED_SLICE_CRA:        return "CRA";
-    case NAL_UNIT_CODED_SLICE_RADL_R:     return "RADL_R";
-    case NAL_UNIT_CODED_SLICE_RASL_R:     return "RASL_R";
-    case NAL_UNIT_VPS:                    return "VPS";
-    case NAL_UNIT_SPS:                    return "SPS";
-    case NAL_UNIT_PPS:                    return "PPS";
-    case NAL_UNIT_ACCESS_UNIT_DELIMITER:  return "AUD";
-    case NAL_UNIT_EOS:                    return "EOS";
-    case NAL_UNIT_EOB:                    return "EOB";
-    case NAL_UNIT_FILLER_DATA:            return "FILLER";
-    case NAL_UNIT_PREFIX_SEI:             return "SEI";
-    case NAL_UNIT_SUFFIX_SEI:             return "SEI";
-    default:                              return "UNK";
-    }
-}
-
-#endif // if VERBOSE_RATE
-
 /**
  * Produce an ascii(hex) representation of picture digest.
  *
@@ -756,8 +779,7 @@
     return string;
 }
 
-/* Returns Number of bits in current encoded pic */
-uint64_t Encoder::calculateHashAndPSNR(TComPic* pic, FrameEncoder *curEncoder, NALUnitEBSP **nalunits)
+void Encoder::finishFrameStats(TComPic* pic, FrameEncoder *curEncoder, uint64_t bits)
 {
     TComPicYuv* recon = pic->getPicYuvRec();
 
@@ -779,29 +801,11 @@
     double psnrU = (ssdU ? 10.0 * log10(refValueC / (double)ssdU) : 99.99);
     double psnrV = (ssdV ? 10.0 * log10(refValueC / (double)ssdV) : 99.99);
 
-    /* calculate the size of the access unit, excluding:
-     *  - any AnnexB contributions (start_code_prefix, zero_byte, etc.,)
-     *  - SEI NAL units
-     */
-    uint32_t numRBSPBytes = 0;
-    for (int count = 0; nalunits[count] != NULL; count++)
-    {
-        uint32_t numRBSPBytes_nal = nalunits[count]->m_packetSize;
-#if VERBOSE_RATE
-        printf("*** %6s numBytesInNALunit: %u\n", nalUnitTypeToString((*it)->m_nalUnitType), numRBSPBytes_nal);
-#endif
-        if (nalunits[count]->m_nalUnitType != NAL_UNIT_PREFIX_SEI && nalunits[count]->m_nalUnitType != NAL_UNIT_SUFFIX_SEI)
-        {
-            numRBSPBytes += numRBSPBytes_nal;
-        }
-    }
-
-    uint32_t bits = numRBSPBytes * 8;
-
     TComSlice*  slice = pic->getSlice();
 
     //===== add bits, psnr and ssim =====
     m_analyzeAll.addBits(bits);
+    m_analyzeAll.addQP(pic->m_avgQpRc);
 
     if (param.bEnablePsnr)
     {
@@ -817,6 +821,7 @@
     if (slice->isIntra())
     {
         m_analyzeI.addBits(bits);
+        m_analyzeI.addQP(pic->m_avgQpRc);
         if (param.bEnablePsnr)
             m_analyzeI.addPsnr(psnrY, psnrU, psnrV);
         if (param.bEnableSsim)
@@ -825,6 +830,7 @@
     else if (slice->isInterP())
     {
         m_analyzeP.addBits(bits);
+        m_analyzeP.addQP(pic->m_avgQpRc);
         if (param.bEnablePsnr)
             m_analyzeP.addPsnr(psnrY, psnrU, psnrV);
         if (param.bEnableSsim)
@@ -833,6 +839,7 @@
     else if (slice->isInterB())
     {
         m_analyzeB.addBits(bits);
+        m_analyzeB.addQP(pic->m_avgQpRc);
         if (param.bEnablePsnr)
             m_analyzeB.addPsnr(psnrY, psnrU, psnrV);
         if (param.bEnableSsim)
@@ -844,13 +851,12 @@
     {
         char c = (slice->isIntra() ? 'I' : slice->isInterP() ? 'P' : 'B');
         int poc = slice->getPOC();
-        int QP = slice->getSliceQp();
         if (!slice->isReferenced())
             c += 32; // lower case if unreferenced
 
         char buf[1024];
         int p;
-        p = sprintf(buf, "POC:%d %c QP %2d %10d bits", poc, c, QP, bits);
+        p = sprintf(buf, "POC:%d %c QP %2.2lf %10d bits", poc, c, pic->m_avgQpRc, bits);
         if (param.bEnablePsnr)
             p += sprintf(buf + p, " [Y:%6.2lf U:%6.2lf V:%6.2lf]", psnrY, psnrU, psnrV);
         if (param.bEnableSsim)
@@ -875,7 +881,7 @@
         // per frame CSV logging if the file handle is valid
         if (m_csvfpt)
         {
-            fprintf(m_csvfpt, "%d, %c-SLICE, %4d, %d, %10d,", m_outputCount++, c, poc, QP, bits);
+            fprintf(m_csvfpt, "%d, %c-SLICE, %4d, %2.2lf, %10d,", m_outputCount++, c, poc, pic->m_avgQpRc, bits);
             double psnr = (psnrY * 6 + psnrU + psnrV) / 8;
             if (param.bEnablePsnr)
                 fprintf(m_csvfpt, "%.3lf, %.3lf, %.3lf, %.3lf,", psnrY, psnrU, psnrV, psnr);
@@ -929,8 +935,6 @@
         x265_log(&param, X265_LOG_DEBUG, "%s\n", buf);
         fflush(stderr);
     }
-
-    return bits;
 }
 
 #if defined(_MSC_VER)
diff -r 444d7eaf1ec1 -r e0adb30ddf64 source/encoder/encoder.h
--- a/source/encoder/encoder.h	Tue Feb 25 01:23:16 2014 -0600
+++ b/source/encoder/encoder.h	Tue Feb 25 02:03:11 2014 -0600
@@ -38,6 +38,7 @@
     double        m_psnrSumU;
     double        m_psnrSumV;
     double        m_globalSsim;
+    double        m_totalQp;
     uint64_t      m_accBits;
     uint32_t      m_numPics;
 
@@ -46,8 +47,11 @@
         m_psnrSumY = m_psnrSumU = m_psnrSumV = m_globalSsim = 0;
         m_accBits = 0;
         m_numPics = 0;
+        m_totalQp = 0;
     }
 
+    void addQP(double aveQp);
+
     void addPsnr(double psnrY, double psnrU, double psnrV);
 
     void addBits(uint64_t bits);
@@ -145,8 +149,7 @@
 
 protected:
 
-    // Returns total number of bits for encoded pic
-    uint64_t calculateHashAndPSNR(TComPic* pic, FrameEncoder *curEncoder, NALUnitEBSP **nalunits);
+    void finishFrameStats(TComPic* pic, FrameEncoder *curEncoder, uint64_t bits);
 };
 }
 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: x265.patch
Type: text/x-patch
Size: 10371 bytes
Desc: not available
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20140225/c0714473/attachment-0001.bin>


More information about the x265-devel mailing list