[FFmpeg-devel] [PATCH v6 2/3] fftools/opt_common: add memaddresses log flag

softworkz ffmpegagent at gmail.com
Thu Mar 13 11:30:40 EET 2025


From: softworkz <softworkz at hotmail.com>

This commit adds the memaddresses log flag.
When specifying this flag at the command line, context prefixes will
be printed with memory addresses like in earlier ffmpeg versions.
Memory addresses are no longer printed by default.

The benefits are:

- Smaller log file sizes
- The disambiguation is much easier to recognize and to follow
- It eventually allows comparing and viewing log file diffs
  without almost every line being different due to those addresses

Example with memaddresses flag:

[hevc @ 0000018e72a89cc0] .....

without (new behavior):

[hevc #0] .....

Signed-off-by: softworkz <softworkz at hotmail.com>
---
 fftools/cmdutils.c    |  1 +
 fftools/fftools_log.c | 67 +++++++++++++++++++++++++++++++++++++++----
 fftools/fftools_log.h |  5 ++++
 fftools/opt_common.c  |  6 ++++
 4 files changed, 73 insertions(+), 6 deletions(-)

diff --git a/fftools/cmdutils.c b/fftools/cmdutils.c
index 0bf453508d..fb05f3fd2f 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"
diff --git a/fftools/fftools_log.c b/fftools/fftools_log.c
index f8f098fef9..b83c8abcaa 100644
--- a/fftools/fftools_log.c
+++ b/fftools/fftools_log.c
@@ -59,6 +59,53 @@ static inline struct tm *ff_localtime_r(const time_t* clock, struct tm *result)
 #define localtime_r ff_localtime_r
 #endif
 
+#define MAX_CLASS_IDS 1000
+static struct class_ids {
+    void *avcl;
+    uint64_t class_hash;
+    unsigned id;
+} class_ids[MAX_CLASS_IDS];
+
+static uint64_t fnv_hash(const char *str)
+{
+    // FNV-1a 64-bit hash algorithm
+    uint64_t hash = 0xcbf29ce484222325ULL;
+    while (*str) {
+        hash ^= (unsigned char)*str++;
+        hash *= 0x100000001b3ULL;
+    }
+    return hash;
+}
+
+static unsigned get_class_id(void* avcl)
+{
+    AVClass* avc = avcl ? *(AVClass **) avcl : NULL;
+    unsigned i, nb_ids = 0;
+    uint64_t class_hash;
+
+    for (i = 0; i < MAX_CLASS_IDS && class_ids[i].avcl; i++) {
+        if (class_ids[i].avcl == avcl)
+            return class_ids[i].id;
+    }
+
+    class_hash = fnv_hash(avc->class_name);
+
+    for (i = 0; i < MAX_CLASS_IDS; i++) {
+        if (class_ids[i].class_hash == class_hash)
+            nb_ids++;
+
+        if (!class_ids[i].avcl) {
+            class_ids[i].avcl = avcl;
+            class_ids[i].class_hash = class_hash;
+            class_ids[i].id = nb_ids;
+            return class_ids[i].id;
+        }
+    }
+
+    // exceeded MAX_CLASS_IDS entries in class_ids[]
+    return 0;
+}
+
 static AVMutex mutex = AV_MUTEX_INITIALIZER;
 
 #define LINE_SZ 1024
@@ -316,6 +363,15 @@ static void format_date_now(AVBPrint* bp_time, int include_date)
     }
 }
 
+static void log_formatprefix(AVBPrint* buffer, AVClass** avcl)
+{
+    const int print_mem = ff_log_flags & FF_LOG_PRINT_MEMADDRESSES;
+    if (print_mem)
+        av_bprintf(buffer+0, "[%s @ %p] ", item_name(avcl, *avcl), avcl);
+    else
+        av_bprintf(buffer+0, "[%s #%u] ", item_name(avcl, *avcl), get_class_id(avcl));
+}
+
 static void format_line(void *avcl, int level, const char *fmt, va_list vl,
                         AVBPrint part[5], int *print_prefix, int type[2])
 {
@@ -328,17 +384,16 @@ static void format_line(void *avcl, int level, const char *fmt, va_list vl,
 
     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);
+            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);
+                log_formatprefix(part, parent);
                 if(type) type[0] = get_category(parent);
             }
         }
-        av_bprintf(part+1, "[%s @ %p] ",
-                   item_name(avcl, avc), avcl);
+        log_formatprefix(part, avcl);
+
         if(type) type[1] = get_category(avcl);
     }
 
diff --git a/fftools/fftools_log.h b/fftools/fftools_log.h
index 4dba15ff7f..6333e4d3c1 100644
--- a/fftools/fftools_log.h
+++ b/fftools/fftools_log.h
@@ -92,5 +92,10 @@ int ff_log_get_flags(void);
  */
 #define FF_LOG_PRINT_DATETIME 8
 
+/**
+ * Print memory addresses instead of logical ids in the AVClass prefix.
+ */
+#define FF_LOG_PRINT_MEMADDRESSES 16
+
 
 #endif /* FFTOOLS_FFTOOLS_LOG_H */
diff --git a/fftools/opt_common.c b/fftools/opt_common.c
index 702f62a6fe..53b6fb2257 100644
--- a/fftools/opt_common.c
+++ b/fftools/opt_common.c
@@ -1305,6 +1305,12 @@ int opt_loglevel(void *optctx, const char *opt, const char *arg)
             } else {
                 flags |= FF_LOG_PRINT_DATETIME;
             }
+        } else if (av_strstart(token, "memaddresses", &arg)) {
+            if (cmd == '-') {
+                flags &= ~FF_LOG_PRINT_MEMADDRESSES;
+            } else {
+                flags |= FF_LOG_PRINT_MEMADDRESSES;
+            }
         } else {
             break;
         }
-- 
ffmpeg-codebot



More information about the ffmpeg-devel mailing list