<div dir="ltr"><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Jan 1, 2018 at 6:05 PM, Andrey Semashev <span dir="ltr"><<a href="mailto:andrey.semashev@gmail.com" target="_blank">andrey.semashev@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"># HG changeset patch<br>
# User Andrey Semashev <<a href="mailto:andrey.semashev@gmail.com">andrey.semashev@gmail.com</a>><br>
# Date 1514810081 -10800<br>
# Mon Jan 01 15:34:41 2018 +0300<br>
# Branch add_custom_logging<br>
# Node ID 248f862033e9fb01ee54d3e466dc28<wbr>4eeeb30365<br>
# Parent ff02513b92c000c3bb3dcc51deb79a<wbr>f57f5358d5<br>
Add support for customizing logging.<br>
<br>
This commit adds support for customizing logging behavior. This can be used<br>
by the application using libx265 to override the default behavior of printing<br>
messages to the console with the application-specific logging system. This is<br>
especially important if the console is not available or monitored for the<br>
application (e.g. if it runs as a service or daemon).<br></blockquote><div><br></div><div>I like this patch - it is a good feature to have to support better logging for application that includes libx265. We have to increase BUILD_NUMBER as there is a change to the API but that is a trivial change.</div><div>Having the g_x265_log as a global may result in some issues when the application instantiates multiple instances of x265 but I think we can live with it for now; a follow-up patch to clean this up would be great :-).</div><div><br></div><div>We will regress it and update the repo.</div><div> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
diff -r ff02513b92c0 -r 248f862033e9 source/common/common.cpp<br>
--- a/source/common/common.cpp Fri Dec 22 18:23:24 2017 +0530<br>
+++ b/source/common/common.cpp Mon Jan 01 15:34:41 2018 +0300<br>
@@ -102,49 +102,9 @@<br>
return (x265_exp2_lut[i & 63] + 256) << (i >> 6) >> 8;<br>
}<br>
<br>
-void general_log(const x265_param* param, const char* caller, int level, const char* fmt, ...)<br>
-{<br>
- if (param && level > param->logLevel)<br>
- return;<br>
- const int bufferSize = 4096;<br>
- char buffer[bufferSize];<br>
- int p = 0;<br>
- const char* log_level;<br>
- switch (level)<br>
- {<br>
- case X265_LOG_ERROR:<br>
- log_level = "error";<br>
- break;<br>
- case X265_LOG_WARNING:<br>
- log_level = "warning";<br>
- break;<br>
- case X265_LOG_INFO:<br>
- log_level = "info";<br>
- break;<br>
- case X265_LOG_DEBUG:<br>
- log_level = "debug";<br>
- break;<br>
- case X265_LOG_FULL:<br>
- log_level = "full";<br>
- break;<br>
- default:<br>
- log_level = "unknown";<br>
- break;<br>
- }<br>
+x265_log_t g_x265_log = &general_log;<br>
<br>
- if (caller)<br>
- p += sprintf(buffer, "%-4s [%s]: ", caller, log_level);<br>
- va_list arg;<br>
- va_start(arg, fmt);<br>
- vsnprintf(buffer + p, bufferSize - p, fmt, arg);<br>
- va_end(arg);<br>
- fputs(buffer, stderr);<br>
-}<br>
-<br>
-#if _WIN32<br>
-/* For Unicode filenames in Windows we convert UTF-8 strings to UTF-16 and we use _w functions.<br>
- * For other OS we do not make any changes. */<br>
-void general_log_file(const x265_param* param, const char* caller, int level, const char* fmt, ...)<br>
+void general_log(const x265_param* param, const char* caller, int national, int level, const char* fmt, ...)<br>
{<br>
if (param && level > param->logLevel)<br>
return;<br>
@@ -181,19 +141,31 @@<br>
vsnprintf(buffer + p, bufferSize - p, fmt, arg);<br>
va_end(arg);<br>
<br>
- HANDLE console = GetStdHandle(STD_ERROR_HANDLE)<wbr>;<br>
- DWORD mode;<br>
- if (GetConsoleMode(console, &mode))<br>
+#if _WIN32<br>
+ if (national)<br>
{<br>
- wchar_t buf_utf16[bufferSize];<br>
- int length_utf16 = MultiByteToWideChar(CP_UTF8, 0, buffer, -1, buf_utf16, sizeof(buf_utf16)/sizeof(<wbr>wchar_t)) - 1;<br>
- if (length_utf16 > 0)<br>
- WriteConsoleW(console, buf_utf16, length_utf16, &mode, NULL);<br>
+ HANDLE console = GetStdHandle(STD_ERROR_HANDLE)<wbr>;<br>
+ DWORD mode;<br>
+ if (GetConsoleMode(console, &mode))<br>
+ {<br>
+ wchar_t buf_utf16[bufferSize];<br>
+ int length_utf16 = MultiByteToWideChar(CP_UTF8, 0, buffer, -1, buf_utf16, sizeof(buf_utf16)/sizeof(<wbr>wchar_t)) - 1;<br>
+ if (length_utf16 > 0)<br>
+ WriteConsoleW(console, buf_utf16, length_utf16, &mode, NULL);<br>
+ return;<br>
+ }<br>
}<br>
- else<br>
- fputs(buffer, stderr);<br>
+#else<br>
+ // Suppress warnings about unused argument<br>
+ (void)national;<br>
+#endif<br>
+<br>
+ fputs(buffer, stderr);<br>
}<br>
<br>
+#if _WIN32<br>
+/* For Unicode filenames in Windows we convert UTF-8 strings to UTF-16 and we use _w functions.<br>
+ * For other OS we do not make any changes. */<br>
FILE* x265_fopen(const char* fileName, const char* mode)<br>
{<br>
wchar_t buf_utf16[MAX_PATH * 2], mode_utf16[16];<br>
diff -r ff02513b92c0 -r 248f862033e9 source/common/common.h<br>
--- a/source/common/common.h Fri Dec 22 18:23:24 2017 +0530<br>
+++ b/source/common/common.h Mon Jan 01 15:34:41 2018 +0300<br>
@@ -411,16 +411,15 @@<br>
<br>
/* located in common.cpp */<br>
int64_t x265_mdate(void);<br>
-#define x265_log(param, ...) general_log(param, "x265", __VA_ARGS__)<br>
-#define x265_log_file(param, ...) general_log_file(param, "x265", __VA_ARGS__)<br>
-void general_log(const x265_param* param, const char* caller, int level, const char* fmt, ...);<br>
+extern x265_log_t g_x265_log;<br>
+#define x265_log(param, ...) X265_NS::g_x265_log(param, "x265", 0, __VA_ARGS__)<br>
+#define x265_log_file(param, ...) X265_NS::g_x265_log(param, "x265", 1, __VA_ARGS__)<br>
+void general_log(const x265_param* param, const char* caller, int national, int level, const char* fmt, ...);<br>
#if _WIN32<br>
-void general_log_file(const x265_param* param, const char* caller, int level, const char* fmt, ...);<br>
FILE* x265_fopen(const char* fileName, const char* mode);<br>
int x265_unlink(const char* fileName);<br>
int x265_rename(const char* oldName, const char* newName);<br>
#else<br>
-#define general_log_file(param, caller, level, fmt, ...) general_log(param, caller, level, fmt, __VA_ARGS__)<br>
#define x265_fopen(fileName, mode) fopen(fileName, mode)<br>
#define x265_unlink(fileName) unlink(fileName)<br>
#define x265_rename(oldName, newName) rename(oldName, newName)<br>
diff -r ff02513b92c0 -r 248f862033e9 source/encoder/api.cpp<br>
--- a/source/encoder/api.cpp Fri Dec 22 18:23:24 2017 +0530<br>
+++ b/source/encoder/api.cpp Mon Jan 01 15:34:41 2018 +0300<br>
@@ -414,6 +414,11 @@<br>
return x265_free(p);<br>
}<br>
<br>
+void x265_set_log(x265_log_t log)<br>
+{<br>
+ X265_NS::g_x265_log = log;<br>
+}<br>
+<br>
static const x265_api libapi =<br>
{<br>
X265_MAJOR_VERSION,<br>
@@ -456,7 +461,9 @@<br>
&x265_csvlog_frame,<br>
&x265_csvlog_encode,<br>
&x265_dither_image,<br>
- &x265_set_analysis_data<br>
+ &x265_set_analysis_data,<br>
+<br>
+ &x265_set_log<br>
};<br>
<br>
typedef const x265_api* (*api_get_func)(int bitDepth);<br>
diff -r ff02513b92c0 -r 248f862033e9 source/encoder/encoder.cpp<br>
--- a/source/encoder/encoder.cpp Fri Dec 22 18:23:24 2017 +0530<br>
+++ b/source/encoder/encoder.cpp Mon Jan 01 15:34:41 2018 +0300<br>
@@ -1774,10 +1774,10 @@<br>
p += sprintf(buffer + p, ", SSIM Mean Y: %.7f (%6.3f dB)", m_analyzeAll.m_globalSsim / m_analyzeAll.m_numPics, x265_ssim2dB(m_analyzeAll.m_<wbr>globalSsim / m_analyzeAll.m_numPics));<br>
<br>
sprintf(buffer + p, "\n");<br>
- general_log(m_param, NULL, X265_LOG_INFO, buffer);<br>
+ g_x265_log(m_param, NULL, false, X265_LOG_INFO, buffer);<br>
}<br>
else<br>
- general_log(m_param, NULL, X265_LOG_INFO, "\nencoded 0 frames\n");<br>
+ g_x265_log(m_param, NULL, false, X265_LOG_INFO, "\nencoded 0 frames\n");<br>
<br>
#if DETAILED_CU_STATS<br>
/* Summarize stats from all frame encoders */<br>
diff -r ff02513b92c0 -r 248f862033e9 source/output/reconplay.cpp<br>
--- a/source/output/reconplay.cpp Fri Dec 22 18:23:24 2017 +0530<br>
+++ b/source/output/reconplay.cpp Mon Jan 01 15:34:41 2018 +0300<br>
@@ -43,7 +43,7 @@<br>
static void sigpipe_handler(int)<br>
{<br>
if (ReconPlay::pipeValid)<br>
- general_log(NULL, "exec", X265_LOG_ERROR, "pipe closed\n");<br>
+ g_x265_log(NULL, "exec", false, X265_LOG_ERROR, "pipe closed\n");<br>
ReconPlay::pipeValid = false;<br>
}<br>
#endif<br>
@@ -52,7 +52,7 @@<br>
{<br>
#ifndef _WIN32<br>
if (signal(SIGPIPE, sigpipe_handler) == SIG_ERR)<br>
- general_log(¶m, "exec", X265_LOG_ERROR, "Unable to register SIGPIPE handler: %s\n", strerror(errno));<br>
+ g_x265_log(¶m, "exec", false, X265_LOG_ERROR, "Unable to register SIGPIPE handler: %s\n", strerror(errno));<br>
#endif<br>
<br>
width = param.sourceWidth;<br>
@@ -83,7 +83,7 @@<br>
return;<br>
}<br>
else<br>
- general_log(¶m, "exec", X265_LOG_ERROR, "popen(%s) failed\n", commandLine);<br>
+ g_x265_log(¶m, "exec", false, X265_LOG_ERROR, "popen(%s) failed\n", commandLine);<br>
<br>
fail:<br>
threadActive = false;<br>
diff -r ff02513b92c0 -r 248f862033e9 source/x265.cpp<br>
--- a/source/x265.cpp Fri Dec 22 18:23:24 2017 +0530<br>
+++ b/source/x265.cpp Mon Jan 01 15:34:41 2018 +0300<br>
@@ -416,7 +416,7 @@<br>
else<br>
sprintf(buf + p, " frames %u - %d of %d", this->seek, this->seek + this->framesToBeEncoded - 1, info.frameCount);<br>
<br>
- general_log(param, input->getName(), X265_LOG_INFO, "%s\n", buf);<br>
+ general_log(param, input->getName(), false, X265_LOG_INFO, "%s\n", buf);<br>
}<br>
<br>
this->input->startReader();<br>
@@ -434,7 +434,7 @@<br>
this->recon = 0;<br>
}<br>
else<br>
- general_log(param, this->recon->getName(), X265_LOG_INFO,<br>
+ general_log(param, this->recon->getName(), false, X265_LOG_INFO,<br>
"reconstructed images %dx%d fps %d/%d %s\n",<br>
param->sourceWidth, param->sourceHeight, param->fpsNum, param->fpsDenom,<br>
x265_source_csp_names[param-><wbr>internalCsp]);<br>
@@ -446,7 +446,7 @@<br>
x265_log_file(param, X265_LOG_ERROR, "failed to open output file <%s> for writing\n", outputfn);<br>
return true;<br>
}<br>
- general_log_file(param, this->output->getName(), X265_LOG_INFO, "output file: %s\n", outputfn);<br>
+ general_log(param, this->output->getName(), true, X265_LOG_INFO, "output file: %s\n", outputfn);<br>
return false;<br>
}<br>
<br>
@@ -740,7 +740,7 @@<br>
cliopt.output->closeFile(<wbr>largest_pts, second_largest_pts);<br>
<br>
if (b_ctrl_c)<br>
- general_log(param, NULL, X265_LOG_INFO, "aborted at input frame %d, output frame %d\n",<br>
+ general_log(param, NULL, false, X265_LOG_INFO, "aborted at input frame %d, output frame %d\n",<br>
cliopt.seek + inFrameCount, stats.encodedPictureCount);<br>
<br>
api->cleanup(); /* Free library singletons */<br>
diff -r ff02513b92c0 -r 248f862033e9 source/x265.h<br>
--- a/source/x265.h Fri Dec 22 18:23:24 2017 +0530<br>
+++ b/source/x265.h Mon Jan 01 15:34:41 2018 +0300<br>
@@ -1787,6 +1787,20 @@<br>
* the residual bits to dither each row. */<br>
void x265_dither_image(x265_picture *, int picWidth, int picHeight, int16_t *errorBuf, int bitDepth);<br>
<br>
+/* Logging function. The function is called whenever a log message is emitted.<br>
+ * The default function prints the message to stderr.<br>
+ * @param param Parameters of the encoder that emitted the message<br>
+ * @param caller A string identifying the log message originator<br>
+ * @param national If not 0, the message may contain national characters<br>
+ * @param level Log verbosity level, one of X265_LOG_*<br>
+ * @param fmt printf-style format string of the message; any subsequent arguments<br>
+ * are to be formatted into the message according to this string */<br>
+typedef void (*x265_log_t)(const x265_param* param, const char* caller, int national, int level, const char* fmt, ...);<br>
+<br>
+/* x265_set_log:<br>
+ * Sets a custom logger function */<br>
+void x265_set_log(x265_log_t log);<br>
+<br>
#define X265_MAJOR_VERSION 1<br>
<br>
/* === Multi-lib API ===<br>
@@ -1840,6 +1854,8 @@<br>
void (*dither_image)(x265_picture*, int, int, int16_t*, int);<br>
int (*set_analysis_data)(x265_<wbr>encoder *encoder, x265_analysis_data *analysis_data, int poc, uint32_t cuBytes);<br>
/* add new pointers to the end, or increment X265_MAJOR_VERSION */<br>
+<br>
+ void (*set_log)(x265_log_t log);<br>
} x265_api;<br>
<br>
/* Force a link error in the case of linking against an incompatible API version.<br>
______________________________<wbr>_________________<br>
x265-devel mailing list<br>
<a href="mailto:x265-devel@videolan.org">x265-devel@videolan.org</a><br>
<a href="https://mailman.videolan.org/listinfo/x265-devel" rel="noreferrer" target="_blank">https://mailman.videolan.org/<wbr>listinfo/x265-devel</a><br>
</blockquote></div><br></div></div>