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