[x265] [PATCH] stats: add x265_frame_stats structure and copy frame level data to it

Divya Manivannan divya at multicorewareinc.com
Thu Jun 11 12:20:08 CEST 2015


# HG changeset patch
# User Divya Manivannan <divya at multicorewareinc.com>
# Date 1433942708 -19800
#      Wed Jun 10 18:55:08 2015 +0530
# Node ID 1a8237500ea1e19d4e3ca18bd97fa68e3c87162f
# Parent  10102a58efdb70ff5ffc78120a4087b48fd252ee
stats: add x265_frame_stats structure and copy frame level data to it

diff -r 10102a58efdb -r 1a8237500ea1 source/CMakeLists.txt
--- a/source/CMakeLists.txt	Wed Jun 10 18:44:52 2015 +0530
+++ b/source/CMakeLists.txt	Wed Jun 10 18:55:08 2015 +0530
@@ -30,7 +30,7 @@
 mark_as_advanced(FPROFILE_USE FPROFILE_GENERATE NATIVE_BUILD)
 
 # X265_BUILD must be incremented each time the public API is changed
-set(X265_BUILD 62)
+set(X265_BUILD 63)
 configure_file("${PROJECT_SOURCE_DIR}/x265.def.in"
                "${PROJECT_BINARY_DIR}/x265.def")
 configure_file("${PROJECT_SOURCE_DIR}/x265_config.h.in"
diff -r 10102a58efdb -r 1a8237500ea1 source/encoder/api.cpp
--- a/source/encoder/api.cpp	Wed Jun 10 18:44:52 2015 +0530
+++ b/source/encoder/api.cpp	Wed Jun 10 18:55:08 2015 +0530
@@ -190,13 +190,13 @@
     }
 }
 
-void x265_encoder_log(x265_encoder* enc, int, char **)
-{
-    if (enc)
-    {
-        Encoder *encoder = static_cast<Encoder*>(enc);
-        x265_log(encoder->m_param, X265_LOG_WARNING, "x265_encoder_log will not generate the log file. It is obsolete\n");
-    }
+void x265_encoder_log(x265_encoder* enc, int, char **)
+{
+    if (enc)
+    {
+        Encoder *encoder = static_cast<Encoder*>(enc);
+        x265_log(encoder->m_param, X265_LOG_WARNING, "x265_encoder_log will not generate the log file. It is obsolete\n");
+    }
 }
 
 void x265_encoder_close(x265_encoder *enc)
@@ -259,6 +259,7 @@
     sizeof(x265_analysis_data),
     sizeof(x265_zone),
     sizeof(x265_stats),
+    sizeof(x265_frame_stats),
 
     x265_max_bit_depth,
     x265_version_str,
diff -r 10102a58efdb -r 1a8237500ea1 source/encoder/encoder.cpp
--- a/source/encoder/encoder.cpp	Wed Jun 10 18:44:52 2015 +0530
+++ b/source/encoder/encoder.cpp	Wed Jun 10 18:55:08 2015 +0530
@@ -530,6 +530,7 @@
         if (outFrame)
         {
             Slice *slice = outFrame->m_encData->m_slice;
+            x265_frame_stats* frameData = NULL;
 
             /* Free up pic_in->analysisData since it has already been used */
             if (m_param->analysisMode == X265_ANALYSIS_LOAD)
@@ -542,6 +543,7 @@
                 pic_out->bitDepth = X265_DEPTH;
                 pic_out->userData = outFrame->m_userData;
                 pic_out->colorSpace = m_param->internalCsp;
+                frameData = &(pic_out->frameData);
 
                 pic_out->pts = outFrame->m_pts;
                 pic_out->dts = outFrame->m_dts;
@@ -608,7 +610,7 @@
             if (m_aborted)
                 return -1;
 
-            finishFrameStats(outFrame, curEncoder, curEncoder->m_accessUnitBits);
+            finishFrameStats(outFrame, curEncoder, curEncoder->m_accessUnitBits, frameData);
 
             /* Allow this frame to be recycled if no frame encoders are using it for reference */
             if (!pic_out)
@@ -995,9 +997,9 @@
             stats->elapsedVideoTime = 0;
         }
 
-        double fps = (double)m_param->fpsNum / m_param->fpsDenom;
-        double scale = fps / 1000;
-
+        double fps = (double)m_param->fpsNum / m_param->fpsDenom;
+        double scale = fps / 1000;
+
         stats->statsI.numPics = m_analyzeI.m_numPics;
         stats->statsI.avgQp   = m_analyzeI.m_totalQp / (double)m_analyzeI.m_numPics;
         stats->statsI.bitrate = m_analyzeI.m_accBits * scale / (double)m_analyzeI.m_numPics;
@@ -1054,7 +1056,7 @@
     return string;
 }
 
