[x265] [PATCH] CSV log: Enable frame-by-frame CSV logging

kavitha at multicorewareinc.com kavitha at multicorewareinc.com
Wed Oct 23 12:33:45 CEST 2013


# HG changeset patch
# User Kavitha Sampath <kavitha at multicorewareinc.com>
# Date 1382524397 -19800
#      Wed Oct 23 16:03:17 2013 +0530
# Node ID 50e50189a722499d439b5be7450a4c590c8ce5be
# Parent  6d96d64c4e9a2c526b57274760a7147241328cb3
CSV log: Enable frame-by-frame CSV logging

diff -r 6d96d64c4e9a -r 50e50189a722 source/Lib/TLibCommon/TComPic.cpp
--- a/source/Lib/TLibCommon/TComPic.cpp	Tue Oct 22 23:36:36 2013 +0530
+++ b/source/Lib/TLibCommon/TComPic.cpp	Wed Oct 23 16:03:17 2013 +0530
@@ -65,6 +65,8 @@
     m_SSDY = 0;
     m_SSDU = 0;
     m_SSDV = 0;
+    m_frameTime = 0.0;
+    m_elapsedCompressTime = 0.0;
 }
 
 TComPic::~TComPic()
diff -r 6d96d64c4e9a -r 50e50189a722 source/Lib/TLibCommon/TComPic.h
--- a/source/Lib/TLibCommon/TComPic.h	Tue Oct 22 23:36:36 2013 +0530
+++ b/source/Lib/TLibCommon/TComPic.h	Wed Oct 23 16:03:17 2013 +0530
@@ -89,6 +89,8 @@
     UInt64                m_SSDY;
     UInt64                m_SSDU;
     UInt64                m_SSDV;
+    double                m_elapsedCompressTime;
+    double                m_frameTime;
 
     TComPic();
     virtual ~TComPic();
diff -r 6d96d64c4e9a -r 50e50189a722 source/common/common.cpp
--- a/source/common/common.cpp	Tue Oct 22 23:36:36 2013 +0530
+++ b/source/common/common.cpp	Wed Oct 23 16:03:17 2013 +0530
@@ -32,6 +32,13 @@
 #include <string.h>
 #include <stdarg.h>
 
+#if _WIN32
+#include <sys/types.h>
+#include <sys/timeb.h>
+#else
+#include <sys/time.h>
+#endif
+
 using namespace x265;
 
 #define X265_ALIGNBYTES 32
@@ -43,6 +50,19 @@
 #include "malloc.h"
 #endif
 
+int64_t x265_mdate(void)
+{
+#if _WIN32
+    struct timeb tb;
+    ftime(&tb);
+    return ((int64_t)tb.time * 1000 + (int64_t)tb.millitm) * 1000;
+#else
+    struct timeval tv_date;
+    gettimeofday(&tv_date, NULL);
+    return (int64_t)tv_date.tv_sec * 1000000 + (int64_t)tv_date.tv_usec;
+#endif
+}
+
 void *x265_malloc(size_t size)
 {
     return _aligned_malloc(size, X265_ALIGNBYTES);
diff -r 6d96d64c4e9a -r 50e50189a722 source/common/common.h
--- a/source/common/common.h	Tue Oct 22 23:36:36 2013 +0530
+++ b/source/common/common.h	Wed Oct 23 16:03:17 2013 +0530
@@ -110,6 +110,7 @@
 #endif
 
 /* defined in common.cpp */
+int64_t x265_mdate(void);
 void x265_log(x265_param_t *param, int level, const char *fmt, ...);
 int  x265_check_params(x265_param_t *param);
 void x265_print_params(x265_param_t *param);
diff -r 6d96d64c4e9a -r 50e50189a722 source/encoder/encoder.cpp
--- a/source/encoder/encoder.cpp	Tue Oct 22 23:36:36 2013 +0530
+++ b/source/encoder/encoder.cpp	Wed Oct 23 16:03:17 2013 +0530
@@ -59,6 +59,8 @@
     m_globalSsim = 0;
     m_nals = NULL;
     m_packetData = NULL;
+    m_outputCount = 0;
+    m_csvfpt = NULL;
 
 #if ENC_DEC_TRACE
     g_hTrace = fopen("TraceEnc.txt", "wb");
@@ -94,6 +96,25 @@
     m_lookahead = new Lookahead(this, m_threadPool);
     m_dpb = new DPB(this);
     m_rateControl = new RateControl(this);
+    if (param.csvfn && param.logLevel >= X265_LOG_DEBUG)
+    {
+        m_csvfpt = fopen(param.csvfn, "r");
+        if (m_csvfpt)
+        {
+            // file already exists, re-open for append
+            fclose(m_csvfpt);
+            m_csvfpt = fopen(param.csvfn, "ab");
+        }
+        else
+        {
+            // new CSV file, write header
+            m_csvfpt = fopen(param.csvfn, "wb");
+            if (m_csvfpt)
+            {
+                fprintf(m_csvfpt, "Encode Order, Type, POC, nQP, QP, Bits, PSNR Y, PSNR U, PSNR V, PSNR, SSIM, Encoding time, Elapsed time, List 0, List 1\n");
+            }
+        }
+    }
 }
 
 void Encoder::destroy()
