[x265] [PATCH] Add support for customizing logging

Pradeep Ramachandran pradeep at multicorewareinc.com
Wed Jan 10 09:52:07 CET 2018


On Mon, Jan 1, 2018 at 6:05 PM, Andrey Semashev <andrey.semashev at gmail.com>
wrote:

> # HG changeset patch
> # User Andrey Semashev <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.
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(&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
> https://mailman.videolan.org/listinfo/x265-devel
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20180110/b468af46/attachment-0001.html>


More information about the x265-devel mailing list