summaryrefslogtreecommitdiffstats
path: root/common/av_log.c
diff options
context:
space:
mode:
Diffstat (limited to 'common/av_log.c')
-rw-r--r--common/av_log.c79
1 files changed, 47 insertions, 32 deletions
diff --git a/common/av_log.c b/common/av_log.c
index d7df24e05c..54b78a617d 100644
--- a/common/av_log.c
+++ b/common/av_log.c
@@ -22,22 +22,29 @@
#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 "config.h"
+#include "misc/bstr.h"
+#include "osdep/threads.h"
#include <libavutil/avutil.h>
#include <libavutil/log.h>
+#include <libavutil/version.h>
#include <libavcodec/avcodec.h>
+#include <libavcodec/version.h>
#include <libavformat/avformat.h>
+#include <libavformat/version.h>
#include <libswresample/swresample.h>
+#include <libswresample/version.h>
#include <libswscale/swscale.h>
+#include <libswscale/version.h>
#include <libavfilter/avfilter.h>
+#include <libavfilter/version.h>
#if HAVE_LIBAVDEVICE
#include <libavdevice/avdevice.h>
@@ -45,10 +52,11 @@
// Needed because the av_log callback does not provide a library-safe message
// callback.
-static pthread_mutex_t log_lock = PTHREAD_MUTEX_INITIALIZER;
+static mp_static_mutex log_lock = MP_STATIC_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 bstr log_buffer;
static int av_log_level_to_mp_level(int av_level)
{
@@ -74,7 +82,7 @@ static struct mp_log *get_av_log(void *ptr)
if (!avc) {
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");
+ "This is a bug in one of FFmpeg libraries used.\n");
return log_root;
}
@@ -100,6 +108,11 @@ static struct mp_log *get_av_log(void *ptr)
return log_root;
}
+static const char *avclass_item_name(void *obj, const AVClass *avc)
+{
+ return (avc->item_name ? avc->item_name : av_default_item_name)(obj);
+}
+
static void mp_msg_av_log_callback(void *ptr, int level, const char *fmt,
va_list vl)
{
@@ -107,10 +120,10 @@ static void mp_msg_av_log_callback(void *ptr, int level, const char *fmt,
int mp_level = av_log_level_to_mp_level(level);
// Note: mp_log is thread-safe, but destruction of the log instances is not.
- pthread_mutex_lock(&log_lock);
+ mp_mutex_lock(&log_lock);
if (!log_mpv_instance) {
- pthread_mutex_unlock(&log_lock);
+ mp_mutex_unlock(&log_lock);
// Fallback to stderr
vfprintf(stderr, fmt, vl);
return;
@@ -119,34 +132,36 @@ static void mp_msg_av_log_callback(void *ptr, int level, const char *fmt,
struct mp_log *log = get_av_log(ptr);
if (mp_msg_test(log, mp_level)) {
- char buffer[4096] = "";
- int pos = 0;
- const char *prefix = avc ? avc->item_name(ptr) : NULL;
- if (log_print_prefix && prefix)
- pos = snprintf(buffer, sizeof(buffer), "%s: ", prefix);
- log_print_prefix = fmt[strlen(fmt) - 1] == '\n';
-
- pos = MPMIN(MPMAX(pos, 0), sizeof(buffer));
- vsnprintf(buffer + pos, sizeof(buffer) - pos, fmt, vl);
-
- mp_msg(log, mp_level, "%s", buffer);
+ log_buffer.len = 0;
+ bstr_xappend_vasprintf(log_root, &log_buffer, fmt, vl);
+ if (!log_buffer.len)
+ goto done;
+ const char *prefix = avc ? avclass_item_name(ptr, avc) : NULL;
+ if (log_print_prefix && prefix) {
+ mp_msg(log, mp_level, "%s: %.*s", prefix, BSTR_P(log_buffer));
+ } else {
+ mp_msg(log, mp_level, "%.*s", BSTR_P(log_buffer));
+ }
+ log_print_prefix = log_buffer.start[log_buffer.len - 1] == '\n';
}
- pthread_mutex_unlock(&log_lock);
+done:
+ mp_mutex_unlock(&log_lock);
}
void init_libav(struct mpv_global *global)
{
- pthread_mutex_lock(&log_lock);
+ mp_mutex_lock(&log_lock);
if (!log_mpv_instance) {
log_mpv_instance = global;
log_root = mp_log_new(NULL, global->log, "ffmpeg");
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");
+ log_buffer = (bstr){0};
av_log_set_callback(mp_msg_av_log_callback);
}
- pthread_mutex_unlock(&log_lock);
+ mp_mutex_unlock(&log_lock);
avformat_network_init();
@@ -157,13 +172,13 @@ void init_libav(struct mpv_global *global)
void uninit_libav(struct mpv_global *global)
{
- pthread_mutex_lock(&log_lock);
+ mp_mutex_lock(&log_lock);
if (log_mpv_instance == global) {
av_log_set_callback(av_log_default_callback);
log_mpv_instance = NULL;
talloc_free(log_root);
}
- pthread_mutex_unlock(&log_lock);
+ mp_mutex_unlock(&log_lock);
}
#define V(x) AV_VERSION_MAJOR(x), \
@@ -176,7 +191,7 @@ struct lib {
unsigned runv;
};
-bool print_libav_versions(struct mp_log *log, int v)
+void check_library_versions(struct mp_log *log, int v)
{
const struct lib libs[] = {
{"libavutil", LIBAVUTIL_VERSION_INT, avutil_version()},
@@ -187,23 +202,23 @@ bool print_libav_versions(struct mp_log *log, int v)
{"libswresample", LIBSWRESAMPLE_VERSION_INT, swresample_version()},
};
+ mp_msg(log, v, "FFmpeg version: %s\n", av_version_info());
mp_msg(log, v, "FFmpeg library versions:\n");
- bool mismatch = false;
for (int n = 0; n < MP_ARRAY_SIZE(libs); n++) {
const struct lib *l = &libs[n];
mp_msg(log, v, " %-15s %d.%d.%d", l->name, V(l->buildv));
- if (l->buildv != l->runv) {
+ if (l->buildv != l->runv)
mp_msg(log, v, " (runtime %d.%d.%d)", V(l->runv));
- mismatch = l->buildv > l->runv ||
- AV_VERSION_MAJOR(l->buildv) != AV_VERSION_MAJOR(l->runv);
- }
mp_msg(log, v, "\n");
+ if (l->buildv > l->runv ||
+ AV_VERSION_MAJOR(l->buildv) != AV_VERSION_MAJOR(l->runv))
+ {
+ fprintf(stderr, "%s: %d.%d.%d -> %d.%d.%d\n",
+ l->name, V(l->buildv), V(l->runv));
+ abort();
+ }
}
-
- mp_msg(log, v, "FFmpeg version: %s\n", av_version_info());
-
- return !mismatch;
}
#undef V