@@ -132,6 +153,8 @@
 
     X265_FREE(m_nals);
     X265_FREE(m_packetData);
+    if (m_csvfpt)
+        fclose(m_csvfpt);
 }
 
 void Encoder::init()
@@ -494,44 +517,62 @@
     {
         m_analyzeB.addResult(psnrY, psnrU, psnrV, (double)bits);
     }
+    double ssim = 0.0;
     if (param.bEnableSsim)
     {
         if (pic->getSlice()->m_ssimCnt > 0)
         {
-            double ssim = pic->getSlice()->m_ssim / pic->getSlice()->m_ssimCnt;
+            ssim = pic->getSlice()->m_ssim / pic->getSlice()->m_ssimCnt;
             m_globalSsim += ssim;
         }
     }
+
+    // if debug log level is enabled, per frame logging is performed
     if (param.logLevel >= X265_LOG_DEBUG)
     {
         char c = (slice->isIntra() ? 'I' : slice->isInterP() ? 'P' : 'B');
-
+        int poc = slice->getPOC();
+        int QP_Base = slice->getSliceQpBase();
+        int QP = slice->getSliceQp();
         if (!slice->isReferenced())
             c += 32; // lower case if unreferenced
-
-        fprintf(stderr, "\rPOC %4d ( %c-SLICE, nQP %d QP %d) %10d bits",
-                slice->getPOC(),
-                c,
-                slice->getSliceQpBase(),
-                slice->getSliceQp(),
-                bits);
-
-        fprintf(stderr, " [Y:%6.2lf U:%6.2lf V:%6.2lf]", psnrY, psnrU, psnrV);
-
+        fprintf(stderr, "\rPOC %4d ( %c-SLICE, nQP %d QP %d) %10d bits", poc, c, QP_Base, QP, bits);
+        fprintf(m_csvfpt, "\n%d, %c-SLICE, %4d, %d, %d, %10d,", m_outputCount++, c, poc, QP_Base, QP, bits);
+        if (param.bEnablePsnr)
+        {
+            fprintf(stderr, " [Y:%6.2lf U:%6.2lf V:%6.2lf]", psnrY, psnrU, psnrV);
+            double psnr = (psnrY * 6 + psnrU + psnrV) / 8;
+            fprintf(m_csvfpt, "%.3lf, %.3lf, %.3lf, %.3lf,", psnrY, psnrU, psnrV, psnr);
+        }
+        else
+            fprintf(m_csvfpt, " -, -, -, -,");
+        if (param.bEnableSsim)
+            fprintf(m_csvfpt, " %.3lf,", ssim);
+        else
+            fprintf(m_csvfpt, " -,");
+        fprintf(m_csvfpt, " %.3lf, %.3lf", pic->m_frameTime, pic->m_elapsedCompressTime);
         if (!slice->isIntra())
         {
             int numLists = slice->isInterP() ? 1 : 2;
             for (int list = 0; list < numLists; list++)
             {
                 fprintf(stderr, " [L%d ", list);
+                fprintf(m_csvfpt, ", ");
                 for (int ref = 0; ref < slice->getNumRefIdx(RefPicList(list)); ref++)
                 {
-                    fprintf(stderr, "%d ", slice->getRefPOC(RefPicList(list), ref) - slice->getLastIDR());
+                    int k = slice->getRefPOC(RefPicList(list), ref) - slice->getLastIDR();
+                    fprintf(stderr, "%d ",k);
+                    fprintf(m_csvfpt, " %d", k);
                 }
 
                 fprintf(stderr, "]");
             }
+            if (numLists == 1)
+                fprintf(m_csvfpt, ", -");
         }
+        else
+            fprintf(m_csvfpt, ", -, -");
+
         if (digestStr && param.logLevel >= 4)
         {
             if (param.decodedPictureHashSEI == 1)
diff -r 6d96d64c4e9a -r 50e50189a722 source/encoder/encoder.h
--- a/source/encoder/encoder.h	Tue Oct 22 23:36:36 2013 +0530
+++ b/source/encoder/encoder.h	Wed Oct 23 16:03:17 2013 +0530
@@ -48,6 +48,7 @@
 private:
 
     int                m_pocLast;          ///< time index (POC)
+    int                m_outputCount;
     PicList            m_freeList;
 
     ThreadPool*        m_threadPool;
@@ -65,7 +66,7 @@
     TEncAnalyze        m_analyzeP;
     TEncAnalyze        m_analyzeB;
     double             m_globalSsim;
-
+    FILE*              m_csvfpt;
     // quality control
     TComScalingList    m_scalingList;      ///< quantization matrix information
 
diff -r 6d96d64c4e9a -r 50e50189a722 source/encoder/frameencoder.cpp
--- a/source/encoder/frameencoder.cpp	Tue Oct 22 23:36:36 2013 +0530
+++ b/source/encoder/frameencoder.cpp	Wed Oct 23 16:03:17 2013 +0530
@@ -30,6 +30,7 @@
 #include "encoder.h"
 #include "frameencoder.h"
 #include "cturow.h"
+#include "common.h"
 
 #include <math.h>
 
@@ -62,6 +63,7 @@
     }
 
     m_nalCount = 0;
+    m_totalTime = 0;
 }
 
 void FrameEncoder::setThreadPool(ThreadPool *p)
