diff options
author | wm4 <wm4@nowhere> | 2013-12-21 23:15:32 +0100 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2013-12-21 23:15:32 +0100 |
commit | 0a3e9a9ac3a90da831b497e0613dfb66bc14f3d2 (patch) | |
tree | b70f214f8c3fc802d6d6edbf8395273c854ac0fd /common/av_log.c | |
parent | a4fe95b0d8d339ba5afbdb5346ad8fd367a4a1c1 (diff) | |
parent | 245e5b844177e9ad9a9c07eff5efab7c3fccdebc (diff) | |
download | mpv-0a3e9a9ac3a90da831b497e0613dfb66bc14f3d2.tar.bz2 mpv-0a3e9a9ac3a90da831b497e0613dfb66bc14f3d2.tar.xz |
Merge branch 'msg_refactor'
This branch changes mp_msg() so that it doesn't require global context.
The changes are pretty violent.
Diffstat (limited to 'common/av_log.c')
-rw-r--r-- | common/av_log.c | 125 |
1 files changed, 80 insertions, 45 deletions
diff --git a/common/av_log.c b/common/av_log.c index ba47500572..1fcaf55fcc 100644 --- a/common/av_log.c +++ b/common/av_log.c @@ -21,11 +21,16 @@ */ #include <stdlib.h> +#include <stdio.h> #include <stdbool.h> +#include <pthread.h> #include "av_log.h" #include "config.h" +#include "common/common.h" +#include "common/global.h" #include "common/msg.h" + #include <libavutil/avutil.h> #include <libavutil/log.h> @@ -48,10 +53,23 @@ #include <libswresample/swresample.h> #endif +#if LIBAVCODEC_VERSION_MICRO >= 100 +#define LIB_PREFIX "ffmpeg" +#else +#define LIB_PREFIX "libav" +#endif + +// Needed because the av_log callback does not provide a library-safe message +// callback. +static pthread_mutex_t log_lock = PTHREAD_MUTEX_INITIALIZER; +static struct mpv_global *log_mpv_instance; +static struct mp_log *log_root, *log_decaudio, *log_decvideo, *log_demuxer; +static bool log_print_prefix = true; + static int av_log_level_to_mp_level(int av_level) { if (av_level > AV_LOG_VERBOSE) - return MSGL_DBG2; + return MSGL_DEBUG; if (av_level > AV_LOG_INFO) return MSGL_V; if (av_level > AV_LOG_WARNING) @@ -63,17 +81,17 @@ static int av_log_level_to_mp_level(int av_level) return MSGL_FATAL; } -static int extract_msg_type_from_ctx(void *ptr) +static struct mp_log *get_av_log(void *ptr) { if (!ptr) - return MSGT_FIXME; + return log_root; AVClass *avc = *(AVClass **)ptr; if (!avc) { - mp_msg(MSGT_FIXME, MSGL_WARN, + mp_warn(log_root, "av_log callback called with bad parameters (NULL AVClass).\n" "This is a bug in one of Libav/FFmpeg libraries used.\n"); - return MSGT_FIXME; + return log_root; } if (!strcmp(avc->class_name, "AVCodecContext")) { @@ -81,59 +99,65 @@ static int extract_msg_type_from_ctx(void *ptr) if (s->codec) { if (s->codec->type == AVMEDIA_TYPE_AUDIO) { if (s->codec->decode) - return MSGT_DECAUDIO; + return log_decaudio; } else if (s->codec->type == AVMEDIA_TYPE_VIDEO) { if (s->codec->decode) - return MSGT_DECVIDEO; + return log_decvideo; } - // FIXME subtitles, encoders - // What msgt for them? There is nothing appropriate... } - return MSGT_FIXME; } if (!strcmp(avc->class_name, "AVFormatContext")) { AVFormatContext *s = ptr; if (s->iformat) - return MSGT_DEMUXER; - else if (s->oformat) - return MSGT_MUXER; - return MSGT_FIXME; + return log_demuxer; } - return MSGT_FIXME; + return log_root; } -#if LIBAVCODEC_VERSION_MICRO >= 100 -#define LIB_PREFIX "ffmpeg" -#else -#define LIB_PREFIX "libav" -#endif - -static bool print_prefix = true; - static void mp_msg_av_log_callback(void *ptr, int level, const char *fmt, va_list vl) { AVClass *avc = ptr ? *(AVClass **)ptr : NULL; int mp_level = av_log_level_to_mp_level(level); - int type = extract_msg_type_from_ctx(ptr); - if (!mp_msg_test(type, mp_level)) + // Note: mp_log is thread-safe, but destruction of the log instances is not. + pthread_mutex_lock(&log_lock); + + if (!log_mpv_instance) { + pthread_mutex_unlock(&log_lock); + // Fallback to stderr + vfprintf(stderr, fmt, vl); return; + } + + struct mp_log *log = get_av_log(ptr); + + if (mp_msg_test(log, mp_level)) { + if (log_print_prefix) + mp_msg(log, mp_level, "%s: ", avc ? avc->item_name(ptr) : "?"); + log_print_prefix = fmt[strlen(fmt) - 1] == '\n'; - if (print_prefix) { - mp_msg(type, mp_level, "[%s/%s] ", LIB_PREFIX, - avc ? avc->item_name(ptr) : "?"); + mp_msg_va(log, mp_level, fmt, vl); } - print_prefix = fmt[strlen(fmt) - 1] == '\n'; - mp_msg_va(type, mp_level, fmt, vl); + pthread_mutex_unlock(&log_lock); } -void init_libav(void) +void init_libav(struct mpv_global *global) { - av_log_set_callback(mp_msg_av_log_callback); + pthread_mutex_lock(&log_lock); + if (!log_mpv_instance) { + log_mpv_instance = global; + log_root = mp_log_new(NULL, global->log, LIB_PREFIX); + log_decaudio = mp_log_new(log_root, log_root, "audio"); + log_decvideo = mp_log_new(log_root, log_root, "video"); + log_demuxer = mp_log_new(log_root, log_root, "demuxer"); + av_log_set_callback(mp_msg_av_log_callback); + } + pthread_mutex_unlock(&log_lock); + avcodec_register_all(); av_register_all(); avformat_network_init(); @@ -146,31 +170,42 @@ void init_libav(void) #endif } +void uninit_libav(struct mpv_global *global) +{ + pthread_mutex_lock(&log_lock); + if (log_mpv_instance == global) { + log_mpv_instance = NULL; + talloc_free(log_root); + } + pthread_mutex_unlock(&log_lock); +} + #define V(x) (x)>>16, (x)>>8 & 255, (x) & 255 -static void print_version(int v, char *name, unsigned buildv, unsigned runv) +static void print_version(struct mp_log *log, int v, char *name, + unsigned buildv, unsigned runv) { - mp_msg(MSGT_CPLAYER, v, " %-15s %d.%d.%d", name, V(buildv)); + mp_msg(log, v, " %-15s %d.%d.%d", name, V(buildv)); if (buildv != runv) - mp_msg(MSGT_CPLAYER, v, " (runtime %d.%d.%d)", V(runv)); - mp_msg(MSGT_CPLAYER, v, "\n"); + mp_msg(log, v, " (runtime %d.%d.%d)", V(runv)); + mp_msg(log, v, "\n"); } #undef V -void print_libav_versions(int v) +void print_libav_versions(struct mp_log *log, int v) { - mp_msg(MSGT_CPLAYER, v, "%s library versions:\n", LIB_PREFIX); + mp_msg(log, v, "%s library versions:\n", LIB_PREFIX); - print_version(v, "libavutil", LIBAVUTIL_VERSION_INT, avutil_version()); - print_version(v, "libavcodec", LIBAVCODEC_VERSION_INT, avcodec_version()); - print_version(v, "libavformat", LIBAVFORMAT_VERSION_INT, avformat_version()); - print_version(v, "libswscale", LIBSWSCALE_VERSION_INT, swscale_version()); + print_version(log, v, "libavutil", LIBAVUTIL_VERSION_INT, avutil_version()); + print_version(log, v, "libavcodec", LIBAVCODEC_VERSION_INT, avcodec_version()); + print_version(log, v, "libavformat", LIBAVFORMAT_VERSION_INT, avformat_version()); + print_version(log, v, "libswscale", LIBSWSCALE_VERSION_INT, swscale_version()); #if HAVE_LIBAVFILTER - print_version(v, "libavfilter", LIBAVFILTER_VERSION_INT, avfilter_version()); + print_version(log, v, "libavfilter", LIBAVFILTER_VERSION_INT, avfilter_version()); #endif #if HAVE_LIBAVRESAMPLE - print_version(v, "libavresample", LIBAVRESAMPLE_VERSION_INT, avresample_version()); + print_version(log, v, "libavresample", LIBAVRESAMPLE_VERSION_INT, avresample_version()); #endif #if HAVE_LIBSWRESAMPLE - print_version(v, "libswresample", LIBSWRESAMPLE_VERSION_INT, swresample_version()); + print_version(log, v, "libswresample", LIBSWRESAMPLE_VERSION_INT, swresample_version()); #endif } |