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".
next prev parent 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