@@ -304,6 +306,7 @@
 void FrameEncoder::compressFrame()
 {
     PPAScopeEvent(FrameEncoder_compressFrame);
+    int64_t startCompressTime = x265_mdate();
     TEncEntropy* entropyCoder = getEntropyCoder(0);
     TComSlice*   slice        = m_pic->getSlice();
     m_nalCount = 0;
@@ -682,7 +685,7 @@
             ATOMIC_DEC(&refpic->m_countRefEncoders);
         }
     }
-
+    m_pic->m_elapsedCompressTime = (double)(x265_mdate() - startCompressTime) / 1000000;
     delete[] outStreams;
     delete bitstreamRedirect;
 }
@@ -974,12 +977,15 @@
             }
         }
     }
+    m_pic->m_frameTime = (double)m_totalTime / 1000000;
+    m_totalTime = 0;
 }
 
 void FrameEncoder::processRowEncoder(int row)
 {
     PPAScopeEvent(Thread_ProcessRow);
 
+    int64_t startTime = x265_mdate();
     // Called by worker threads
     CTURow& curRow  = m_rows[row];
     CTURow& codeRow = m_rows[m_cfg->param.bEnableWavefront ? row : 0];
@@ -1021,6 +1027,7 @@
         if (row > 0 && m_rows[row].m_completed < numCols - 1 && m_rows[row - 1].m_completed < m_rows[row].m_completed + 2)
         {
             curRow.m_active = false;
+            m_totalTime = m_totalTime + (x265_mdate() - startTime);
             return;
         }
     }
@@ -1043,6 +1050,7 @@
             enableRowFilter(i);
         }
     }
+    m_totalTime = m_totalTime + (x265_mdate() - startTime);
 }
 
 TComPic *FrameEncoder::getEncodedPicture(NALUnitEBSP **nalunits)
diff -r 6d96d64c4e9a -r 50e50189a722 source/encoder/frameencoder.h
--- a/source/encoder/frameencoder.h	Tue Oct 22 23:36:36 2013 +0530
+++ b/source/encoder/frameencoder.h	Wed Oct 23 16:03:17 2013 +0530
@@ -183,6 +183,7 @@
     int                      m_filterRowDelay;
     CTURow*                  m_rows;
     Event                    m_completionEvent;
+    int64_t                  m_totalTime;
 };
 }
 
diff -r 6d96d64c4e9a -r 50e50189a722 source/x265.cpp
--- a/source/x265.cpp	Tue Oct 22 23:36:36 2013 +0530
+++ b/source/x265.cpp	Wed Oct 23 16:03:17 2013 +0530
@@ -36,12 +36,6 @@
 #endif
 #include "PPA/ppa.h"
 
-#if _WIN32
-#include <sys/types.h>
-#include <sys/timeb.h>
-#else
-#include <sys/time.h>
-#endif
 #include <time.h>
 
 #include <signal.h>
@@ -63,19 +57,6 @@
 #define SetConsoleTitle(t)
 #endif
 
