summaryrefslogtreecommitdiffstats
path: root/src/multimedia/platform/windows
diff options
context:
space:
mode:
Diffstat (limited to 'src/multimedia/platform/windows')
-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
4 files changed, 41 insertions, 215 deletions
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();