Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
 help / color / mirror / Atom feed
From: softworkz <ffmpegagent@gmail.com>
To: ffmpeg-devel@ffmpeg.org
Cc: softworkz <softworkz@hotmail.com>
Subject: [FFmpeg-devel] [PATCH v6 1/3] fftools: Add a local logging callback function
Date: Thu, 13 Mar 2025 09:30:39 +0000
Message-ID: <8080f15800d1f63e1c846b649d2bbe9f08e8a163.1741858241.git.ffmpegagent@gmail.com> (raw)
In-Reply-To: <pull.59.v6.ffstaging.FFmpeg.1741858241.ffmpegagent@gmail.com>

From: softworkz <softworkz@hotmail.com>

This gets fftools its own management of log level and flags for and
provides an fftools-specific logging callback.
This makes it easier to implement specific logging behaviors which are
incompatible with direct use of the av libs and cannot be done in
libavutil.

Signed-off-by: softworkz <softworkz@hotmail.com>
---
 fftools/Makefile      |   7 +-
 fftools/cmdutils.c    |   3 +-
 fftools/ffmpeg.c      |  10 +-
 fftools/ffplay.c      |   6 +-
 fftools/ffprobe.c     |   4 +-
 fftools/fftools_log.c | 448 ++++++++++++++++++++++++++++++++++++++++++
 fftools/fftools_log.h |  96 +++++++++
 fftools/opt_common.c  |  41 ++--
 8 files changed, 586 insertions(+), 29 deletions(-)
 create mode 100644 fftools/fftools_log.c
 create mode 100644 fftools/fftools_log.h

diff --git a/fftools/Makefile b/fftools/Makefile
index 4499799818..5ae3e7af10 100644
--- a/fftools/Makefile
+++ b/fftools/Makefile
@@ -19,10 +19,15 @@ OBJS-ffmpeg +=                  \
     fftools/ffmpeg_mux_init.o   \
     fftools/ffmpeg_opt.o        \
     fftools/ffmpeg_sched.o      \
+    fftools/fftools_log.o       \
     fftools/sync_queue.o        \
     fftools/thread_queue.o      \
 
-OBJS-ffplay += fftools/ffplay_renderer.o
+OBJS-ffprobe +=                 \
+    fftools/fftools_log.o       \
+
+OBJS-ffplay += fftools/ffplay_renderer.o  \
+               fftools/fftools_log.o      \
 
 define DOFFTOOL
 OBJS-$(1) += fftools/cmdutils.o fftools/opt_common.o fftools/$(1).o $(OBJS-$(1)-yes)
diff --git a/fftools/cmdutils.c b/fftools/cmdutils.c
index 8ac20bf049..0bf453508d 100644
--- a/fftools/cmdutils.c
+++ b/fftools/cmdutils.c
@@ -46,6 +46,7 @@
 #include "libavutil/dict.h"
 #include "libavutil/opt.h"
 #include "cmdutils.h"
+#include "fftools_log.h"
 #include "fopen_utf8.h"
 #include "opt_common.h"
 #ifdef _WIN32
@@ -608,7 +609,7 @@ int opt_default(void *optctx, const char *opt, const char *arg)
 #endif
 
     if (!strcmp(opt, "debug") || !strcmp(opt, "fdebug"))
-        av_log_set_level(AV_LOG_DEBUG);
+        ff_log_set_level(AV_LOG_DEBUG);
 
     if (!(p = strchr(opt, ':')))
         p = opt + strlen(opt);
diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c
index dc321fb4a2..b845fa2ba4 100644
--- a/fftools/ffmpeg.c
+++ b/fftools/ffmpeg.c
@@ -81,6 +81,7 @@
 #include "ffmpeg.h"
 #include "ffmpeg_sched.h"
 #include "ffmpeg_utils.h"
+#include "fftools_log.h"
 
 const char program_name[] = "ffmpeg";
 const int program_birth_year = 2000;
