diff --git a/mythplugins/mythmusic/mythmusic/avfdecoder.cpp b/mythplugins/mythmusic/mythmusic/avfdecoder.cpp index 9e07f9df6bb..f04544c9975 100644 --- a/mythplugins/mythmusic/mythmusic/avfdecoder.cpp +++ b/mythplugins/mythmusic/mythmusic/avfdecoder.cpp @@ -75,6 +75,73 @@ static int64_t SeekFunc(void *opaque, int64_t offset, int whence) return -1; } +static void myth_av_log(void *ptr, int level, const char* fmt, va_list vl) +{ + if (VERBOSE_LEVEL_NONE) + return; + + static QString full_line(""); + static const int msg_len = 255; + static QMutex string_lock; + uint64_t verbose_mask = VB_GENERAL; + LogLevel_t verbose_level = LOG_DEBUG; + + // determine mythtv debug level from av log level + switch (level) + { + case AV_LOG_PANIC: + verbose_level = LOG_EMERG; + break; + case AV_LOG_FATAL: + verbose_level = LOG_CRIT; + break; + case AV_LOG_ERROR: + verbose_level = LOG_ERR; + verbose_mask |= VB_LIBAV; + break; + case AV_LOG_DEBUG: + case AV_LOG_VERBOSE: + case AV_LOG_INFO: + verbose_level = LOG_DEBUG; + verbose_mask |= VB_LIBAV; + break; + case AV_LOG_WARNING: + verbose_mask |= VB_LIBAV; + break; + default: + return; + } + + if (!VERBOSE_LEVEL_CHECK(verbose_mask, verbose_level)) + return; + + string_lock.lock(); + if (full_line.isEmpty() && ptr) { + AVClass* avc = *(AVClass**)ptr; + full_line.sprintf("[%s @ %p] ", avc->item_name(ptr), avc); + } + + char str[msg_len+1]; + int bytes = vsnprintf(str, msg_len+1, fmt, vl); + + // check for truncated messages and fix them + if (bytes > msg_len) + { + LOG(VB_GENERAL, LOG_WARNING, + QString("Libav log output truncated %1 of %2 bytes written") + .arg(msg_len).arg(bytes)); + str[msg_len-1] = '\n'; + } + + full_line += QString(str); + if (full_line.endsWith("\n")) + { + LOG(verbose_mask, verbose_level, full_line.trimmed()); + full_line.truncate(0); + } + string_lock.unlock(); +} + avfDecoder::avfDecoder(const QString &file, DecoderFactory *d, QIODevice *i, AudioOutput *o) : Decoder(d, i, o), @@ -94,6 +161,10 @@ avfDecoder::avfDecoder(const QString &file, DecoderFactory *d, QIODevice *i, { setObjectName("avfDecoder"); setFilename(file); + + bool debug = VERBOSE_LEVEL_CHECK(VB_LIBAV, LOG_ANY); + av_log_set_level((debug) ? AV_LOG_DEBUG : AV_LOG_ERROR); + av_log_set_callback(myth_av_log); } avfDecoder::~avfDecoder(void)