[x265] [PATCH] Add csv feature into libx265
Divya Manivannan
divya at multicorewareinc.com
Mon Jun 12 11:47:11 CEST 2017
# HG changeset patch
# User Divya Manivannan <divya at multicorewareinc.com>
# Date 1497012715 -19800
# Fri Jun 09 18:21:55 2017 +0530
# Node ID 12097d65c3cc2d0624ca7a2a70cee2d53241c71d
# Parent b19bc0c7b4eccfe336ecd381df25203ee6f57d05
Add csv feature into libx265
diff -r b19bc0c7b4ec -r 12097d65c3cc doc/reST/api.rst
--- a/doc/reST/api.rst Tue Jun 06 11:13:19 2017 +0530
+++ b/doc/reST/api.rst Fri Jun 09 18:21:55 2017 +0530
@@ -347,6 +347,14 @@
Cleanup
=======
+At the end of the encode, the application will want to trigger logging
+of the final encode statistics, if :option:`--csv` had been specified::
+
+ /* x265_encoder_log:
+ * write a line to the configured CSV file. If a CSV filename was not
+ * configured, or file open failed, this function will perform no write. */
+ void x265_encoder_log(x265_encoder *encoder, int argc, char **argv);
+
Finally, the encoder must be closed in order to free all of its
resources. An encoder that has been flushed cannot be restarted and
reused. Once **x265_encoder_close()** has been called, the encoder
diff -r b19bc0c7b4ec -r 12097d65c3cc doc/reST/cli.rst
--- a/doc/reST/cli.rst Tue Jun 06 11:13:19 2017 +0530
+++ b/doc/reST/cli.rst Fri Jun 09 18:21:55 2017 +0530
@@ -52,8 +52,7 @@
2. unable to open encoder
3. unable to generate stream headers
4. encoder abort
- 5. unable to open csv file
-
+
Logging/Statistic Options
=========================
@@ -182,8 +181,6 @@
is more of a problem for P frames where some blocks are much more
expensive than others.
- **CLI ONLY**
-
.. option:: --csv-log-level <integer>
Controls the level of detail (and size) of --csv log files
@@ -192,8 +189,6 @@
1. frame level logging
2. frame level logging with performance statistics
- **CLI ONLY**
-
.. option:: --ssim, --no-ssim
Calculate and report Structural Similarity values. It is
diff -r b19bc0c7b4ec -r 12097d65c3cc source/CMakeLists.txt
--- a/source/CMakeLists.txt Tue Jun 06 11:13:19 2017 +0530
+++ b/source/CMakeLists.txt Fri Jun 09 18:21:55 2017 +0530
@@ -29,7 +29,7 @@
option(STATIC_LINK_CRT "Statically link C runtime for release builds" OFF)
mark_as_advanced(FPROFILE_USE FPROFILE_GENERATE NATIVE_BUILD)
# X265_BUILD must be incremented each time the public API is changed
-set(X265_BUILD 121)
+set(X265_BUILD 122)
configure_file("${PROJECT_SOURCE_DIR}/x265.def.in"
"${PROJECT_BINARY_DIR}/x265.def")
configure_file("${PROJECT_SOURCE_DIR}/x265_config.h.in"
@@ -650,16 +650,16 @@
# Xcode seems unable to link the CLI with libs, so link as one targget
if(ENABLE_DYNAMIC_HDR10)
add_executable(cli ../COPYING ${InputFiles} ${OutputFiles} ${GETOPT}
- x265.cpp x265.h x265cli.h x265-extras.h x265-extras.cpp
+ x265.cpp x265.h x265cli.h
$<TARGET_OBJECTS:encoder> $<TARGET_OBJECTS:common> $<TARGET_OBJECTS:dynamicHDR10> ${ASM_OBJS} ${ASM_SRCS})
else()
add_executable(cli ../COPYING ${InputFiles} ${OutputFiles} ${GETOPT}
- x265.cpp x265.h x265cli.h x265-extras.h x265-extras.cpp
+ x265.cpp x265.h x265cli.h
$<TARGET_OBJECTS:encoder> $<TARGET_OBJECTS:common> ${ASM_OBJS} ${ASM_SRCS})
endif()
else()
add_executable(cli ../COPYING ${InputFiles} ${OutputFiles} ${GETOPT} ${X265_RC_FILE}
- ${ExportDefs} x265.cpp x265.h x265cli.h x265-extras.h x265-extras.cpp)
+ ${ExportDefs} x265.cpp x265.h x265cli.h)
if(WIN32 OR NOT ENABLE_SHARED OR INTEL_CXX)
# The CLI cannot link to the shared library on Windows, it
# requires internal APIs not exported from the DLL
diff -r b19bc0c7b4ec -r 12097d65c3cc source/common/param.cpp
--- a/source/common/param.cpp Tue Jun 06 11:13:19 2017 +0530
+++ b/source/common/param.cpp Fri Jun 09 18:21:55 2017 +0530
@@ -110,6 +110,7 @@
param->frameNumThreads = 0;
param->logLevel = X265_LOG_INFO;
+ param->csvLogLevel = 0;
param->csvfn = NULL;
param->rc.lambdaFileName = NULL;
param->bLogCuStats = 0;
@@ -927,6 +928,8 @@
if (bExtraParams)
{
if (0) ;
+ OPT("csv") p->csvfn = strdup(value);
+ OPT("csv-log-level") p->csvLogLevel = atoi(value);
OPT("qpmin") p->rc.qpMin = atoi(value);
OPT("analyze-src-pics") p->bSourceReferenceEstimation = atobool(value);
OPT("log2-max-poc-lsb") p->log2MaxPocLsb = atoi(value);
@@ -1516,6 +1519,8 @@
BOOL(p->bEnablePsnr, "psnr");
BOOL(p->bEnableSsim, "ssim");
s += sprintf(s, " log-level=%d", p->logLevel);
+ if (p->csvfn)
+ s += sprintf(s, " csvfn=%s csv-log-level=%d", p->csvfn, p->csvLogLevel);
s += sprintf(s, " bitdepth=%d", p->internalBitDepth);
s += sprintf(s, " input-csp=%d", p->internalCsp);
s += sprintf(s, " fps=%u/%u", p->fpsNum, p->fpsDenom);
diff -r b19bc0c7b4ec -r 12097d65c3cc source/encoder/CMakeLists.txt
--- a/source/encoder/CMakeLists.txt Tue Jun 06 11:13:19 2017 +0530
+++ b/source/encoder/CMakeLists.txt Fri Jun 09 18:21:55 2017 +0530
@@ -43,4 +43,5 @@
reference.cpp reference.h
encoder.cpp encoder.h
api.cpp
- weightPrediction.cpp)
+ weightPrediction.cpp
+ ../x265-extras.cpp ../x265-extras.h)
diff -r b19bc0c7b4ec -r 12097d65c3cc source/encoder/api.cpp
--- a/source/encoder/api.cpp Tue Jun 06 11:13:19 2017 +0530
+++ b/source/encoder/api.cpp Fri Jun 09 18:21:55 2017 +0530
@@ -30,6 +30,7 @@
#include "level.h"
#include "nal.h"
#include "bitcost.h"
+#include "x265-extras.h"
/* multilib namespace reflectors */
#if LINKED_8BIT
@@ -119,6 +120,17 @@
}
encoder->create();
+ /* Try to open CSV file handle */
+ if (encoder->m_param->csvfn)
+ {
+ encoder->m_csvfpt = x265_csvlog_open(*encoder->m_param, encoder->m_param->csvfn, encoder->m_param->csvLogLevel);
+ if (!encoder->m_csvfpt)
+ {
+ x265_log(encoder->m_param, X265_LOG_ERROR, "Unable to open CSV log file <%s>, aborting\n", encoder->m_param->csvfn);
+ encoder->m_aborted = true;
+ }
+ }
+
encoder->m_latestParam = latestParam;
memcpy(latestParam, param, sizeof(x265_param));
if (encoder->m_aborted)
@@ -144,7 +156,10 @@
if (encoder->m_param->rc.bStatRead && encoder->m_param->bMultiPassOptRPS)
{
if (!encoder->computeSPSRPSIndex())
+ {
+ encoder->m_aborted = true;
return -1;
+ }
}
encoder->getStreamHeaders(encoder->m_nalList, sbacCoder, bs);
*pp_nal = &encoder->m_nalList.m_nal[0];
@@ -152,6 +167,11 @@
return encoder->m_nalList.m_occupancy;
}
+ if (enc)
+ {
+ Encoder *encoder = static_cast<Encoder*>(enc);
+ encoder->m_aborted = true;
+ }
return -1;
}
@@ -251,6 +271,12 @@
else if (pi_nal)
*pi_nal = 0;
+ if (numEncoded && encoder->m_param->csvLogLevel)
+ x265_csvlog_frame(encoder->m_csvfpt, *encoder->m_param, *pic_out, encoder->m_param->csvLogLevel);
+
+ if (numEncoded < 0)
+ encoder->m_aborted = true;
+
return numEncoded;
}
@@ -263,12 +289,16 @@
}
}
-void x265_encoder_log(x265_encoder* enc, int, char **)
+void x265_encoder_log(x265_encoder* enc, int argc, char **argv)
{
if (enc)
{
Encoder *encoder = static_cast<Encoder*>(enc);
- x265_log(encoder->m_param, X265_LOG_WARNING, "x265_encoder_log is now deprecated\n");
+ x265_stats stats;
+ int padx = encoder->m_sps.conformanceWindow.rightOffset;
+ int pady = encoder->m_sps.conformanceWindow.bottomOffset;
+ encoder->fetchStats(&stats, sizeof(stats));
+ x265_csvlog_encode(encoder->m_csvfpt, x265_version_str, *encoder->m_param, padx, pady, stats, encoder->m_param->csvLogLevel, argc, argv);
}
}
diff -r b19bc0c7b4ec -r 12097d65c3cc source/encoder/encoder.cpp
--- a/source/encoder/encoder.cpp Tue Jun 06 11:13:19 2017 +0530
+++ b/source/encoder/encoder.cpp Fri Jun 09 18:21:55 2017 +0530
@@ -70,6 +70,7 @@
m_exportedPic = NULL;
m_numDelayedPic = 0;
m_outputCount = 0;
+ m_csvfpt = NULL;
m_param = NULL;
m_latestParam = NULL;
m_threadPool = NULL;
@@ -468,6 +469,9 @@
if (m_analysisFile)
fclose(m_analysisFile);
+ if (m_csvfpt)
+ fclose(m_csvfpt);
+
if (m_latestParam != NULL && m_latestParam != m_param)
{
if (m_latestParam->scalingLists != m_param->scalingLists)
@@ -504,6 +508,7 @@
free((char*)m_param->rc.statFileName);
free((char*)m_param->analysisFileName);
free((char*)m_param->scalingLists);
+ free((char*)m_param->csvfn);
free((char*)m_param->numaPools);
free((char*)m_param->masteringDisplayColorVolume);
free((char*)m_param->toneMapFile);
@@ -2605,9 +2610,6 @@
if (p->bLogCuStats)
x265_log(p, X265_LOG_WARNING, "--cu-stats option is now deprecated\n");
- if (p->csvfn)
- x265_log(p, X265_LOG_WARNING, "libx265 no longer supports CSV file statistics\n");
-
if (p->log2MaxPocLsb < 4)
{
x265_log(p, X265_LOG_WARNING, "maximum of the picture order count can not be less than 4\n");
diff -r b19bc0c7b4ec -r 12097d65c3cc source/encoder/encoder.h
--- a/source/encoder/encoder.h Tue Jun 06 11:13:19 2017 +0530
+++ b/source/encoder/encoder.h Fri Jun 09 18:21:55 2017 +0530
@@ -137,6 +137,7 @@
x265_param* m_latestParam; // Holds latest param during a reconfigure
RateControl* m_rateControl;
Lookahead* m_lookahead;
+ FILE* m_csvfpt;
/* Collect statistics globally */
EncStats m_analyzeAll;
diff -r b19bc0c7b4ec -r 12097d65c3cc source/x265-extras.cpp
--- a/source/x265-extras.cpp Tue Jun 06 11:13:19 2017 +0530
+++ b/source/x265-extras.cpp Fri Jun 09 18:21:55 2017 +0530
@@ -25,7 +25,7 @@
#include "x265.h"
#include "x265-extras.h"
-
+#include "param.h"
#include "common.h"
using namespace X265_NS;
@@ -38,14 +38,8 @@
"B count, B ave-QP, B kbps, B-PSNR Y, B-PSNR U, B-PSNR V, B-SSIM (dB), "
"MaxCLL, MaxFALL, Version\n";
-FILE* x265_csvlog_open(const x265_api& api, const x265_param& param, const char* fname, int level)
+FILE* x265_csvlog_open(const x265_param& param, const char* fname, int level)
{
- if (sizeof(x265_stats) != api.sizeof_stats || sizeof(x265_picture) != api.sizeof_picture)
- {
- fprintf(stderr, "extras [error]: structure size skew, unable to create CSV logfile\n");
- return NULL;
- }
-
FILE *csvfp = x265_fopen(fname, "r");
if (csvfp)
{
@@ -255,7 +249,7 @@
fflush(stderr);
}
-void x265_csvlog_encode(FILE* csvfp, const char* version, const x265_param& param, const x265_stats& stats, int level, int argc, char** argv)
+void x265_csvlog_encode(FILE* csvfp, const char* version, const x265_param& param, int padx, int pady, const x265_stats& stats, int level, int argc, char** argv)
{
if (!csvfp)
return;
@@ -268,13 +262,27 @@
}
// CLI arguments or other
- fputc('"', csvfp);
- for (int i = 1; i < argc; i++)
+ if (argc)
{
- fputc(' ', csvfp);
- fputs(argv[i], csvfp);
+ fputc('"', csvfp);
+ for (int i = 1; i < argc; i++)
+ {
+ fputc(' ', csvfp);
+ fputs(argv[i], csvfp);
+ }
+ fputc('"', csvfp);
}
- fputc('"', csvfp);
+ else
+ {
+ const x265_param* paramTemp = ¶m;
+ char *opts = x265_param2string((x265_param*)paramTemp, padx, pady);
+ if (opts)
+ {
+ fputc('"', csvfp);
+ fputs(opts, csvfp);
+ fputc('"', csvfp);
+ }
+ }
// current date and time
time_t now;
diff -r b19bc0c7b4ec -r 12097d65c3cc source/x265-extras.h
--- a/source/x265-extras.h Tue Jun 06 11:13:19 2017 +0530
+++ b/source/x265-extras.h Fri Jun 09 18:21:55 2017 +0530
@@ -44,7 +44,7 @@
* closed by the caller using fclose(). If level is 0, then no frame logging
* header is written to the file. This function will return NULL if it is unable
* to open the file for write or if it detects a structure size skew */
-LIBAPI FILE* x265_csvlog_open(const x265_api& api, const x265_param& param, const char* fname, int level);
+LIBAPI FILE* x265_csvlog_open(const x265_param& param, const char* fname, int level);
/* Log frame statistics to the CSV file handle. level should have been non-zero
* in the call to x265_csvlog_open() if this function is called. */
@@ -53,7 +53,7 @@
/* Log final encode statistics to the CSV file handle. 'argc' and 'argv' are
* intended to be command line arguments passed to the encoder. Encode
* statistics should be queried from the encoder just prior to closing it. */
-LIBAPI void x265_csvlog_encode(FILE* csvfp, const char* version, const x265_param& param, const x265_stats& stats, int level, int argc, char** argv);
+LIBAPI void x265_csvlog_encode(FILE* csvfp, const char* version, const x265_param& param, int padx, int pady, const x265_stats& stats, int level, int argc, char** argv);
/* In-place downshift from a bit-depth greater than 8 to a bit-depth of 8, using
* the residual bits to dither each row. */
diff -r b19bc0c7b4ec -r 12097d65c3cc source/x265.cpp
--- a/source/x265.cpp Tue Jun 06 11:13:19 2017 +0530
+++ b/source/x265.cpp Fri Jun 09 18:21:55 2017 +0530
@@ -73,15 +73,12 @@
ReconFile* recon;
OutputFile* output;
FILE* qpfile;
- FILE* csvfpt;
- const char* csvfn;
const char* reconPlayCmd;
const x265_api* api;
x265_param* param;
bool bProgress;
bool bForceY4m;
bool bDither;
- int csvLogLevel;
uint32_t seek; // number of frames to skip from the beginning
uint32_t framesToBeEncoded; // number of frames to encode
uint64_t totalbytes;
@@ -97,8 +94,6 @@
recon = NULL;
output = NULL;
qpfile = NULL;
- csvfpt = NULL;
- csvfn = NULL;
reconPlayCmd = NULL;
api = NULL;
param = NULL;
@@ -109,7 +104,6 @@
startTime = x265_mdate();
prevUpdateTime = 0;
bDither = false;
- csvLogLevel = 0;
}
void destroy();
@@ -129,9 +123,6 @@
if (qpfile)
fclose(qpfile);
qpfile = NULL;
- if (csvfpt)
- fclose(csvfpt);
- csvfpt = NULL;
if (output)
output->release();
output = NULL;
@@ -292,8 +283,6 @@
if (0) ;
OPT2("frame-skip", "seek") this->seek = (uint32_t)x265_atoi(optarg, bError);
OPT("frames") this->framesToBeEncoded = (uint32_t)x265_atoi(optarg, bError);
- OPT("csv") this->csvfn = optarg;
- OPT("csv-log-level") this->csvLogLevel = x265_atoi(optarg, bError);
OPT("no-progress") this->bProgress = false;
OPT("output") outputfn = optarg;
OPT("input") inputfn = optarg;
@@ -530,8 +519,7 @@
* 1 - unable to parse command line
* 2 - unable to open encoder
* 3 - unable to generate stream headers
- * 4 - encoder abort
- * 5 - unable to open csv file */
+ * 4 - encoder abort */
int main(int argc, char **argv)
{
@@ -586,20 +574,7 @@
/* get the encoder parameters post-initialization */
api->encoder_parameters(encoder, param);
- if (cliopt.csvfn)
- {
- cliopt.csvfpt = x265_csvlog_open(*api, *param, cliopt.csvfn, cliopt.csvLogLevel);
- if (!cliopt.csvfpt)
- {
- x265_log_file(param, X265_LOG_ERROR, "Unable to open CSV log file <%s>, aborting\n", cliopt.csvfn);
- cliopt.destroy();
- if (cliopt.api)
- cliopt.api->param_free(cliopt.param);
- exit(5);
- }
- }
-
- /* Control-C handler */
+ /* Control-C handler */
if (signal(SIGINT, sigint_handler) == SIG_ERR)
x265_log(param, X265_LOG_ERROR, "Unable to register CTRL+C handler: %s\n", strerror(errno));
@@ -607,7 +582,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 || cliopt.csvLogLevel) ? &pic_out : NULL;
+ x265_picture *pic_recon = (cliopt.recon || !!param->analysisMode || pts_queue || reconPlay || param->csvLogLevel) ? &pic_out : NULL;
uint32_t inFrameCount = 0;
uint32_t outFrameCount = 0;
x265_nal *p_nal;
@@ -698,8 +673,6 @@
}
cliopt.printStatus(outFrameCount);
- if (numEncoded && cliopt.csvLogLevel)
- x265_csvlog_frame(cliopt.csvfpt, *param, *pic_recon, cliopt.csvLogLevel);
}
/* Flush the encoder */
@@ -730,8 +703,6 @@
}
cliopt.printStatus(outFrameCount);
- if (numEncoded && cliopt.csvLogLevel)
- x265_csvlog_frame(cliopt.csvfpt, *param, *pic_recon, cliopt.csvLogLevel);
if (!numEncoded)
break;
@@ -746,8 +717,8 @@
delete reconPlay;
api->encoder_get_stats(encoder, &stats, sizeof(stats));
- if (cliopt.csvfpt && !b_ctrl_c)
- x265_csvlog_encode(cliopt.csvfpt, api->version_str, *param, stats, cliopt.csvLogLevel, argc, argv);
+ if (param->csvfn && !b_ctrl_c)
+ api->encoder_log(encoder, argc, argv);
api->encoder_close(encoder);
int64_t second_largest_pts = 0;
diff -r b19bc0c7b4ec -r 12097d65c3cc source/x265.h
--- a/source/x265.h Tue Jun 06 11:13:19 2017 +0530
+++ b/source/x265.h Fri Jun 09 18:21:55 2017 +0530
@@ -654,7 +654,14 @@
* X265_LOG_FULL, default is X265_LOG_INFO */
int logLevel;
- /* Filename of CSV log. Now deprecated */
+ /* Level of csv logging. 0 is summary, 1 is frame level logging,
+ * 2 is frame level logging with performance statistics */
+ int csvLogLevel;
+
+ /* filename of CSV log. If csvLogLevel is non-zero, 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) */
const char* csvfn;
/*== Internal Picture Specification ==*/
@@ -1620,7 +1627,8 @@
void x265_encoder_get_stats(x265_encoder *encoder, x265_stats *, uint32_t statsSizeBytes);
/* x265_encoder_log:
- * This function is deprecated */
+ * write a line to the configured CSV file. If a CSV filename was not
+ * configured, or file open failed, this function will perform no write. */
void x265_encoder_log(x265_encoder *encoder, int argc, char **argv);
/* x265_encoder_close:
-------------- next part --------------
A non-text attachment was scrubbed...
Name: x265.patch
Type: text/x-patch
Size: 18875 bytes
Desc: not available
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20170612/b051f44d/attachment-0001.bin>
More information about the x265-devel
mailing list