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