summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArtem Dyomin <artem.dyomin@qt.io>2024-01-17 19:02:50 +0100
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2024-01-19 18:30:55 +0000
commita6d342e9f7106a18d2663189d32a7e0b9d1fbfeb (patch)
treee6f1be0f6a66ea9cbd1f6fc88909ca4a06abe491
parentcee4a0ea3f71f8004d6991625a63673aade9092f (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.cpp67
-rw-r--r--src/plugins/multimedia/ffmpeg/qffmpeg_p.h20
-rw-r--r--src/plugins/multimedia/ffmpeg/qffmpegresampler.cpp45
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;