[x265] [PATCH 1 of 2] stats: introduce X265_LOG_FRAME for file level CSV logging without console logs

Steve Borho steve at borho.org
Wed Jan 28 22:29:19 CET 2015


# HG changeset patch
# User Steve Borho <steve at borho.org>
# Date 1422480325 21600
#      Wed Jan 28 15:25:25 2015 -0600
# Node ID dd004d21656cd75e4fe2fd8ae2eb25a4250b7485
# Parent  f45b12a0ded860550915bc0916a5ddcf8f399817
stats: introduce X265_LOG_FRAME for file level CSV logging without console logs

Using --log-level debug to trigger frame level CSV logging is problematic since
the console logging is often a big enough overhead that it influences the
performance characteristics. --log-level frame will log frame level stats to
the CSV without enabling frame-level console logging. Note that this does not
change the behavior of --log-level debug, but it does change the behavior of
--log-level 3.

diff -r f45b12a0ded8 -r dd004d21656c doc/reST/cli.rst
--- a/doc/reST/cli.rst	Wed Jan 28 14:27:22 2015 -0600
+++ b/doc/reST/cli.rst	Wed Jan 28 15:25:25 2015 -0600
@@ -28,7 +28,7 @@
 
 Generally, when an option expects a string value from a list of strings
 the user may specify the integer ordinal of the value they desire. ie:
-:option:`--log-level` 3 is equivalent to :option:`--log-level` debug.
+:option:`--log-level` 4 is equivalent to :option:`--log-level` debug.
 
 Executable Options
 ==================
@@ -51,7 +51,7 @@
 .. option:: --log-level <integer|string>
 
 	Logging level. Debug level enables per-frame QP, metric, and bitrate
-	logging. If a CSV file is being generated, debug level makes the log
+	logging. If a CSV file is being generated, frame level makes the log
 	be per-frame rather than per-encode. Full level enables hash and
 	weight logging. -1 disables all logging, except certain fatal
 	errors, and can be specified by the string "none".
@@ -59,8 +59,9 @@
 	0. error
 	1. warning
 	2. info **(default)**
-	3. debug
-	4. full
+	3. frame
+	4. debug
+	5. full
 
 .. option:: --no-progress
 
@@ -72,7 +73,7 @@
 
 	Writes encoding results to a comma separated value log file. Creates
 	the file if it doesnt already exist, else adds one line per run.  if
-	:option:`--log-level` is debug or above, it writes one line per
+	:option:`--log-level` is frame or above, it writes one line per
 	frame. Default none
 
 	When frame level logging is enabled, several frame performance
diff -r f45b12a0ded8 -r dd004d21656c source/common/param.h
--- a/source/common/param.h	Wed Jan 28 14:27:22 2015 -0600
+++ b/source/common/param.h	Wed Jan 28 15:25:25 2015 -0600
@@ -37,7 +37,7 @@
 bool  parseLambdaFile(x265_param *param);
 
 /* this table is kept internal to avoid confusion, since log level indices start at -1 */
-static const char * const logLevelNames[] = { "none", "error", "warning", "info", "debug", "full", 0 };
+static const char * const logLevelNames[] = { "none", "error", "warning", "info", "frame", "debug", "full", 0 };
 
 #define MAXPARAMSIZE 2000
 }
