[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