@@ -671,7 +672,7 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti
 
     if (print_stats || is_last_report) {
         const char end = is_last_report ? '\n' : '\r';
-        if (print_stats==1 && AV_LOG_INFO > av_log_get_level()) {
+        if (print_stats==1 && AV_LOG_INFO > ff_log_get_level()) {
             fprintf(stderr, "%s    %c", buf.str, end);
         } else
             av_log(NULL, AV_LOG_INFO, "%s    %c", buf.str, end);
@@ -801,8 +802,8 @@ static int check_keyboard_interaction(int64_t cur_time)
         av_log(NULL, AV_LOG_INFO, "\n\n[q] command received. Exiting.\n\n");
         return AVERROR_EXIT;
     }
-    if (key == '+') av_log_set_level(av_log_get_level()+10);
-    if (key == '-') av_log_set_level(av_log_get_level()-10);
+    if (key == '+') ff_log_set_level(ff_log_get_level()+10);
+    if (key == '-') ff_log_set_level(ff_log_get_level()-10);
     if (key == 'c' || key == 'C'){
         char buf[4096], target[64], command[256], arg[256] = {0};
         double time;
@@ -954,7 +955,8 @@ int main(int argc, char **argv)
 
     setvbuf(stderr,NULL,_IONBF,0); /* win32 runtime needs this */
 
-    av_log_set_flags(AV_LOG_SKIP_REPEATED);
+    ff_log_set_flags(FF_LOG_SKIP_REPEATED);
+    init_logging();
     parse_loglevel(argc, argv, options);
 
 #if CONFIG_AVDEVICE
diff --git a/fftools/ffplay.c b/fftools/ffplay.c
index 2a572fc3aa..1d4870fd99 100644
--- a/fftools/ffplay.c
+++ b/fftools/ffplay.c
@@ -57,6 +57,7 @@
 #include "cmdutils.h"
 #include "ffplay_renderer.h"
 #include "opt_common.h"
+#include "fftools_log.h"
 
 const char program_name[] = "ffplay";
 const int program_birth_year = 2003;
@@ -1735,7 +1736,7 @@ display:
                       vqsize / 1024,
                       sqsize);
 
-            if (show_status == 1 && AV_LOG_INFO > av_log_get_level())
+            if (show_status == 1 && AV_LOG_INFO > ff_log_get_level())
                 fprintf(stderr, "%s", buf.str);
             else
                 av_log(NULL, AV_LOG_INFO, "%s", buf.str);
@@ -3761,7 +3762,8 @@ int main(int argc, char **argv)
 
     init_dynload();
 
-    av_log_set_flags(AV_LOG_SKIP_REPEATED);
+    ff_log_set_flags(FF_LOG_SKIP_REPEATED);
+    init_logging();
     parse_loglevel(argc, argv, options);
 
     /* register all codecs, demux and protocols */
diff --git a/fftools/ffprobe.c b/fftools/ffprobe.c
index 7341731d2f..98540982c4 100644
--- a/fftools/ffprobe.c
+++ b/fftools/ffprobe.c
@@ -68,6 +68,7 @@
 #include "libavfilter/version.h"
 #include "cmdutils.h"
 #include "opt_common.h"
+#include "fftools_log.h"
 
 #include "libavutil/thread.h"
 
@@ -4651,7 +4652,8 @@ int main(int argc, char **argv)
 
     init_dynload();
 
-    av_log_set_flags(AV_LOG_SKIP_REPEATED);
+    ff_log_set_flags(FF_LOG_SKIP_REPEATED);
+    init_logging();
 
     options = real_options;
     parse_loglevel(argc, argv, options);
diff --git a/fftools/fftools_log.c b/fftools/fftools_log.c
new file mode 100644
index 0000000000..f8f098fef9
--- /dev/null
+++ b/fftools/fftools_log.c
@@ -0,0 +1,448 @@
+/*
+ * Copyright (c) The FFmpeg developers
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+
+#include "config.h"
+
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_IO_H
+#include <io.h>
+#endif
+#include <inttypes.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#include "libavutil/bprint.h"
+#include "libavutil/common.h"
+#include "libavutil/log.h"
+#include "libavutil/thread.h"
+#include "libavutil/time.h"
+
+#include "fftools_log.h"
+
+
+static int ff_log_level = AV_LOG_INFO;
+static int ff_log_flags;
+
+
+#if !HAVE_LOCALTIME_R && !defined(localtime_r)
+static inline struct tm *ff_localtime_r(const time_t* clock, struct tm *result)
+{
+    struct tm *ptr = localtime(clock);
+    if (!ptr)
+        return NULL;
+    *result = *ptr;
+    return result;
+}
+#define localtime_r ff_localtime_r
+#endif
+
+static AVMutex mutex = AV_MUTEX_INITIALIZER;
+
+#define LINE_SZ 1024
+
+#if HAVE_VALGRIND_VALGRIND_H && CONFIG_VALGRIND_BACKTRACE
+#include <valgrind/valgrind.h>
+/* this is the log level at which valgrind will output a full backtrace */
+#define BACKTRACE_LOGLEVEL AV_LOG_ERROR
+#endif
+
+#define NB_LEVELS 8
+#if defined(_WIN32) && HAVE_SETCONSOLETEXTATTRIBUTE && HAVE_GETSTDHANDLE
+#include <windows.h>
+static const uint8_t color[16 + AV_CLASS_CATEGORY_NB] = {
+    [AV_LOG_PANIC  /8] = 12,
+    [AV_LOG_FATAL  /8] = 12,
+    [AV_LOG_ERROR  /8] = 12,
+    [AV_LOG_WARNING/8] = 14,
+    [AV_LOG_INFO   /8] =  7,
+    [AV_LOG_VERBOSE/8] = 10,
+    [AV_LOG_DEBUG  /8] = 10,
+    [AV_LOG_TRACE  /8] = 8,
+    [16+AV_CLASS_CATEGORY_NA              ] =  7,
+    [16+AV_CLASS_CATEGORY_INPUT           ] = 13,
+    [16+AV_CLASS_CATEGORY_OUTPUT          ] =  5,
+    [16+AV_CLASS_CATEGORY_MUXER           ] = 13,
+    [16+AV_CLASS_CATEGORY_DEMUXER         ] =  5,
+    [16+AV_CLASS_CATEGORY_ENCODER         ] = 11,
+    [16+AV_CLASS_CATEGORY_DECODER         ] =  3,
+    [16+AV_CLASS_CATEGORY_FILTER          ] = 10,
+    [16+AV_CLASS_CATEGORY_BITSTREAM_FILTER] =  9,
+    [16+AV_CLASS_CATEGORY_SWSCALER        ] =  7,
+    [16+AV_CLASS_CATEGORY_SWRESAMPLER     ] =  7,
+    [16+AV_CLASS_CATEGORY_DEVICE_VIDEO_OUTPUT ] = 13,
+    [16+AV_CLASS_CATEGORY_DEVICE_VIDEO_INPUT  ] = 5,
+    [16+AV_CLASS_CATEGORY_DEVICE_AUDIO_OUTPUT ] = 13,
+    [16+AV_CLASS_CATEGORY_DEVICE_AUDIO_INPUT  ] = 5,
+    [16+AV_CLASS_CATEGORY_DEVICE_OUTPUT       ] = 13,
+    [16+AV_CLASS_CATEGORY_DEVICE_INPUT        ] = 5,
+};
+
+static int16_t background, attr_orig;
+static HANDLE con;
+#else
+
+static const uint32_t color[16 + AV_CLASS_CATEGORY_NB] = {
+    [AV_LOG_PANIC  /8] =  52 << 16 | 196 << 8 | 0x41,
+    [AV_LOG_FATAL  /8] = 208 <<  8 | 0x41,
+    [AV_LOG_ERROR  /8] = 196 <<  8 | 0x11,
+    [AV_LOG_WARNING/8] = 226 <<  8 | 0x03,
+    [AV_LOG_INFO   /8] = 253 <<  8 | 0x09,
+    [AV_LOG_VERBOSE/8] =  40 <<  8 | 0x02,
+    [AV_LOG_DEBUG  /8] =  34 <<  8 | 0x02,
+    [AV_LOG_TRACE  /8] =  34 <<  8 | 0x07,
+    [16+AV_CLASS_CATEGORY_NA              ] = 250 << 8 | 0x09,
+    [16+AV_CLASS_CATEGORY_INPUT           ] = 219 << 8 | 0x15,
+    [16+AV_CLASS_CATEGORY_OUTPUT          ] = 201 << 8 | 0x05,
+    [16+AV_CLASS_CATEGORY_MUXER           ] = 213 << 8 | 0x15,
+    [16+AV_CLASS_CATEGORY_DEMUXER         ] = 207 << 8 | 0x05,
+    [16+AV_CLASS_CATEGORY_ENCODER         ] =  51 << 8 | 0x16,
+    [16+AV_CLASS_CATEGORY_DECODER         ] =  39 << 8 | 0x06,
+    [16+AV_CLASS_CATEGORY_FILTER          ] = 155 << 8 | 0x12,
+    [16+AV_CLASS_CATEGORY_BITSTREAM_FILTER] = 192 << 8 | 0x14,
+    [16+AV_CLASS_CATEGORY_SWSCALER        ] = 153 << 8 | 0x14,
+    [16+AV_CLASS_CATEGORY_SWRESAMPLER     ] = 147 << 8 | 0x14,
+    [16+AV_CLASS_CATEGORY_DEVICE_VIDEO_OUTPUT ] = 213 << 8 | 0x15,
+    [16+AV_CLASS_CATEGORY_DEVICE_VIDEO_INPUT  ] = 207 << 8 | 0x05,
+    [16+AV_CLASS_CATEGORY_DEVICE_AUDIO_OUTPUT ] = 213 << 8 | 0x15,
+    [16+AV_CLASS_CATEGORY_DEVICE_AUDIO_INPUT  ] = 207 << 8 | 0x05,
+    [16+AV_CLASS_CATEGORY_DEVICE_OUTPUT       ] = 213 << 8 | 0x15,
+    [16+AV_CLASS_CATEGORY_DEVICE_INPUT        ] = 207 << 8 | 0x05,
+};
+
+#endif
+static int use_color = -1;
+
+#if defined(_WIN32) && HAVE_SETCONSOLETEXTATTRIBUTE && HAVE_GETSTDHANDLE
+static void win_console_puts(const char *str)
+{
+    const uint8_t *q = str;
+    uint16_t line[LINE_SZ];
+
+    while (*q) {
+        uint16_t *buf = line;
+        DWORD nb_chars = 0;
+        DWORD written;
+
+        while (*q && nb_chars < LINE_SZ - 1) {
+            uint32_t ch;
+            uint16_t tmp;
+
+            GET_UTF8(ch, *q ? *q++ : 0, ch = 0xfffd; goto continue_on_invalid;)
+continue_on_invalid:
+            PUT_UTF16(ch, tmp, *buf++ = tmp; nb_chars++;)
+        }
+
+        WriteConsoleW(con, line, nb_chars, &written, NULL);
+    }
+}
+#endif
+
+static void check_color_terminal(void)
+{
+    char *term = getenv("TERM");
+
+#if defined(_WIN32) && HAVE_SETCONSOLETEXTATTRIBUTE && HAVE_GETSTDHANDLE
+    CONSOLE_SCREEN_BUFFER_INFO con_info;
+    DWORD dummy;
+    con = GetStdHandle(STD_ERROR_HANDLE);
+    if (con != INVALID_HANDLE_VALUE && !GetConsoleMode(con, &dummy))
+        con = INVALID_HANDLE_VALUE;
+    if (con != INVALID_HANDLE_VALUE) {
+        GetConsoleScreenBufferInfo(con, &con_info);
+        attr_orig  = con_info.wAttributes;
+        background = attr_orig & 0xF0;
+    }
+#endif
+
+    if (getenv("AV_LOG_FORCE_NOCOLOR")) {
+        use_color = 0;
+    } else if (getenv("AV_LOG_FORCE_COLOR")) {
+        use_color = 1;
+    } else {
+#if defined(_WIN32) && HAVE_SETCONSOLETEXTATTRIBUTE && HAVE_GETSTDHANDLE
+        use_color = (con != INVALID_HANDLE_VALUE);
+#elif HAVE_ISATTY
+        use_color = (term && isatty(2));
+#else
+        use_color = 0;
+#endif
+    }
+
+    if (getenv("AV_LOG_FORCE_256COLOR") || term && strstr(term, "256color"))
+        use_color *= 256;
+}
+
+static void ansi_fputs(int level, int tint, const char *str, int local_use_color)
+{
+    if (local_use_color == 1) {
+        fprintf(stderr,
+                "\033[%"PRIu32";3%"PRIu32"m%s\033[0m",
+                (color[level] >> 4) & 15,
+                color[level] & 15,
+                str);
+    } else if (tint && use_color == 256) {
+        fprintf(stderr,
+                "\033[48;5;%"PRIu32"m\033[38;5;%dm%s\033[0m",
+                (color[level] >> 16) & 0xff,
+                tint,
+                str);
+    } else if (local_use_color == 256) {
+        fprintf(stderr,
+                "\033[48;5;%"PRIu32"m\033[38;5;%"PRIu32"m%s\033[0m",
+                (color[level] >> 16) & 0xff,
+                (color[level] >> 8) & 0xff,
+                str);
+    } else
+        fputs(str, stderr);
+}
+
+static void colored_fputs(int level, int tint, const char *str)
+{
+    int local_use_color;
+    if (!*str)
+        return;
+
+    if (use_color < 0)
+        check_color_terminal();
+
+    if (level == AV_LOG_INFO/8) local_use_color = 0;
+    else                        local_use_color = use_color;
+
+#if defined(_WIN32) && HAVE_SETCONSOLETEXTATTRIBUTE && HAVE_GETSTDHANDLE
+    if (con != INVALID_HANDLE_VALUE) {
+        if (local_use_color)
+            SetConsoleTextAttribute(con, background | color[level]);
+        win_console_puts(str);
+        if (local_use_color)
+            SetConsoleTextAttribute(con, attr_orig);
+    } else {
+        ansi_fputs(level, tint, str, local_use_color);
+    }
+#else
+    ansi_fputs(level, tint, str, local_use_color);
+#endif
+
+}
+
+static void sanitize(uint8_t *line){
+    while(*line){
+        if(*line < 0x08 || (*line > 0x0D && *line < 0x20))
+            *line='?';
+        line++;
+    }
+}
+
+static int get_category(void *ptr){
+    AVClass *avc = *(AVClass **) ptr;
+    if(    !avc
+        || (avc->version&0xFF)<100
+        ||  avc->version < (51 << 16 | 59 << 8)
+        ||  avc->category >= AV_CLASS_CATEGORY_NB) return AV_CLASS_CATEGORY_NA + 16;
+
+    if(avc->get_category)
+        return avc->get_category(ptr) + 16;
+
+    return avc->category + 16;
+}
+
+static const char *get_level_str(int level)
+{
+    switch (level) {
+    case AV_LOG_QUIET:
+        return "quiet";
+    case AV_LOG_DEBUG:
+        return "debug";
+    case AV_LOG_TRACE:
+        return "trace";
+    case AV_LOG_VERBOSE:
+        return "verbose";
+    case AV_LOG_INFO:
+        return "info";
+    case AV_LOG_WARNING:
+        return "warning";
+    case AV_LOG_ERROR:
+        return "error";
+    case AV_LOG_FATAL:
+        return "fatal";
+    case AV_LOG_PANIC:
+        return "panic";
+    default:
+        return "";
+    }
+}
+
+static const char *item_name(void *obj, const AVClass *cls)
+{
+    return (cls->item_name ? cls->item_name : av_default_item_name)(obj);
+}
+
+static void format_date_now(AVBPrint* bp_time, int include_date)
+{
+    struct tm *ptm, tmbuf;
+    const int64_t time_us = av_gettime();
+    const int64_t time_ms = time_us / 1000;
+    const time_t time_s   = time_ms / 1000;
+    const int millisec    = time_ms - (time_s * 1000);
+    ptm                   = localtime_r(&time_s, &tmbuf);
+    if (ptm) {
+        if (include_date)
+            av_bprint_strftime(bp_time, "%Y-%m-%d ", ptm);
+
+        av_bprint_strftime(bp_time, "%H:%M:%S", ptm);
+        av_bprintf(bp_time, ".%03d ", millisec);
+    }
+}
+
+static void format_line(void *avcl, int level, const char *fmt, va_list vl,
+                        AVBPrint part[5], int *print_prefix, int type[2])
+{
+    AVClass* avc = avcl ? *(AVClass **) avcl : NULL;
+    av_bprint_init(part+0, 0, AV_BPRINT_SIZE_AUTOMATIC);
+    av_bprint_init(part+1, 0, AV_BPRINT_SIZE_AUTOMATIC);
+    av_bprint_init(part+2, 0, AV_BPRINT_SIZE_AUTOMATIC);
+    av_bprint_init(part+3, 0, 65536);
+    av_bprint_init(part+4, 0, AV_BPRINT_SIZE_AUTOMATIC);
+
+    if(type) type[0] = type[1] = AV_CLASS_CATEGORY_NA + 16;
+    if (*print_prefix && avc) {
+        if (avc->parent_log_context_offset) {
+            AVClass** parent = *(AVClass ***) (((uint8_t *) avcl) +
+                                   avc->parent_log_context_offset);
+            if (parent && *parent) {
+                av_bprintf(part+0, "[%s @ %p] ",
+                           item_name(parent, *parent), parent);
+                if(type) type[0] = get_category(parent);
+            }
+        }
+        av_bprintf(part+1, "[%s @ %p] ",
+                   item_name(avcl, avc), avcl);
+        if(type) type[1] = get_category(avcl);
+    }
+
+    if (*print_prefix && (level > AV_LOG_QUIET) && (ff_log_flags & (FF_LOG_PRINT_TIME | FF_LOG_PRINT_DATETIME)))
+        format_date_now(&part[4], ff_log_flags & FF_LOG_PRINT_DATETIME);
+
+    if (*print_prefix && (level > AV_LOG_QUIET) && (ff_log_flags & FF_LOG_PRINT_LEVEL))
+        av_bprintf(part+2, "[%s] ", get_level_str(level));
+
+    av_vbprintf(part+3, fmt, vl);
+
+    if(*part[0].str || *part[1].str || *part[2].str || *part[3].str) {
+        char lastc = part[3].len && part[3].len <= part[3].size ? part[3].str[part[3].len - 1] : 0;
+        *print_prefix = lastc == '\n' || lastc == '\r';
+    }
+}
+
+void fftools_log_callback(void* ptr, int level, const char* fmt, va_list vl)
+{
+    static int print_prefix = 1;
+    static int count;
+    static char prev[LINE_SZ];
+    AVBPrint part[5];
+    char line[LINE_SZ];
+    static int is_atty;
+    int type[2];
+    unsigned tint = 0;
+
+    if (level >= 0) {
+        tint = level & 0xff00;
+        level &= 0xff;
+    }
+
+    if (level > ff_log_level)
+        return;
+
+    ff_mutex_lock(&mutex);
+
+    format_line(ptr, level, fmt, vl, part, &print_prefix, type);
+    snprintf(line, sizeof(line), "%s%s%s%s", part[0].str, part[1].str, part[2].str, part[3].str);
+
+#if HAVE_ISATTY
+    if (!is_atty)
+        is_atty = isatty(2) ? 1 : -1;
+#endif
+
+    if (print_prefix && (ff_log_flags & FF_LOG_SKIP_REPEATED) && !strcmp(line, prev) &&
+        *line && line[strlen(line) - 1] != '\r'){
+        count++;
+        if (is_atty == 1)
+            fprintf(stderr, "    Last message repeated %d times\r", count);
+        goto end;
+    }
+    if (count > 0) {
+        fprintf(stderr, "    Last message repeated %d times\n", count);
+        count = 0;
+    }
+    strcpy(prev, line);
+
+    sanitize(part[4].str);
+    colored_fputs(7, 0, part[4].str);
+    sanitize(part[0].str);
+    colored_fputs(type[0], 0, part[0].str);
+    sanitize(part[1].str);
+    colored_fputs(type[1], 0, part[1].str);
+    sanitize(part[2].str);
+    colored_fputs(av_clip(level >> 3, 0, NB_LEVELS - 1), tint >> 8, part[2].str);
+    sanitize(part[3].str);
+    colored_fputs(av_clip(level >> 3, 0, NB_LEVELS - 1), tint >> 8, part[3].str);
+
+#if CONFIG_VALGRIND_BACKTRACE
+    if (level <= BACKTRACE_LOGLEVEL)
+        VALGRIND_PRINTF_BACKTRACE("%s", "");
+#endif
+end:
+    av_bprint_finalize(part+3, NULL);
+    ff_mutex_unlock(&mutex);
+}
+
+
+void init_logging(void)
+{
+    av_log_set_callback(&fftools_log_callback);
+}
+
+int ff_log_get_level(void)
+{
+    return ff_log_level;
+}
+
+void ff_log_set_level(int level)
+{
+    ff_log_level = level;
+
+    av_log_set_level(level);
+}
+
+void ff_log_set_flags(int arg)
+{
+    ff_log_flags = arg;
+}
+
+int ff_log_get_flags(void)
+{
+    return ff_log_flags;
+}
+
diff --git a/fftools/fftools_log.h b/fftools/fftools_log.h
new file mode 100644
index 0000000000..4dba15ff7f
--- /dev/null
+++ b/fftools/fftools_log.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) The FFmpeg developers
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef FFTOOLS_FFTOOLS_LOG_H
+#define FFTOOLS_FFTOOLS_LOG_H
+
+#include <stdint.h>
+
+#include "config.h"
+#include "libavcodec/avcodec.h"
+#include "libavfilter/avfilter.h"
+#include "libavformat/avformat.h"
+#include "libswscale/swscale.h"
+
+
+/**
+ * Custom logging callback for fftools.
+ */
+void fftools_log_callback(void* ptr, int level, const char* fmt, va_list vl);
+
+/**
+ * Sets the logging callback function.
+ */
+void init_logging(void);
+
+
+/**
+ * Get the current log level
+ *
+ * @see lavu_log_constants
+ *
+ * @return Current log level
+ */
+int ff_log_get_level(void);
+
+/**
+ * Set the log level
+ *
+ * @see lavu_log_constants
+ *
+ * @param level Logging level
+ */
+void ff_log_set_level(int level);
+
+void ff_log_set_flags(int arg);
+
+int ff_log_get_flags(void);
+
+
+/**
+ * Skip repeated messages, this requires the user app to use av_log() instead of
+ * (f)printf as the 2 would otherwise interfere and lead to
+ * "Last message repeated x times" messages below (f)printf messages with some
+ * bad luck.
+ * Also to receive the last, "last repeated" line if any, the user app must
+ * call av_log(NULL, AV_LOG_QUIET, "%s", ""); at the end
+ */
+#define FF_LOG_SKIP_REPEATED 1
+
+/**
+ * Include the log severity in messages originating from codecs.
+ *
+ * Results in messages such as:
+ * [rawvideo @ 0xDEADBEEF] [error] encode did not produce valid pts
+ */
+#define FF_LOG_PRINT_LEVEL 2
+
+/**
+ * Include system time in log output.
+ */
+#define FF_LOG_PRINT_TIME 4
+
+/**
+ * Include system date and time in log output.
+ */
+#define FF_LOG_PRINT_DATETIME 8
+
+
+#endif /* FFTOOLS_FFTOOLS_LOG_H */
diff --git a/fftools/opt_common.c b/fftools/opt_common.c
index 2ac3fd4fb3..702f62a6fe 100644
--- a/fftools/opt_common.c
+++ b/fftools/opt_common.c
@@ -25,6 +25,7 @@
 #include "cmdutils.h"
 #include "opt_common.h"
 