diff -r f45b12a0ded8 -r dd004d21656c source/encoder/encoder.cpp
--- a/source/encoder/encoder.cpp	Wed Jan 28 14:27:22 2015 -0600
+++ b/source/encoder/encoder.cpp	Wed Jan 28 15:25:25 2015 -0600
@@ -208,7 +208,7 @@
             m_csvfpt = fopen(m_param->csvfn, "wb");
             if (m_csvfpt)
             {
-                if (m_param->logLevel >= X265_LOG_DEBUG)
+                if (m_param->logLevel >= X265_LOG_FRAME)
                 {
                     fprintf(m_csvfpt, "Encode Order, Type, POC, QP, Bits, ");
                     if (m_param->rc.rateControlMode == X265_RC_CRF)
@@ -977,7 +977,7 @@
 {
     if (m_csvfpt)
     {
-        if (m_param->logLevel >= X265_LOG_DEBUG)
+        if (m_param->logLevel >= X265_LOG_FRAME)
         {
             // adding summary to a per-frame csv log file needs a summary header
             fprintf(m_csvfpt, "\nSummary\n");
@@ -1116,14 +1116,14 @@
             m_analyzeB.addSsim(ssim);
     }
 
-    // if debug log level is enabled, per frame logging is performed
+    char c = (slice->isIntra() ? 'I' : slice->isInterP() ? 'P' : 'B');
+    int poc = slice->m_poc;
+    if (!IS_REFERENCED(curFrame))
+        c += 32; // lower case if unreferenced
+
+    // if debug log level is enabled, per frame console logging is performed
     if (m_param->logLevel >= X265_LOG_DEBUG)
     {
-        char c = (slice->isIntra() ? 'I' : slice->isInterP() ? 'P' : 'B');
-        int poc = slice->m_poc;
-        if (!IS_REFERENCED(curFrame))
-            c += 32; // lower case if unreferenced
-
         char buf[1024];
         int p;
         p = sprintf(buf, "POC:%d %c QP %2.2lf(%d) %10d bits", poc, c, curEncData.m_avgQpAq, slice->m_sliceQp, (int)bits);
@@ -1150,58 +1150,6 @@
             }
         }
 
-        // per frame CSV logging if the file handle is valid
-        if (m_csvfpt)
-        {
-            fprintf(m_csvfpt, "%d, %c-SLICE, %4d, %2.2lf, %10d,", m_outputCount++, c, poc, curEncData.m_avgQpAq, (int)bits);
-            if (m_param->rc.rateControlMode == X265_RC_CRF)
-                fprintf(m_csvfpt, "%.3lf,", curEncData.m_rateFactor);
-            double psnr = (psnrY * 6 + psnrU + psnrV) / 8;
-            if (m_param->bEnablePsnr)
-                fprintf(m_csvfpt, "%.3lf, %.3lf, %.3lf, %.3lf,", psnrY, psnrU, psnrV, psnr);
-            else
-                fputs(" -, -, -, -,", m_csvfpt);
-            if (m_param->bEnableSsim)
-                fprintf(m_csvfpt, " %.6f, %6.3f", ssim, x265_ssim2dB(ssim));
-            else
-                fputs(" -, -", m_csvfpt);
-            if (slice->isIntra())
-                fputs(", -, -", m_csvfpt);
-            else
-            {
-                int numLists = slice->isInterP() ? 1 : 2;
-                for (int list = 0; list < numLists; list++)
-                {
-                    fprintf(m_csvfpt, ", ");
-                    for (int ref = 0; ref < slice->m_numRefIdx[list]; ref++)
-                    {
-                        int k = slice->m_refPOCList[list][ref] - slice->m_lastIDR;
-                        fprintf(m_csvfpt, " %d", k);
-                    }
-                }
-
-                if (numLists == 1)
-                    fputs(", -", m_csvfpt);
-            }
-
-#define ELAPSED_MSEC(start, end) (((double)(end) - (start)) / 1000)
-
-            // detailed frame statistics
-            fprintf(m_csvfpt, ", %.1lf, %.1lf, %.1lf, %.1lf, %.1lf, %.1lf",
-                ELAPSED_MSEC(0, curEncoder->m_slicetypeWaitTime),
-                ELAPSED_MSEC(curEncoder->m_startCompressTime, curEncoder->m_row0WaitTime),
-                ELAPSED_MSEC(curEncoder->m_row0WaitTime, curEncoder->m_endCompressTime),
-                ELAPSED_MSEC(curEncoder->m_row0WaitTime, curEncoder->m_allRowsAvailableTime),
-                ELAPSED_MSEC(0, curEncoder->m_totalWorkerElapsedTime),
-                ELAPSED_MSEC(0, curEncoder->m_totalNoWorkerTime));
-            if (curEncoder->m_totalActiveWorkerCount)
-                fprintf(m_csvfpt, ", %.3lf", (double)curEncoder->m_totalActiveWorkerCount / curEncoder->m_activeWorkerCountSamples);
-            else
-                fputs(", 1", m_csvfpt);
-            fprintf(m_csvfpt, ", %d", curEncoder->m_countRowBlocks);
-            fprintf(m_csvfpt, "\n");
-        }
-
         if (m_param->decodedPictureHashSEI && m_param->logLevel >= X265_LOG_FULL)
         {
             const char* digestStr = NULL;
@@ -1221,7 +1169,60 @@
                 p += sprintf(buf + p, " [Checksum:%s]", digestStr);
             }
         }
+
         x265_log(m_param, X265_LOG_DEBUG, "%s\n", buf);
+    }
+
+    if (m_param->logLevel >= X265_LOG_FRAME && m_csvfpt)
+    {
+        // per frame CSV logging if the file handle is valid
+        fprintf(m_csvfpt, "%d, %c-SLICE, %4d, %2.2lf, %10d,", m_outputCount++, c, poc, curEncData.m_avgQpAq, (int)bits);
+        if (m_param->rc.rateControlMode == X265_RC_CRF)
+            fprintf(m_csvfpt, "%.3lf,", curEncData.m_rateFactor);
+        double psnr = (psnrY * 6 + psnrU + psnrV) / 8;
+        if (m_param->bEnablePsnr)
+            fprintf(m_csvfpt, "%.3lf, %.3lf, %.3lf, %.3lf,", psnrY, psnrU, psnrV, psnr);
+        else
+            fputs(" -, -, -, -,", m_csvfpt);
+        if (m_param->bEnableSsim)
+            fprintf(m_csvfpt, " %.6f, %6.3f", ssim, x265_ssim2dB(ssim));
+        else
+            fputs(" -, -", m_csvfpt);
+        if (slice->isIntra())
+            fputs(", -, -", m_csvfpt);
+        else
+        {
+            int numLists = slice->isInterP() ? 1 : 2;
+            for (int list = 0; list < numLists; list++)
+            {
+                fprintf(m_csvfpt, ", ");
+                for (int ref = 0; ref < slice->m_numRefIdx[list]; ref++)
+                {
+                    int k = slice->m_refPOCList[list][ref] - slice->m_lastIDR;
+                    fprintf(m_csvfpt, " %d", k);
+                }
+            }
+
+            if (numLists == 1)
+                fputs(", -", m_csvfpt);
+        }
+
+#define ELAPSED_MSEC(start, end) (((double)(end) - (start)) / 1000)
+
+        // detailed frame statistics
+        fprintf(m_csvfpt, ", %.1lf, %.1lf, %.1lf, %.1lf, %.1lf, %.1lf",
+            ELAPSED_MSEC(0, curEncoder->m_slicetypeWaitTime),
+            ELAPSED_MSEC(curEncoder->m_startCompressTime, curEncoder->m_row0WaitTime),
+            ELAPSED_MSEC(curEncoder->m_row0WaitTime, curEncoder->m_endCompressTime),
+            ELAPSED_MSEC(curEncoder->m_row0WaitTime, curEncoder->m_allRowsAvailableTime),
+            ELAPSED_MSEC(0, curEncoder->m_totalWorkerElapsedTime),
+            ELAPSED_MSEC(0, curEncoder->m_totalNoWorkerTime));
+        if (curEncoder->m_totalActiveWorkerCount)
+            fprintf(m_csvfpt, ", %.3lf", (double)curEncoder->m_totalActiveWorkerCount / curEncoder->m_activeWorkerCountSamples);
+        else
+            fputs(", 1", m_csvfpt);
+        fprintf(m_csvfpt, ", %d", curEncoder->m_countRowBlocks);
+        fprintf(m_csvfpt, "\n");
         fflush(stderr);
     }
 }
