[FFmpeg-devel] [PATCH 3/3] libavutil: enable indentation of dynamic call graph

Martin Carroll martin.carroll at alcatel-lucent.com
Wed Jul 18 17:22:21 CEST 2012


To make it easier to view the program's dynamic call graph,
the logger can now be configured to push and pop indentation
levels on the log messages.  The new macros LOGPUSH and LOGPOP
respectively increase and decrease the current indentation
level and also print information about the name and file
location of the function that is being entered or returned
from.  To enable this feature, the variable do_pushpop in
libavutil/log.c must be set to 1.

Signed-off-by: Martin Carroll <martin.carroll at alcatel-lucent.com>
---
 libavutil/log.c |   58 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 libavutil/log.h |   35 +++++++++++++++++++++++++++++++++
 2 files changed, 93 insertions(+), 0 deletions(-)

diff --git a/libavutil/log.c b/libavutil/log.c
index bee612f..05bf57a 100644
--- a/libavutil/log.c
+++ b/libavutil/log.c
@@ -52,12 +52,14 @@ typedef struct {
     void *fcn;
     int instance_num_of_fcn;
     int sole_instance_of_fcn;
+    int indent;
 } Thread_info;
 
 static pthread_rwlock_t thread_info_rwlock = PTHREAD_RWLOCK_INITIALIZER;
 static Thread_info thread_info[MAX_THREAD_INFOS];
 static int num_thread_infos = 0;
 static int print_threadname = 0; /* set to 1 to prefix all log messages with name of thread */
+static int do_pushpop = 0; /* set to 1 to enable calls to LOGPUSH, LOGPOP, and LOGPOPI */
 static int av_log_level = AV_LOG_INFO;
 static int flags;
 
@@ -204,6 +206,7 @@ void av_log_set_threadname(pthread_t pid, const char *name, void *fcn)
             }
         }
         info = &thread_info[num_thread_infos];
+    	info->indent = 0;
         info->pid = pid;
         info->fcn = fcn;
         info->instance_num_of_fcn = instance_num_of_fcn;
@@ -228,6 +231,45 @@ static Thread_info* lookup_thread_info(void)
     return NULL;
 }
 
+void
+av_log_push(const char *file, int line, const char *fcn)
+{
+    Thread_info *info;
+
+    if (!do_pushpop) return;
+    info = lookup_thread_info();
+    if (info) {
+    	av_log(NULL, av_log_level, "->%s @ %s:%d\n", fcn, file, line);
+    	++info->indent;
+    }
+}
+
+void
+av_log_pop(const char *file, int line, const char *fcn)
+{
+    Thread_info *info;
+
+    if (!do_pushpop) return;
+    info = lookup_thread_info();
+    if (info) {
+    	--info->indent;
+    	av_log(NULL, av_log_level, "<-%s @ %s:%d\n", fcn, file, line);
+    }
+}
+
+void
+av_log_popi(const char *file, int line, const char *fcn, int ret)
+{
+    Thread_info *info;
+
+    if (!do_pushpop) return;
+    info = lookup_thread_info();
+    if (info) {
+    	--info->indent;
+    	av_log(NULL, av_log_level, "<-%s=%d @ %s:%d\n", fcn, ret, file, line);
+    }
+}
+
 static void format_line(void *ptr, int level, const char *fmt, va_list vl,
                         char part[5][LINE_SZ], int part_size, int *print_prefix, int type[2])
 {
@@ -254,10 +296,26 @@ static void format_line(void *ptr, int level, const char *fmt, va_list vl,
 		pthread_rwlock_rdlock(&thread_info_rwlock);
         info = lookup_thread_info();
         if (info) {
+			int i;
+            char *ptr;
+            char *part_end;
+            const char *space;
+            int spacelen;
+
             if (info->sole_instance_of_fcn)
                 snprintf(part[2], part_size, "%s: ", info->name);
             else
                 snprintf(part[2], part_size, "%s(%d): ", info->name, info->instance_num_of_fcn);
+
+            ptr = part[3];
+            part_end = ptr + 512;
+            space = "   ";
+            spacelen = strlen(space);
+            for (i = 0; i < info->indent && ptr + spacelen + 1 < part_end; ++i) {
+                strcpy(ptr, space);
+                ptr += spacelen;
+            }
+            *ptr = 0;
         }
 		pthread_rwlock_unlock(&thread_info_rwlock);
     }
diff --git a/libavutil/log.h b/libavutil/log.h
index da96016..3407ed8 100644
--- a/libavutil/log.h
+++ b/libavutil/log.h
@@ -181,6 +181,41 @@ void av_log(void *avcl, int level, const char *fmt, ...) av_printf_format(3, 4);
  */
 void av_log_set_threadname(pthread_t pid, const char* name, void *fcn);
 
+/* these next three functions are helper functions that users are 
+* not expected to directly call but must appear in this header file 
+* because they are called by the macros LOGPUSH, LOGPOP, and LOGPOPI
+* defined below
+*/
+void av_log_push(const char *file, int line, const char *fcn);
+void av_log_pop(const char *file, int line, const char *fcn);
+void av_log_popi(const char *file, int line, const char *fcn, int ret);
+
+/**
+ * If the logger is configured to allow pushing and popping of
+ * indentation levels (see libavutil/log.c), then push an indentation
+ * level and also print information about the function that was
+ * (presumably) just entered.
+ */
+#define LOGPUSH av_log_push(__FILE__, __LINE__, __func__)
+
+/**
+ * If the logger is configured to allow pushing and popping of
+ * indentation levels (see libavutil/log.c), then pop an indentation
+ * level and also print information about the function that is
+ * (presumably) about to be returned from.
+ */
+#define LOGPOP av_log_pop(__FILE__, __LINE__, __func__)
+
+/**
+ * If the logger is configured to allow pushing and popping of
+ * indentation levels (see libavutil/log.c), then pop an indentation
+ * level and also print information about the function that is
+ * (presumably) about to be returned from.
+ *
+ * @param retval The function's return value.
+ */
+#define LOGPOPI(retval) av_log_popi(__FILE__, __LINE__, __func__, (int)(retval))
+
 void av_vlog(void *avcl, int level, const char *fmt, va_list);
 int av_log_get_level(void);
 void av_log_set_level(int);
-- 
1.7.8.6



More information about the ffmpeg-devel mailing list