diff options
author | Artem Dyomin <artem.dyomin@qt.io> | 2023-08-11 12:42:53 +0200 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2023-08-11 16:30:36 +0000 |
commit | e78d7d156930a73bbc772f3224fc3b4db9ca2504 (patch) | |
tree | 02f3342bc5ebfa0f597b76364e6df2718292c8b2 | |
parent | d562f0716a2777c676716dc5cad2ea739a58a2dc (diff) |
Improve debug dumping of ffmpeg codecs details
Dumping of specific flags is very useful for investigation of
ffmpeg hw acceleration features.
Change-Id: Ica313fce870d222f16e7a8af7b53562e2734ad22
Reviewed-by: Artem Dyomin <artem.dyomin@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
(cherry picked from commit fa6f7bf67df6980d45c66c9018a42c154399b8f0)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r-- | src/plugins/multimedia/ffmpeg/qffmpeg.cpp | 86 |
1 files changed, 79 insertions, 7 deletions
diff --git a/src/plugins/multimedia/ffmpeg/qffmpeg.cpp b/src/plugins/multimedia/ffmpeg/qffmpeg.cpp index 8755cde2b..55f4c859a 100644 --- a/src/plugins/multimedia/ffmpeg/qffmpeg.cpp +++ b/src/plugins/multimedia/ffmpeg/qffmpeg.cpp @@ -47,23 +47,85 @@ struct CodecsComparator bool operator()(const AVCodec *a, AVCodecID id) const { return a->id < id; } }; +template<typename FlagNames> +static QString flagsToString(int flags, const FlagNames &flagNames) +{ + QString result; + int leftover = flags; + for (const auto &flagAndName : flagNames) + if ((flags & flagAndName.first) != 0) { + leftover &= ~flagAndName.first; + if (!result.isEmpty()) + result += ", "; + result += flagAndName.second; + } + + if (leftover) { + if (!result.isEmpty()) + result += ", "; + result += QString::number(leftover, 16); + } + return result; +} + static void dumpCodecInfo(const AVCodec *codec) { + using FlagNames = std::initializer_list<std::pair<int, const char *>>; const auto mediaType = codec->type == AVMEDIA_TYPE_VIDEO ? "video" : codec->type == AVMEDIA_TYPE_AUDIO ? "audio" : codec->type == AVMEDIA_TYPE_SUBTITLE ? "subtitle" : "other_type"; - qCDebug(qLcFFmpegUtils) << mediaType << (av_codec_is_encoder(codec) ? "encoder:" : "decoder:") - << codec->name << "id:" << codec->id - << "capabilities:" << codec->capabilities; + + const auto type = av_codec_is_encoder(codec) + ? av_codec_is_decoder(codec) ? "encoder/decoder:" : "encoder:" + : "decoder:"; + + static const FlagNames capabilitiesNames = { + { AV_CODEC_CAP_DRAW_HORIZ_BAND, "DRAW_HORIZ_BAND" }, + { AV_CODEC_CAP_DR1, "DRAW_HORIZ_DR1" }, + { AV_CODEC_CAP_DELAY, "DELAY" }, + { AV_CODEC_CAP_SMALL_LAST_FRAME, "SMALL_LAST_FRAME" }, + { AV_CODEC_CAP_SUBFRAMES, "SUBFRAMES" }, + { AV_CODEC_CAP_EXPERIMENTAL, "EXPERIMENTAL" }, + { AV_CODEC_CAP_CHANNEL_CONF, "CHANNEL_CONF" }, + { AV_CODEC_CAP_FRAME_THREADS, "FRAME_THREADS" }, + { AV_CODEC_CAP_SLICE_THREADS, "SLICE_THREADS" }, + { AV_CODEC_CAP_PARAM_CHANGE, "PARAM_CHANGE" }, + { AV_CODEC_CAP_OTHER_THREADS, "OTHER_THREADS" }, + { AV_CODEC_CAP_VARIABLE_FRAME_SIZE, "VARIABLE_FRAME_SIZE" }, + { AV_CODEC_CAP_AVOID_PROBING, "AVOID_PROBING" }, + { AV_CODEC_CAP_HARDWARE, "HARDWARE" }, + { AV_CODEC_CAP_HYBRID, "HYBRID" }, + { AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, "ENCODER_REORDERED_OPAQUE" }, + { AV_CODEC_CAP_ENCODER_FLUSH, "ENCODER_FLUSH" }, + }; + + qCDebug(qLcFFmpegUtils) << mediaType << type << codec->name << "id:" << codec->id + << "capabilities:" + << flagsToString(codec->capabilities, capabilitiesNames); + if (codec->pix_fmts) { + static const FlagNames flagNames = { + { AV_PIX_FMT_FLAG_BE, "BE" }, + { AV_PIX_FMT_FLAG_PAL, "PAL" }, + { AV_PIX_FMT_FLAG_BITSTREAM, "BITSTREAM" }, + { AV_PIX_FMT_FLAG_HWACCEL, "HWACCEL" }, + { AV_PIX_FMT_FLAG_PLANAR, "PLANAR" }, + { AV_PIX_FMT_FLAG_RGB, "RGB" }, + { AV_PIX_FMT_FLAG_ALPHA, "ALPHA" }, + { AV_PIX_FMT_FLAG_BAYER, "BAYER" }, + { AV_PIX_FMT_FLAG_FLOAT, "FLOAT" }, + }; + qCDebug(qLcFFmpegUtils) << " pix_fmts:"; for (auto f = codec->pix_fmts; *f != AV_PIX_FMT_NONE; ++f) { auto desc = av_pix_fmt_desc_get(*f); - qCDebug(qLcFFmpegUtils) << " id:" << *f << desc->name - << ((desc->flags & AV_PIX_FMT_FLAG_HWACCEL) ? "hw" : "sw") - << "depth:" << desc->comp[0].depth << "flags:" << desc->flags; + qCDebug(qLcFFmpegUtils) + << " id:" << *f << desc->name << "depth:" << desc->comp[0].depth + << "flags:" << flagsToString(desc->flags, flagNames); } + } else if (codec->type == AVMEDIA_TYPE_VIDEO) { + qCDebug(qLcFFmpegUtils) << " pix_fmts: null"; } if (codec->sample_fmts) { @@ -74,9 +136,18 @@ static void dumpCodecInfo(const AVCodec *codec) << "bytes_per_sample:" << av_get_bytes_per_sample(*f) << "is_planar:" << av_sample_fmt_is_planar(*f); } + } else if (codec->type == AVMEDIA_TYPE_AUDIO) { + qCDebug(qLcFFmpegUtils) << " sample_fmts: null"; } if (avcodec_get_hw_config(codec, 0)) { + static const FlagNames hwConfigMethodNames = { + { AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX, "HW_DEVICE_CTX" }, + { AV_CODEC_HW_CONFIG_METHOD_HW_FRAMES_CTX, "HW_FRAMES_CTX" }, + { AV_CODEC_HW_CONFIG_METHOD_INTERNAL, "INTERNAL" }, + { AV_CODEC_HW_CONFIG_METHOD_AD_HOC, "AD_HOC" } + }; + qCDebug(qLcFFmpegUtils) << " hw config:"; for (int index = 0; auto config = avcodec_get_hw_config(codec, index); ++index) { const auto pixFmtForDevice = pixelFormatForHwDevice(config->device_type); @@ -86,7 +157,8 @@ static void dumpCodecInfo(const AVCodec *codec) << " device_type:" << config->device_type << "pix_fmt:" << config->pix_fmt << (pixFmtDesc ? pixFmtDesc->name : "unknown") << "pixelFormatForHwDevice:" << pixelFormatForHwDevice(config->device_type) - << (pixFmtForDeviceDesc ? pixFmtForDeviceDesc->name : "unknown"); + << (pixFmtForDeviceDesc ? pixFmtForDeviceDesc->name : "unknown") + << "hw_config_methods:" << flagsToString(config->methods, hwConfigMethodNames); } } } |