summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/multimedia/audio/qaudiodecoder.cpp56
-rw-r--r--src/multimedia/audio/qaudiodecoder.h21
-rw-r--r--src/multimedia/platform/darwin/audio/avfaudiodecoder.mm51
-rw-r--r--src/multimedia/platform/darwin/audio/avfaudiodecoder_p.h10
-rw-r--r--src/multimedia/platform/gstreamer/audio/qgstreameraudiodecoder.cpp53
-rw-r--r--src/multimedia/platform/gstreamer/audio/qgstreameraudiodecoder_p.h11
-rw-r--r--src/multimedia/platform/gstreamer/common/qgstutils.cpp10
-rw-r--r--src/multimedia/platform/gstreamer/common/qgstutils_p.h1
-rw-r--r--src/multimedia/platform/qplatformaudiodecoder.cpp36
-rw-r--r--src/multimedia/platform/qplatformaudiodecoder_p.h16
-rw-r--r--src/multimedia/platform/windows/decoder/mfaudiodecodercontrol.cpp235
-rw-r--r--src/multimedia/platform/windows/decoder/mfaudiodecodercontrol_p.h10
-rw-r--r--src/multimedia/platform/windows/decoder/mfdecodersourcereader.cpp9
-rw-r--r--src/multimedia/platform/windows/decoder/mfdecodersourcereader_p.h2
14 files changed, 93 insertions, 428 deletions
diff --git a/src/multimedia/audio/qaudiodecoder.cpp b/src/multimedia/audio/qaudiodecoder.cpp
index 9c2c3bc36..8b8db59ba 100644
--- a/src/multimedia/audio/qaudiodecoder.cpp
+++ b/src/multimedia/audio/qaudiodecoder.cpp
@@ -89,17 +89,17 @@ QAudioDecoder::~QAudioDecoder() = default;
/*!
Returns true is audio decoding is supported on this platform.
*/
-bool QAudioDecoder::isAvailable() const
+bool QAudioDecoder::isSupported() const
{
return decoder != nullptr;
}
/*!
- Returns the current state of the audio decoder.
+ Returns true if the decoder is currently running and decoding audio data.
*/
-QAudioDecoder::State QAudioDecoder::state() const
+bool QAudioDecoder::isDecoding() const
{
- return decoder ? decoder->state() : QAudioDecoder::StoppedState;
+ return decoder && decoder->isDecoding();
}
/*!
@@ -151,8 +151,10 @@ void QAudioDecoder::start()
*/
void QAudioDecoder::stop()
{
- if (decoder != nullptr)
- decoder->stop();
+ if (!decoder)
+ return;
+
+ decoder->stop();
}
/*!
@@ -207,47 +209,9 @@ QIODevice *QAudioDecoder::sourceDevice() const
*/
void QAudioDecoder::setSourceDevice(QIODevice *device)
{
- if (decoder != nullptr)
- decoder->setSourceDevice(device);
-}
-
-/*!
- Returns the current audio format of the decoded stream.
-
- Any buffers returned should have this format.
-
- \sa setAudioFormat(), formatChanged()
-*/
-QAudioFormat QAudioDecoder::audioFormat() const
-{
- if (decoder)
- return decoder->audioFormat();
- return QAudioFormat();
-}
-
-/*!
- Set the desired audio format for decoded samples to \a format.
-
- This property can only be set while the decoder is stopped.
- Setting this property at other times will be ignored.
-
- If the decoder does not support this format, \l error() will
- be set to \c FormatError.
-
- If you do not specify a format, the format of the decoded
- audio itself will be used. Otherwise, some format conversion
- will be applied.
-
- If you wish to reset the decoded format to that of the original
- audio file, you can specify an invalid \a format.
-*/
-void QAudioDecoder::setAudioFormat(const QAudioFormat &format)
-{
- if (state() != QAudioDecoder::StoppedState)
+ if (!decoder)
return;
-
- if (decoder != nullptr)
- decoder->setAudioFormat(format);
+ decoder->setSourceDevice(device);
}
/*!
diff --git a/src/multimedia/audio/qaudiodecoder.h b/src/multimedia/audio/qaudiodecoder.h
index 9dd257cc9..465bb3974 100644
--- a/src/multimedia/audio/qaudiodecoder.h
+++ b/src/multimedia/audio/qaudiodecoder.h
@@ -52,18 +52,11 @@ class Q_MULTIMEDIA_EXPORT QAudioDecoder : public QObject
{
Q_OBJECT
Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged)
- Q_PROPERTY(State state READ state NOTIFY stateChanged)
+ Q_PROPERTY(bool isDecoding READ isDecoding NOTIFY isDecodingChanged)
Q_PROPERTY(QString error READ errorString)
Q_PROPERTY(bool bufferAvailable READ bufferAvailable NOTIFY bufferAvailableChanged)
public:
- enum State
- {
- StoppedState,
- DecodingState
- };
- Q_ENUM(State)
-
enum Error
{
NoError,
@@ -77,8 +70,8 @@ public:
explicit QAudioDecoder(QObject *parent = nullptr);
~QAudioDecoder();
- bool isAvailable() const;
- State state() const;
+ bool isSupported() const;
+ bool isDecoding() const;
QUrl source() const;
void setSource(const QUrl &fileName);
@@ -86,9 +79,6 @@ public:
QIODevice* sourceDevice() const;
void setSourceDevice(QIODevice *device);
- QAudioFormat audioFormat() const;
- void setAudioFormat(const QAudioFormat &format);
-
Error error() const;
QString errorString() const;
@@ -106,9 +96,7 @@ Q_SIGNALS:
void bufferAvailableChanged(bool);
void bufferReady();
void finished();
-
- void stateChanged(QAudioDecoder::State newState);
- void formatChanged(const QAudioFormat &format);
+ void isDecodingChanged(bool);
void error(QAudioDecoder::Error error);
@@ -124,7 +112,6 @@ private:
QT_END_NAMESPACE
-Q_MEDIA_ENUM_DEBUG(QAudioDecoder, State)
Q_MEDIA_ENUM_DEBUG(QAudioDecoder, Error)
#endif // QAUDIODECODER_H
diff --git a/src/multimedia/platform/darwin/audio/avfaudiodecoder.mm b/src/multimedia/platform/darwin/audio/avfaudiodecoder.mm
index 2ff872212..ecea99f74 100644
--- a/src/multimedia/platform/darwin/audio/avfaudiodecoder.mm
+++ b/src/multimedia/platform/darwin/audio/avfaudiodecoder.mm
@@ -90,7 +90,7 @@ QT_USE_NAMESPACE
return;
const AudioStreamBasicDescription* const asbd = CMAudioFormatDescriptionGetStreamBasicDescription(formatDescription);
QAudioFormat qtFormat = CoreAudioUtils::toQAudioFormat(*asbd);
- if (!qtFormat.isValid() || qtFormat != m_decoder->audioFormat())
+ if (!qtFormat.isValid())
return;
// Get the required size to allocate to audioBufferList
@@ -314,7 +314,7 @@ void AVFAudioDecoder::setSourceDevice(QIODevice *device)
void AVFAudioDecoder::start()
{
Q_ASSERT(!m_buffersAvailable);
- if (m_state != QAudioDecoder::StoppedState)
+ if (isDecoding())
return;
if (m_position != -1) {
@@ -348,16 +348,13 @@ void AVFAudioDecoder::start()
];
if (m_device && m_loadingSource) {
- m_state = QAudioDecoder::DecodingState;
- emit stateChanged(m_state);
+ setIsDecoding(true);
return;
}
}
void AVFAudioDecoder::stop()
{
- QAudioDecoder::State oldState = m_state;
- m_state = QAudioDecoder::StoppedState;
if (m_asset)
[m_asset cancelLoading];
if (m_reader)
@@ -375,21 +372,7 @@ void AVFAudioDecoder::stop()
m_duration = -1;
emit durationChanged(m_duration);
}
- if (m_state != oldState)
- emit stateChanged(m_state);
-}
-
-QAudioFormat AVFAudioDecoder::audioFormat() const
-{
- return m_format;
-}
-
-void AVFAudioDecoder::setAudioFormat(const QAudioFormat &format)
-{
- if (m_format != format) {
- m_format = format;
- emit formatChanged(m_format);
- }
+ setIsDecoding(false);
}
QAudioBuffer AVFAudioDecoder::read()
@@ -444,18 +427,10 @@ void AVFAudioDecoder::initAssetReader()
// Set format
QAudioFormat format;
- if (m_format.isValid()) {
- format = m_format;
- } else {
- format = qt_format_for_audio_track(track);
- if (!format.isValid())
- {
- processInvalidMedia(QAudioDecoder::FormatError, tr("Unsupported source format"));
- return;
- }
- // ### Change QAudioDecoder's format to resolved one?
- m_format = format;
- emit formatChanged(m_format);
+ format = qt_format_for_audio_track(track);
+ if (!format.isValid()) {
+ processInvalidMedia(QAudioDecoder::FormatError, tr("Unsupported source format"));
+ return;
}
// Set duration
@@ -498,10 +473,7 @@ void AVFAudioDecoder::startReading()
return;
}
- QAudioDecoder::State oldState = m_state;
- m_state = QAudioDecoder::DecodingState;
- if (oldState != m_state)
- emit stateChanged(m_state);
+ setIsDecoding(true);
// Since copyNextSampleBuffer is synchronous, submit it to an async dispatch queue
// to run in a separate thread. Call the handleNextSampleBuffer "callback" on another
@@ -515,11 +487,8 @@ void AVFAudioDecoder::startReading()
CFRelease(sampleBuffer);
});
}
- if (m_reader.status == AVAssetReaderStatusCompleted) {
- m_state = QAudioDecoder::StoppedState;
+ if (m_reader.status == AVAssetReaderStatusCompleted)
emit finished();
- emit stateChanged(m_state);
- }
});
}
diff --git a/src/multimedia/platform/darwin/audio/avfaudiodecoder_p.h b/src/multimedia/platform/darwin/audio/avfaudiodecoder_p.h
index 9f302cc39..5348b06fd 100644
--- a/src/multimedia/platform/darwin/audio/avfaudiodecoder_p.h
+++ b/src/multimedia/platform/darwin/audio/avfaudiodecoder_p.h
@@ -75,9 +75,6 @@ public:
AVFAudioDecoder(QAudioDecoder *parent);
virtual ~AVFAudioDecoder();
- // QAudioDecoder interface
- QAudioDecoder::State state() const override { return m_state; }
-
QUrl source() const override;
void setSource(const QUrl &fileName) override;
@@ -87,9 +84,6 @@ public:
void start() override;
void stop() override;
- QAudioFormat audioFormat() const override;
- void setAudioFormat(const QAudioFormat &format) override;
-
QAudioBuffer read() override;
bool bufferAvailable() const override;
@@ -108,12 +102,8 @@ private:
void processInvalidMedia(QAudioDecoder::Error errorCode, const QString& errorString);
void initAssetReader();
- QAudioDecoder::State m_state = QAudioDecoder::StoppedState;
- QAudioDecoder::State m_pendingState = QAudioDecoder::StoppedState;
-
QUrl m_source;
QIODevice *m_device = nullptr;
- QAudioFormat m_format;
int m_buffersAvailable = 0;
QList<QAudioBuffer> m_cachedBuffers;
diff --git a/src/multimedia/platform/gstreamer/audio/qgstreameraudiodecoder.cpp b/src/multimedia/platform/gstreamer/audio/qgstreameraudiodecoder.cpp
index 817e168bf..db23ac80f 100644
--- a/src/multimedia/platform/gstreamer/audio/qgstreameraudiodecoder.cpp
+++ b/src/multimedia/platform/gstreamer/audio/qgstreameraudiodecoder.cpp
@@ -163,21 +163,17 @@ bool QGstreamerAudioDecoder::processBusMessage(const QGstreamerMessage &message)
.arg(states[pending]) << "internal" << m_state;
#endif
- QAudioDecoder::State prevState = m_state;
-
+ bool isDecoding = false;
switch (newState) {
case GST_STATE_VOID_PENDING:
case GST_STATE_NULL:
- m_state = QAudioDecoder::StoppedState;
- break;
case GST_STATE_READY:
- m_state = QAudioDecoder::StoppedState;
break;
case GST_STATE_PLAYING:
- m_state = QAudioDecoder::DecodingState;
+ isDecoding = true;
break;
case GST_STATE_PAUSED:
- m_state = QAudioDecoder::DecodingState;
+ isDecoding = true;
//gstreamer doesn't give a reliable indication the duration
//information is ready, GST_MESSAGE_DURATION is not sent by most elements
@@ -187,15 +183,12 @@ bool QGstreamerAudioDecoder::processBusMessage(const QGstreamerMessage &message)
break;
}
- if (prevState != m_state)
- emit stateChanged(m_state);
+ setIsDecoding(isDecoding);
}
break;
case GST_MESSAGE_EOS:
- m_pendingState = m_state = QAudioDecoder::StoppedState;
- emit finished();
- emit stateChanged(m_state);
+ finished();
break;
case GST_MESSAGE_ERROR: {
@@ -338,24 +331,15 @@ void QGstreamerAudioDecoder::start()
// Set audio format
if (m_appSink) {
- if (mFormat.isValid()) {
- setAudioFlags(false);
- QGstMutableCaps caps = QGstUtils::capsForAudioFormat(mFormat);
- gst_app_sink_set_caps(m_appSink, caps.get());
- } else {
- // We want whatever the native audio format is
- setAudioFlags(true);
- gst_app_sink_set_caps(m_appSink, nullptr);
- }
+ // We want whatever the native audio format is
+ setAudioFlags(true);
+ gst_app_sink_set_caps(m_appSink, nullptr);
}
- m_pendingState = QAudioDecoder::DecodingState;
if (m_playbin.setState(GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) {
qWarning() << "GStreamer; Unable to start decoding process";
m_playbin.dumpGraph("failed");
- m_pendingState = m_state = QAudioDecoder::StoppedState;
-
- emit stateChanged(m_state);
+ return;
}
}
@@ -367,9 +351,6 @@ void QGstreamerAudioDecoder::stop()
m_playbin.setState(GST_STATE_NULL);
removeAppSink();
- QAudioDecoder::State oldState = m_state;
- m_pendingState = m_state = QAudioDecoder::StoppedState;
-
// GStreamer thread is stopped. Can safely access m_buffersAvailable
if (m_buffersAvailable != 0) {
m_buffersAvailable = 0;
@@ -386,21 +367,7 @@ void QGstreamerAudioDecoder::stop()
emit durationChanged(m_duration);
}
- if (oldState != m_state)
- emit stateChanged(m_state);
-}
-
-QAudioFormat QGstreamerAudioDecoder::audioFormat() const
-{
- return mFormat;
-}
-
-void QGstreamerAudioDecoder::setAudioFormat(const QAudioFormat &format)
-{
- if (mFormat != format) {
- mFormat = format;
- emit formatChanged(mFormat);
- }
+ setIsDecoding(false);
}
QAudioBuffer QGstreamerAudioDecoder::read()
diff --git a/src/multimedia/platform/gstreamer/audio/qgstreameraudiodecoder_p.h b/src/multimedia/platform/gstreamer/audio/qgstreameraudiodecoder_p.h
index be2343916..de9d59baf 100644
--- a/src/multimedia/platform/gstreamer/audio/qgstreameraudiodecoder_p.h
+++ b/src/multimedia/platform/gstreamer/audio/qgstreameraudiodecoder_p.h
@@ -81,9 +81,6 @@ public:
QGstreamerAudioDecoder(QAudioDecoder *parent);
virtual ~QGstreamerAudioDecoder();
- // QAudioDecoder interface
- QAudioDecoder::State state() const override { return m_state; }
-
QUrl source() const override;
void setSource(const QUrl &fileName) override;
@@ -93,9 +90,6 @@ public:
void start() override;
void stop() override;
- QAudioFormat audioFormat() const override;
- void setAudioFormat(const QAudioFormat &format) override;
-
QAudioBuffer read() override;
bool bufferAvailable() const override;
@@ -105,8 +99,6 @@ public:
// GStreamerBusMessageFilter interface
bool processBusMessage(const QGstreamerMessage &message) override;
- QAudioDecoder::State pendingState() const { return m_pendingState; }
-
#if QT_CONFIG(gstreamer_app)
QGstAppSrc *appsrc() const { return m_appSrc; }
static void configureAppSrcElement(GObject*, GObject*, GParamSpec*, QGstreamerAudioDecoder *_this);
@@ -125,8 +117,6 @@ private:
void processInvalidMedia(QAudioDecoder::Error errorCode, const QString& errorString);
static qint64 getPositionFromBuffer(GstBuffer* buffer);
- QAudioDecoder::State m_state = QAudioDecoder::StoppedState;
- QAudioDecoder::State m_pendingState = QAudioDecoder::StoppedState;
QGstPipeline m_playbin;
QGstBin m_outputBin;
QGstElement m_audioConvert;
@@ -135,7 +125,6 @@ private:
QUrl mSource;
QIODevice *mDevice = nullptr;
- QAudioFormat mFormat;
mutable QMutex m_buffersMutex;
int m_buffersAvailable = 0;
diff --git a/src/multimedia/platform/gstreamer/common/qgstutils.cpp b/src/multimedia/platform/gstreamer/common/qgstutils.cpp
index 7dd733f00..5d88f7e13 100644
--- a/src/multimedia/platform/gstreamer/common/qgstutils.cpp
+++ b/src/multimedia/platform/gstreamer/common/qgstutils.cpp
@@ -100,12 +100,16 @@ static QAudioFormat::SampleFormat gstSampleFormatToSampleFormat(const char *fmt)
*/
QAudioFormat QGstUtils::audioFormatForSample(GstSample *sample)
{
- GstCaps* caps = gst_sample_get_caps(sample);
- if (!caps)
+ QGstCaps caps = gst_sample_get_caps(sample);
+ if (caps.isNull())
return QAudioFormat();
+ return audioFormatForCaps(caps);
+}
+QAudioFormat QGstUtils::audioFormatForCaps(QGstCaps caps)
+{
QAudioFormat format;
- QGstStructure s = QGstCaps(caps).at(0);
+ QGstStructure s = caps.at(0);
if (s.name() != "audio/x-raw")
return format;
diff --git a/src/multimedia/platform/gstreamer/common/qgstutils_p.h b/src/multimedia/platform/gstreamer/common/qgstutils_p.h
index 651152950..0e6e76954 100644
--- a/src/multimedia/platform/gstreamer/common/qgstutils_p.h
+++ b/src/multimedia/platform/gstreamer/common/qgstutils_p.h
@@ -72,6 +72,7 @@ class QVideoFrameFormat;
namespace QGstUtils {
Q_MULTIMEDIA_EXPORT QAudioFormat audioFormatForSample(GstSample *sample);
+ QAudioFormat audioFormatForCaps(QGstCaps caps);
Q_MULTIMEDIA_EXPORT QGstMutableCaps capsForAudioFormat(const QAudioFormat &format);
Q_MULTIMEDIA_EXPORT QVideoFrameFormat formatForCaps(
diff --git a/src/multimedia/platform/qplatformaudiodecoder.cpp b/src/multimedia/platform/qplatformaudiodecoder.cpp
index b7da0a304..817e0656f 100644
--- a/src/multimedia/platform/qplatformaudiodecoder.cpp
+++ b/src/multimedia/platform/qplatformaudiodecoder.cpp
@@ -67,28 +67,6 @@ QPlatformAudioDecoder::QPlatformAudioDecoder(QAudioDecoder *parent)
}
/*!
- \fn QPlatformAudioDecoder::state() const
-
- Returns the state of a player control.
-*/
-
-void QPlatformAudioDecoder::stateChanged(QAudioDecoder::State newState)
-{
- if (m_state == newState)
- return;
- m_state = newState;
- emit q->stateChanged(newState);
-}
-
-/*!
- \fn QPlatformAudioDecoder::stateChanged(QAudioDecoder::State newState)
-
- Signals that the state of a player control has changed to \a newState.
-
- \sa state()
-*/
-
-/*!
\fn QPlatformAudioDecoder::source() const
Returns the current media source filename, or a null QString if none (or a device)
@@ -150,6 +128,7 @@ void QPlatformAudioDecoder::error(int error, const QString &errorString)
return;
m_error = QAudioDecoder::Error(error);
m_errorString = errorString;
+ setIsDecoding(false);
emit q->error(m_error);
}
@@ -193,18 +172,6 @@ void QPlatformAudioDecoder::sourceChanged()
}
/*!
- \fn QPlatformAudioDecoder::formatChanged(const QAudioFormat &format)
-
- Signals that the current audio format of the decoder has changed to \a format.
-
- \sa audioFormat(), setAudioFormat()
-*/
-void QPlatformAudioDecoder::formatChanged(const QAudioFormat &format)
-{
- emit q->formatChanged(format);
-}
-
-/*!
\fn void QPlatformAudioDecoder::finished()
Signals that the decoding has finished successfully.
@@ -214,6 +181,7 @@ void QPlatformAudioDecoder::formatChanged(const QAudioFormat &format)
*/
void QPlatformAudioDecoder::finished()
{
+ setIsDecoding(false);
emit q->finished();
}
diff --git a/src/multimedia/platform/qplatformaudiodecoder_p.h b/src/multimedia/platform/qplatformaudiodecoder_p.h
index 91877e647..e097b79fa 100644
--- a/src/multimedia/platform/qplatformaudiodecoder_p.h
+++ b/src/multimedia/platform/qplatformaudiodecoder_p.h
@@ -66,8 +66,6 @@ class Q_MULTIMEDIA_EXPORT QPlatformAudioDecoder : public QObject
Q_OBJECT
public:
- virtual QAudioDecoder::State state() const { return m_state; }
-
virtual QUrl source() const = 0;
virtual void setSource(const QUrl &fileName) = 0;
@@ -77,17 +75,12 @@ public:
virtual void start() = 0;
virtual void stop() = 0;
- virtual QAudioFormat audioFormat() const = 0;
- virtual void setAudioFormat(const QAudioFormat &format) = 0;
-
virtual QAudioBuffer read() = 0;
virtual bool bufferAvailable() const = 0;
virtual qint64 position() const = 0;
virtual qint64 duration() const = 0;
- void stateChanged(QAudioDecoder::State newState);
- void formatChanged(const QAudioFormat &format);
void sourceChanged();
void error(int error, const QString &errorString);
@@ -95,7 +88,14 @@ public:
void bufferReady();
void bufferAvailableChanged(bool available);
+ void setIsDecoding(bool running = true) {
+ if (m_isDecoding == running)
+ return;
+ m_isDecoding = running;
+ emit q->isDecodingChanged(m_isDecoding);
+ }
void finished();
+ bool isDecoding() const { return m_isDecoding; }
void positionChanged(qint64 position);
void durationChanged(qint64 duration);
@@ -108,9 +108,9 @@ protected:
private:
QAudioDecoder *q = nullptr;
- QAudioDecoder::State m_state = QAudioDecoder::StoppedState;
QAudioDecoder::Error m_error = QAudioDecoder::NoError;
QString m_errorString;
+ bool m_isDecoding = false;
};
QT_END_NAMESPACE
diff --git a/src/multimedia/platform/windows/decoder/mfaudiodecodercontrol.cpp b/src/multimedia/platform/windows/decoder/mfaudiodecodercontrol.cpp
index 953281f31..7a460533d 100644
--- a/src/multimedia/platform/windows/decoder/mfaudiodecodercontrol.cpp
+++ b/src/multimedia/platform/windows/decoder/mfaudiodecodercontrol.cpp
@@ -44,8 +44,6 @@ MFAudioDecoderControl::MFAudioDecoderControl(QAudioDecoder *parent)
: QPlatformAudioDecoder(parent)
, m_decoderSourceReader(new MFDecoderSourceReader)
, m_sourceResolver(new SourceResolver)
- , m_resampler(0)
- , m_state(QAudioDecoder::StoppedState)
, m_device(0)
, m_mfInputStreamID(0)
, m_mfOutputStreamID(0)
@@ -56,21 +54,10 @@ MFAudioDecoderControl::MFAudioDecoderControl(QAudioDecoder *parent)
, m_mfOutputType(0)
, m_convertSample(0)
, m_sourceReady(false)
- , m_resamplerDirty(false)
{
- CoCreateInstance(CLSID_CResamplerMediaObject, NULL, CLSCTX_INPROC_SERVER, IID_IMFTransform, (LPVOID*)(&m_resampler));
- if (!m_resampler) {
- qCritical("MFAudioDecoderControl: Failed to create resampler(CLSID_CResamplerMediaObject)!");
- return;
- }
- m_resampler->AddInputStreams(1, &m_mfInputStreamID);
-
connect(m_sourceResolver, SIGNAL(mediaSourceReady()), this, SLOT(handleMediaSourceReady()));
connect(m_sourceResolver, SIGNAL(error(long)), this, SLOT(handleMediaSourceError(long)));
connect(m_decoderSourceReader, SIGNAL(finished()), this, SLOT(handleSourceFinished()));
-
- QAudioFormat defaultFormat;
- setAudioFormat(defaultFormat);
}
MFAudioDecoderControl::~MFAudioDecoderControl()
@@ -80,13 +67,6 @@ MFAudioDecoderControl::~MFAudioDecoderControl()
m_decoderSourceReader->shutdown();
m_decoderSourceReader->Release();
m_sourceResolver->Release();
- if (m_resampler)
- m_resampler->Release();
-}
-
-QAudioDecoder::State MFAudioDecoderControl::state() const
-{
- return m_state;
}
QUrl MFAudioDecoderControl::source() const
@@ -107,9 +87,9 @@ void MFAudioDecoderControl::onSourceCleared()
durationDirty = true;
}
if (positionDirty)
- emit positionChanged(m_position);
+ positionChanged(m_position);
if (durationDirty)
- emit durationChanged(m_duration);
+ durationChanged(m_duration);
}
void MFAudioDecoderControl::setSource(const QUrl &fileName)
@@ -118,7 +98,7 @@ void MFAudioDecoderControl::setSource(const QUrl &fileName)
return;
m_sourceReady = false;
m_sourceResolver->cancel();
- m_decoderSourceReader->setSource(0, m_audioFormat);
+ m_decoderSourceReader->setSource(nullptr);
m_device = 0;
m_source = fileName;
if (!m_source.isEmpty()) {
@@ -128,7 +108,7 @@ void MFAudioDecoderControl::setSource(const QUrl &fileName)
} else {
onSourceCleared();
}
- emit sourceChanged();
+ sourceChanged();
}
QIODevice* MFAudioDecoderControl::sourceDevice() const
@@ -142,7 +122,7 @@ void MFAudioDecoderControl::setSourceDevice(QIODevice *device)
return;
m_sourceReady = false;
m_sourceResolver->cancel();
- m_decoderSourceReader->setSource(0, m_audioFormat);
+ m_decoderSourceReader->setSource(nullptr);
m_source.clear();
m_device = device;
if (m_device) {
@@ -152,48 +132,17 @@ void MFAudioDecoderControl::setSourceDevice(QIODevice *device)
} else {
onSourceCleared();
}
- emit sourceChanged();
-}
-
-void MFAudioDecoderControl::updateResamplerOutputType()
-{
- m_resamplerDirty = false;
- if (m_audioFormat == m_sourceOutputFormat)
- return;
- HRESULT hr = m_resampler->SetOutputType(m_mfOutputStreamID, m_mfOutputType, 0);
- if (SUCCEEDED(hr)) {
- MFT_OUTPUT_STREAM_INFO streamInfo;
- m_resampler->GetOutputStreamInfo(m_mfOutputStreamID, &streamInfo);
- if ((streamInfo.dwFlags & (MFT_OUTPUT_STREAM_PROVIDES_SAMPLES | MFT_OUTPUT_STREAM_CAN_PROVIDE_SAMPLES)) == 0) {
- //if resampler does not allocate output sample memory, we do it here
- if (m_convertSample) {
- m_convertSample->Release();
- m_convertSample = 0;
- }
- if (SUCCEEDED(MFCreateSample(&m_convertSample))) {
- IMFMediaBuffer *mbuf = 0;;
- if (SUCCEEDED(MFCreateMemoryBuffer(streamInfo.cbSize, &mbuf))) {
- m_convertSample->AddBuffer(mbuf);
- mbuf->Release();
- }
- }
- }
- } else {
- qWarning() << "MFAudioDecoderControl: failed to SetOutputType of resampler" << hr;
- }
+ sourceChanged();
}
void MFAudioDecoderControl::handleMediaSourceReady()
{
m_loadingSource = false;
m_sourceReady = true;
- IMFMediaType *mediaType = m_decoderSourceReader->setSource(m_sourceResolver->mediaSource(), m_audioFormat);
+ IMFMediaType *mediaType = m_decoderSourceReader->setSource(m_sourceResolver->mediaSource());
m_sourceOutputFormat = QAudioFormat();
if (mediaType) {
- m_sourceOutputFormat = m_audioFormat;
- QAudioFormat af = m_audioFormat;
-
UINT32 val = 0;
if (SUCCEEDED(mediaType->GetUINT32(MF_MT_AUDIO_NUM_CHANNELS, &val))) {
m_sourceOutputFormat.setChannelCount(int(val));
@@ -210,30 +159,15 @@ void MFAudioDecoderControl::handleMediaSourceReady()
m_sourceOutputFormat.setSampleFormat(QAudioFormat::Float);
} else if (bitsPerSample == 8) {
m_sourceOutputFormat.setSampleFormat(QAudioFormat::UInt8);
- } else {
+ } else if (bitsPerSample == 16) {
m_sourceOutputFormat.setSampleFormat(QAudioFormat::Int16);
+ } else if (bitsPerSample == 32){
+ m_sourceOutputFormat.setSampleFormat(QAudioFormat::Int32);
}
}
-
- if (m_audioFormat.channelCount() <= 0) {
- af.setChannelCount(m_sourceOutputFormat.channelCount());
- }
- if (m_audioFormat.sampleRate() <= 0) {
- af.setSampleRate(m_sourceOutputFormat.sampleRate());
- }
- setAudioFormat(af);
}
if (m_sourceResolver->mediaSource()) {
- if (mediaType && m_resampler) {
- HRESULT hr = S_OK;
- hr = m_resampler->SetInputType(m_mfInputStreamID, mediaType, 0);
- if (SUCCEEDED(hr)) {
- updateResamplerOutputType();
- } else {
- qWarning() << "MFAudioDecoderControl: failed to SetInputType of resampler" << hr;
- }
- }
IMFPresentationDescriptor *pd;
if (SUCCEEDED(m_sourceResolver->mediaSource()->CreatePresentationDescriptor(&pd))) {
UINT64 duration = 0;
@@ -242,15 +176,14 @@ void MFAudioDecoderControl::handleMediaSourceReady()
duration /= 10000;
if (m_duration != qint64(duration)) {
m_duration = qint64(duration);
- emit durationChanged(m_duration);
+ durationChanged(m_duration);
}
}
- if (m_state == QAudioDecoder::DecodingState) {
+ if (isDecoding()) {
activatePipeline();
}
- } else if (m_state != QAudioDecoder::StoppedState) {
- m_state = QAudioDecoder::StoppedState;
- emit stateChanged(m_state);
+ } else if (isDecoding()) {
+ setIsDecoding(false);
}
}
@@ -258,58 +191,49 @@ void MFAudioDecoderControl::handleMediaSourceError(long hr)
{
Q_UNUSED(hr);
m_loadingSource = false;
- m_decoderSourceReader->setSource(0, m_audioFormat);
- if (m_state != QAudioDecoder::StoppedState) {
- m_state = QAudioDecoder::StoppedState;
- emit stateChanged(m_state);
- }
+ m_decoderSourceReader->setSource(nullptr);
+ setIsDecoding(false);
}
void MFAudioDecoderControl::activatePipeline()
{
Q_ASSERT(!m_bufferReady);
- m_state = QAudioDecoder::DecodingState;
+ setIsDecoding(true);
connect(m_decoderSourceReader, SIGNAL(sampleAdded()), this, SLOT(handleSampleAdded()));
- if (m_resamplerDirty) {
- updateResamplerOutputType();
- }
m_decoderSourceReader->reset();
m_decoderSourceReader->readNextSample();
if (m_position != 0) {
m_position = 0;
- emit positionChanged(0);
+ positionChanged(0);
}
}
void MFAudioDecoderControl::start()
{
- if (m_state != QAudioDecoder::StoppedState)
+ if (isDecoding())
return;
if (m_loadingSource) {
//deferred starting
- m_state = QAudioDecoder::DecodingState;
- emit stateChanged(m_state);
+ setIsDecoding(true);
return;
}
if (!m_decoderSourceReader->mediaSource())
return;
activatePipeline();
- emit stateChanged(m_state);
}
void MFAudioDecoderControl::stop()
{
- if (m_state == QAudioDecoder::StoppedState)
+ if (!isDecoding())
return;
- m_state = QAudioDecoder::StoppedState;
disconnect(m_decoderSourceReader, SIGNAL(sampleAdded()), this, SLOT(handleSampleAdded()));
if (m_bufferReady) {
m_bufferReady = false;
emit bufferAvailableChanged(m_bufferReady);
}
- emit stateChanged(m_state);
+ setIsDecoding(false);
}
void MFAudioDecoderControl::handleSampleAdded()
@@ -317,64 +241,29 @@ void MFAudioDecoderControl::handleSampleAdded()
QList<IMFSample*> samples = m_decoderSourceReader->takeSamples();
Q_ASSERT(samples.count() > 0);
Q_ASSERT(!m_bufferReady);
- Q_ASSERT(m_resampler);
LONGLONG sampleStartTime = 0;
IMFSample *firstSample = samples.first();
firstSample->GetSampleTime(&sampleStartTime);
QByteArray abuf;
- if (m_sourceOutputFormat == m_audioFormat) {
- //no need for resampling
- for (IMFSample *s : qAsConst(samples)) {
- IMFMediaBuffer *buffer;
- s->ConvertToContiguousBuffer(&buffer);
- DWORD bufLen = 0;
- BYTE *buf = 0;
- if (SUCCEEDED(buffer->Lock(&buf, NULL, &bufLen))) {
- abuf.push_back(QByteArray(reinterpret_cast<char*>(buf), bufLen));
- buffer->Unlock();
- }
- buffer->Release();
- LONGLONG sampleTime = 0, sampleDuration = 0;
- s->GetSampleTime(&sampleTime);
- s->GetSampleDuration(&sampleDuration);
- m_position = qint64(sampleTime + sampleDuration) / 10000;
- s->Release();
- }
- } else {
- for (IMFSample *s : qAsConst(samples)) {
- HRESULT hr = m_resampler->ProcessInput(m_mfInputStreamID, s, 0);
- if (SUCCEEDED(hr)) {
- MFT_OUTPUT_DATA_BUFFER outputDataBuffer;
- outputDataBuffer.dwStreamID = m_mfOutputStreamID;
- while (true) {
- outputDataBuffer.pEvents = 0;
- outputDataBuffer.dwStatus = 0;
- outputDataBuffer.pSample = m_convertSample;
- DWORD status = 0;
- if (SUCCEEDED(m_resampler->ProcessOutput(0, 1, &outputDataBuffer, &status))) {
- IMFMediaBuffer *buffer;
- outputDataBuffer.pSample->ConvertToContiguousBuffer(&buffer);
- DWORD bufLen = 0;
- BYTE *buf = 0;
- if (SUCCEEDED(buffer->Lock(&buf, NULL, &bufLen))) {
- abuf.push_back(QByteArray(reinterpret_cast<char*>(buf), bufLen));
- buffer->Unlock();
- }
- buffer->Release();
- } else {
- break;
- }
- }
- }
- LONGLONG sampleTime = 0, sampleDuration = 0;
- s->GetSampleTime(&sampleTime);
- s->GetSampleDuration(&sampleDuration);
- m_position = qint64(sampleTime + sampleDuration) / 10000;
- s->Release();
+ for (IMFSample *s : qAsConst(samples)) {
+ IMFMediaBuffer *buffer;
+ s->ConvertToContiguousBuffer(&buffer);
+ DWORD bufLen = 0;
+ BYTE *buf = 0;
+ if (SUCCEEDED(buffer->Lock(&buf, NULL, &bufLen))) {
+ abuf.push_back(QByteArray(reinterpret_cast<char*>(buf), bufLen));
+ buffer->Unlock();
}
+ buffer->Release();
+ LONGLONG sampleTime = 0, sampleDuration = 0;
+ s->GetSampleTime(&sampleTime);
+ s->GetSampleDuration(&sampleDuration);
+ m_position = qint64(sampleTime + sampleDuration) / 10000;
+ s->Release();
}
+
// WMF uses 100-nanosecond units, QAudioDecoder uses milliseconds, QAudioBuffer uses microseconds...
- m_cachedAudioBuffer = QAudioBuffer(abuf, m_audioFormat, qint64(sampleStartTime / 10));
+ m_cachedAudioBuffer = QAudioBuffer(abuf, m_sourceOutputFormat, qint64(sampleStartTime / 10));
m_bufferReady = true;
emit positionChanged(m_position);
emit bufferAvailableChanged(m_bufferReady);
@@ -387,54 +276,6 @@ void MFAudioDecoderControl::handleSourceFinished()
emit finished();
}
-QAudioFormat MFAudioDecoderControl::audioFormat() const
-{
- return m_audioFormat;
-}
-
-void MFAudioDecoderControl::setAudioFormat(const QAudioFormat &format)
-{
- if (m_audioFormat == format || !m_resampler)
- return;
- m_audioFormat = format;
-
- if (m_audioFormat.isValid()) {
- IMFMediaType *mediaType = 0;
- MFCreateMediaType(&mediaType);
- mediaType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio);
- if (format.sampleFormat() == QAudioFormat::Float) {
- mediaType->SetGUID(MF_MT_SUBTYPE, MFAudioFormat_Float);
- } else {
- mediaType->SetGUID(MF_MT_SUBTYPE, MFAudioFormat_PCM);
- }
-
- mediaType->SetUINT32(MF_MT_AUDIO_NUM_CHANNELS, UINT32(m_audioFormat.channelCount()));
- mediaType->SetUINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, UINT32(m_audioFormat.sampleRate()));
- UINT32 alignmentBlock = UINT32(m_audioFormat.bytesPerFrame());
- mediaType->SetUINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT, alignmentBlock);
- UINT32 avgBytesPerSec = UINT32(m_audioFormat.sampleRate() * m_audioFormat.bytesPerFrame());
- mediaType->SetUINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND, avgBytesPerSec);
- mediaType->SetUINT32(MF_MT_AUDIO_BITS_PER_SAMPLE, UINT32(m_audioFormat.bytesPerSample()*8));
- mediaType->SetUINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE);
-
- if (m_mfOutputType)
- m_mfOutputType->Release();
- m_mfOutputType = mediaType;
- } else {
- if (m_mfOutputType)
- m_mfOutputType->Release();
- m_mfOutputType = NULL;
- }
-
- if (m_sourceReady && m_state == QAudioDecoder::StoppedState) {
- updateResamplerOutputType();
- } else {
- m_resamplerDirty = true;
- }
-
- emit formatChanged(m_audioFormat);
-}
-
QAudioBuffer MFAudioDecoderControl::read()
{
if (!m_bufferReady)
diff --git a/src/multimedia/platform/windows/decoder/mfaudiodecodercontrol_p.h b/src/multimedia/platform/windows/decoder/mfaudiodecodercontrol_p.h
index 56edb95c0..8cd769e67 100644
--- a/src/multimedia/platform/windows/decoder/mfaudiodecodercontrol_p.h
+++ b/src/multimedia/platform/windows/decoder/mfaudiodecodercontrol_p.h
@@ -64,8 +64,6 @@ public:
MFAudioDecoderControl(QAudioDecoder *parent);
~MFAudioDecoderControl();
- QAudioDecoder::State state() const;
-
QUrl source() const;
void setSource(const QUrl &fileName);
@@ -75,9 +73,6 @@ public:
void start();
void stop();
- QAudioFormat audioFormat() const;
- void setAudioFormat(const QAudioFormat &format);
-
QAudioBuffer read();
bool bufferAvailable() const;
@@ -91,17 +86,13 @@ private Q_SLOTS:
void handleSourceFinished();
private:
- void updateResamplerOutputType();
void activatePipeline();
void onSourceCleared();
MFDecoderSourceReader *m_decoderSourceReader;
SourceResolver *m_sourceResolver;
- IMFTransform *m_resampler;
- QAudioDecoder::State m_state;
QUrl m_source;
QIODevice *m_device;
- QAudioFormat m_audioFormat;
DWORD m_mfInputStreamID;
DWORD m_mfOutputStreamID;
bool m_bufferReady;
@@ -113,7 +104,6 @@ private:
IMFSample *m_convertSample;
QAudioFormat m_sourceOutputFormat;
bool m_sourceReady;
- bool m_resamplerDirty;
};
#endif//MFAUDIODECODERCONTROL_H
diff --git a/src/multimedia/platform/windows/decoder/mfdecodersourcereader.cpp b/src/multimedia/platform/windows/decoder/mfdecodersourcereader.cpp
index 381c60dc5..d10839a63 100644
--- a/src/multimedia/platform/windows/decoder/mfdecodersourcereader.cpp
+++ b/src/multimedia/platform/windows/decoder/mfdecodersourcereader.cpp
@@ -64,7 +64,7 @@ IMFMediaSource* MFDecoderSourceReader::mediaSource()
return m_source;
}
-IMFMediaType* MFDecoderSourceReader::setSource(IMFMediaSource *source, const QAudioFormat &audioFormat)
+IMFMediaType* MFDecoderSourceReader::setSource(IMFMediaSource *source)
{
IMFMediaType *mediaType = NULL;
if (m_source == source)
@@ -90,12 +90,7 @@ IMFMediaType* MFDecoderSourceReader::setSource(IMFMediaSource *source, const QAu
IMFMediaType *pPartialType = NULL;
MFCreateMediaType(&pPartialType);
pPartialType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio);
-
- if (audioFormat.sampleFormat() == QAudioFormat::Float) {
- pPartialType->SetGUID(MF_MT_SUBTYPE, MFAudioFormat_Float);
- } else {
- pPartialType->SetGUID(MF_MT_SUBTYPE, MFAudioFormat_PCM);
- }
+ pPartialType->SetGUID(MF_MT_SUBTYPE, MFAudioFormat_PCM);
m_sourceReader->SetCurrentMediaType(DWORD(MF_SOURCE_READER_FIRST_AUDIO_STREAM), NULL, pPartialType);
pPartialType->Release();
diff --git a/src/multimedia/platform/windows/decoder/mfdecodersourcereader_p.h b/src/multimedia/platform/windows/decoder/mfdecodersourcereader_p.h
index 7d63f5368..6730dbf7f 100644
--- a/src/multimedia/platform/windows/decoder/mfdecodersourcereader_p.h
+++ b/src/multimedia/platform/windows/decoder/mfdecodersourcereader_p.h
@@ -69,7 +69,7 @@ public:
void shutdown();
IMFMediaSource* mediaSource();
- IMFMediaType* setSource(IMFMediaSource *source, const QAudioFormat &audioFormat);
+ IMFMediaType* setSource(IMFMediaSource *source);
void reset();
void readNextSample();