diff -r f45b12a0ded8 -r dd004d21656c source/x265.h
--- a/source/x265.h	Wed Jan 28 14:27:22 2015 -0600
+++ b/source/x265.h	Wed Jan 28 15:25:25 2015 -0600
@@ -221,8 +221,9 @@
 #define X265_LOG_ERROR          0
 #define X265_LOG_WARNING        1
 #define X265_LOG_INFO           2
-#define X265_LOG_DEBUG          3
-#define X265_LOG_FULL           4
+#define X265_LOG_FRAME          3
+#define X265_LOG_DEBUG          4
+#define X265_LOG_FULL           5
 
 #define X265_B_ADAPT_NONE       0
 #define X265_B_ADAPT_FAST       1
@@ -404,11 +405,12 @@
     /* Enable the measurement and reporting of SSIM. Default is disabled */
     int       bEnableSsim;
 
-    /* filename of CSV log. If logLevel is X265_LOG_DEBUG, the encoder will emit
-     * per-slice statistics to this log file in encode order. Otherwise the
-     * encoder will emit per-stream statistics into the log file when
-     * x265_encoder_log is called (presumably at the end of the encode) */
-    char *csvfn;
+    /* filename of CSV log. If logLevel greater than or equal to X265_LOG_FRAME,
+     * the encoder will emit per-slice statistics to this log file in encode
+     * order. Otherwise the encoder will emit per-stream statistics into the log
+     * file when x265_encoder_log is called (presumably at the end of the
+     * encode) */
+    char*     csvfn;
 
     /* Enable the generation of SEI messages for each encoded frame containing
      * the hashes of the three reconstructed picture planes. Most decoders will


More information about the x265-devel mailing list