diff options
author | Artem Dyomin <artem.dyomin@qt.io> | 2024-01-17 19:02:50 +0100 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2024-01-19 18:30:55 +0000 |
commit | a6d342e9f7106a18d2663189d32a7e0b9d1fbfeb (patch) | |
tree | e6f1be0f6a66ea9cbd1f6fc88909ca4a06abe491 | |
parent | cee4a0ea3f71f8004d6991625a63673aade9092f (diff) |
Move creation of ffmpeg audio resampler to utils
The refactoring is needed for the implementation
of QPlatformAudioResampler in the next commits.
Pick-to: 6.5
Task-number: QTBUG-118099
Change-Id: I6372dcba41011717c78bd586adf6c38dba8466d9
Reviewed-by: Lars Knoll <lars@knoll.priv.no>
(cherry picked from commit c2f4dae915b8d341a316739a12c0be81abfb836d)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit d4a863bc813e80b753c7e566646863ad489dc20d)
-rw-r--r-- | src/plugins/multimedia/ffmpeg/qffmpeg.cpp | 67 | ||||
-rw-r--r-- | src/plugins/multimedia/ffmpeg/qffmpeg_p.h | 20 | ||||
-rw-r--r-- | src/plugins/multimedia/ffmpeg/qffmpegresampler.cpp | 45 |
3 files changed, 91 insertions, 41 deletions
diff --git a/src/plugins/multimedia/ffmpeg/qffmpeg.cpp b/src/plugins/multimedia/ffmpeg/qffmpeg.cpp index 73c6c6788..f5b97566a 100644 --- a/src/plugins/multimedia/ffmpeg/qffmpeg.cpp +++ b/src/plugins/multimedia/ffmpeg/qffmpeg.cpp @@ -2,6 +2,8 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "qffmpeg_p.h" +#include "qaudioformat.h" +#include "qffmpegmediaformatinfo_p.h" #include <qdebug.h> #include <qloggingcategory.h> @@ -15,6 +17,7 @@ extern "C" { #include <libavutil/pixdesc.h> #include <libavutil/samplefmt.h> +#include <libavutil/opt.h> #ifdef Q_OS_DARWIN #include <libavutil/hwcontext_videotoolbox.h> @@ -427,6 +430,70 @@ const AVPacketSideData *streamSideData(const AVStream *stream, AVPacketSideDataT #endif } +ResampleAudioFormat::ResampleAudioFormat(const AVCodecParameters* codecPar) + : sampleFormat(AVSampleFormat(codecPar->format)), sampleRate(codecPar->sample_rate) +{ +#if QT_FFMPEG_OLD_CHANNEL_LAYOUT + if (codecPar->channel_layout) { + channelLayoutMask = codecPar->channel_layout; + } + else { + const auto channelConfig = + QAudioFormat::defaultChannelConfigForChannelCount(codecPar->channels); + channelLayoutMask = QFFmpegMediaFormatInfo::avChannelLayout(channelConfig); + } +#else + channelLayout = codecPar->ch_layout; +#endif +} + +ResampleAudioFormat::ResampleAudioFormat(const QAudioFormat& audioFormat) + : sampleFormat(QFFmpegMediaFormatInfo::avSampleFormat(audioFormat.sampleFormat())) + , sampleRate(audioFormat.sampleRate()) +{ + const auto channelConfig = audioFormat.channelConfig() == QAudioFormat::ChannelConfigUnknown ? + QAudioFormat::defaultChannelConfigForChannelCount(audioFormat.channelCount()) : + audioFormat.channelConfig(); + + const auto mask = QFFmpegMediaFormatInfo::avChannelLayout(channelConfig); + +#if QT_FFMPEG_OLD_CHANNEL_LAYOUT + channelLayoutMask = mask; +#else + av_channel_layout_from_mask(&channelLayout, mask); +#endif +} + +SwrContextUPtr createResampleContext(const ResampleAudioFormat& inputFormat, + const ResampleAudioFormat& outputFormat) +{ + SwrContext *resampler = nullptr; +#if QT_FFMPEG_OLD_CHANNEL_LAYOUT + resampler = swr_alloc_set_opts(nullptr, + outputFormat.channelLayoutMask, + outputFormat.sampleFormat, + outputFormat.sampleRate, + inputFormat.channelLayoutMask, + inputFormat.sampleFormat, + inputFormat.sampleRate, + 0, + nullptr); +#else + swr_alloc_set_opts2(&resampler, + &outputFormat.channelLayout, + outputFormat.sampleFormat, + outputFormat.sampleRate, + &inputFormat.channelLayout, + inputFormat.sampleFormat, + inputFormat.sampleRate, + 0, + nullptr); +#endif + + swr_init(resampler); + return SwrContextUPtr(resampler); +} + #ifdef Q_OS_DARWIN bool isCVFormatSupported(uint32_t cvFormat) { diff --git a/src/plugins/multimedia/ffmpeg/qffmpeg_p.h b/src/plugins/multimedia/ffmpeg/qffmpeg_p.h index b4db6e20d..27d5e723c 100644 --- a/src/plugins/multimedia/ffmpeg/qffmpeg_p.h +++ b/src/plugins/multimedia/ffmpeg/qffmpeg_p.h @@ -27,6 +27,8 @@ extern "C" { QT_BEGIN_NAMESPACE +class QAudioFormat; + namespace QFFmpeg { @@ -201,6 +203,24 @@ AVPixelFormat pixelFormatForHwDevice(AVHWDeviceType deviceType); const AVPacketSideData *streamSideData(const AVStream *stream, AVPacketSideDataType type); +struct ResampleAudioFormat +{ + ResampleAudioFormat(const AVCodecParameters* codecPar); + + ResampleAudioFormat(const QAudioFormat& audioFormat); + +#if QT_FFMPEG_OLD_CHANNEL_LAYOUT + uint64_t channelLayoutMask; +#else + AVChannelLayout channelLayout; +#endif + AVSampleFormat sampleFormat; + int sampleRate; +}; + +SwrContextUPtr createResampleContext(const ResampleAudioFormat& inputFormat, + const ResampleAudioFormat& outputFormat); + #ifdef Q_OS_DARWIN bool isCVFormatSupported(uint32_t format); diff --git a/src/plugins/multimedia/ffmpeg/qffmpegresampler.cpp b/src/plugins/multimedia/ffmpeg/qffmpegresampler.cpp index f84aecfbc..c5c277213 100644 --- a/src/plugins/multimedia/ffmpeg/qffmpegresampler.cpp +++ b/src/plugins/multimedia/ffmpeg/qffmpegresampler.cpp @@ -5,10 +5,6 @@ #include "qffmpegmediaformatinfo_p.h" #include <qloggingcategory.h> -extern "C" { -#include <libavutil/opt.h> -} - static Q_LOGGING_CATEGORY(qLcResampler, "qt.multimedia.ffmpeg.resampler") QT_BEGIN_NAMESPACE @@ -19,50 +15,17 @@ namespace QFFmpeg Resampler::Resampler(const Codec *codec, const QAudioFormat &outputFormat) : m_outputFormat(outputFormat) { + Q_ASSERT(codec); + qCDebug(qLcResampler) << "createResampler"; const AVStream *audioStream = codec->stream(); - const auto *codecpar = audioStream->codecpar; if (!m_outputFormat.isValid()) // want the native format m_outputFormat = QFFmpegMediaFormatInfo::audioFormatFromCodecParameters(audioStream->codecpar); - QAudioFormat::ChannelConfig config = m_outputFormat.channelConfig(); - if (config == QAudioFormat::ChannelConfigUnknown) - config = QAudioFormat::defaultChannelConfigForChannelCount(m_outputFormat.channelCount()); - - - qCDebug(qLcResampler) << "init resampler" << m_outputFormat.sampleRate() << config << codecpar->sample_rate; - SwrContext *resampler = nullptr; -#if QT_FFMPEG_OLD_CHANNEL_LAYOUT - auto inConfig = codecpar->channel_layout; - if (inConfig == 0) - inConfig = QFFmpegMediaFormatInfo::avChannelLayout(QAudioFormat::defaultChannelConfigForChannelCount(codecpar->channels)); - 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 - m_outputFormat.sampleRate(), // out_sample_rate - inConfig, // in_ch_layout - AVSampleFormat(codecpar->format), // in_sample_fmt - 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 - swr_init(resampler); - m_resampler.reset(resampler); + m_resampler = createResampleContext(ResampleAudioFormat(audioStream->codecpar), + ResampleAudioFormat(m_outputFormat)); } Resampler::~Resampler() = default; |