diff options
Diffstat (limited to 'src')
-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; |