On 01/10/18 11:52, Pradeep Ramachandran wrote:

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

    # HG changeset patch
    # User Andrey Semashev <andrey.semas...@gmail.com
    <mailto: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.

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@videolan.org <mailto:x265-devel@videolan.org>
    https://mailman.videolan.org/listinfo/x265-devel
    <https://mailman.videolan.org/listinfo/x265-devel>




_______________________________________________
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

Reply via email to