summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-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;