-void Encoder::finishFrameStats(Frame* curFrame, FrameEncoder *curEncoder, uint64_t bits)
+void Encoder::finishFrameStats(Frame* curFrame, FrameEncoder *curEncoder, uint64_t bits, x265_frame_stats* frameStats)
 {
     PicYuv* reconPic = curFrame->m_reconPic;
 
@@ -1125,6 +1127,55 @@
     if (!IS_REFERENCED(curFrame))
         c += 32; // lower case if unreferenced
 
+    if (frameStats)
+    {
+        frameStats->encoderOrder = m_outputCount++;
+        frameStats->sliceType = c;
+        frameStats->poc = poc;
+        frameStats->qp = curEncData.m_avgQpAq;
+        frameStats->bits = bits;
+        if (m_param->rc.rateControlMode == X265_RC_CRF)
+            frameStats->rateFactor = curEncData.m_rateFactor;
+        frameStats->psnrY = psnrY;
+        frameStats->psnrU = psnrU;
+        frameStats->psnrV = psnrV;
+        double psnr = (psnrY * 6 + psnrU + psnrV) / 8;
+        frameStats->psnr = psnr;
+        frameStats->ssim = ssim;
+        if (!slice->isIntra())
+        {
+            int p = 0;
+            for (int ref = 0; ref < slice->m_numRefIdx[0]; ref++)
+            {
+                int k = slice->m_refPOCList[0][ref] - slice->m_lastIDR;
+                p += sprintf(frameStats->list1Buf + p, "%d ", k);
+            }
+            if (!slice->isInterP())
+            {
+                int p1 = 0;
+                for (int ref = 0; ref < slice->m_numRefIdx[1]; ref++)
+                {
+                    int k = slice->m_refPOCList[1][ref] - slice->m_lastIDR;
+                    p1 += sprintf(frameStats->list2Buf + p1, "%d ", k);
+                }
+            }
+        }
+
+#define ELAPSED_MSEC(start, end) (((double)(end) - (start)) / 1000)
+
+        frameStats->decideWaitTime = ELAPSED_MSEC(0, curEncoder->m_slicetypeWaitTime);
+        frameStats->row0WaitTime = ELAPSED_MSEC(curEncoder->m_startCompressTime, curEncoder->m_row0WaitTime);
+        frameStats->wallTime = ELAPSED_MSEC(curEncoder->m_row0WaitTime, curEncoder->m_endCompressTime);
+        frameStats->refWaitWallTime = ELAPSED_MSEC(curEncoder->m_row0WaitTime, curEncoder->m_allRowsAvailableTime);
+        frameStats->totalCTUTime = ELAPSED_MSEC(0, curEncoder->m_totalWorkerElapsedTime);
+        frameStats->stallTime = ELAPSED_MSEC(0, curEncoder->m_totalNoWorkerTime);
+        if (curEncoder->m_totalActiveWorkerCount)
+            frameStats->avgWPP = (double)curEncoder->m_totalActiveWorkerCount / curEncoder->m_activeWorkerCountSamples;
+        else
+            frameStats->avgWPP = 1;
+        frameStats->countRowBlocks = curEncoder->m_countRowBlocks;
+    }
+
     // if debug log level is enabled, per frame console logging is performed
     if (m_param->logLevel >= X265_LOG_DEBUG)
     {
diff -r 10102a58efdb -r 1a8237500ea1 source/encoder/encoder.h
--- a/source/encoder/encoder.h	Wed Jun 10 18:44:52 2015 +0530
+++ b/source/encoder/encoder.h	Wed Jun 10 18:55:08 2015 +0530
@@ -164,7 +164,7 @@
 
     void writeAnalysisFile(x265_analysis_data* pic);
 
-    void finishFrameStats(Frame* pic, FrameEncoder *curEncoder, uint64_t bits);
+    void finishFrameStats(Frame* pic, FrameEncoder *curEncoder, uint64_t bits, x265_frame_stats* frameStats);
 
 protected:
 
diff -r 10102a58efdb -r 1a8237500ea1 source/x265.cpp
--- a/source/x265.cpp	Wed Jun 10 18:44:52 2015 +0530
+++ b/source/x265.cpp	Wed Jun 10 18:55:08 2015 +0530
@@ -676,7 +676,7 @@
     x265_picture *pic_in = &pic_orig;
     /* Allocate recon picture if analysisMode is enabled */
     std::priority_queue<int64_t>* pts_queue = cliopt.output->needPTS() ? new std::priority_queue<int64_t>() : NULL;
-    x265_picture *pic_recon = (cliopt.recon || !!param->analysisMode || pts_queue || reconPlay) ? &pic_out : NULL;
+    x265_picture *pic_recon = (cliopt.recon || !!param->analysisMode || pts_queue || reconPlay || cliopt.csvData > 0) ? &pic_out : NULL;
     uint32_t inFrameCount = 0;
     uint32_t outFrameCount = 0;
     x265_nal *p_nal;
diff -r 10102a58efdb -r 1a8237500ea1 source/x265.h
--- a/source/x265.h	Wed Jun 10 18:44:52 2015 +0530
+++ b/source/x265.h	Wed Jun 10 18:55:08 2015 +0530
@@ -100,6 +100,32 @@
     uint32_t         numPartitions;
 } x265_analysis_data;
 
+/* Frame level statistics*/
+typedef struct x265_frame_stats
+{
+    double           qp;
+    double           rateFactor;
+    double           psnrY;
+    double           psnrU;
+    double           psnrV;
+    double           psnr;
+    double           ssim;
+    double           decideWaitTime;
+    double           row0WaitTime;
+    double           wallTime;
+    double           refWaitWallTime;
+    double           totalCTUTime;
+    double           stallTime;
+    double           avgWPP;
+    uint64_t         bits;
+    int              encoderOrder;
+    int              poc;
+    int              countRowBlocks;
+    char             list1Buf[16];
+    char             list2Buf[16];
+    char             sliceType;
+} x265_frame_stats;
+
 /* Used to pass pictures into the encoder, and to get picture data back out of
  * the encoder.  The input and output semantics are different */
 typedef struct x265_picture
@@ -161,6 +187,9 @@
      * this data structure */
     x265_analysis_data analysisData;
 
+    /* Frame level statistics*/
+    x265_frame_stats frameData;
+
 } x265_picture;
 
 typedef enum
@@ -1270,8 +1299,8 @@
  *       returns encoder statistics */
 void x265_encoder_get_stats(x265_encoder *encoder, x265_stats *, uint32_t statsSizeBytes);
 
-/* x265_encoder_log:
- *       This function is obsolete. */
+/* x265_encoder_log:
+ *       This function is obsolete. */
 void x265_encoder_log(x265_encoder *encoder, int argc, char **argv);
 
 /* x265_encoder_close:
@@ -1299,6 +1328,7 @@
     int           sizeof_analysis_data; /* sizeof(x265_analysis_data) */
     int           sizeof_zone;          /* sizeof(x265_zone) */
     int           sizeof_stats;         /* sizeof(x265_stats) */
+    int           sizeof_frame_stats;   /* sizeof(x265_frame_stats) */
 
     int           bit_depth;
     const char*   version_str;


More information about the x265-devel mailing list