-static int64_t x265_mdate(void)
-{
-#if _WIN32
-    struct timeb tb;
-    ftime(&tb);
-    return ((int64_t)tb.time * 1000 + (int64_t)tb.millitm) * 1000;
-#else
-    struct timeval tv_date;
-    gettimeofday(&tv_date, NULL);
-    return (int64_t)tv_date.tv_sec * 1000000 + (int64_t)tv_date.tv_usec;
-#endif
-}
-
 using namespace x265;
 
 static const char short_options[] = "o:f:F:r:i:b:s:q:m:hwV";
@@ -427,7 +408,6 @@
     const char *inputfn = NULL;
     const char *reconfn = NULL;
     const char *bitstreamfn = NULL;
-    const char *csvfn = NULL;
     const char *inputRes = NULL;
 
     x265_param_default(param);
@@ -484,7 +464,7 @@
             OPT("frames") this->framesToBeEncoded = (uint32_t)atoi(optarg);
             OPT("no-progress") this->bProgress = false;
             OPT("frame-skip") this->frameSkip = (uint32_t)atoi(optarg);
-            OPT("csv") csvfn = optarg;
+            OPT("csv") param->csvfn = optarg;
             OPT("output") bitstreamfn = optarg;
             OPT("input") inputfn = optarg;
             OPT("recon") reconfn = optarg;
@@ -600,22 +580,22 @@
         return true;
     }
 
-    if (csvfn)
+    if (param->csvfn && param->logLevel < X265_LOG_DEBUG)
     {
-        csvfp = fopen(csvfn, "r");
+        csvfp = fopen(param->csvfn, "r");
         if (csvfp)
         {
             // file already exists, re-open for append
             fclose(csvfp);
-            csvfp = fopen(csvfn, "ab");
+            csvfp = fopen(param->csvfn, "ab");
         }
         else
         {
             // new CSV file, write header
-            csvfp = fopen(csvfn, "wb");
+            csvfp = fopen(param->csvfn, "wb");
             if (csvfp)
             {
-                fprintf(csvfp, "CLI arguments, date/time, elapsed time, fps, bitrate, global PSNR, version\n");
+                fprintf(csvfp, "CLI arguments, date/time, elapsed time, fps, bitrate, global PSNR Y, global PSNR U, global PSNR V, global PSNR, global SSIM, version\n");
             }
         }
     }
@@ -744,9 +724,10 @@
 
     x265_cleanup(); /* Free library singletons */
 
-    if (cliopt.csvfp)
+    if (param.logLevel < X265_LOG_DEBUG && cliopt.csvfp)
     {
         // CLI arguments, date/time, elapsed time, fps, bitrate, global PSNR
+        fprintf(cliopt.csvfp,"\n");
         for (int i = 1; i < argc; i++)
         {
             if (i) fputc(' ', cliopt.csvfp);
@@ -759,8 +740,18 @@
         timeinfo = localtime(&now);
         char buffer[128];
         strftime(buffer, 128, "%c", timeinfo);
-        fprintf(cliopt.csvfp, ", %s, %.2f, %.2f, %.2f, %.2f, %s\n",
-                buffer, elapsed, outFrameCount / elapsed, bitrate, stats.globalPsnr, x265_version_str);
+        fprintf(cliopt.csvfp, ", %s, %.2f, %.2f, %.2f,", buffer, elapsed, outFrameCount / elapsed, bitrate);
+        if (param.bEnablePsnr)
+            fprintf(cliopt.csvfp, " %.3lf, %.3lf, %.3lf, %.3lf,",
+                    stats.globalPsnrY/stats.totalNumPics, stats.globalPsnrU/stats.totalNumPics,
+                    stats.globalPsnrV/stats.totalNumPics, stats.globalPsnr);
+        else
+            fprintf(cliopt.csvfp, " -, -, -, -,");
+        if (param.bEnableSsim)
+            fprintf(cliopt.csvfp, " %.2f,", stats.globalSsim);
+        else
+            fprintf(cliopt.csvfp, " -,");
+        fprintf(cliopt.csvfp, " %s\n", x265_version_str);
     }
 
     cliopt.destroy();
diff -r 6d96d64c4e9a -r 50e50189a722 source/x265.h
--- a/source/x265.h	Tue Oct 22 23:36:36 2013 +0530
+++ b/source/x265.h	Wed Oct 23 16:03:17 2013 +0530
@@ -254,6 +254,8 @@
 
     int       internalBitDepth;                ///< bit-depth the codec operates at
 
+    const char *csvfn;                        ///< csv log filename
+
     // source specification
     int       frameRate;                       ///< source frame-rate in Hz
     int       sourceWidth;                     ///< source width in pixels


More information about the x265-devel mailing list