From ddf562ea01b5c3a1205283540be8c43dbf51abf2 Mon Sep 17 00:00:00 2001 From: Piotr Srebrny Date: Tue, 23 Aug 2022 12:31:27 +0200 Subject: Add support for FFmpeg version 5.1 Fixes: QTBUG-105819 Change-Id: Ib81afd95047af64d2e08f054fed1230acde7395f Reviewed-by: Lars Knoll (cherry picked from commit 557c2996e0a8fbef3a7c34f4b653a72b867eb2bd) Reviewed-by: Qt Cherry-pick Bot --- src/plugins/multimedia/ffmpeg/qffmpeg_p.h | 2 ++ src/plugins/multimedia/ffmpeg/qffmpegdecoder.cpp | 4 ++++ src/plugins/multimedia/ffmpeg/qffmpegencoder.cpp | 18 ++++++++++++++++++ src/plugins/multimedia/ffmpeg/qffmpeghwaccel.cpp | 2 +- .../multimedia/ffmpeg/qffmpegmediaformatinfo.cpp | 12 +++++++++--- src/plugins/multimedia/ffmpeg/qffmpegresampler.cpp | 20 +++++++++++++++++--- 6 files changed, 51 insertions(+), 7 deletions(-) diff --git a/src/plugins/multimedia/ffmpeg/qffmpeg_p.h b/src/plugins/multimedia/ffmpeg/qffmpeg_p.h index ac4ffccce..3f06f5f56 100644 --- a/src/plugins/multimedia/ffmpeg/qffmpeg_p.h +++ b/src/plugins/multimedia/ffmpeg/qffmpeg_p.h @@ -14,6 +14,8 @@ extern "C" { #include } +#define QT_FFMPEG_OLD_CHANNEL_LAYOUT (LIBAVCODEC_VERSION_INT < AV_VERSION_INT(59,24,100)) + QT_BEGIN_NAMESPACE namespace QFFmpeg diff --git a/src/plugins/multimedia/ffmpeg/qffmpegdecoder.cpp b/src/plugins/multimedia/ffmpeg/qffmpegdecoder.cpp index 241b19c07..0b406e5a9 100644 --- a/src/plugins/multimedia/ffmpeg/qffmpegdecoder.cpp +++ b/src/plugins/multimedia/ffmpeg/qffmpegdecoder.cpp @@ -782,7 +782,11 @@ void AudioRenderer::updateOutput(const Codec *codec) // formats agree. AVSampleFormat requiredFormat = QFFmpegMediaFormatInfo::avSampleFormat(format.sampleFormat()); +#if QT_FFMPEG_OLD_CHANNEL_LAYOUT qCDebug(qLcAudioRenderer) << "init resampler" << requiredFormat << audioStream->codecpar->channels; +#else + qCDebug(qLcAudioRenderer) << "init resampler" << requiredFormat << audioStream->codecpar->ch_layout.nb_channels; +#endif resampler.reset(new Resampler(codec, format)); } diff --git a/src/plugins/multimedia/ffmpeg/qffmpegencoder.cpp b/src/plugins/multimedia/ffmpeg/qffmpegencoder.cpp index ea5c75315..186e254fd 100644 --- a/src/plugins/multimedia/ffmpeg/qffmpegencoder.cpp +++ b/src/plugins/multimedia/ffmpeg/qffmpegencoder.cpp @@ -240,8 +240,12 @@ AudioEncoder::AudioEncoder(Encoder *encoder, QFFmpegAudioInput *input, const QMe stream->id = encoder->formatContext->nb_streams - 1; stream->codecpar->codec_type = AVMEDIA_TYPE_AUDIO; stream->codecpar->codec_id = codecID; +#if QT_FFMPEG_OLD_CHANNEL_LAYOUT stream->codecpar->channel_layout = av_get_default_channel_layout(format.channelCount()); stream->codecpar->channels = format.channelCount(); +#else + av_channel_layout_default(&stream->codecpar->ch_layout, format.channelCount()); +#endif stream->codecpar->sample_rate = format.sampleRate(); stream->codecpar->frame_size = 1024; stream->codecpar->format = bestSampleFormat; @@ -259,6 +263,7 @@ AudioEncoder::AudioEncoder(Encoder *encoder, QFFmpegAudioInput *input, const QMe qCDebug(qLcFFmpegEncoder) << "audio codec params: fmt=" << codec->sample_fmt << "rate=" << codec->sample_rate; if (codec->sample_fmt != requested) { +#if QT_FFMPEG_OLD_CHANNEL_LAYOUT resampler = swr_alloc_set_opts(nullptr, // we're allocating a new context codec->channel_layout, // out_ch_layout codec->sample_fmt, // out_sample_fmt @@ -268,6 +273,15 @@ AudioEncoder::AudioEncoder(Encoder *encoder, QFFmpegAudioInput *input, const QMe format.sampleRate(), // in_sample_rate 0, // log_offset nullptr); +#else + AVChannelLayout in_ch_layout = {}; + av_channel_layout_default(&in_ch_layout, format.channelCount()); + swr_alloc_set_opts2(&resampler, // we're allocating a new context + &codec->ch_layout, codec->sample_fmt, codec->sample_rate, + &in_ch_layout, requested, format.sampleRate(), + 0, nullptr); +#endif + swr_init(resampler); } } @@ -346,8 +360,12 @@ void AudioEncoder::loop() AVFrame *frame = av_frame_alloc(); frame->format = codec->sample_fmt; +#if QT_FFMPEG_OLD_CHANNEL_LAYOUT frame->channel_layout = codec->channel_layout; frame->channels = codec->channels; +#else + frame->ch_layout = codec->ch_layout; +#endif frame->sample_rate = codec->sample_rate; frame->nb_samples = buffer.frameCount(); if (frame->nb_samples) diff --git a/src/plugins/multimedia/ffmpeg/qffmpeghwaccel.cpp b/src/plugins/multimedia/ffmpeg/qffmpeghwaccel.cpp index e75a3ca18..c2bc4f6e1 100644 --- a/src/plugins/multimedia/ffmpeg/qffmpeghwaccel.cpp +++ b/src/plugins/multimedia/ffmpeg/qffmpeghwaccel.cpp @@ -99,7 +99,7 @@ static AVBufferRef *hardwareContextForCodec(const AVCodec *codec) AVPixelFormat getFormat(AVCodecContext *s, const AVPixelFormat *fmt) { // First check HW accelerated codecs, the HW device context must be set - if (s->hw_device_ctx && s->codec->hw_configs) { + if (s->hw_device_ctx) { auto *device_ctx = (AVHWDeviceContext*)s->hw_device_ctx->data; for (int i = 0; const AVCodecHWConfig *config = avcodec_get_hw_config(s->codec, i); i++) { if (!(config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX)) diff --git a/src/plugins/multimedia/ffmpeg/qffmpegmediaformatinfo.cpp b/src/plugins/multimedia/ffmpeg/qffmpegmediaformatinfo.cpp index 9e5e17c0d..2561d564d 100644 --- a/src/plugins/multimedia/ffmpeg/qffmpegmediaformatinfo.cpp +++ b/src/plugins/multimedia/ffmpeg/qffmpegmediaformatinfo.cpp @@ -488,11 +488,17 @@ QAudioFormat QFFmpegMediaFormatInfo::audioFormatFromCodecParameters(AVCodecParam QAudioFormat format; format.setSampleFormat(sampleFormat(AVSampleFormat(codecpar->format))); format.setSampleRate(codecpar->sample_rate); - - auto channelLayout = codecpar->channel_layout; +#if QT_FFMPEG_OLD_CHANNEL_LAYOUT + uint64_t channelLayout = codecpar->channel_layout; if (!channelLayout) channelLayout = avChannelLayout(QAudioFormat::defaultChannelConfigForChannelCount(codecpar->channels)); - +#else + uint64_t channelLayout = 0; + if (codecpar->ch_layout.order == AV_CHANNEL_ORDER_NATIVE) + channelLayout = codecpar->ch_layout.u.mask; + else + channelLayout = avChannelLayout(QAudioFormat::defaultChannelConfigForChannelCount(codecpar->ch_layout.nb_channels)); +#endif format.setChannelConfig(channelConfigForAVLayout(channelLayout)); return format; } diff --git a/src/plugins/multimedia/ffmpeg/qffmpegresampler.cpp b/src/plugins/multimedia/ffmpeg/qffmpegresampler.cpp index 14b2cf899..bb15aa0e1 100644 --- a/src/plugins/multimedia/ffmpeg/qffmpegresampler.cpp +++ b/src/plugins/multimedia/ffmpeg/qffmpegresampler.cpp @@ -31,11 +31,12 @@ Resampler::Resampler(const Codec *codec, const QAudioFormat &outputFormat) if (config == QAudioFormat::ChannelConfigUnknown) config = QAudioFormat::defaultChannelConfigForChannelCount(m_outputFormat.channelCount()); + + qCDebug(qLcResampler) << "init resampler" << m_outputFormat.sampleRate() << config << codecpar->sample_rate; +#if QT_FFMPEG_OLD_CHANNEL_LAYOUT auto inConfig = codecpar->channel_layout; if (inConfig == 0) inConfig = QFFmpegMediaFormatInfo::avChannelLayout(QAudioFormat::defaultChannelConfigForChannelCount(codecpar->channels)); - - qCDebug(qLcResampler) << "init resampler" << m_outputFormat.sampleRate() << config << codecpar->sample_rate; resampler = swr_alloc_set_opts(nullptr, // we're allocating a new context QFFmpegMediaFormatInfo::avChannelLayout(config), // out_ch_layout QFFmpegMediaFormatInfo::avSampleFormat(m_outputFormat.sampleFormat()), // out_sample_fmt @@ -45,7 +46,20 @@ Resampler::Resampler(const Codec *codec, const QAudioFormat &outputFormat) codecpar->sample_rate, // in_sample_rate 0, // log_offset nullptr); - +#else + AVChannelLayout in_ch_layout = codecpar->ch_layout; + AVChannelLayout out_ch_layout = {}; + av_channel_layout_from_mask(&out_ch_layout, QFFmpegMediaFormatInfo::avChannelLayout(config)); + swr_alloc_set_opts2(&resampler, // we're allocating a new context + &out_ch_layout, + QFFmpegMediaFormatInfo::avSampleFormat(m_outputFormat.sampleFormat()), + m_outputFormat.sampleRate(), + &in_ch_layout, + AVSampleFormat(codecpar->format), + codecpar->sample_rate, + 0, + nullptr); +#endif // if we're not the master clock, we might need to handle clock adjustments, initialize for that av_opt_set_double(resampler, "async", m_outputFormat.sampleRate()/50, 0); -- cgit v1.2.3