[x265] [PATCH] Add support for customizing logging

Andrey Semashev andrey.semashev at gmail.com
Wed Jan 10 16:05:36 CET 2018


On 01/10/18 11:52, Pradeep Ramachandran wrote:
> 
> On Mon, Jan 1, 2018 at 6:05 PM, Andrey Semashev 
> <andrey.semashev at gmail.com <mailto:andrey.semashev at gmail.com>> wrote:
> 
>     # HG changeset patch
>     # User Andrey Semashev <andrey.semashev at gmail.com
>     <mailto:andrey.semashev at 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.

I can increment X265_BUILD in source/CMakeLists.txt and prepare a new patch.

> 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 :-).

The problem with this is that in quite a few places x265_log is invoked 
with no x265_params, so the logging system has no way to know the 
current encoder state or params, where the logging function pointer 
could be stored. For now, I think the only way is to use the global 
function pointer.

> 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(&param, "exec", X265_LOG_ERROR, "Unable to
>     register SIGPIPE handler: %s\n", strerror(errno));
>     +        g_x265_log(&param, "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(&param, "exec", X265_LOG_ERROR, "popen(%s)
>     failed\n", commandLine);
>     +        g_x265_log(&param, "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 at videolan.org <mailto:x265-devel at videolan.org>
>     https://mailman.videolan.org/listinfo/x265-devel
>     <https://mailman.videolan.org/listinfo/x265-devel>
> 
> 
> 
> 
> _______________________________________________
> x265-devel mailing list
> x265-devel at videolan.org
> https://mailman.videolan.org/listinfo/x265-devel
> 



More information about the x265-devel mailing list