+#include "fftools_log.h"
 #include "libavutil/avassert.h"
 #include "libavutil/avstring.h"
 #include "libavutil/bprint.h"
@@ -1203,7 +1204,7 @@ int init_report(const char *env, FILE **file)
         return AVERROR(ENOMEM);
     }
 
-    prog_loglevel = av_log_get_level();
+    prog_loglevel = ff_log_get_level();
     if (!envlevel)
         report_file_level = FFMAX(report_file_level, prog_loglevel);
 
@@ -1265,8 +1266,8 @@ int opt_loglevel(void *optctx, const char *opt, const char *arg)
     };
     const char *token;
     char *tail;
-    int flags = av_log_get_flags();
-    int level = av_log_get_level();
+    int flags = ff_log_get_flags();
+    int level = ff_log_get_level();
     int cmd, i = 0;
 
     av_assert0(arg);
@@ -1282,27 +1283,27 @@ int opt_loglevel(void *optctx, const char *opt, const char *arg)
         }
         if (av_strstart(token, "repeat", &arg)) {
             if (cmd == '-') {
-                flags |= AV_LOG_SKIP_REPEATED;
+                flags |= FF_LOG_SKIP_REPEATED;
             } else {
-                flags &= ~AV_LOG_SKIP_REPEATED;
+                flags &= ~FF_LOG_SKIP_REPEATED;
             }
         } else if (av_strstart(token, "level", &arg)) {
             if (cmd == '-') {
-                flags &= ~AV_LOG_PRINT_LEVEL;
+                flags &= ~FF_LOG_PRINT_LEVEL;
             } else {
-                flags |= AV_LOG_PRINT_LEVEL;
+                flags |= FF_LOG_PRINT_LEVEL;
             }
         } else if (av_strstart(token, "time", &arg)) {
             if (cmd == '-') {
-                flags &= ~AV_LOG_PRINT_TIME;
+                flags &= ~FF_LOG_PRINT_TIME;
             } else {
-                flags |= AV_LOG_PRINT_TIME;
+                flags |= FF_LOG_PRINT_TIME;
             }
         } else if (av_strstart(token, "datetime", &arg)) {
             if (cmd == '-') {
-                flags &= ~AV_LOG_PRINT_DATETIME;
+                flags &= ~FF_LOG_PRINT_DATETIME;
             } else {
-                flags |= AV_LOG_PRINT_DATETIME;
+                flags |= FF_LOG_PRINT_DATETIME;
             }
         } else {
             break;
@@ -1314,7 +1315,7 @@ int opt_loglevel(void *optctx, const char *opt, const char *arg)
     } else if (*arg == '+') {
         arg++;
     } else if (!i) {
-        flags = av_log_get_flags();  /* level value without prefix, reset flags */
+        flags = ff_log_get_flags();  /* level value without prefix, reset flags */
     }
 
     for (i = 0; i < FF_ARRAY_ELEMS(log_levels); i++) {
@@ -1339,8 +1340,8 @@ int opt_loglevel(void *optctx, const char *opt, const char *arg)
     }
 
 end:
-    av_log_set_flags(flags);
-    av_log_set_level(level);
+    ff_log_set_flags(flags);
+    ff_log_set_level(level);
     return 0;
 }
 
@@ -1436,9 +1437,9 @@ int show_sources(void *optctx, const char *opt, const char *arg)
     char *dev = NULL;
     AVDictionary *opts = NULL;
     int ret = 0;
-    int error_level = av_log_get_level();
+    int error_level = ff_log_get_level();
 
-    av_log_set_level(AV_LOG_WARNING);
+    ff_log_set_level(AV_LOG_WARNING);
 
     if ((ret = show_sinks_sources_parse_arg(arg, &dev, &opts)) < 0)
         goto fail;
@@ -1464,7 +1465,7 @@ int show_sources(void *optctx, const char *opt, const char *arg)
   fail:
     av_dict_free(&opts);
     av_free(dev);
-    av_log_set_level(error_level);
+    ff_log_set_level(error_level);
     return ret;
 }
 
@@ -1474,9 +1475,9 @@ int show_sinks(void *optctx, const char *opt, const char *arg)
     char *dev = NULL;
     AVDictionary *opts = NULL;
     int ret = 0;
-    int error_level = av_log_get_level();
+    int error_level = ff_log_get_level();
 
-    av_log_set_level(AV_LOG_WARNING);
+    ff_log_set_level(AV_LOG_WARNING);
 
     if ((ret = show_sinks_sources_parse_arg(arg, &dev, &opts)) < 0)
         goto fail;
@@ -1500,7 +1501,7 @@ int show_sinks(void *optctx, const char *opt, const char *arg)
   fail:
     av_dict_free(&opts);
     av_free(dev);
-    av_log_set_level(error_level);
+    ff_log_set_level(error_level);
     return ret;
 }
 #endif /* CONFIG_AVDEVICE */
-- 
ffmpeg-codebot

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

  reply	other threads:[~2025-03-13  9:31 UTC|newest]

Thread overview: 56+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-03-05 15:38 [FFmpeg-devel] [PATCH] avutil/log: Replace addresses in log output with simple ids softworkz
2025-03-05 15:40 ` Nicolas George
2025-03-05 15:45   ` Soft Works
2025-03-05 15:48   ` Soft Works
2025-03-06 10:08     ` Nicolas George
2025-03-06 17:02       ` Soft Works
2025-03-06 17:38         ` Marvin Scholz
2025-03-06 17:44           ` Soft Works
2025-03-06 17:49             ` Marvin Scholz
2025-03-06 18:16               ` Soft Works
2025-03-06 18:58                 ` Marvin Scholz
2025-03-06 19:27                   ` Soft Works
2025-03-06 20:01                     ` Marvin Scholz
2025-03-06 20:48                       ` Soft Works
2025-03-06 20:56       ` Soft Works
2025-03-05 15:42 ` Soft Works
2025-03-05 16:23 ` Gyan Doshi
2025-03-05 16:30   ` Soft Works
2025-03-05 17:14     ` Gyan Doshi
2025-03-05 18:19 ` [FFmpeg-devel] [PATCH v2 0/3] " ffmpegagent
2025-03-05 18:19   ` [FFmpeg-devel] [PATCH v2 1/3] " softworkz
2025-03-05 18:19   ` [FFmpeg-devel] [PATCH v2 2/3] fftools/opt_common: add memaddresses log flag softworkz
2025-03-05 18:19   ` [FFmpeg-devel] [PATCH v2 3/3] doc/fftools-common-opts: document " softworkz
2025-03-06 10:04   ` [FFmpeg-devel] [PATCH v2 0/3] avutil/log: Replace addresses in log output with simple ids Nicolas George
2025-03-06 16:38     ` Soft Works
2025-03-06 16:43       ` Nicolas George
2025-03-06 17:05         ` Soft Works
2025-03-06 17:38           ` Soft Works
2025-03-06 20:59   ` [FFmpeg-devel] [PATCH v3 0/4] " ffmpegagent
2025-03-06 20:59     ` [FFmpeg-devel] [PATCH v3 1/4] avutil/log: Add callback for context prefix formatting softworkz
2025-03-07  9:44       ` Nicolas George
2025-03-07 17:23         ` Soft Works
2025-03-07 17:30           ` Hendrik Leppkes
2025-03-07 18:02             ` Soft Works
2025-03-06 20:59     ` [FFmpeg-devel] [PATCH v3 2/4] fftools/opt_common: add memaddresses log flag softworkz
2025-03-06 20:59     ` [FFmpeg-devel] [PATCH v3 3/4] fftools: Provide a log formatting callback for context prefixes softworkz
2025-03-06 20:59     ` [FFmpeg-devel] [PATCH v3 4/4] doc/fftools-common-opts: document memaddresses log flag softworkz
2025-03-08 23:02     ` [FFmpeg-devel] [PATCH v4 0/4] avutil/log: Replace addresses in log output with simple ids ffmpegagent
2025-03-08 23:02       ` [FFmpeg-devel] [PATCH v4 1/4] avutil/log: Add AV_LOG_PRINT_MEMADDRESSES logging flag softworkz
2025-03-08 23:02       ` [FFmpeg-devel] [PATCH v4 2/4] fftools/opt_common: add memaddresses log flag softworkz
2025-03-08 23:02       ` [FFmpeg-devel] [PATCH v4 3/4] fftools: Provide a an fftools-specific logging callback function softworkz
2025-03-09 17:52         ` Michael Niedermayer
2025-03-09 18:59           ` Soft Works
2025-03-08 23:02       ` [FFmpeg-devel] [PATCH v4 4/4] doc/fftools-common-opts: document memaddresses log flag softworkz
2025-03-09 19:01       ` [FFmpeg-devel] [PATCH v5 0/5] avutil/log: Replace addresses in log output with simple ids ffmpegagent
2025-03-09 19:01         ` [FFmpeg-devel] [PATCH v5 1/5] avutil/log: Add AV_LOG_PRINT_MEMADDRESSES logging flag softworkz
2025-03-09 19:05           ` Nicolas George
2025-03-09 19:11             ` Soft Works
2025-03-09 19:01         ` [FFmpeg-devel] [PATCH v5 2/5] fftools/opt_common: add memaddresses log flag softworkz
2025-03-09 19:01         ` [FFmpeg-devel] [PATCH v5 3/5] fftools: Provide a an fftools-specific logging callback function softworkz
2025-03-09 19:01         ` [FFmpeg-devel] [PATCH v5 4/5] doc/fftools-common-opts: document memaddresses log flag softworkz
2025-03-09 19:01         ` [FFmpeg-devel] [PATCH v5 5/5] Remove commented lines softworkz
2025-03-13  9:30         ` [FFmpeg-devel] [PATCH v6 0/3] avutil/log: Replace addresses in log output with simple ids ffmpegagent
2025-03-13  9:30           ` softworkz [this message]
2025-03-13  9:30           ` [FFmpeg-devel] [PATCH v6 2/3] fftools/opt_common: add memaddresses log flag softworkz
2025-03-13  9:30           ` [FFmpeg-devel] [PATCH v6 3/3] doc/fftools-common-opts: document " softworkz

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=8080f15800d1f63e1c846b649d2bbe9f08e8a163.1741858241.git.ffmpegagent@gmail.com \
    --to=ffmpegagent@gmail.com \
    --cc=ffmpeg-devel@ffmpeg.org \
    --cc=softworkz@hotmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
		ffmpegdev@gitmailbox.com
	public-inbox-index ffmpegdev

Example config snippet for mirrors.


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git