summaryrefslogtreecommitdiffstats
path: root/src/plugins/wmf
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/wmf')
-rw-r--r--src/plugins/wmf/decoder/decoder.pri14
-rw-r--r--src/plugins/wmf/decoder/mfaudiodecodercontrol.cpp486
-rw-r--r--src/plugins/wmf/decoder/mfaudiodecodercontrol.h108
-rw-r--r--src/plugins/wmf/decoder/mfdecoderservice.cpp65
-rw-r--r--src/plugins/wmf/decoder/mfdecoderservice.h56
-rw-r--r--src/plugins/wmf/decoder/mfdecodersourcereader.cpp197
-rw-r--r--src/plugins/wmf/decoder/mfdecodersourcereader.h89
-rw-r--r--src/plugins/wmf/mfstream.cpp361
-rw-r--r--src/plugins/wmf/mfstream.h148
-rw-r--r--src/plugins/wmf/player/mfactivate.cpp87
-rw-r--r--src/plugins/wmf/player/mfactivate.h212
-rw-r--r--src/plugins/wmf/player/mfaudioendpointcontrol.cpp180
-rw-r--r--src/plugins/wmf/player/mfaudioendpointcontrol.h82
-rw-r--r--src/plugins/wmf/player/mfaudioprobecontrol.cpp75
-rw-r--r--src/plugins/wmf/player/mfaudioprobecontrol.h66
-rw-r--r--src/plugins/wmf/player/mfevrvideowindowcontrol.cpp91
-rw-r--r--src/plugins/wmf/player/mfevrvideowindowcontrol.h63
-rw-r--r--src/plugins/wmf/player/mfmetadatacontrol.cpp431
-rw-r--r--src/plugins/wmf/player/mfmetadatacontrol.h72
-rw-r--r--src/plugins/wmf/player/mfplayercontrol.cpp316
-rw-r--r--src/plugins/wmf/player/mfplayercontrol.h122
-rw-r--r--src/plugins/wmf/player/mfplayerservice.cpp167
-rw-r--r--src/plugins/wmf/player/mfplayerservice.h87
-rw-r--r--src/plugins/wmf/player/mfplayersession.cpp1818
-rw-r--r--src/plugins/wmf/player/mfplayersession.h239
-rw-r--r--src/plugins/wmf/player/mftvideo.cpp753
-rw-r--r--src/plugins/wmf/player/mftvideo.h117
-rw-r--r--src/plugins/wmf/player/mfvideoprobecontrol.cpp54
-rw-r--r--src/plugins/wmf/player/mfvideoprobecontrol.h59
-rw-r--r--src/plugins/wmf/player/mfvideorenderercontrol.cpp2426
-rw-r--r--src/plugins/wmf/player/mfvideorenderercontrol.h81
-rw-r--r--src/plugins/wmf/player/player.pri34
-rw-r--r--src/plugins/wmf/player/samplegrabber.cpp173
-rw-r--r--src/plugins/wmf/player/samplegrabber.h96
-rw-r--r--src/plugins/wmf/sourceresolver.cpp325
-rw-r--r--src/plugins/wmf/sourceresolver.h104
-rw-r--r--src/plugins/wmf/wmf.json4
-rw-r--r--src/plugins/wmf/wmf.pro28
-rw-r--r--src/plugins/wmf/wmfserviceplugin.cpp117
-rw-r--r--src/plugins/wmf/wmfserviceplugin.h71
40 files changed, 0 insertions, 10074 deletions
diff --git a/src/plugins/wmf/decoder/decoder.pri b/src/plugins/wmf/decoder/decoder.pri
deleted file mode 100644
index 7637ac848..000000000
--- a/src/plugins/wmf/decoder/decoder.pri
+++ /dev/null
@@ -1,14 +0,0 @@
-INCLUDEPATH += $$PWD
-
-LIBS += -lmfreadwrite -lwmcodecdspuuid
-QMAKE_USE += wmf
-
-HEADERS += \
- $$PWD/mfdecoderservice.h \
- $$PWD/mfdecodersourcereader.h \
- $$PWD/mfaudiodecodercontrol.h
-
-SOURCES += \
- $$PWD/mfdecoderservice.cpp \
- $$PWD/mfdecodersourcereader.cpp \
- $$PWD/mfaudiodecodercontrol.cpp
diff --git a/src/plugins/wmf/decoder/mfaudiodecodercontrol.cpp b/src/plugins/wmf/decoder/mfaudiodecodercontrol.cpp
deleted file mode 100644
index c0eada324..000000000
--- a/src/plugins/wmf/decoder/mfaudiodecodercontrol.cpp
+++ /dev/null
@@ -1,486 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "Wmcodecdsp.h"
-#include "mfaudiodecodercontrol.h"
-
-MFAudioDecoderControl::MFAudioDecoderControl(QObject *parent)
- : QAudioDecoderControl(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)
- , m_bufferReady(false)
- , m_duration(0)
- , m_position(0)
- , m_loadingSource(false)
- , 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;
- defaultFormat.setCodec("audio/pcm");
- setAudioFormat(defaultFormat);
-}
-
-MFAudioDecoderControl::~MFAudioDecoderControl()
-{
- if (m_mfOutputType)
- m_mfOutputType->Release();
- m_decoderSourceReader->shutdown();
- m_decoderSourceReader->Release();
- m_sourceResolver->Release();
- if (m_resampler)
- m_resampler->Release();
-}
-
-QAudioDecoder::State MFAudioDecoderControl::state() const
-{
- return m_state;
-}
-
-QString MFAudioDecoderControl::sourceFilename() const
-{
- return m_sourceFilename;
-}
-
-void MFAudioDecoderControl::onSourceCleared()
-{
- bool positionDirty = false;
- bool durationDirty = false;
- if (m_position != 0) {
- m_position = 0;
- positionDirty = true;
- }
- if (m_duration != 0) {
- m_duration = 0;
- durationDirty = true;
- }
- if (positionDirty)
- emit positionChanged(m_position);
- if (durationDirty)
- emit durationChanged(m_duration);
-}
-
-void MFAudioDecoderControl::setSourceFilename(const QString &fileName)
-{
- if (!m_device && m_sourceFilename == fileName)
- return;
- m_sourceReady = false;
- m_sourceResolver->cancel();
- m_decoderSourceReader->setSource(0, m_audioFormat);
- m_device = 0;
- m_sourceFilename = fileName;
- if (!m_sourceFilename.isEmpty()) {
- m_sourceResolver->shutdown();
- QUrl url;
- if (m_sourceFilename.startsWith(':'))
- url = QUrl(QStringLiteral("qrc%1").arg(m_sourceFilename));
- else
- url = QUrl::fromLocalFile(m_sourceFilename);
- m_sourceResolver->load(url, 0);
- m_loadingSource = true;
- } else {
- onSourceCleared();
- }
- emit sourceChanged();
-}
-
-QIODevice* MFAudioDecoderControl::sourceDevice() const
-{
- return m_device;
-}
-
-void MFAudioDecoderControl::setSourceDevice(QIODevice *device)
-{
- if (m_device == device && m_sourceFilename.isEmpty())
- return;
- m_sourceReady = false;
- m_sourceResolver->cancel();
- m_decoderSourceReader->setSource(0, m_audioFormat);
- m_sourceFilename.clear();
- m_device = device;
- if (m_device) {
- m_sourceResolver->shutdown();
- m_sourceResolver->load(QUrl(), m_device);
- m_loadingSource = true;
- } 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;
- }
-}
-
-void MFAudioDecoderControl::handleMediaSourceReady()
-{
- m_loadingSource = false;
- m_sourceReady = true;
- IMFMediaType *mediaType = m_decoderSourceReader->setSource(m_sourceResolver->mediaSource(), m_audioFormat);
- 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));
- }
- if (SUCCEEDED(mediaType->GetUINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, &val))) {
- m_sourceOutputFormat.setSampleRate(int(val));
- }
- if (SUCCEEDED(mediaType->GetUINT32(MF_MT_AUDIO_BITS_PER_SAMPLE, &val))) {
- m_sourceOutputFormat.setSampleSize(int(val));
- }
-
- GUID subType;
- if (SUCCEEDED(mediaType->GetGUID(MF_MT_SUBTYPE, &subType))) {
- if (subType == MFAudioFormat_Float) {
- m_sourceOutputFormat.setSampleType(QAudioFormat::Float);
- } else if (m_sourceOutputFormat.sampleSize() == 8) {
- m_sourceOutputFormat.setSampleType(QAudioFormat::UnSignedInt);
- } else {
- m_sourceOutputFormat.setSampleType(QAudioFormat::SignedInt);
- }
- }
- if (m_sourceOutputFormat.sampleType() != QAudioFormat::Float) {
- m_sourceOutputFormat.setByteOrder(QAudioFormat::LittleEndian);
- }
-
- if (m_audioFormat.sampleType() != QAudioFormat::Float
- && m_audioFormat.sampleType() != QAudioFormat::SignedInt) {
- af.setSampleType(m_sourceOutputFormat.sampleType());
- }
- if (af.sampleType() == QAudioFormat::SignedInt) {
- af.setByteOrder(QAudioFormat::LittleEndian);
- }
- if (m_audioFormat.channelCount() <= 0) {
- af.setChannelCount(m_sourceOutputFormat.channelCount());
- }
- if (m_audioFormat.sampleRate() <= 0) {
- af.setSampleRate(m_sourceOutputFormat.sampleRate());
- }
- if (m_audioFormat.sampleSize() <= 0) {
- af.setSampleSize(m_sourceOutputFormat.sampleSize());
- }
- 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;
- pd->GetUINT64(MF_PD_DURATION, &duration);
- pd->Release();
- duration /= 10000;
- if (m_duration != qint64(duration)) {
- m_duration = qint64(duration);
- emit durationChanged(m_duration);
- }
- }
- if (m_state == QAudioDecoder::DecodingState) {
- activatePipeline();
- }
- } else if (m_state != QAudioDecoder::StoppedState) {
- m_state = QAudioDecoder::StoppedState;
- emit stateChanged(m_state);
- }
-}
-
-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);
- }
-}
-
-void MFAudioDecoderControl::activatePipeline()
-{
- Q_ASSERT(!m_bufferReady);
- m_state = QAudioDecoder::DecodingState;
- 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);
- }
-}
-
-void MFAudioDecoderControl::start()
-{
- if (m_state != QAudioDecoder::StoppedState)
- return;
-
- if (m_loadingSource) {
- //deferred starting
- m_state = QAudioDecoder::DecodingState;
- emit stateChanged(m_state);
- return;
- }
-
- if (!m_decoderSourceReader->mediaSource())
- return;
- activatePipeline();
- emit stateChanged(m_state);
-}
-
-void MFAudioDecoderControl::stop()
-{
- if (m_state == QAudioDecoder::StoppedState)
- 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);
-}
-
-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();
- }
- }
- // WMF uses 100-nanosecond units, QAudioDecoder uses milliseconds, QAudioBuffer uses microseconds...
- m_cachedAudioBuffer = QAudioBuffer(abuf, m_audioFormat, qint64(sampleStartTime / 10));
- m_bufferReady = true;
- emit positionChanged(m_position);
- emit bufferAvailableChanged(m_bufferReady);
- emit bufferReady();
-}
-
-void MFAudioDecoderControl::handleSourceFinished()
-{
- stop();
- emit finished();
-}
-
-QAudioFormat MFAudioDecoderControl::audioFormat() const
-{
- return m_audioFormat;
-}
-
-void MFAudioDecoderControl::setAudioFormat(const QAudioFormat &format)
-{
- if (m_audioFormat == format || !m_resampler)
- return;
- if (format.codec() != QLatin1String("audio/x-wav") && format.codec() != QLatin1String("audio/pcm")) {
- qWarning("MFAudioDecoderControl does not accept non-pcm audio format!");
- return;
- }
- m_audioFormat = format;
-
- if (m_audioFormat.isValid()) {
- IMFMediaType *mediaType = 0;
- MFCreateMediaType(&mediaType);
- mediaType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio);
- if (format.sampleType() == 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.channelCount() * m_audioFormat.sampleSize() / 8);
- mediaType->SetUINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT, alignmentBlock);
- UINT32 avgBytesPerSec = UINT32(m_audioFormat.sampleRate() * m_audioFormat.sampleSize() / 8 * m_audioFormat.channelCount());
- mediaType->SetUINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND, avgBytesPerSec);
- mediaType->SetUINT32(MF_MT_AUDIO_BITS_PER_SAMPLE, UINT32(m_audioFormat.sampleSize()));
- 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)
- return QAudioBuffer();
- QAudioBuffer buffer = m_cachedAudioBuffer;
- m_bufferReady = false;
- emit bufferAvailableChanged(m_bufferReady);
- m_decoderSourceReader->readNextSample();
- return buffer;
-}
-
-bool MFAudioDecoderControl::bufferAvailable() const
-{
- return m_bufferReady;
-}
-
-qint64 MFAudioDecoderControl::position() const
-{
- return m_position;
-}
-
-qint64 MFAudioDecoderControl::duration() const
-{
- return m_duration;
-}
diff --git a/src/plugins/wmf/decoder/mfaudiodecodercontrol.h b/src/plugins/wmf/decoder/mfaudiodecodercontrol.h
deleted file mode 100644
index cfb8e9091..000000000
--- a/src/plugins/wmf/decoder/mfaudiodecodercontrol.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef MFAUDIODECODERCONTROL_H
-#define MFAUDIODECODERCONTROL_H
-
-#include "qaudiodecodercontrol.h"
-#include "mfdecodersourcereader.h"
-#include "sourceresolver.h"
-
-QT_USE_NAMESPACE
-
-class MFAudioDecoderControl : public QAudioDecoderControl
-{
- Q_OBJECT
-public:
- MFAudioDecoderControl(QObject *parent = 0);
- ~MFAudioDecoderControl();
-
- QAudioDecoder::State state() const;
-
- QString sourceFilename() const;
- void setSourceFilename(const QString &fileName);
-
- QIODevice* sourceDevice() const;
- void setSourceDevice(QIODevice *device);
-
- void start();
- void stop();
-
- QAudioFormat audioFormat() const;
- void setAudioFormat(const QAudioFormat &format);
-
- QAudioBuffer read();
- bool bufferAvailable() const;
-
- qint64 position() const;
- qint64 duration() const;
-
-private Q_SLOTS:
- void handleMediaSourceReady();
- void handleMediaSourceError(long hr);
- void handleSampleAdded();
- void handleSourceFinished();
-
-private:
- void updateResamplerOutputType();
- void activatePipeline();
- void onSourceCleared();
-
- MFDecoderSourceReader *m_decoderSourceReader;
- SourceResolver *m_sourceResolver;
- IMFTransform *m_resampler;
- QAudioDecoder::State m_state;
- QString m_sourceFilename;
- QIODevice *m_device;
- QAudioFormat m_audioFormat;
- DWORD m_mfInputStreamID;
- DWORD m_mfOutputStreamID;
- bool m_bufferReady;
- QAudioBuffer m_cachedAudioBuffer;
- qint64 m_duration;
- qint64 m_position;
- bool m_loadingSource;
- IMFMediaType *m_mfOutputType;
- IMFSample *m_convertSample;
- QAudioFormat m_sourceOutputFormat;
- bool m_sourceReady;
- bool m_resamplerDirty;
-};
-
-#endif//MFAUDIODECODERCONTROL_H
diff --git a/src/plugins/wmf/decoder/mfdecoderservice.cpp b/src/plugins/wmf/decoder/mfdecoderservice.cpp
deleted file mode 100644
index c6ed3976a..000000000
--- a/src/plugins/wmf/decoder/mfdecoderservice.cpp
+++ /dev/null
@@ -1,65 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "mfdecoderservice.h"
-#include "mfaudiodecodercontrol.h"
-
-MFAudioDecoderService::MFAudioDecoderService(QObject *parent)
- : QMediaService(parent)
-{
-}
-
-MFAudioDecoderService::~MFAudioDecoderService()
-{
-}
-
-QMediaControl* MFAudioDecoderService::requestControl(const char *name)
-{
- if (qstrcmp(name, QAudioDecoderControl_iid) == 0) {
- return new MFAudioDecoderControl(this);
- }
- return 0;
-}
-
-void MFAudioDecoderService::releaseControl(QMediaControl *control)
-{
- if (control && control->inherits("MFAudioDecoderControl")) {
- delete control;
- }
-}
diff --git a/src/plugins/wmf/decoder/mfdecoderservice.h b/src/plugins/wmf/decoder/mfdecoderservice.h
deleted file mode 100644
index 14899ee39..000000000
--- a/src/plugins/wmf/decoder/mfdecoderservice.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef MFDECODERSERVICE_H
-#define MFDECODERSERVICE_H
-
-#include "qmediaservice.h"
-
-class MFAudioDecoderService : public QMediaService
-{
- Q_OBJECT
-public:
- MFAudioDecoderService(QObject *parent = 0);
- ~MFAudioDecoderService();
-
- QMediaControl* requestControl(const char *name);
- void releaseControl(QMediaControl *control);
-};
-
-#endif//MFDECODERSERVICE_H
diff --git a/src/plugins/wmf/decoder/mfdecodersourcereader.cpp b/src/plugins/wmf/decoder/mfdecodersourcereader.cpp
deleted file mode 100644
index e907cfaf0..000000000
--- a/src/plugins/wmf/decoder/mfdecodersourcereader.cpp
+++ /dev/null
@@ -1,197 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "mfdecodersourcereader.h"
-
-MFDecoderSourceReader::MFDecoderSourceReader(QObject *parent)
- : m_cRef(1)
- , m_sourceReader(0)
- , m_source(0)
-{
- Q_UNUSED(parent);
-}
-
-void MFDecoderSourceReader::shutdown()
-{
- if (m_source) {
- m_source->Release();
- m_source = NULL;
- }
- if (m_sourceReader) {
- m_sourceReader->Release();
- m_sourceReader = NULL;
- }
-}
-
-IMFMediaSource* MFDecoderSourceReader::mediaSource()
-{
- return m_source;
-}
-
-IMFMediaType* MFDecoderSourceReader::setSource(IMFMediaSource *source, const QAudioFormat &audioFormat)
-{
- IMFMediaType *mediaType = NULL;
- if (m_source == source)
- return mediaType;
- if (m_source) {
- m_source->Release();
- m_source = NULL;
- }
- if (m_sourceReader) {
- m_sourceReader->Release();
- m_sourceReader = NULL;
- }
- if (!source)
- return mediaType;
- IMFAttributes *attr = NULL;
- MFCreateAttributes(&attr, 1);
- if (SUCCEEDED(attr->SetUnknown(MF_SOURCE_READER_ASYNC_CALLBACK, this))) {
- if (SUCCEEDED(MFCreateSourceReaderFromMediaSource(source, attr, &m_sourceReader))) {
- m_source = source;
- m_source->AddRef();
- m_sourceReader->SetStreamSelection(DWORD(MF_SOURCE_READER_ALL_STREAMS), FALSE);
- m_sourceReader->SetStreamSelection(DWORD(MF_SOURCE_READER_FIRST_AUDIO_STREAM), TRUE);
- IMFMediaType *pPartialType = NULL;
- MFCreateMediaType(&pPartialType);
- pPartialType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio);
-
- if (audioFormat.sampleType() == QAudioFormat::Float) {
- pPartialType->SetGUID(MF_MT_SUBTYPE, MFAudioFormat_Float);
- } else {
- pPartialType->SetGUID(MF_MT_SUBTYPE, MFAudioFormat_PCM);
- }
-
- m_sourceReader->SetCurrentMediaType(DWORD(MF_SOURCE_READER_FIRST_AUDIO_STREAM), NULL, pPartialType);
- pPartialType->Release();
- m_sourceReader->GetCurrentMediaType(DWORD(MF_SOURCE_READER_FIRST_AUDIO_STREAM), &mediaType);
- // Ensure the stream is selected.
- m_sourceReader->SetStreamSelection(DWORD(MF_SOURCE_READER_FIRST_AUDIO_STREAM), TRUE);
- }
- attr->Release();
- }
- return mediaType;
-}
-
-void MFDecoderSourceReader::reset()
-{
- if (!m_sourceReader)
- return;
- PROPVARIANT vPos;
- PropVariantInit(&vPos);
- vPos.vt = VT_I8;
- vPos.uhVal.QuadPart = 0;
- m_sourceReader->SetCurrentPosition(GUID_NULL, vPos);
-}
-
-void MFDecoderSourceReader::readNextSample()
-{
- if (!m_sourceReader)
- return;
- m_sourceReader->ReadSample(MF_SOURCE_READER_FIRST_AUDIO_STREAM, 0, NULL, NULL, NULL, NULL);
-}
-
-QList<IMFSample*> MFDecoderSourceReader::takeSamples() //internal samples will be cleared after this
-{
- QList<IMFSample*> samples;
- m_samplesMutex.lock();
- samples = m_cachedSamples;
- m_cachedSamples.clear();
- m_samplesMutex.unlock();
- return samples;
-}
-
-//from IUnknown
-STDMETHODIMP MFDecoderSourceReader::QueryInterface(REFIID riid, LPVOID *ppvObject)
-{
- if (!ppvObject)
- return E_POINTER;
- if (riid == IID_IMFSourceReaderCallback) {
- *ppvObject = static_cast<IMFSourceReaderCallback*>(this);
- } else if (riid == IID_IUnknown) {
- *ppvObject = static_cast<IUnknown*>(this);
- } else {
- *ppvObject = NULL;
- return E_NOINTERFACE;
- }
- AddRef();
- return S_OK;
-}
-
-STDMETHODIMP_(ULONG) MFDecoderSourceReader::AddRef(void)
-{
- return InterlockedIncrement(&m_cRef);
-}
-
-STDMETHODIMP_(ULONG) MFDecoderSourceReader::Release(void)
-{
- LONG cRef = InterlockedDecrement(&m_cRef);
- if (cRef == 0) {
- this->deleteLater();
- }
- return cRef;
-}
-
-//from IMFSourceReaderCallback
-STDMETHODIMP MFDecoderSourceReader::OnReadSample(HRESULT hrStatus, DWORD dwStreamIndex,
- DWORD dwStreamFlags, LONGLONG llTimestamp, IMFSample *pSample)
-{
- Q_UNUSED(hrStatus);
- Q_UNUSED(dwStreamIndex);
- Q_UNUSED(llTimestamp);
- if (pSample) {
- pSample->AddRef();
- m_samplesMutex.lock();
- m_cachedSamples.push_back(pSample);
- m_samplesMutex.unlock();
- emit sampleAdded();
- } else if ((dwStreamFlags & MF_SOURCE_READERF_ENDOFSTREAM) == MF_SOURCE_READERF_ENDOFSTREAM) {
- emit finished();
- }
- return S_OK;
-}
-
-STDMETHODIMP MFDecoderSourceReader::OnFlush(DWORD)
-{
- return S_OK;
-}
-
-STDMETHODIMP MFDecoderSourceReader::OnEvent(DWORD, IMFMediaEvent*)
-{
- return S_OK;
-}
diff --git a/src/plugins/wmf/decoder/mfdecodersourcereader.h b/src/plugins/wmf/decoder/mfdecodersourcereader.h
deleted file mode 100644
index 21c6b5eb3..000000000
--- a/src/plugins/wmf/decoder/mfdecodersourcereader.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt Mobility Components.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef MFDECODERSOURCEREADER_H
-#define MFDECODERSOURCEREADER_H
-#include <mfapi.h>
-#include <mfidl.h>
-#include <Mfreadwrite.h>
-
-#include <QtCore/qobject.h>
-#include <QtCore/qmutex.h>
-#include "qaudioformat.h"
-
-QT_USE_NAMESPACE
-
-class MFDecoderSourceReader : public QObject, public IMFSourceReaderCallback
-{
- Q_OBJECT
-public:
- MFDecoderSourceReader(QObject *parent = 0);
- void shutdown();
-
- IMFMediaSource* mediaSource();
- IMFMediaType* setSource(IMFMediaSource *source, const QAudioFormat &audioFormat);
-
- void reset();
- void readNextSample();
- QList<IMFSample*> takeSamples(); //internal samples will be cleared after this
-
- //from IUnknown
- STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppvObject);
- STDMETHODIMP_(ULONG) AddRef(void);
- STDMETHODIMP_(ULONG) Release(void);
-
- //from IMFSourceReaderCallback
- STDMETHODIMP OnReadSample(HRESULT hrStatus, DWORD dwStreamIndex,
- DWORD dwStreamFlags, LONGLONG llTimestamp, IMFSample *pSample);
- STDMETHODIMP OnFlush(DWORD dwStreamIndex);
- STDMETHODIMP OnEvent(DWORD dwStreamIndex, IMFMediaEvent *pEvent);
-
-Q_SIGNALS:
- void sampleAdded();
- void finished();
-
-private:
- long m_cRef;
- QList<IMFSample*> m_cachedSamples;
- QMutex m_samplesMutex;
-
- IMFSourceReader *m_sourceReader;
- IMFMediaSource *m_source;
-};
-#endif//MFDECODERSOURCEREADER_H
diff --git a/src/plugins/wmf/mfstream.cpp b/src/plugins/wmf/mfstream.cpp
deleted file mode 100644
index a98b5a704..000000000
--- a/src/plugins/wmf/mfstream.cpp
+++ /dev/null
@@ -1,361 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt Mobility Components.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "mfstream.h"
-#include <QtCore/qcoreapplication.h>
-
-//MFStream is added for supporting QIODevice type of media source.
-//It is used to delegate invocations from media foundation(through IMFByteStream) to QIODevice.
-
-MFStream::MFStream(QIODevice *stream, bool ownStream)
- : m_cRef(1)
- , m_stream(stream)
- , m_ownStream(ownStream)
- , m_currentReadResult(0)
-{
- //Move to the thread of the stream object
- //to make sure invocations on stream
- //are happened in the same thread of stream object
- this->moveToThread(stream->thread());
- connect(stream, SIGNAL(readyRead()), this, SLOT(handleReadyRead()));
-}
-
-MFStream::~MFStream()
-{
- if (m_currentReadResult)
- m_currentReadResult->Release();
- if (m_ownStream)
- m_stream->deleteLater();
-}
-
-//from IUnknown
-STDMETHODIMP MFStream::QueryInterface(REFIID riid, LPVOID *ppvObject)
-{
- if (!ppvObject)
- return E_POINTER;
- if (riid == IID_IMFByteStream) {
- *ppvObject = static_cast<IMFByteStream*>(this);
- } else if (riid == IID_IUnknown) {
- *ppvObject = static_cast<IUnknown*>(this);
- } else {
- *ppvObject = NULL;
- return E_NOINTERFACE;
- }
- AddRef();
- return S_OK;
-}
-
-STDMETHODIMP_(ULONG) MFStream::AddRef(void)
-{
- return InterlockedIncrement(&m_cRef);
-}
-
-STDMETHODIMP_(ULONG) MFStream::Release(void)
-{
- LONG cRef = InterlockedDecrement(&m_cRef);
- if (cRef == 0) {
- this->deleteLater();
- }
- return cRef;
-}
-
-
-//from IMFByteStream
-STDMETHODIMP MFStream::GetCapabilities(DWORD *pdwCapabilities)
-{
- if (!pdwCapabilities)
- return E_INVALIDARG;
- *pdwCapabilities = MFBYTESTREAM_IS_READABLE;
- if (!m_stream->isSequential())
- *pdwCapabilities |= MFBYTESTREAM_IS_SEEKABLE;
- return S_OK;
-}
-
-STDMETHODIMP MFStream::GetLength(QWORD *pqwLength)
-{
- if (!pqwLength)
- return E_INVALIDARG;
- QMutexLocker locker(&m_mutex);
- *pqwLength = QWORD(m_stream->size());
- return S_OK;
-}
-
-STDMETHODIMP MFStream::SetLength(QWORD)
-{
- return E_NOTIMPL;
-}
-
-STDMETHODIMP MFStream::GetCurrentPosition(QWORD *pqwPosition)
-{
- if (!pqwPosition)
- return E_INVALIDARG;
- QMutexLocker locker(&m_mutex);
- *pqwPosition = m_stream->pos();
- return S_OK;
-}
-
-STDMETHODIMP MFStream::SetCurrentPosition(QWORD qwPosition)
-{
- QMutexLocker locker(&m_mutex);
- //SetCurrentPosition may happend during the BeginRead/EndRead pair,
- //refusing to execute SetCurrentPosition during that time seems to be
- //the simplest workable solution
- if (m_currentReadResult)
- return S_FALSE;
-
- bool seekOK = m_stream->seek(qint64(qwPosition));
- if (seekOK)
- return S_OK;
- else
- return S_FALSE;
-}
-
-STDMETHODIMP MFStream::IsEndOfStream(BOOL *pfEndOfStream)
-{
- if (!pfEndOfStream)
- return E_INVALIDARG;
- QMutexLocker locker(&m_mutex);
- *pfEndOfStream = m_stream->atEnd() ? TRUE : FALSE;
- return S_OK;
-}
-
-STDMETHODIMP MFStream::Read(BYTE *pb, ULONG cb, ULONG *pcbRead)
-{
- QMutexLocker locker(&m_mutex);
- qint64 read = m_stream->read((char*)(pb), qint64(cb));
- if (pcbRead)
- *pcbRead = ULONG(read);
- return S_OK;
-}
-
-STDMETHODIMP MFStream::BeginRead(BYTE *pb, ULONG cb, IMFAsyncCallback *pCallback,
- IUnknown *punkState)
-{
- if (!pCallback || !pb)
- return E_INVALIDARG;
-
- Q_ASSERT(m_currentReadResult == NULL);
-
- AsyncReadState *state = new (std::nothrow) AsyncReadState(pb, cb);
- if (state == NULL)
- return E_OUTOFMEMORY;
-
- HRESULT hr = MFCreateAsyncResult(state, pCallback, punkState, &m_currentReadResult);
- state->Release();
- if (FAILED(hr))
- return hr;
-
- QCoreApplication::postEvent(this, new QEvent(QEvent::User));
- return hr;
-}
-
-STDMETHODIMP MFStream::EndRead(IMFAsyncResult* pResult, ULONG *pcbRead)
-{
- if (!pcbRead)
- return E_INVALIDARG;
- IUnknown *pUnk;
- pResult->GetObject(&pUnk);
- AsyncReadState *state = static_cast<AsyncReadState*>(pUnk);
- *pcbRead = state->bytesRead();
- pUnk->Release();
-
- m_currentReadResult->Release();
- m_currentReadResult = NULL;
-
- return S_OK;
-}
-
-STDMETHODIMP MFStream::Write(const BYTE *, ULONG, ULONG *)
-{
- return E_NOTIMPL;
-}
-
-STDMETHODIMP MFStream::BeginWrite(const BYTE *, ULONG ,
- IMFAsyncCallback *,
- IUnknown *)
-{
- return E_NOTIMPL;
-}
-
-STDMETHODIMP MFStream::EndWrite(IMFAsyncResult *,
- ULONG *)
-{
- return E_NOTIMPL;
-}
-
-STDMETHODIMP MFStream::Seek(
- MFBYTESTREAM_SEEK_ORIGIN SeekOrigin,
- LONGLONG llSeekOffset,
- DWORD,
- QWORD *pqwCurrentPosition)
-{
- QMutexLocker locker(&m_mutex);
- if (m_currentReadResult)
- return S_FALSE;
-
- qint64 pos = qint64(llSeekOffset);
- switch (SeekOrigin) {
- case msoBegin:
- break;
- case msoCurrent:
- pos += m_stream->pos();
- break;
- }
- bool seekOK = m_stream->seek(pos);
- if (pqwCurrentPosition)
- *pqwCurrentPosition = pos;
- if (seekOK)
- return S_OK;
- else
- return S_FALSE;
-}
-
-STDMETHODIMP MFStream::Flush()
-{
- return E_NOTIMPL;
-}
-
-STDMETHODIMP MFStream::Close()
-{
- QMutexLocker locker(&m_mutex);
- if (m_ownStream)
- m_stream->close();
- return S_OK;
-}
-
-void MFStream::doRead()
-{
- bool readDone = true;
- IUnknown *pUnk = NULL;
- HRESULT hr = m_currentReadResult->GetObject(&pUnk);
- if (SUCCEEDED(hr)) {
- //do actual read
- AsyncReadState *state = static_cast<AsyncReadState*>(pUnk);
- ULONG cbRead;
- Read(state->pb(), state->cb() - state->bytesRead(), &cbRead);
- pUnk->Release();
-
- state->setBytesRead(cbRead + state->bytesRead());
- if (state->cb() > state->bytesRead() && !m_stream->atEnd()) {
- readDone = false;
- }
- }
-
- if (readDone) {
- //now inform the original caller
- m_currentReadResult->SetStatus(hr);
- MFInvokeCallback(m_currentReadResult);
- }
-}
-
-
-void MFStream::handleReadyRead()
-{
- doRead();
-}
-
-void MFStream::customEvent(QEvent *event)
-{
- if (event->type() != QEvent::User) {
- QObject::customEvent(event);
- return;
- }
- doRead();
-}
-
-//AsyncReadState is a helper class used in BeginRead for asynchronous operation
-//to record some BeginRead parameters, so these parameters could be
-//used later when actually executing the read operation in another thread.
-MFStream::AsyncReadState::AsyncReadState(BYTE *pb, ULONG cb)
- : m_cRef(1)
- , m_pb(pb)
- , m_cb(cb)
- , m_cbRead(0)
-{
-}
-
-//from IUnknown
-STDMETHODIMP MFStream::AsyncReadState::QueryInterface(REFIID riid, LPVOID *ppvObject)
-{
- if (!ppvObject)
- return E_POINTER;
-
- if (riid == IID_IUnknown) {
- *ppvObject = static_cast<IUnknown*>(this);
- } else {
- *ppvObject = NULL;
- return E_NOINTERFACE;
- }
- AddRef();
- return S_OK;
-}
-
-STDMETHODIMP_(ULONG) MFStream::AsyncReadState::AddRef(void)
-{
- return InterlockedIncrement(&m_cRef);
-}
-
-STDMETHODIMP_(ULONG) MFStream::AsyncReadState::Release(void)
-{
- LONG cRef = InterlockedDecrement(&m_cRef);
- if (cRef == 0)
- delete this;
- // For thread safety, return a temporary variable.
- return cRef;
-}
-
-BYTE* MFStream::AsyncReadState::pb() const
-{
- return m_pb;
-}
-
-ULONG MFStream::AsyncReadState::cb() const
-{
- return m_cb;
-}
-
-ULONG MFStream::AsyncReadState::bytesRead() const
-{
- return m_cbRead;
-}
-
-void MFStream::AsyncReadState::setBytesRead(ULONG cbRead)
-{
- m_cbRead = cbRead;
-}
diff --git a/src/plugins/wmf/mfstream.h b/src/plugins/wmf/mfstream.h
deleted file mode 100644
index f98ab42a9..000000000
--- a/src/plugins/wmf/mfstream.h
+++ /dev/null
@@ -1,148 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt Mobility Components.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef MFSTREAM_H
-#define MFSTREAM_H
-
-#include <mfapi.h>
-#include <mfidl.h>
-#include <QtCore/qmutex.h>
-#include <QtCore/qiodevice.h>
-#include <QtCore/qcoreevent.h>
-
-QT_USE_NAMESPACE
-
-class MFStream : public QObject, public IMFByteStream
-{
- Q_OBJECT
-public:
- MFStream(QIODevice *stream, bool ownStream);
-
- ~MFStream();
-
- //from IUnknown
- STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppvObject);
-
- STDMETHODIMP_(ULONG) AddRef(void);
-
- STDMETHODIMP_(ULONG) Release(void);
-
-
- //from IMFByteStream
- STDMETHODIMP GetCapabilities(DWORD *pdwCapabilities);
-
- STDMETHODIMP GetLength(QWORD *pqwLength);
-
- STDMETHODIMP SetLength(QWORD);
-
- STDMETHODIMP GetCurrentPosition(QWORD *pqwPosition);
-
- STDMETHODIMP SetCurrentPosition(QWORD qwPosition);
-
- STDMETHODIMP IsEndOfStream(BOOL *pfEndOfStream);
-
- STDMETHODIMP Read(BYTE *pb, ULONG cb, ULONG *pcbRead);
-
- STDMETHODIMP BeginRead(BYTE *pb, ULONG cb, IMFAsyncCallback *pCallback,
- IUnknown *punkState);
-
- STDMETHODIMP EndRead(IMFAsyncResult* pResult, ULONG *pcbRead);
-
- STDMETHODIMP Write(const BYTE *, ULONG, ULONG *);
-
- STDMETHODIMP BeginWrite(const BYTE *, ULONG ,
- IMFAsyncCallback *,
- IUnknown *);
-
- STDMETHODIMP EndWrite(IMFAsyncResult *,
- ULONG *);
-
- STDMETHODIMP Seek(
- MFBYTESTREAM_SEEK_ORIGIN SeekOrigin,
- LONGLONG llSeekOffset,
- DWORD,
- QWORD *pqwCurrentPosition);
-
- STDMETHODIMP Flush();
-
- STDMETHODIMP Close();
-
-private:
- class AsyncReadState : public IUnknown
- {
- public:
- AsyncReadState(BYTE *pb, ULONG cb);
-
- //from IUnknown
- STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppvObject);
-
- STDMETHODIMP_(ULONG) AddRef(void);
-
- STDMETHODIMP_(ULONG) Release(void);
-
- BYTE* pb() const;
- ULONG cb() const;
- ULONG bytesRead() const;
-
- void setBytesRead(ULONG cbRead);
-
- private:
- long m_cRef;
- BYTE *m_pb;
- ULONG m_cb;
- ULONG m_cbRead;
- };
-
- long m_cRef;
- QIODevice *m_stream;
- bool m_ownStream;
- DWORD m_workQueueId;
- QMutex m_mutex;
-
- void doRead();
-
-private Q_SLOTS:
- void handleReadyRead();
-
-protected:
- void customEvent(QEvent *event);
- IMFAsyncResult *m_currentReadResult;
-};
-
-#endif
diff --git a/src/plugins/wmf/player/mfactivate.cpp b/src/plugins/wmf/player/mfactivate.cpp
deleted file mode 100644
index e06906584..000000000
--- a/src/plugins/wmf/player/mfactivate.cpp
+++ /dev/null
@@ -1,87 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "mfactivate.h"
-
-#include <mfapi.h>
-
-MFAbstractActivate::MFAbstractActivate()
- : m_attributes(0)
- , m_cRef(1)
-{
- MFCreateAttributes(&m_attributes, 0);
-}
-
-MFAbstractActivate::~MFAbstractActivate()
-{
- if (m_attributes)
- m_attributes->Release();
-}
-
-
-HRESULT MFAbstractActivate::QueryInterface(REFIID riid, LPVOID *ppvObject)
-{
- if (!ppvObject)
- return E_POINTER;
- if (riid == IID_IMFActivate) {
- *ppvObject = static_cast<IMFActivate*>(this);
- } else if (riid == IID_IMFAttributes) {
- *ppvObject = static_cast<IMFAttributes*>(this);
- } else if (riid == IID_IUnknown) {
- *ppvObject = static_cast<IUnknown*>(static_cast<IMFActivate*>(this));
- } else {
- *ppvObject = NULL;
- return E_NOINTERFACE;
- }
- AddRef();
- return S_OK;
-}
-
-ULONG MFAbstractActivate::AddRef(void)
-{
- return InterlockedIncrement(&m_cRef);
-}
-
-ULONG MFAbstractActivate::Release(void)
-{
- ULONG cRef = InterlockedDecrement(&m_cRef);
- if (cRef == 0)
- delete this;
- return cRef;
-}
diff --git a/src/plugins/wmf/player/mfactivate.h b/src/plugins/wmf/player/mfactivate.h
deleted file mode 100644
index 3243296e8..000000000
--- a/src/plugins/wmf/player/mfactivate.h
+++ /dev/null
@@ -1,212 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef MFACTIVATE_H
-#define MFACTIVATE_H
-
-#include <mfidl.h>
-
-class MFAbstractActivate : public IMFActivate
-{
-public:
- explicit MFAbstractActivate();
- virtual ~MFAbstractActivate();
-
- //from IUnknown
- STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppvObject);
- STDMETHODIMP_(ULONG) AddRef(void);
- STDMETHODIMP_(ULONG) Release(void);
-
- //from IMFAttributes
- STDMETHODIMP GetItem(REFGUID guidKey, PROPVARIANT *pValue)
- {
- return m_attributes->GetItem(guidKey, pValue);
- }
-
- STDMETHODIMP GetItemType(REFGUID guidKey, MF_ATTRIBUTE_TYPE *pType)
- {
- return m_attributes->GetItemType(guidKey, pType);
- }
-
- STDMETHODIMP CompareItem(REFGUID guidKey, REFPROPVARIANT Value, BOOL *pbResult)
- {
- return m_attributes->CompareItem(guidKey, Value, pbResult);
- }
-
- STDMETHODIMP Compare(IMFAttributes *pTheirs, MF_ATTRIBUTES_MATCH_TYPE MatchType, BOOL *pbResult)
- {
- return m_attributes->Compare(pTheirs, MatchType, pbResult);
- }
-
- STDMETHODIMP GetUINT32(REFGUID guidKey, UINT32 *punValue)
- {
- return m_attributes->GetUINT32(guidKey, punValue);
- }
-
- STDMETHODIMP GetUINT64(REFGUID guidKey, UINT64 *punValue)
- {
- return m_attributes->GetUINT64(guidKey, punValue);
- }
-
- STDMETHODIMP GetDouble(REFGUID guidKey, double *pfValue)
- {
- return m_attributes->GetDouble(guidKey, pfValue);
- }
-
- STDMETHODIMP GetGUID(REFGUID guidKey, GUID *pguidValue)
- {
- return m_attributes->GetGUID(guidKey, pguidValue);
- }
-
- STDMETHODIMP GetStringLength(REFGUID guidKey, UINT32 *pcchLength)
- {
- return m_attributes->GetStringLength(guidKey, pcchLength);
- }
-
- STDMETHODIMP GetString(REFGUID guidKey, LPWSTR pwszValue, UINT32 cchBufSize, UINT32 *pcchLength)
- {
- return m_attributes->GetString(guidKey, pwszValue, cchBufSize, pcchLength);
- }
-
- STDMETHODIMP GetAllocatedString(REFGUID guidKey, LPWSTR *ppwszValue, UINT32 *pcchLength)
- {
- return m_attributes->GetAllocatedString(guidKey, ppwszValue, pcchLength);
- }
-
- STDMETHODIMP GetBlobSize(REFGUID guidKey, UINT32 *pcbBlobSize)
- {
- return m_attributes->GetBlobSize(guidKey, pcbBlobSize);
- }
-
- STDMETHODIMP GetBlob(REFGUID guidKey, UINT8 *pBuf, UINT32 cbBufSize, UINT32 *pcbBlobSize)
- {
- return m_attributes->GetBlob(guidKey, pBuf, cbBufSize, pcbBlobSize);
- }
-
- STDMETHODIMP GetAllocatedBlob(REFGUID guidKey, UINT8 **ppBuf, UINT32 *pcbSize)
- {
- return m_attributes->GetAllocatedBlob(guidKey, ppBuf, pcbSize);
- }
-
- STDMETHODIMP GetUnknown(REFGUID guidKey, REFIID riid, LPVOID *ppv)
- {
- return m_attributes->GetUnknown(guidKey, riid, ppv);
- }
-
- STDMETHODIMP SetItem(REFGUID guidKey, REFPROPVARIANT Value)
- {
- return m_attributes->SetItem(guidKey, Value);
- }
-
- STDMETHODIMP DeleteItem(REFGUID guidKey)
- {
- return m_attributes->DeleteItem(guidKey);
- }
-
- STDMETHODIMP DeleteAllItems()
- {
- return m_attributes->DeleteAllItems();
- }
-
- STDMETHODIMP SetUINT32(REFGUID guidKey, UINT32 unValue)
- {
- return m_attributes->SetUINT32(guidKey, unValue);
- }
-
- STDMETHODIMP SetUINT64(REFGUID guidKey, UINT64 unValue)
- {
- return m_attributes->SetUINT64(guidKey, unValue);
- }
-
- STDMETHODIMP SetDouble(REFGUID guidKey, double fValue)
- {
- return m_attributes->SetDouble(guidKey, fValue);
- }
-
- STDMETHODIMP SetGUID(REFGUID guidKey, REFGUID guidValue)
- {
- return m_attributes->SetGUID(guidKey, guidValue);
- }
-
- STDMETHODIMP SetString(REFGUID guidKey, LPCWSTR wszValue)
- {
- return m_attributes->SetString(guidKey, wszValue);
- }
-
- STDMETHODIMP SetBlob(REFGUID guidKey, const UINT8 *pBuf, UINT32 cbBufSize)
- {
- return m_attributes->SetBlob(guidKey, pBuf, cbBufSize);
- }
-
- STDMETHODIMP SetUnknown(REFGUID guidKey, IUnknown *pUnknown)
- {
- return m_attributes->SetUnknown(guidKey, pUnknown);
- }
-
- STDMETHODIMP LockStore()
- {
- return m_attributes->LockStore();
- }
-
- STDMETHODIMP UnlockStore()
- {
- return m_attributes->UnlockStore();
- }
-
- STDMETHODIMP GetCount(UINT32 *pcItems)
- {
- return m_attributes->GetCount(pcItems);
- }
-
- STDMETHODIMP GetItemByIndex(UINT32 unIndex, GUID *pguidKey, PROPVARIANT *pValue)
- {
- return m_attributes->GetItemByIndex(unIndex, pguidKey, pValue);
- }
-
- STDMETHODIMP CopyAllItems(IMFAttributes *pDest)
- {
- return m_attributes->CopyAllItems(pDest);
- }
-
-private:
- IMFAttributes *m_attributes;
- ULONG m_cRef;
-};
-
-#endif // MFACTIVATE_H
diff --git a/src/plugins/wmf/player/mfaudioendpointcontrol.cpp b/src/plugins/wmf/player/mfaudioendpointcontrol.cpp
deleted file mode 100644
index 3b86c52b7..000000000
--- a/src/plugins/wmf/player/mfaudioendpointcontrol.cpp
+++ /dev/null
@@ -1,180 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt Mobility Components.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "QtCore/qdebug.h"
-#include "mfaudioendpointcontrol.h"
-
-#include <mmdeviceapi.h>
-
-MFAudioEndpointControl::MFAudioEndpointControl(QObject *parent)
- : QAudioOutputSelectorControl(parent)
- , m_currentActivate(0)
-{
-}
-
-MFAudioEndpointControl::~MFAudioEndpointControl()
-{
- clear();
-}
-
-void MFAudioEndpointControl::clear()
-{
- m_activeEndpoint.clear();
-
- for (auto it = m_devices.cbegin(), end = m_devices.cend(); it != end; ++it)
- CoTaskMemFree(it.value());
-
- m_devices.clear();
-
- if (m_currentActivate)
- m_currentActivate->Release();
- m_currentActivate = NULL;
-}
-
-QList<QString> MFAudioEndpointControl::availableOutputs() const
-{
- return m_devices.keys();
-}
-
-QString MFAudioEndpointControl::outputDescription(const QString &name) const
-{
- return name.section(QLatin1Char('\\'), -1);
-}
-
-QString MFAudioEndpointControl::defaultOutput() const
-{
- return m_defaultEndpoint;
-}
-
-QString MFAudioEndpointControl::activeOutput() const
-{
- return m_activeEndpoint;
-}
-
-void MFAudioEndpointControl::setActiveOutput(const QString &name)
-{
- if (m_activeEndpoint == name)
- return;
- QMap<QString, LPWSTR>::iterator it = m_devices.find(name);
- if (it == m_devices.end())
- return;
-
- LPWSTR wstrID = *it;
- IMFActivate *activate = NULL;
- HRESULT hr = MFCreateAudioRendererActivate(&activate);
- if (FAILED(hr)) {
- qWarning() << "Failed to create audio renderer activate";
- return;
- }
-
- if (wstrID) {
- hr = activate->SetString(MF_AUDIO_RENDERER_ATTRIBUTE_ENDPOINT_ID, wstrID);
- } else {
- //This is the default one that has been inserted in updateEndpoints(),
- //so give the activate a hint that we want to use the device for multimedia playback
- //then the media foundation will choose an appropriate one.
-
- //from MSDN:
- //The ERole enumeration defines constants that indicate the role that the system has assigned to an audio endpoint device.
- //eMultimedia: Music, movies, narration, and live music recording.
- hr = activate->SetUINT32(MF_AUDIO_RENDERER_ATTRIBUTE_ENDPOINT_ROLE, eMultimedia);
- }
-
- if (FAILED(hr)) {
- qWarning() << "Failed to set attribute for audio device" << name;
- return;
- }
-
- if (m_currentActivate)
- m_currentActivate->Release();
- m_currentActivate = activate;
- m_activeEndpoint = name;
-}
-
-IMFActivate* MFAudioEndpointControl::createActivate()
-{
- clear();
-
- updateEndpoints();
-
- // Check if an endpoint is available ("Default" is always inserted)
- if (m_devices.count() <= 1)
- return NULL;
-
- setActiveOutput(m_defaultEndpoint);
-
- return m_currentActivate;
-}
-
-void MFAudioEndpointControl::updateEndpoints()
-{
- m_defaultEndpoint = QString::fromLatin1("Default");
- m_devices.insert(m_defaultEndpoint, NULL);
-
- IMMDeviceEnumerator *pEnum = NULL;
- HRESULT hr = CoCreateInstance(__uuidof(MMDeviceEnumerator),
- NULL, CLSCTX_ALL,
- __uuidof(IMMDeviceEnumerator),
- (void**)&pEnum);
- if (SUCCEEDED(hr)) {
- IMMDeviceCollection *pDevices = NULL;
- hr = pEnum->EnumAudioEndpoints(eRender, DEVICE_STATE_ACTIVE, &pDevices);
- if (SUCCEEDED(hr)) {
- UINT count;
- hr = pDevices->GetCount(&count);
- if (SUCCEEDED(hr)) {
- for (UINT i = 0; i < count; ++i) {
- IMMDevice *pDevice = NULL;
- hr = pDevices->Item(i, &pDevice);
- if (SUCCEEDED(hr)) {
- LPWSTR wstrID = NULL;
- hr = pDevice->GetId(&wstrID);
- if (SUCCEEDED(hr)) {
- QString deviceId = QString::fromWCharArray(wstrID);
- m_devices.insert(deviceId, wstrID);
- }
- pDevice->Release();
- }
- }
- }
- pDevices->Release();
- }
- pEnum->Release();
- }
-}
diff --git a/src/plugins/wmf/player/mfaudioendpointcontrol.h b/src/plugins/wmf/player/mfaudioendpointcontrol.h
deleted file mode 100644
index a439c31a5..000000000
--- a/src/plugins/wmf/player/mfaudioendpointcontrol.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt Mobility Components.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef MFAUDIOENDPOINTCONTROL_H
-#define MFAUDIOENDPOINTCONTROL_H
-
-#include <mfapi.h>
-#include <mfidl.h>
-
-#include "qaudiooutputselectorcontrol.h"
-
-class MFPlayerService;
-
-QT_USE_NAMESPACE
-
-class MFAudioEndpointControl : public QAudioOutputSelectorControl
-{
- Q_OBJECT
-public:
- MFAudioEndpointControl(QObject *parent = 0);
- ~MFAudioEndpointControl();
-
- QList<QString> availableOutputs() const;
-
- QString outputDescription(const QString &name) const;
-
- QString defaultOutput() const;
- QString activeOutput() const;
-
- void setActiveOutput(const QString& name);
-
- IMFActivate* createActivate();
-
-private:
- void clear();
- void updateEndpoints();
-
- QString m_defaultEndpoint;
- QString m_activeEndpoint;
- QMap<QString, LPWSTR> m_devices;
- IMFActivate *m_currentActivate;
-
-};
-
-#endif
-
diff --git a/src/plugins/wmf/player/mfaudioprobecontrol.cpp b/src/plugins/wmf/player/mfaudioprobecontrol.cpp
deleted file mode 100644
index c703922c8..000000000
--- a/src/plugins/wmf/player/mfaudioprobecontrol.cpp
+++ /dev/null
@@ -1,75 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "mfaudioprobecontrol.h"
-
-MFAudioProbeControl::MFAudioProbeControl(QObject *parent):
- QMediaAudioProbeControl(parent)
-{
-}
-
-MFAudioProbeControl::~MFAudioProbeControl()
-{
-}
-
-void MFAudioProbeControl::bufferProbed(const char *data, quint32 size, const QAudioFormat& format, qint64 startTime)
-{
- if (!format.isValid())
- return;
-
- QAudioBuffer audioBuffer = QAudioBuffer(QByteArray(data, size), format, startTime);
-
- {
- QMutexLocker locker(&m_bufferMutex);
- m_pendingBuffer = audioBuffer;
- QMetaObject::invokeMethod(this, "bufferProbed", Qt::QueuedConnection);
- }
-}
-
-void MFAudioProbeControl::bufferProbed()
-{
- QAudioBuffer audioBuffer;
- {
- QMutexLocker locker(&m_bufferMutex);
- if (!m_pendingBuffer.isValid())
- return;
- audioBuffer = m_pendingBuffer;
- }
- emit audioBufferProbed(audioBuffer);
-}
diff --git a/src/plugins/wmf/player/mfaudioprobecontrol.h b/src/plugins/wmf/player/mfaudioprobecontrol.h
deleted file mode 100644
index c8a06148f..000000000
--- a/src/plugins/wmf/player/mfaudioprobecontrol.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef MFAUDIOPROBECONTROL_H
-#define MFAUDIOPROBECONTROL_H
-
-#include <qmediaaudioprobecontrol.h>
-#include <QtCore/qmutex.h>
-#include <qaudiobuffer.h>
-
-QT_USE_NAMESPACE
-
-class MFAudioProbeControl : public QMediaAudioProbeControl
-{
- Q_OBJECT
-public:
- explicit MFAudioProbeControl(QObject *parent);
- virtual ~MFAudioProbeControl();
-
- void bufferProbed(const char *data, quint32 size, const QAudioFormat& format, qint64 startTime);
-
-private slots:
- void bufferProbed();
-
-private:
- QAudioBuffer m_pendingBuffer;
- QMutex m_bufferMutex;
-};
-
-#endif
diff --git a/src/plugins/wmf/player/mfevrvideowindowcontrol.cpp b/src/plugins/wmf/player/mfevrvideowindowcontrol.cpp
deleted file mode 100644
index 4b3e0f303..000000000
--- a/src/plugins/wmf/player/mfevrvideowindowcontrol.cpp
+++ /dev/null
@@ -1,91 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "mfevrvideowindowcontrol.h"
-
-#include <qdebug.h>
-
-MFEvrVideoWindowControl::MFEvrVideoWindowControl(QObject *parent)
- : EvrVideoWindowControl(parent)
- , m_currentActivate(NULL)
- , m_evrSink(NULL)
-{
-}
-
-MFEvrVideoWindowControl::~MFEvrVideoWindowControl()
-{
- clear();
-}
-
-void MFEvrVideoWindowControl::clear()
-{
- setEvr(NULL);
-
- if (m_evrSink)
- m_evrSink->Release();
- if (m_currentActivate) {
- m_currentActivate->ShutdownObject();
- m_currentActivate->Release();
- }
- m_evrSink = NULL;
- m_currentActivate = NULL;
-}
-
-IMFActivate* MFEvrVideoWindowControl::createActivate()
-{
- clear();
-
- if (FAILED(MFCreateVideoRendererActivate(0, &m_currentActivate))) {
- qWarning() << "Failed to create evr video renderer activate!";
- return NULL;
- }
- if (FAILED(m_currentActivate->ActivateObject(IID_IMFMediaSink, (LPVOID*)(&m_evrSink)))) {
- qWarning() << "Failed to activate evr media sink!";
- return NULL;
- }
- if (!setEvr(m_evrSink))
- return NULL;
-
- return m_currentActivate;
-}
-
-void MFEvrVideoWindowControl::releaseActivate()
-{
- clear();
-}
diff --git a/src/plugins/wmf/player/mfevrvideowindowcontrol.h b/src/plugins/wmf/player/mfevrvideowindowcontrol.h
deleted file mode 100644
index 96634e6d8..000000000
--- a/src/plugins/wmf/player/mfevrvideowindowcontrol.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef MFEVRVIDEOWINDOWCONTROL_H
-#define MFEVRVIDEOWINDOWCONTROL_H
-
-#include "evrvideowindowcontrol.h"
-
-QT_USE_NAMESPACE
-
-class MFEvrVideoWindowControl : public EvrVideoWindowControl
-{
-public:
- MFEvrVideoWindowControl(QObject *parent = 0);
- ~MFEvrVideoWindowControl();
-
- IMFActivate* createActivate();
- void releaseActivate();
-
-private:
- void clear();
-
- IMFActivate *m_currentActivate;
- IMFMediaSink *m_evrSink;
-};
-
-#endif // MFEVRVIDEOWINDOWCONTROL_H
diff --git a/src/plugins/wmf/player/mfmetadatacontrol.cpp b/src/plugins/wmf/player/mfmetadatacontrol.cpp
deleted file mode 100644
index 74063f7d1..000000000
--- a/src/plugins/wmf/player/mfmetadatacontrol.cpp
+++ /dev/null
@@ -1,431 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt Mobility Components.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <qmediametadata.h>
-#include <qdatetime.h>
-#include <qimage.h>
-
-#include "mfmetadatacontrol.h"
-#include "mfplayerservice.h"
-#include "Propkey.h"
-
-//#define DEBUG_MEDIAFOUNDATION
-
-static QString nameForGUID(GUID guid)
-{
- // Audio formats
- if (guid == MFAudioFormat_AAC)
- return QStringLiteral("MPEG AAC Audio");
- else if (guid == MFAudioFormat_ADTS)
- return QStringLiteral("MPEG ADTS AAC Audio");
- else if (guid == MFAudioFormat_Dolby_AC3_SPDIF)
- return QStringLiteral("Dolby AC-3 SPDIF");
- else if (guid == MFAudioFormat_DRM)
- return QStringLiteral("DRM");
- else if (guid == MFAudioFormat_DTS)
- return QStringLiteral("Digital Theater Systems Audio (DTS)");
- else if (guid == MFAudioFormat_Float)
- return QStringLiteral("IEEE Float Audio");
- else if (guid == MFAudioFormat_MP3)
- return QStringLiteral("MPEG Audio Layer-3 (MP3)");
- else if (guid == MFAudioFormat_MPEG)
- return QStringLiteral("MPEG-1 Audio");
- else if (guid == MFAudioFormat_MSP1)
- return QStringLiteral("Windows Media Audio Voice");
- else if (guid == MFAudioFormat_PCM)
- return QStringLiteral("Uncompressed PCM Audio");
- else if (guid == MFAudioFormat_WMASPDIF)
- return QStringLiteral("Windows Media Audio 9 SPDIF");
- else if (guid == MFAudioFormat_WMAudioV8)
- return QStringLiteral("Windows Media Audio 8 (WMA2)");
- else if (guid == MFAudioFormat_WMAudioV9)
- return QStringLiteral("Windows Media Audio 9 (WMA3");
- else if (guid == MFAudioFormat_WMAudio_Lossless)
- return QStringLiteral("Windows Media Audio 9 Lossless");
-
- // Video formats
- if (guid == MFVideoFormat_DV25)
- return QStringLiteral("DVCPRO 25 (DV25)");
- else if (guid == MFVideoFormat_DV50)
- return QStringLiteral("DVCPRO 50 (DV50)");
- else if (guid == MFVideoFormat_DVC)
- return QStringLiteral("DVC/DV Video");
- else if (guid == MFVideoFormat_DVH1)
- return QStringLiteral("DVCPRO 100 (DVH1)");
- else if (guid == MFVideoFormat_DVHD)
- return QStringLiteral("HD-DVCR (DVHD)");
- else if (guid == MFVideoFormat_DVSD)
- return QStringLiteral("SDL-DVCR (DVSD)");
- else if (guid == MFVideoFormat_DVSL)
- return QStringLiteral("SD-DVCR (DVSL)");
- else if (guid == MFVideoFormat_H264)
- return QStringLiteral("H.264 Video");
- else if (guid == MFVideoFormat_M4S2)
- return QStringLiteral("MPEG-4 part 2 Video (M4S2)");
- else if (guid == MFVideoFormat_MJPG)
- return QStringLiteral("Motion JPEG (MJPG)");
- else if (guid == MFVideoFormat_MP43)
- return QStringLiteral("Microsoft MPEG 4 version 3 (MP43)");
- else if (guid == MFVideoFormat_MP4S)
- return QStringLiteral("ISO MPEG 4 version 1 (MP4S)");
- else if (guid == MFVideoFormat_MP4V)
- return QStringLiteral("MPEG-4 part 2 Video (MP4V)");
- else if (guid == MFVideoFormat_MPEG2)
- return QStringLiteral("MPEG-2 Video");
- else if (guid == MFVideoFormat_MPG1)
- return QStringLiteral("MPEG-1 Video");
- else if (guid == MFVideoFormat_MSS1)
- return QStringLiteral("Windows Media Screen 1 (MSS1)");
- else if (guid == MFVideoFormat_MSS2)
- return QStringLiteral("Windows Media Video 9 Screen (MSS2)");
- else if (guid == MFVideoFormat_WMV1)
- return QStringLiteral("Windows Media Video 7 (WMV1)");
- else if (guid == MFVideoFormat_WMV2)
- return QStringLiteral("Windows Media Video 8 (WMV2)");
- else if (guid == MFVideoFormat_WMV3)
- return QStringLiteral("Windows Media Video 9 (WMV3)");
- else if (guid == MFVideoFormat_WVC1)
- return QStringLiteral("Windows Media Video VC1 (WVC1)");
-
- else
- return QStringLiteral("Unknown codec");
-}
-
-MFMetaDataControl::MFMetaDataControl(QObject *parent)
- : QMetaDataReaderControl(parent)
- , m_metaData(0)
- , m_content(0)
-{
-}
-
-MFMetaDataControl::~MFMetaDataControl()
-{
- if (m_metaData)
- m_metaData->Release();
- if (m_content)
- m_content->Release();
-}
-
-bool MFMetaDataControl::isMetaDataAvailable() const
-{
- return m_content || m_metaData;
-}
-
-QVariant MFMetaDataControl::metaData(const QString &key) const
-{
- QVariant value;
- if (!isMetaDataAvailable())
- return value;
-
- int index = m_availableMetaDatas.indexOf(key);
- if (index < 0)
- return value;
-
- PROPVARIANT var;
- PropVariantInit(&var);
- HRESULT hr = S_FALSE;
- if (m_content)
- hr = m_content->GetValue(m_commonKeys[index], &var);
- else if (m_metaData)
- hr = m_metaData->GetProperty(reinterpret_cast<LPCWSTR>(m_commonNames[index].utf16()), &var);
-
- if (SUCCEEDED(hr)) {
- value = convertValue(var);
-
- // some metadata needs to be reformatted
- if (value.isValid() && m_content) {
- if (key == QMediaMetaData::MediaType) {
- QString v = value.toString();
- if (v == QLatin1String("{D1607DBC-E323-4BE2-86A1-48A42A28441E}"))
- value = QStringLiteral("Music");
- else if (v == QLatin1String("{DB9830BD-3AB3-4FAB-8A37-1A995F7FF74B}"))
- value = QStringLiteral("Video");
- else if (v == QLatin1String("{01CD0F29-DA4E-4157-897B-6275D50C4F11}"))
- value = QStringLiteral("Audio");
- else if (v == QLatin1String("{FCF24A76-9A57-4036-990D-E35DD8B244E1}"))
- value = QStringLiteral("Other");
- } else if (key == QMediaMetaData::Duration) {
- // duration is provided in 100-nanosecond units, convert to milliseconds
- value = (value.toLongLong() + 10000) / 10000;
- } else if (key == QMediaMetaData::AudioCodec || key == QMediaMetaData::VideoCodec) {
- GUID guid;
- if (SUCCEEDED(CLSIDFromString((const WCHAR*)value.toString().utf16(), &guid)))
- value = nameForGUID(guid);
- } else if (key == QMediaMetaData::Resolution) {
- QSize res;
- res.setHeight(value.toUInt());
- if (m_content && SUCCEEDED(m_content->GetValue(PKEY_Video_FrameWidth, &var)))
- res.setWidth(convertValue(var).toUInt());
- value = res;
- } else if (key == QMediaMetaData::Orientation) {
- uint orientation = 0;
- if (m_content && SUCCEEDED(m_content->GetValue(PKEY_Video_Orientation, &var)))
- orientation = convertValue(var).toUInt();
- value = orientation;
- } else if (key == QMediaMetaData::PixelAspectRatio) {
- QSize aspectRatio;
- aspectRatio.setWidth(value.toUInt());
- if (m_content && SUCCEEDED(m_content->GetValue(PKEY_Video_VerticalAspectRatio, &var)))
- aspectRatio.setHeight(convertValue(var).toUInt());
- value = aspectRatio;
- } else if (key == QMediaMetaData::VideoFrameRate) {
- value = value.toReal() / 1000.f;
- }
- }
- }
-
- PropVariantClear(&var);
- return value;
-}
-
-QVariant MFMetaDataControl::convertValue(const PROPVARIANT& var) const
-{
- QVariant value;
- switch (var.vt) {
- case VT_LPWSTR:
- value = QString::fromUtf16(reinterpret_cast<const ushort*>(var.pwszVal));
- break;
- case VT_UI4:
- value = uint(var.ulVal);
- break;
- case VT_UI8:
- value = qulonglong(var.uhVal.QuadPart);
- break;
- case VT_BOOL:
- value = bool(var.boolVal);
- break;
- case VT_FILETIME:
- SYSTEMTIME sysDate;
- if (!FileTimeToSystemTime(&var.filetime, &sysDate))
- break;
- value = QDate(sysDate.wYear, sysDate.wMonth, sysDate.wDay);
- break;
- case VT_STREAM:
- {
- STATSTG stat;
- if (FAILED(var.pStream->Stat(&stat, STATFLAG_NONAME)))
- break;
- void *data = malloc(stat.cbSize.QuadPart);
- ULONG read = 0;
- if (FAILED(var.pStream->Read(data, stat.cbSize.QuadPart, &read))) {
- free(data);
- break;
- }
- value = QImage::fromData((const uchar*)data, read);
- free(data);
- }
- break;
- case VT_VECTOR | VT_LPWSTR:
- QStringList vList;
- for (ULONG i = 0; i < var.calpwstr.cElems; ++i)
- vList.append(QString::fromUtf16(reinterpret_cast<const ushort*>(var.calpwstr.pElems[i])));
- value = vList;
- break;
- }
- return value;
-}
-
-QStringList MFMetaDataControl::availableMetaData() const
-{
- return m_availableMetaDatas;
-}
-
-void MFMetaDataControl::updateSource(IMFPresentationDescriptor* sourcePD, IMFMediaSource* mediaSource)
-{
- if (m_metaData) {
- m_metaData->Release();
- m_metaData = 0;
- }
-
- if (m_content) {
- m_content->Release();
- m_content = 0;
- }
-
- m_availableMetaDatas.clear();
- m_commonKeys.clear();
- m_commonNames.clear();
-
- if (SUCCEEDED(MFGetService(mediaSource, MF_PROPERTY_HANDLER_SERVICE, IID_PPV_ARGS(&m_content)))) {
- DWORD cProps;
- if (SUCCEEDED(m_content->GetCount(&cProps))) {
- for (DWORD i = 0; i < cProps; i++)
- {
- PROPERTYKEY key;
- if (FAILED(m_content->GetAt(i, &key)))
- continue;
- bool common = true;
- if (key == PKEY_Author) {
- m_availableMetaDatas.push_back(QMediaMetaData::Author);
- } else if (key == PKEY_Title) {
- m_availableMetaDatas.push_back(QMediaMetaData::Title);
- } else if (key == PKEY_Media_SubTitle) {
- m_availableMetaDatas.push_back(QMediaMetaData::SubTitle);
- } else if (key == PKEY_ParentalRating) {
- m_availableMetaDatas.push_back(QMediaMetaData::ParentalRating);
- } else if (key == PKEY_Media_EncodingSettings) {
- m_availableMetaDatas.push_back(QMediaMetaData::Description);
- } else if (key == PKEY_Copyright) {
- m_availableMetaDatas.push_back(QMediaMetaData::Copyright);
- } else if (key == PKEY_Comment) {
- m_availableMetaDatas.push_back(QMediaMetaData::Comment);
- } else if (key == PKEY_Media_ProviderStyle) {
- m_availableMetaDatas.push_back(QMediaMetaData::Genre);
- } else if (key == PKEY_Media_Year) {
- m_availableMetaDatas.push_back(QMediaMetaData::Year);
- } else if (key == PKEY_Media_DateEncoded) {
- m_availableMetaDatas.push_back(QMediaMetaData::Date);
- } else if (key == PKEY_Rating) {
- m_availableMetaDatas.push_back(QMediaMetaData::UserRating);
- } else if (key == PKEY_Keywords) {
- m_availableMetaDatas.push_back(QMediaMetaData::Keywords);
- } else if (key == PKEY_Language) {
- m_availableMetaDatas.push_back(QMediaMetaData::Language);
- } else if (key == PKEY_Media_Publisher) {
- m_availableMetaDatas.push_back(QMediaMetaData::Publisher);
- } else if (key == PKEY_Media_ClassPrimaryID) {
- m_availableMetaDatas.push_back(QMediaMetaData::MediaType);
- } else if (key == PKEY_Media_Duration) {
- m_availableMetaDatas.push_back(QMediaMetaData::Duration);
- } else if (key == PKEY_Audio_EncodingBitrate) {
- m_availableMetaDatas.push_back(QMediaMetaData::AudioBitRate);
- } else if (key == PKEY_Audio_Format) {
- m_availableMetaDatas.push_back(QMediaMetaData::AudioCodec);
- } else if (key == PKEY_Media_AverageLevel) {
- m_availableMetaDatas.push_back(QMediaMetaData::AverageLevel);
- } else if (key == PKEY_Audio_ChannelCount) {
- m_availableMetaDatas.push_back(QMediaMetaData::ChannelCount);
- } else if (key == PKEY_Audio_PeakValue) {
- m_availableMetaDatas.push_back(QMediaMetaData::PeakValue);
- } else if (key == PKEY_Audio_SampleRate) {
- m_availableMetaDatas.push_back(QMediaMetaData::SampleRate);
- } else if (key == PKEY_Music_AlbumTitle) {
- m_availableMetaDatas.push_back(QMediaMetaData::AlbumTitle);
- } else if (key == PKEY_Music_AlbumArtist) {
- m_availableMetaDatas.push_back(QMediaMetaData::AlbumArtist);
- } else if (key == PKEY_Music_Artist) {
- m_availableMetaDatas.push_back(QMediaMetaData::ContributingArtist);
- } else if (key == PKEY_Music_Composer) {
- m_availableMetaDatas.push_back(QMediaMetaData::Composer);
- } else if (key == PKEY_Music_Conductor) {
- m_availableMetaDatas.push_back(QMediaMetaData::Conductor);
- } else if (key == PKEY_Music_Lyrics) {
- m_availableMetaDatas.push_back(QMediaMetaData::Lyrics);
- } else if (key == PKEY_Music_Mood) {
- m_availableMetaDatas.push_back(QMediaMetaData::Mood);
- } else if (key == PKEY_Music_TrackNumber) {
- m_availableMetaDatas.push_back(QMediaMetaData::TrackNumber);
- } else if (key == PKEY_Music_Genre) {
- m_availableMetaDatas.push_back(QMediaMetaData::Genre);
- } else if (key == PKEY_ThumbnailStream) {
- m_availableMetaDatas.push_back(QMediaMetaData::ThumbnailImage);
- } else if (key == PKEY_Video_FrameHeight) {
- m_availableMetaDatas.push_back(QMediaMetaData::Resolution);
- } else if (key == PKEY_Video_Orientation) {
- m_availableMetaDatas.push_back(QMediaMetaData::Orientation);
- } else if (key == PKEY_Video_HorizontalAspectRatio) {
- m_availableMetaDatas.push_back(QMediaMetaData::PixelAspectRatio);
- } else if (key == PKEY_Video_FrameRate) {
- m_availableMetaDatas.push_back(QMediaMetaData::VideoFrameRate);
- } else if (key == PKEY_Video_EncodingBitrate) {
- m_availableMetaDatas.push_back(QMediaMetaData::VideoBitRate);
- } else if (key == PKEY_Video_Compression) {
- m_availableMetaDatas.push_back(QMediaMetaData::VideoCodec);
- } else if (key == PKEY_Video_Director) {
- m_availableMetaDatas.push_back(QMediaMetaData::Director);
- } else if (key == PKEY_Media_Writer) {
- m_availableMetaDatas.push_back(QMediaMetaData::Writer);
- } else {
- common = false;
- //TODO: add more extended keys
- }
- if (common)
- m_commonKeys.push_back(key);
- }
- } else {
- m_content->Release();
- m_content = NULL;
- }
- }
-
- if (!m_content) {
- //fallback to Vista approach
- IMFMetadataProvider *provider = NULL;
- if (SUCCEEDED(MFGetService(mediaSource, MF_METADATA_PROVIDER_SERVICE, IID_PPV_ARGS(&provider)))) {
- if (SUCCEEDED(provider->GetMFMetadata(sourcePD, 0, 0, &m_metaData))) {
- PROPVARIANT varNames;
- PropVariantInit(&varNames);
- if (SUCCEEDED(m_metaData->GetAllPropertyNames(&varNames)) && varNames.vt == (VT_VECTOR | VT_LPWSTR)) {
- ULONG cElements = varNames.calpwstr.cElems;
- for (ULONG i = 0; i < cElements; i++)
- {
- const WCHAR* sName = varNames.calpwstr.pElems[i];
-#ifdef DEBUG_MEDIAFOUNDATION
- qDebug() << "metadata: " << QString::fromUtf16(sName);
-#endif
- if (wcscmp(sName, L"Author") == 0) {
- m_availableMetaDatas.push_back(QMediaMetaData::Author);
- } else if (wcscmp(sName, L"Title") == 0) {
- m_availableMetaDatas.push_back(QMediaMetaData::Title);
- } else if (wcscmp(sName, L"Rating") == 0) {
- m_availableMetaDatas.push_back(QMediaMetaData::ParentalRating);
- } else if (wcscmp(sName, L"Description") == 0) {
- m_availableMetaDatas.push_back(QMediaMetaData::Description);
- } else if (wcscmp(sName, L"Copyright") == 0) {
- m_availableMetaDatas.push_back(QMediaMetaData::Copyright);
- //TODO: add more common keys
- } else {
- m_availableMetaDatas.push_back(QString::fromUtf16(reinterpret_cast<const ushort*>(sName)));
- }
- m_commonNames.push_back(QString::fromUtf16(reinterpret_cast<const ushort*>(sName)));
- }
- }
- PropVariantClear(&varNames);
- } else {
- qWarning("Failed to get IMFMetadata");
- }
- provider->Release();
- } else {
- qWarning("Failed to get IMFMetadataProvider from source");
- }
- }
-
- emit metaDataChanged();
- emit metaDataAvailableChanged(m_metaData || m_content);
-}
diff --git a/src/plugins/wmf/player/mfmetadatacontrol.h b/src/plugins/wmf/player/mfmetadatacontrol.h
deleted file mode 100644
index 7ae06cedb..000000000
--- a/src/plugins/wmf/player/mfmetadatacontrol.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt Mobility Components.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef MFMETADATACONTROL_H
-#define MFMETADATACONTROL_H
-
-#include <qmetadatareadercontrol.h>
-#include "Mfidl.h"
-
-QT_USE_NAMESPACE
-
-class MFMetaDataControl : public QMetaDataReaderControl
-{
- Q_OBJECT
-public:
- MFMetaDataControl(QObject *parent = 0);
- ~MFMetaDataControl();
-
- bool isMetaDataAvailable() const;
-
- QVariant metaData(const QString &key) const;
- QStringList availableMetaData() const;
-
- void updateSource(IMFPresentationDescriptor* sourcePD, IMFMediaSource* mediaSource);
-
-private:
- QVariant convertValue(const PROPVARIANT& var) const;
- IPropertyStore *m_content; //for Windows7
- IMFMetadata *m_metaData; //for Vista
-
- QStringList m_availableMetaDatas;
- QList<PROPERTYKEY> m_commonKeys; //for Windows7
- QStringList m_commonNames; //for Vista
-};
-
-#endif
diff --git a/src/plugins/wmf/player/mfplayercontrol.cpp b/src/plugins/wmf/player/mfplayercontrol.cpp
deleted file mode 100644
index b070ce482..000000000
--- a/src/plugins/wmf/player/mfplayercontrol.cpp
+++ /dev/null
@@ -1,316 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt Mobility Components.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "mfplayercontrol.h"
-#include <qtcore/qdebug.h>
-
-//#define DEBUG_MEDIAFOUNDATION
-
-MFPlayerControl::MFPlayerControl(MFPlayerSession *session)
-: QMediaPlayerControl(session)
-, m_state(QMediaPlayer::StoppedState)
-, m_stateDirty(false)
-, m_videoAvailable(false)
-, m_audioAvailable(false)
-, m_duration(-1)
-, m_seekable(false)
-, m_session(session)
-{
- QObject::connect(m_session, SIGNAL(statusChanged()), this, SLOT(handleStatusChanged()));
- QObject::connect(m_session, SIGNAL(videoAvailable()), this, SLOT(handleVideoAvailable()));
- QObject::connect(m_session, SIGNAL(audioAvailable()), this, SLOT(handleAudioAvailable()));
- QObject::connect(m_session, SIGNAL(durationUpdate(qint64)), this, SLOT(handleDurationUpdate(qint64)));
- QObject::connect(m_session, SIGNAL(seekableUpdate(bool)), this, SLOT(handleSeekableUpdate(bool)));
- QObject::connect(m_session, SIGNAL(error(QMediaPlayer::Error,QString,bool)), this, SLOT(handleError(QMediaPlayer::Error,QString,bool)));
- QObject::connect(m_session, SIGNAL(positionChanged(qint64)), this, SIGNAL(positionChanged(qint64)));
- QObject::connect(m_session, SIGNAL(volumeChanged(int)), this, SIGNAL(volumeChanged(int)));
- QObject::connect(m_session, SIGNAL(mutedChanged(bool)), this, SIGNAL(mutedChanged(bool)));
- QObject::connect(m_session, SIGNAL(playbackRateChanged(qreal)), this, SIGNAL(playbackRateChanged(qreal)));
- QObject::connect(m_session, SIGNAL(bufferStatusChanged(int)), this, SIGNAL(bufferStatusChanged(int)));
-}
-
-MFPlayerControl::~MFPlayerControl()
-{
-}
-
-void MFPlayerControl::setMedia(const QMediaContent &media, QIODevice *stream)
-{
- if (m_state != QMediaPlayer::StoppedState) {
- changeState(QMediaPlayer::StoppedState);
- m_session->stop(true);
- refreshState();
- }
-
- m_media = media;
- m_stream = stream;
- resetAudioVideoAvailable();
- handleDurationUpdate(-1);
- handleSeekableUpdate(false);
- m_session->load(media, stream);
- emit mediaChanged(m_media);
-}
-
-void MFPlayerControl::play()
-{
- if (m_state == QMediaPlayer::PlayingState)
- return;
- if (QMediaPlayer::InvalidMedia == m_session->status())
- m_session->load(m_media, m_stream);
-
- switch (m_session->status()) {
- case QMediaPlayer::UnknownMediaStatus:
- case QMediaPlayer::NoMedia:
- case QMediaPlayer::InvalidMedia:
- return;
- case QMediaPlayer::LoadedMedia:
- case QMediaPlayer::BufferingMedia:
- case QMediaPlayer::BufferedMedia:
- case QMediaPlayer::EndOfMedia:
- changeState(QMediaPlayer::PlayingState);
- m_session->start();
- break;
- default: //Loading/Stalled
- changeState(QMediaPlayer::PlayingState);
- break;
- }
- refreshState();
-}
-
-void MFPlayerControl::pause()
-{
- if (m_state != QMediaPlayer::PlayingState)
- return;
- changeState(QMediaPlayer::PausedState);
- m_session->pause();
- refreshState();
-}
-
-void MFPlayerControl::stop()
-{
- if (m_state == QMediaPlayer::StoppedState)
- return;
- changeState(QMediaPlayer::StoppedState);
- m_session->stop();
- refreshState();
-}
-
-void MFPlayerControl::changeState(QMediaPlayer::State state)
-{
- if (m_state == state)
- return;
- m_state = state;
- m_stateDirty = true;
-}
-
-void MFPlayerControl::refreshState()
-{
- if (!m_stateDirty)
- return;
- m_stateDirty = false;
-#ifdef DEBUG_MEDIAFOUNDATION
- qDebug() << "MFPlayerControl::emit stateChanged" << m_state;
-#endif
- emit stateChanged(m_state);
-}
-
-void MFPlayerControl::handleStatusChanged()
-{
- QMediaPlayer::MediaStatus status = m_session->status();
- switch (status) {
- case QMediaPlayer::EndOfMedia:
- changeState(QMediaPlayer::StoppedState);
- break;
- case QMediaPlayer::InvalidMedia:
- break;
- case QMediaPlayer::LoadedMedia:
- case QMediaPlayer::BufferingMedia:
- case QMediaPlayer::BufferedMedia:
- if (m_state == QMediaPlayer::PlayingState)
- m_session->start();
- break;
- }
- emit mediaStatusChanged(m_session->status());
- refreshState();
-}
-
-void MFPlayerControl::handleVideoAvailable()
-{
- if (m_videoAvailable)
- return;
- m_videoAvailable = true;
- emit videoAvailableChanged(m_videoAvailable);
-}
-
-void MFPlayerControl::handleAudioAvailable()
-{
- if (m_audioAvailable)
- return;
- m_audioAvailable = true;
- emit audioAvailableChanged(m_audioAvailable);
-}
-
-void MFPlayerControl::resetAudioVideoAvailable()
-{
- bool videoDirty = false;
- if (m_videoAvailable) {
- m_videoAvailable = false;
- videoDirty = true;
- }
- if (m_audioAvailable) {
- m_audioAvailable = false;
- emit audioAvailableChanged(m_audioAvailable);
- }
- if (videoDirty)
- emit videoAvailableChanged(m_videoAvailable);
-}
-
-void MFPlayerControl::handleDurationUpdate(qint64 duration)
-{
- if (m_duration == duration)
- return;
- m_duration = duration;
- emit durationChanged(m_duration);
-}
-
-void MFPlayerControl::handleSeekableUpdate(bool seekable)
-{
- if (m_seekable == seekable)
- return;
- m_seekable = seekable;
- emit seekableChanged(m_seekable);
-}
-
-QMediaPlayer::State MFPlayerControl::state() const
-{
- return m_state;
-}
-
-QMediaPlayer::MediaStatus MFPlayerControl::mediaStatus() const
-{
- return m_session->status();
-}
-
-qint64 MFPlayerControl::duration() const
-{
- return m_duration;
-}
-
-qint64 MFPlayerControl::position() const
-{
- return m_session->position();
-}
-
-void MFPlayerControl::setPosition(qint64 position)
-{
- if (!m_seekable || position == m_session->position())
- return;
- m_session->setPosition(position);
-}
-
-int MFPlayerControl::volume() const
-{
- return m_session->volume();
-}
-
-void MFPlayerControl::setVolume(int volume)
-{
- m_session->setVolume(volume);
-}
-
-bool MFPlayerControl::isMuted() const
-{
- return m_session->isMuted();
-}
-
-void MFPlayerControl::setMuted(bool muted)
-{
- m_session->setMuted(muted);
-}
-
-int MFPlayerControl::bufferStatus() const
-{
- return m_session->bufferStatus();
-}
-
-bool MFPlayerControl::isAudioAvailable() const
-{
- return m_audioAvailable;
-}
-
-bool MFPlayerControl::isVideoAvailable() const
-{
- return m_videoAvailable;
-}
-
-bool MFPlayerControl::isSeekable() const
-{
- return m_seekable;
-}
-
-QMediaTimeRange MFPlayerControl::availablePlaybackRanges() const
-{
- return m_session->availablePlaybackRanges();
-}
-
-qreal MFPlayerControl::playbackRate() const
-{
- return m_session->playbackRate();
-}
-
-void MFPlayerControl::setPlaybackRate(qreal rate)
-{
- m_session->setPlaybackRate(rate);
-}
-
-QMediaContent MFPlayerControl::media() const
-{
- return m_media;
-}
-
-const QIODevice* MFPlayerControl::mediaStream() const
-{
- return m_stream;
-}
-
-void MFPlayerControl::handleError(QMediaPlayer::Error errorCode, const QString& errorString, bool isFatal)
-{
- if (isFatal)
- stop();
- emit error(int(errorCode), errorString);
-}
diff --git a/src/plugins/wmf/player/mfplayercontrol.h b/src/plugins/wmf/player/mfplayercontrol.h
deleted file mode 100644
index a75fac493..000000000
--- a/src/plugins/wmf/player/mfplayercontrol.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt Mobility Components.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef MFPLAYERCONTROL_H
-#define MFPLAYERCONTROL_H
-
-#include "qmediacontent.h"
-#include "qmediaplayercontrol.h"
-
-#include <QtCore/qcoreevent.h>
-
-#include "mfplayersession.h"
-
-QT_USE_NAMESPACE
-
-class MFPlayerControl : public QMediaPlayerControl
-{
- Q_OBJECT
-public:
- MFPlayerControl(MFPlayerSession *session);
- ~MFPlayerControl();
-
- QMediaPlayer::State state() const;
-
- QMediaPlayer::MediaStatus mediaStatus() const;
-
- qint64 duration() const;
-
- qint64 position() const;
- void setPosition(qint64 position);
-
- int volume() const;
- void setVolume(int volume);
-
- bool isMuted() const;
- void setMuted(bool muted);
-
- int bufferStatus() const;
-
- bool isAudioAvailable() const;
- bool isVideoAvailable() const;
-
- bool isSeekable() const;
-
- QMediaTimeRange availablePlaybackRanges() const;
-
- qreal playbackRate() const;
- void setPlaybackRate(qreal rate);
-
- QMediaContent media() const;
- const QIODevice *mediaStream() const;
- void setMedia(const QMediaContent &media, QIODevice *stream);
-
- void play();
- void pause();
- void stop();
-
-private Q_SLOTS:
- void handleStatusChanged();
- void handleVideoAvailable();
- void handleAudioAvailable();
- void handleDurationUpdate(qint64 duration);
- void handleSeekableUpdate(bool seekable);
- void handleError(QMediaPlayer::Error errorCode, const QString& errorString, bool isFatal);
-
-private:
- void changeState(QMediaPlayer::State state);
- void resetAudioVideoAvailable();
- void refreshState();
-
- QMediaPlayer::State m_state;
- bool m_stateDirty;
- QMediaPlayer::MediaStatus m_status;
- QMediaPlayer::Error m_error;
-
- bool m_videoAvailable;
- bool m_audioAvailable;
- qint64 m_duration;
- bool m_seekable;
-
- QIODevice *m_stream;
- QMediaContent m_media;
- MFPlayerSession *m_session;
-};
-
-#endif
diff --git a/src/plugins/wmf/player/mfplayerservice.cpp b/src/plugins/wmf/player/mfplayerservice.cpp
deleted file mode 100644
index b73390ac7..000000000
--- a/src/plugins/wmf/player/mfplayerservice.cpp
+++ /dev/null
@@ -1,167 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt Mobility Components.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qmediacontent.h"
-
-#include <QtCore/qdebug.h>
-
-#include "mfplayercontrol.h"
-#include "mfevrvideowindowcontrol.h"
-#include "mfvideorenderercontrol.h"
-#include "mfaudioendpointcontrol.h"
-#include "mfaudioprobecontrol.h"
-#include "mfvideoprobecontrol.h"
-#include "mfplayerservice.h"
-#include "mfplayersession.h"
-#include "mfmetadatacontrol.h"
-
-MFPlayerService::MFPlayerService(QObject *parent)
- : QMediaService(parent)
- , m_session(0)
- , m_videoWindowControl(0)
- , m_videoRendererControl(0)
-{
- m_audioEndpointControl = new MFAudioEndpointControl(this);
- m_session = new MFPlayerSession(this);
- m_player = new MFPlayerControl(m_session);
- m_metaDataControl = new MFMetaDataControl(this);
-}
-
-MFPlayerService::~MFPlayerService()
-{
- m_session->close();
-
- if (m_videoWindowControl)
- delete m_videoWindowControl;
-
- if (m_videoRendererControl)
- delete m_videoRendererControl;
-
- m_session->Release();
-}
-
-QMediaControl* MFPlayerService::requestControl(const char *name)
-{
- if (qstrcmp(name, QMediaPlayerControl_iid) == 0) {
- return m_player;
- } else if (qstrcmp(name, QAudioOutputSelectorControl_iid) == 0) {
- return m_audioEndpointControl;
- } else if (qstrcmp(name, QMetaDataReaderControl_iid) == 0) {
- return m_metaDataControl;
- } else if (qstrcmp(name, QVideoRendererControl_iid) == 0) {
- if (!m_videoRendererControl && !m_videoWindowControl) {
- m_videoRendererControl = new MFVideoRendererControl;
- return m_videoRendererControl;
- }
- } else if (qstrcmp(name, QVideoWindowControl_iid) == 0) {
- if (!m_videoRendererControl && !m_videoWindowControl) {
- m_videoWindowControl = new MFEvrVideoWindowControl;
- return m_videoWindowControl;
- }
- } else if (qstrcmp(name,QMediaAudioProbeControl_iid) == 0) {
- if (m_session) {
- MFAudioProbeControl *probe = new MFAudioProbeControl(this);
- m_session->addProbe(probe);
- return probe;
- }
- return 0;
- } else if (qstrcmp(name,QMediaVideoProbeControl_iid) == 0) {
- if (m_session) {
- MFVideoProbeControl *probe = new MFVideoProbeControl(this);
- m_session->addProbe(probe);
- return probe;
- }
- return 0;
- }
-
- return 0;
-}
-
-void MFPlayerService::releaseControl(QMediaControl *control)
-{
- if (!control) {
- qWarning("QMediaService::releaseControl():"
- " Attempted release of null control");
- } else if (control == m_videoRendererControl) {
- m_videoRendererControl->setSurface(0);
- delete m_videoRendererControl;
- m_videoRendererControl = 0;
- return;
- } else if (control == m_videoWindowControl) {
- delete m_videoWindowControl;
- m_videoWindowControl = 0;
- return;
- }
-
- MFAudioProbeControl* audioProbe = qobject_cast<MFAudioProbeControl*>(control);
- if (audioProbe) {
- if (m_session)
- m_session->removeProbe(audioProbe);
- delete audioProbe;
- return;
- }
-
- MFVideoProbeControl* videoProbe = qobject_cast<MFVideoProbeControl*>(control);
- if (videoProbe) {
- if (m_session)
- m_session->removeProbe(videoProbe);
- delete videoProbe;
- return;
- }
-}
-
-MFAudioEndpointControl* MFPlayerService::audioEndpointControl() const
-{
- return m_audioEndpointControl;
-}
-
-MFVideoRendererControl* MFPlayerService::videoRendererControl() const
-{
- return m_videoRendererControl;
-}
-
-MFEvrVideoWindowControl* MFPlayerService::videoWindowControl() const
-{
- return m_videoWindowControl;
-}
-
-MFMetaDataControl* MFPlayerService::metaDataControl() const
-{
- return m_metaDataControl;
-}
diff --git a/src/plugins/wmf/player/mfplayerservice.h b/src/plugins/wmf/player/mfplayerservice.h
deleted file mode 100644
index 78423c0b1..000000000
--- a/src/plugins/wmf/player/mfplayerservice.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt Mobility Components.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef MFPLAYERSERVICE_H
-#define MFPLAYERSERVICE_H
-
-#include <mfapi.h>
-#include <mfidl.h>
-
-#include "qmediaplayer.h"
-#include "qmediaservice.h"
-#include "qmediatimerange.h"
-
-QT_BEGIN_NAMESPACE
-class QMediaContent;
-QT_END_NAMESPACE
-
-QT_USE_NAMESPACE
-
-class MFEvrVideoWindowControl;
-class MFAudioEndpointControl;
-class MFVideoRendererControl;
-class MFPlayerControl;
-class MFMetaDataControl;
-class MFPlayerSession;
-
-class MFPlayerService : public QMediaService
-{
- Q_OBJECT
-public:
- MFPlayerService(QObject *parent = 0);
- ~MFPlayerService();
-
- QMediaControl* requestControl(const char *name);
- void releaseControl(QMediaControl *control);
-
- MFAudioEndpointControl* audioEndpointControl() const;
- MFVideoRendererControl* videoRendererControl() const;
- MFEvrVideoWindowControl* videoWindowControl() const;
- MFMetaDataControl* metaDataControl() const;
-
-private:
- MFPlayerSession *m_session;
- MFVideoRendererControl *m_videoRendererControl;
- MFAudioEndpointControl *m_audioEndpointControl;
- MFEvrVideoWindowControl *m_videoWindowControl;
- MFPlayerControl *m_player;
- MFMetaDataControl *m_metaDataControl;
-};
-
-#endif
diff --git a/src/plugins/wmf/player/mfplayersession.cpp b/src/plugins/wmf/player/mfplayersession.cpp
deleted file mode 100644
index 1d145edc4..000000000
--- a/src/plugins/wmf/player/mfplayersession.cpp
+++ /dev/null
@@ -1,1818 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt Mobility Components.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qmediacontent.h"
-#include "qmediaplayercontrol.h"
-
-#include <QtCore/qcoreapplication.h>
-#include <QtCore/qdatetime.h>
-#include <QtCore/qthread.h>
-#include <QtCore/qvarlengtharray.h>
-#include <QtCore/qdebug.h>
-#include <QtCore/qfile.h>
-#include <QtCore/qbuffer.h>
-
-#include "mfplayercontrol.h"
-#include "mfevrvideowindowcontrol.h"
-#include "mfvideorenderercontrol.h"
-#include "mfaudioendpointcontrol.h"
-
-#include "mfplayersession.h"
-#include "mfplayerservice.h"
-#include "mfmetadatacontrol.h"
-#include <mferror.h>
-#include <nserror.h>
-#include "sourceresolver.h"
-#include "samplegrabber.h"
-#include "mftvideo.h"
-#include <wmcodecdsp.h>
-
-//#define DEBUG_MEDIAFOUNDATION
-
-MFPlayerSession::MFPlayerSession(MFPlayerService *playerService)
- : m_playerService(playerService)
- , m_cRef(1)
- , m_session(0)
- , m_presentationClock(0)
- , m_rateControl(0)
- , m_rateSupport(0)
- , m_volumeControl(0)
- , m_netsourceStatistics(0)
- , m_duration(0)
- , m_sourceResolver(0)
- , m_hCloseEvent(0)
- , m_closing(false)
- , m_pendingRate(1)
- , m_volume(100)
- , m_muted(false)
- , m_status(QMediaPlayer::NoMedia)
- , m_scrubbing(false)
- , m_restoreRate(1)
- , m_mediaTypes(0)
- , m_audioSampleGrabber(0)
- , m_audioSampleGrabberNode(0)
- , m_videoProbeMFT(0)
-{
- QObject::connect(this, SIGNAL(sessionEvent(IMFMediaEvent*)), this, SLOT(handleSessionEvent(IMFMediaEvent*)));
-
- m_pendingState = NoPending;
- ZeroMemory(&m_state, sizeof(m_state));
- m_state.command = CmdStop;
- m_state.prevCmd = CmdNone;
- m_state.rate = 1.0f;
- ZeroMemory(&m_request, sizeof(m_request));
- m_request.command = CmdNone;
- m_request.prevCmd = CmdNone;
- m_request.rate = 1.0f;
-
- m_audioSampleGrabber = new AudioSampleGrabberCallback;
-}
-
-void MFPlayerSession::close()
-{
-#ifdef DEBUG_MEDIAFOUNDATION
- qDebug() << "close";
-#endif
-
- clear();
- if (!m_session)
- return;
-
- HRESULT hr = S_OK;
- if (m_session) {
- m_closing = true;
- hr = m_session->Close();
- if (SUCCEEDED(hr)) {
- DWORD dwWaitResult = WaitForSingleObject(m_hCloseEvent, 100);
- if (dwWaitResult == WAIT_TIMEOUT) {
- qWarning() << "session close time out!";
- }
- }
- m_closing = false;
- }
-
- if (SUCCEEDED(hr)) {
- if (m_session)
- m_session->Shutdown();
- if (m_sourceResolver)
- m_sourceResolver->shutdown();
- }
- if (m_sourceResolver) {
- m_sourceResolver->Release();
- m_sourceResolver = 0;
- }
- if (m_videoProbeMFT) {
- m_videoProbeMFT->Release();
- m_videoProbeMFT = 0;
- }
-
- if (m_playerService->videoRendererControl()) {
- m_playerService->videoRendererControl()->releaseActivate();
- } else if (m_playerService->videoWindowControl()) {
- m_playerService->videoWindowControl()->releaseActivate();
- }
-
- if (m_session)
- m_session->Release();
- m_session = 0;
- if (m_hCloseEvent)
- CloseHandle(m_hCloseEvent);
- m_hCloseEvent = 0;
-}
-
-void MFPlayerSession::addProbe(MFAudioProbeControl *probe)
-{
- m_audioSampleGrabber->addProbe(probe);
-}
-
-void MFPlayerSession::removeProbe(MFAudioProbeControl *probe)
-{
- m_audioSampleGrabber->removeProbe(probe);
-}
-
-void MFPlayerSession::addProbe(MFVideoProbeControl* probe)
-{
- if (m_videoProbes.contains(probe))
- return;
-
- m_videoProbes.append(probe);
-
- if (m_videoProbeMFT)
- m_videoProbeMFT->addProbe(probe);
-}
-
-void MFPlayerSession::removeProbe(MFVideoProbeControl* probe)
-{
- m_videoProbes.removeOne(probe);
-
- if (m_videoProbeMFT)
- m_videoProbeMFT->removeProbe(probe);
-}
-
-MFPlayerSession::~MFPlayerSession()
-{
- m_audioSampleGrabber->Release();
-}
-
-
-void MFPlayerSession::load(const QMediaContent &media, QIODevice *stream)
-{
-#ifdef DEBUG_MEDIAFOUNDATION
- qDebug() << "load";
-#endif
- clear();
- QUrl url = media.request().url();
-
- if (m_status == QMediaPlayer::LoadingMedia && m_sourceResolver)
- m_sourceResolver->cancel();
-
- if (url.isEmpty() && !stream) {
- changeStatus(QMediaPlayer::NoMedia);
- } else if (stream && (!stream->isReadable())) {
- changeStatus(QMediaPlayer::InvalidMedia);
- emit error(QMediaPlayer::ResourceError, tr("Invalid stream source."), true);
- } else {
- createSession();
- changeStatus(QMediaPlayer::LoadingMedia);
- m_sourceResolver->load(url, stream);
- }
- emit positionChanged(position());
-}
-
-void MFPlayerSession::handleSourceError(long hr)
-{
- QString errorString;
- QMediaPlayer::Error errorCode = QMediaPlayer::ResourceError;
- switch (hr) {
- case QMediaPlayer::FormatError:
- errorCode = QMediaPlayer::FormatError;
- errorString = tr("Attempting to play invalid Qt resource.");
- break;
- case NS_E_FILE_NOT_FOUND:
- errorString = tr("The system cannot find the file specified.");
- break;
- case NS_E_SERVER_NOT_FOUND:
- errorString = tr("The specified server could not be found.");
- break;
- case MF_E_UNSUPPORTED_BYTESTREAM_TYPE:
- errorCode = QMediaPlayer::FormatError;
- errorString = tr("Unsupported media type.");
- break;
- default:
- errorString = tr("Failed to load source.");
- break;
- }
- changeStatus(QMediaPlayer::InvalidMedia);
- emit error(errorCode, errorString, true);
-}
-
-void MFPlayerSession::handleMediaSourceReady()
-{
- if (QMediaPlayer::LoadingMedia != m_status || !m_sourceResolver || m_sourceResolver != sender())
- return;
-#ifdef DEBUG_MEDIAFOUNDATION
- qDebug() << "handleMediaSourceReady";
-#endif
- HRESULT hr = S_OK;
- IMFMediaSource* mediaSource = m_sourceResolver->mediaSource();
-
- DWORD dwCharacteristics = 0;
- mediaSource->GetCharacteristics(&dwCharacteristics);
- emit seekableUpdate(MFMEDIASOURCE_CAN_SEEK & dwCharacteristics);
-
- IMFPresentationDescriptor* sourcePD;
- hr = mediaSource->CreatePresentationDescriptor(&sourcePD);
- if (SUCCEEDED(hr)) {
- m_duration = 0;
- m_playerService->metaDataControl()->updateSource(sourcePD, mediaSource);
- sourcePD->GetUINT64(MF_PD_DURATION, &m_duration);
- //convert from 100 nanosecond to milisecond
- emit durationUpdate(qint64(m_duration / 10000));
- setupPlaybackTopology(mediaSource, sourcePD);
- sourcePD->Release();
- } else {
- changeStatus(QMediaPlayer::InvalidMedia);
- emit error(QMediaPlayer::ResourceError, tr("Cannot create presentation descriptor."), true);
- }
-}
-
-MFPlayerSession::MediaType MFPlayerSession::getStreamType(IMFStreamDescriptor *stream) const
-{
- if (!stream)
- return Unknown;
-
- struct SafeRelease {
- IMFMediaTypeHandler *ptr = nullptr;
- ~SafeRelease() { if (ptr) ptr->Release(); }
- } typeHandler;
- if (SUCCEEDED(stream->GetMediaTypeHandler(&typeHandler.ptr))) {
- GUID guidMajorType;
- if (SUCCEEDED(typeHandler.ptr->GetMajorType(&guidMajorType))) {
- if (guidMajorType == MFMediaType_Audio)
- return Audio;
- else if (guidMajorType == MFMediaType_Video)
- return Video;
- }
- }
-
- return Unknown;
-}
-
-void MFPlayerSession::setupPlaybackTopology(IMFMediaSource *source, IMFPresentationDescriptor *sourcePD)
-{
- HRESULT hr = S_OK;
- // Get the number of streams in the media source.
- DWORD cSourceStreams = 0;
- hr = sourcePD->GetStreamDescriptorCount(&cSourceStreams);
- if (FAILED(hr)) {
- changeStatus(QMediaPlayer::UnknownMediaStatus);
- emit error(QMediaPlayer::ResourceError, tr("Failed to get stream count."), true);
- return;
- }
-
- IMFTopology *topology;
- hr = MFCreateTopology(&topology);
- if (FAILED(hr)) {
- changeStatus(QMediaPlayer::UnknownMediaStatus);
- emit error(QMediaPlayer::ResourceError, tr("Failed to create topology."), true);
- return;
- }
-
- // Remember output node id for a first video stream
- TOPOID outputNodeId = -1;
-
- // For each stream, create the topology nodes and add them to the topology.
- DWORD succeededCount = 0;
- for (DWORD i = 0; i < cSourceStreams; i++)
- {
- BOOL fSelected = FALSE;
- bool streamAdded = false;
- IMFStreamDescriptor *streamDesc = NULL;
-
- HRESULT hr = sourcePD->GetStreamDescriptorByIndex(i, &fSelected, &streamDesc);
- if (SUCCEEDED(hr)) {
- // The media might have multiple audio and video streams,
- // only use one of each kind, and only if it is selected by default.
- MediaType mediaType = getStreamType(streamDesc);
- if (mediaType != Unknown
- && ((m_mediaTypes & mediaType) == 0) // Check if this type isn't already added
- && fSelected) {
-
- IMFTopologyNode *sourceNode = addSourceNode(topology, source, sourcePD, streamDesc);
- if (sourceNode) {
- IMFTopologyNode *outputNode = addOutputNode(mediaType, topology, 0);
- if (outputNode) {
- bool connected = false;
- if (mediaType == Audio) {
- if (!m_audioSampleGrabberNode)
- connected = setupAudioSampleGrabber(topology, sourceNode, outputNode);
- } else if (mediaType == Video && outputNodeId == -1) {
- // Remember video output node ID.
- outputNode->GetTopoNodeID(&outputNodeId);
- }
-
- if (!connected)
- hr = sourceNode->ConnectOutput(0, outputNode, 0);
-
- if (FAILED(hr)) {
- emit error(QMediaPlayer::FormatError, tr("Unable to play any stream."), false);
- } else {
- streamAdded = true;
- succeededCount++;
- m_mediaTypes |= mediaType;
- switch (mediaType) {
- case Audio:
- emit audioAvailable();
- break;
- case Video:
- emit videoAvailable();
- break;
- }
- }
- outputNode->Release();
- }
- sourceNode->Release();
- }
- }
-
- if (fSelected && !streamAdded)
- sourcePD->DeselectStream(i);
-
- streamDesc->Release();
- }
- }
-
- if (succeededCount == 0) {
- changeStatus(QMediaPlayer::InvalidMedia);
- emit error(QMediaPlayer::ResourceError, tr("Unable to play."), true);
- } else {
- if (outputNodeId != -1) {
- topology = insertMFT(topology, outputNodeId);
- }
-
- hr = m_session->SetTopology(MFSESSION_SETTOPOLOGY_IMMEDIATE, topology);
- if (FAILED(hr)) {
- changeStatus(QMediaPlayer::UnknownMediaStatus);
- emit error(QMediaPlayer::ResourceError, tr("Failed to set topology."), true);
- }
- }
- topology->Release();
-}
-
-IMFTopologyNode* MFPlayerSession::addSourceNode(IMFTopology* topology, IMFMediaSource* source,
- IMFPresentationDescriptor* presentationDesc, IMFStreamDescriptor *streamDesc)
-{
- IMFTopologyNode *node = NULL;
- HRESULT hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, &node);
- if (SUCCEEDED(hr)) {
- hr = node->SetUnknown(MF_TOPONODE_SOURCE, source);
- if (SUCCEEDED(hr)) {
- hr = node->SetUnknown(MF_TOPONODE_PRESENTATION_DESCRIPTOR, presentationDesc);
- if (SUCCEEDED(hr)) {
- hr = node->SetUnknown(MF_TOPONODE_STREAM_DESCRIPTOR, streamDesc);
- if (SUCCEEDED(hr)) {
- hr = topology->AddNode(node);
- if (SUCCEEDED(hr))
- return node;
- }
- }
- }
- node->Release();
- }
- return NULL;
-}
-
-IMFTopologyNode* MFPlayerSession::addOutputNode(MediaType mediaType, IMFTopology* topology, DWORD sinkID)
-{
- IMFTopologyNode *node = NULL;
- if (FAILED(MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &node)))
- return NULL;
-
- IMFActivate *activate = NULL;
- if (mediaType == Audio) {
- activate = m_playerService->audioEndpointControl()->createActivate();
- } else if (mediaType == Video) {
- if (m_playerService->videoRendererControl()) {
- activate = m_playerService->videoRendererControl()->createActivate();
- } else if (m_playerService->videoWindowControl()) {
- activate = m_playerService->videoWindowControl()->createActivate();
- } else {
- qWarning() << "no videoWindowControl or videoRendererControl, unable to add output node for video data";
- }
- } else {
- // Unknown stream type.
- emit error(QMediaPlayer::FormatError, tr("Unknown stream type."), false);
- }
-
- if (!activate
- || FAILED(node->SetObject(activate))
- || FAILED(node->SetUINT32(MF_TOPONODE_STREAMID, sinkID))
- || FAILED(node->SetUINT32(MF_TOPONODE_NOSHUTDOWN_ON_REMOVE, FALSE))
- || FAILED(topology->AddNode(node))) {
- node->Release();
- node = NULL;
- }
-
- return node;
-}
-
-bool MFPlayerSession::addAudioSampleGrabberNode(IMFTopology *topology)
-{
- HRESULT hr = S_OK;
- IMFMediaType *pType = 0;
- IMFActivate *sinkActivate = 0;
- do {
- hr = MFCreateMediaType(&pType);
- if (FAILED(hr))
- break;
-
- hr = pType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio);
- if (FAILED(hr))
- break;
-
- hr = pType->SetGUID(MF_MT_SUBTYPE, MFAudioFormat_PCM);
- if (FAILED(hr))
- break;
-
- hr = MFCreateSampleGrabberSinkActivate(pType, m_audioSampleGrabber, &sinkActivate);
- if (FAILED(hr))
- break;
-
- // Note: Data is distorted if this attribute is enabled
- hr = sinkActivate->SetUINT32(MF_SAMPLEGRABBERSINK_IGNORE_CLOCK, FALSE);
- if (FAILED(hr))
- break;
-
- hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &m_audioSampleGrabberNode);
- if (FAILED(hr))
- break;
-
- hr = m_audioSampleGrabberNode->SetObject(sinkActivate);
- if (FAILED(hr))
- break;
-
- hr = m_audioSampleGrabberNode->SetUINT32(MF_TOPONODE_STREAMID, 0); // Identifier of the stream sink.
- if (FAILED(hr))
- break;
-
- hr = m_audioSampleGrabberNode->SetUINT32(MF_TOPONODE_NOSHUTDOWN_ON_REMOVE, FALSE);
- if (FAILED(hr))
- break;
-
- hr = topology->AddNode(m_audioSampleGrabberNode);
- if (FAILED(hr))
- break;
-
- pType->Release();
- sinkActivate->Release();
- return true;
- } while (false);
-
- if (pType)
- pType->Release();
- if (sinkActivate)
- sinkActivate->Release();
- if (m_audioSampleGrabberNode) {
- m_audioSampleGrabberNode->Release();
- m_audioSampleGrabberNode = NULL;
- }
- return false;
-}
-
-bool MFPlayerSession::setupAudioSampleGrabber(IMFTopology *topology, IMFTopologyNode *sourceNode, IMFTopologyNode *outputNode)
-{
- if (!addAudioSampleGrabberNode(topology))
- return false;
-
- HRESULT hr = S_OK;
- IMFTopologyNode *pTeeNode = NULL;
-
- IMFMediaTypeHandler *typeHandler = NULL;
- IMFMediaType *mediaType = NULL;
- do {
- hr = MFCreateTopologyNode(MF_TOPOLOGY_TEE_NODE, &pTeeNode);
- if (FAILED(hr))
- break;
- hr = sourceNode->ConnectOutput(0, pTeeNode, 0);
- if (FAILED(hr))
- break;
- hr = pTeeNode->ConnectOutput(0, outputNode, 0);
- if (FAILED(hr))
- break;
- hr = pTeeNode->ConnectOutput(1, m_audioSampleGrabberNode, 0);
- if (FAILED(hr))
- break;
- } while (false);
-
- if (pTeeNode)
- pTeeNode->Release();
- if (mediaType)
- mediaType->Release();
- if (typeHandler)
- typeHandler->Release();
- return hr == S_OK;
-}
-
-QAudioFormat MFPlayerSession::audioFormatForMFMediaType(IMFMediaType *mediaType) const
-{
- WAVEFORMATEX *wfx = 0;
- UINT32 size;
- HRESULT hr = MFCreateWaveFormatExFromMFMediaType(mediaType, &wfx, &size, MFWaveFormatExConvertFlag_Normal);
- if (FAILED(hr))
- return QAudioFormat();
-
- if (size < sizeof(WAVEFORMATEX)) {
- CoTaskMemFree(wfx);
- return QAudioFormat();
- }
-
- if (wfx->wFormatTag != WAVE_FORMAT_PCM) {
- CoTaskMemFree(wfx);
- return QAudioFormat();
- }
-
- QAudioFormat format;
- format.setSampleRate(wfx->nSamplesPerSec);
- format.setChannelCount(wfx->nChannels);
- format.setSampleSize(wfx->wBitsPerSample);
- format.setCodec("audio/pcm");
- format.setByteOrder(QAudioFormat::LittleEndian);
- if (format.sampleSize() == 8)
- format.setSampleType(QAudioFormat::UnSignedInt);
- else
- format.setSampleType(QAudioFormat::SignedInt);
-
- CoTaskMemFree(wfx);
- return format;
-}
-
-// BindOutputNode
-// Sets the IMFStreamSink pointer on an output node.
-// IMFActivate pointer in the output node must be converted to an
-// IMFStreamSink pointer before the topology loader resolves the topology.
-HRESULT BindOutputNode(IMFTopologyNode *pNode)
-{
- IUnknown *nodeObject = NULL;
- IMFActivate *activate = NULL;
- IMFStreamSink *stream = NULL;
- IMFMediaSink *sink = NULL;
-
- HRESULT hr = pNode->GetObject(&nodeObject);
- if (FAILED(hr))
- return hr;
-
- hr = nodeObject->QueryInterface(IID_PPV_ARGS(&activate));
- if (SUCCEEDED(hr)) {
- DWORD dwStreamID = 0;
-
- // Try to create the media sink.
- hr = activate->ActivateObject(IID_PPV_ARGS(&sink));
- if (SUCCEEDED(hr))
- dwStreamID = MFGetAttributeUINT32(pNode, MF_TOPONODE_STREAMID, 0);
-
- if (SUCCEEDED(hr)) {
- // First check if the media sink already has a stream sink with the requested ID.
- hr = sink->GetStreamSinkById(dwStreamID, &stream);
- if (FAILED(hr)) {
- // Create the stream sink.
- hr = sink->AddStreamSink(dwStreamID, NULL, &stream);
- }
- }
-
- // Replace the node's object pointer with the stream sink.
- if (SUCCEEDED(hr)) {
- hr = pNode->SetObject(stream);
- }
- } else {
- hr = nodeObject->QueryInterface(IID_PPV_ARGS(&stream));
- }
-
- if (nodeObject)
- nodeObject->Release();
- if (activate)
- activate->Release();
- if (stream)
- stream->Release();
- if (sink)
- sink->Release();
- return hr;
-}
-
-// BindOutputNodes
-// Sets the IMFStreamSink pointers on all of the output nodes in a topology.
-HRESULT BindOutputNodes(IMFTopology *pTopology)
-{
- IMFCollection *collection;
-
- // Get the collection of output nodes.
- HRESULT hr = pTopology->GetOutputNodeCollection(&collection);
-
- // Enumerate all of the nodes in the collection.
- if (SUCCEEDED(hr)) {
- DWORD cNodes;
- hr = collection->GetElementCount(&cNodes);
-
- if (SUCCEEDED(hr)) {
- for (DWORD i = 0; i < cNodes; i++) {
- IUnknown *element;
- hr = collection->GetElement(i, &element);
- if (FAILED(hr))
- break;
-
- IMFTopologyNode *node;
- hr = element->QueryInterface(IID_IMFTopologyNode, (void**)&node);
- element->Release();
- if (FAILED(hr))
- break;
-
- // Bind this node.
- hr = BindOutputNode(node);
- node->Release();
- if (FAILED(hr))
- break;
- }
- }
- collection->Release();
- }
-
- return hr;
-}
-
-// This method binds output nodes to complete the topology,
-// then loads the topology and inserts MFT between the output node
-// and a filter connected to the output node.
-IMFTopology *MFPlayerSession::insertMFT(IMFTopology *topology, TOPOID outputNodeId)
-{
- bool isNewTopology = false;
-
- IMFTopoLoader *topoLoader = 0;
- IMFTopology *resolvedTopology = 0;
- IMFCollection *outputNodes = 0;
-
- do {
- if (FAILED(BindOutputNodes(topology)))
- break;
-
- if (FAILED(MFCreateTopoLoader(&topoLoader)))
- break;
-
- if (FAILED(topoLoader->Load(topology, &resolvedTopology, NULL))) {
- // Topology could not be resolved, adding ourselves a color converter
- // to the topology might solve the problem
- insertColorConverter(topology, outputNodeId);
- if (FAILED(topoLoader->Load(topology, &resolvedTopology, NULL)))
- break;
- }
-
- if (insertResizer(resolvedTopology))
- isNewTopology = true;
-
- // Get all output nodes and search for video output node.
- if (FAILED(resolvedTopology->GetOutputNodeCollection(&outputNodes)))
- break;
-
- DWORD elementCount = 0;
- if (FAILED(outputNodes->GetElementCount(&elementCount)))
- break;
-
- for (DWORD n = 0; n < elementCount; n++) {
- IUnknown *element = 0;
- IMFTopologyNode *node = 0;
- IUnknown *outputObject = 0;
- IMFTopologyNode *inputNode = 0;
- IMFTopologyNode *mftNode = 0;
- bool mftAdded = false;
-
- do {
- if (FAILED(outputNodes->GetElement(n, &element)))
- break;
-
- if (FAILED(element->QueryInterface(IID_IMFTopologyNode, (void**)&node)))
- break;
-
- TOPOID id;
- if (FAILED(node->GetTopoNodeID(&id)))
- break;
-
- if (id != outputNodeId)
- break;
-
- if (FAILED(node->GetObject(&outputObject)))
- break;
-
- m_videoProbeMFT->setVideoSink(outputObject);
-
- // Insert MFT between the output node and the node connected to it.
- DWORD outputIndex = 0;
- if (FAILED(node->GetInput(0, &inputNode, &outputIndex)))
- break;
-
- if (FAILED(MFCreateTopologyNode(MF_TOPOLOGY_TRANSFORM_NODE, &mftNode)))
- break;
-
- if (FAILED(mftNode->SetObject(m_videoProbeMFT)))
- break;
-
- if (FAILED(resolvedTopology->AddNode(mftNode)))
- break;
-
- if (FAILED(inputNode->ConnectOutput(0, mftNode, 0)))
- break;
-
- if (FAILED(mftNode->ConnectOutput(0, node, 0)))
- break;
-
- mftAdded = true;
- isNewTopology = true;
- } while (false);
-
- if (mftNode)
- mftNode->Release();
- if (inputNode)
- inputNode->Release();
- if (node)
- node->Release();
- if (element)
- element->Release();
- if (outputObject)
- outputObject->Release();
-
- if (mftAdded)
- break;
- else
- m_videoProbeMFT->setVideoSink(NULL);
- }
- } while (false);
-
- if (outputNodes)
- outputNodes->Release();
-
- if (topoLoader)
- topoLoader->Release();
-
- if (isNewTopology) {
- topology->Release();
- return resolvedTopology;
- }
-
- if (resolvedTopology)
- resolvedTopology->Release();
-
- return topology;
-}
-
-// This method checks if the topology contains a color converter transform (CColorConvertDMO),
-// if it does it inserts a resizer transform (CResizerDMO) to handle dynamic frame size change
-// of the video stream.
-// Returns true if it inserted a resizer
-bool MFPlayerSession::insertResizer(IMFTopology *topology)
-{
- bool inserted = false;
- WORD elementCount = 0;
- IMFTopologyNode *node = 0;
- IUnknown *object = 0;
- IWMColorConvProps *colorConv = 0;
- IMFTransform *resizer = 0;
- IMFTopologyNode *resizerNode = 0;
- IMFTopologyNode *inputNode = 0;
-
- HRESULT hr = topology->GetNodeCount(&elementCount);
- if (FAILED(hr))
- return false;
-
- for (WORD i = 0; i < elementCount; ++i) {
- if (node) {
- node->Release();
- node = 0;
- }
- if (object) {
- object->Release();
- object = 0;
- }
-
- if (FAILED(topology->GetNode(i, &node)))
- break;
-
- MF_TOPOLOGY_TYPE nodeType;
- if (FAILED(node->GetNodeType(&nodeType)))
- break;
-
- if (nodeType != MF_TOPOLOGY_TRANSFORM_NODE)
- continue;
-
- if (FAILED(node->GetObject(&object)))
- break;
-
- if (FAILED(object->QueryInterface(&colorConv)))
- continue;
-
- if (FAILED(CoCreateInstance(CLSID_CResizerDMO, NULL, CLSCTX_INPROC_SERVER, IID_IMFTransform, (void**)&resizer)))
- break;
-
- if (FAILED(MFCreateTopologyNode(MF_TOPOLOGY_TRANSFORM_NODE, &resizerNode)))
- break;
-
- if (FAILED(resizerNode->SetObject(resizer)))
- break;
-
- if (FAILED(topology->AddNode(resizerNode)))
- break;
-
- DWORD outputIndex = 0;
- if (FAILED(node->GetInput(0, &inputNode, &outputIndex))) {
- topology->RemoveNode(resizerNode);
- break;
- }
-
- if (FAILED(inputNode->ConnectOutput(0, resizerNode, 0))) {
- topology->RemoveNode(resizerNode);
- break;
- }
-
- if (FAILED(resizerNode->ConnectOutput(0, node, 0))) {
- inputNode->ConnectOutput(0, node, 0);
- topology->RemoveNode(resizerNode);
- break;
- }
-
- inserted = true;
- break;
- }
-
- if (node)
- node->Release();
- if (object)
- object->Release();
- if (colorConv)
- colorConv->Release();
- if (resizer)
- resizer->Release();
- if (resizerNode)
- resizerNode->Release();
- if (inputNode)
- inputNode->Release();
-
- return inserted;
-}
-
-// This method inserts a color converter (CColorConvertDMO) in the topology,
-// typically to convert to RGB format.
-// Usually this converter is automatically inserted when the topology is resolved but
-// for some reason it fails to do so in some cases, we then do it ourselves.
-void MFPlayerSession::insertColorConverter(IMFTopology *topology, TOPOID outputNodeId)
-{
- IMFCollection *outputNodes = 0;
-
- if (FAILED(topology->GetOutputNodeCollection(&outputNodes)))
- return;
-
- DWORD elementCount = 0;
- if (FAILED(outputNodes->GetElementCount(&elementCount)))
- goto done;
-
- for (DWORD n = 0; n < elementCount; n++) {
- IUnknown *element = 0;
- IMFTopologyNode *node = 0;
- IMFTopologyNode *inputNode = 0;
- IMFTopologyNode *mftNode = 0;
- IMFTransform *converter = 0;
-
- do {
- if (FAILED(outputNodes->GetElement(n, &element)))
- break;
-
- if (FAILED(element->QueryInterface(IID_IMFTopologyNode, (void**)&node)))
- break;
-
- TOPOID id;
- if (FAILED(node->GetTopoNodeID(&id)))
- break;
-
- if (id != outputNodeId)
- break;
-
- DWORD outputIndex = 0;
- if (FAILED(node->GetInput(0, &inputNode, &outputIndex)))
- break;
-
- if (FAILED(MFCreateTopologyNode(MF_TOPOLOGY_TRANSFORM_NODE, &mftNode)))
- break;
-
- if (FAILED(CoCreateInstance(CLSID_CColorConvertDMO, NULL, CLSCTX_INPROC_SERVER, IID_IMFTransform, (void**)&converter)))
- break;
-
- if (FAILED(mftNode->SetObject(converter)))
- break;
-
- if (FAILED(topology->AddNode(mftNode)))
- break;
-
- if (FAILED(inputNode->ConnectOutput(0, mftNode, 0)))
- break;
-
- if (FAILED(mftNode->ConnectOutput(0, node, 0)))
- break;
-
- } while (false);
-
- if (mftNode)
- mftNode->Release();
- if (inputNode)
- inputNode->Release();
- if (node)
- node->Release();
- if (element)
- element->Release();
- if (converter)
- converter->Release();
- }
-
-done:
- if (outputNodes)
- outputNodes->Release();
-}
-
-void MFPlayerSession::stop(bool immediate)
-{
-#ifdef DEBUG_MEDIAFOUNDATION
- qDebug() << "stop";
-#endif
- if (!immediate && m_pendingState != NoPending) {
- m_request.setCommand(CmdStop);
- } else {
- if (m_state.command == CmdStop)
- return;
-
- if (m_scrubbing)
- scrub(false);
-
- if (SUCCEEDED(m_session->Stop())) {
- m_state.setCommand(CmdStop);
- m_pendingState = CmdPending;
- if (m_status != QMediaPlayer::EndOfMedia) {
- m_varStart.vt = VT_I8;
- m_varStart.hVal.QuadPart = 0;
- }
- } else {
- emit error(QMediaPlayer::ResourceError, tr("Failed to stop."), true);
- }
- }
-}
-
-void MFPlayerSession::start()
-{
- if (m_status == QMediaPlayer::EndOfMedia)
- m_varStart.hVal.QuadPart = 0; // restart from the beginning
-
-#ifdef DEBUG_MEDIAFOUNDATION
- qDebug() << "start";
-#endif
-
- if (m_pendingState != NoPending) {
- m_request.setCommand(CmdStart);
- } else {
- if (m_state.command == CmdStart)
- return;
-
- if (m_scrubbing)
- scrub(false);
-
- if (SUCCEEDED(m_session->Start(&GUID_NULL, &m_varStart))) {
- m_state.setCommand(CmdStart);
- m_pendingState = CmdPending;
- PropVariantInit(&m_varStart);
- } else {
- emit error(QMediaPlayer::ResourceError, tr("failed to start playback"), true);
- }
- }
-}
-
-void MFPlayerSession::pause()
-{
-#ifdef DEBUG_MEDIAFOUNDATION
- qDebug() << "pause";
-#endif
- if (m_pendingState != NoPending) {
- m_request.setCommand(CmdPause);
- } else {
- if (m_state.command == CmdPause)
- return;
-
- if (SUCCEEDED(m_session->Pause())) {
- m_state.setCommand(CmdPause);
- m_pendingState = CmdPending;
- } else {
- emit error(QMediaPlayer::ResourceError, tr("Failed to pause."), false);
- }
- }
-}
-
-void MFPlayerSession::changeStatus(QMediaPlayer::MediaStatus newStatus)
-{
- if (m_status == newStatus)
- return;
-#ifdef DEBUG_MEDIAFOUNDATION
- qDebug() << "MFPlayerSession::changeStatus" << newStatus;
-#endif
- m_status = newStatus;
- emit statusChanged();
-}
-
-QMediaPlayer::MediaStatus MFPlayerSession::status() const
-{
- return m_status;
-}
-
-void MFPlayerSession::createSession()
-{
- close();
-
- m_hCloseEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
-
- m_sourceResolver = new SourceResolver();
- QObject::connect(m_sourceResolver, SIGNAL(mediaSourceReady()), this, SLOT(handleMediaSourceReady()));
- QObject::connect(m_sourceResolver, SIGNAL(error(long)), this, SLOT(handleSourceError(long)));
-
- m_videoProbeMFT = new MFTransform;
- for (int i = 0; i < m_videoProbes.size(); ++i)
- m_videoProbeMFT->addProbe(m_videoProbes.at(i));
-
- Q_ASSERT(m_session == NULL);
- HRESULT hr = MFCreateMediaSession(NULL, &m_session);
- if (FAILED(hr)) {
- changeStatus(QMediaPlayer::UnknownMediaStatus);
- emit error(QMediaPlayer::ResourceError, tr("Unable to create mediasession."), true);
- }
-
- hr = m_session->BeginGetEvent(this, m_session);
-
- if (FAILED(hr)) {
- changeStatus(QMediaPlayer::UnknownMediaStatus);
- emit error(QMediaPlayer::ResourceError, tr("Unable to pull session events."), false);
- }
-
- PropVariantInit(&m_varStart);
- m_varStart.vt = VT_I8;
- m_varStart.hVal.QuadPart = 0;
-}
-
-qint64 MFPlayerSession::position()
-{
- if (m_request.command == CmdSeek || m_request.command == CmdSeekResume)
- return m_request.start;
-
- if (m_pendingState == SeekPending)
- return m_state.start;
-
- if (m_state.command == CmdStop)
- return qint64(m_varStart.hVal.QuadPart / 10000);
-
- if (m_presentationClock) {
- MFTIME time, sysTime;
- if (FAILED(m_presentationClock->GetCorrelatedTime(0, &time, &sysTime)))
- return 0;
- return qint64(time / 10000);
- }
- return 0;
-}
-
-void MFPlayerSession::setPosition(qint64 position)
-{
-#ifdef DEBUG_MEDIAFOUNDATION
- qDebug() << "setPosition";
-#endif
- if (m_pendingState != NoPending) {
- m_request.setCommand(CmdSeek);
- m_request.start = position;
- } else {
- setPositionInternal(position, CmdNone);
- }
-}
-
-void MFPlayerSession::setPositionInternal(qint64 position, Command requestCmd)
-{
- if (m_status == QMediaPlayer::EndOfMedia)
- changeStatus(QMediaPlayer::LoadedMedia);
- if (m_state.command == CmdStop && requestCmd != CmdSeekResume) {
- m_varStart.vt = VT_I8;
- m_varStart.hVal.QuadPart = LONGLONG(position * 10000);
- // Even though the position is not actually set on the session yet,
- // report it to have changed anyway for UI controls to be updated
- emit positionChanged(this->position());
- return;
- }
-
- if (m_state.command == CmdPause)
- scrub(true);
-
-#ifdef DEBUG_MEDIAFOUNDATION
- qDebug() << "setPositionInternal";
-#endif
-
- PROPVARIANT varStart;
- varStart.vt = VT_I8;
- varStart.hVal.QuadPart = LONGLONG(position * 10000);
- if (SUCCEEDED(m_session->Start(NULL, &varStart)))
- {
- PropVariantInit(&m_varStart);
- // Store the pending state.
- m_state.setCommand(CmdStart);
- m_state.start = position;
- m_pendingState = SeekPending;
- } else {
- emit error(QMediaPlayer::ResourceError, tr("Failed to seek."), true);
- }
-}
-
-qreal MFPlayerSession::playbackRate() const
-{
- if (m_scrubbing)
- return m_restoreRate;
- return m_state.rate;
-}
-
-void MFPlayerSession::setPlaybackRate(qreal rate)
-{
- if (m_scrubbing) {
- m_restoreRate = rate;
- emit playbackRateChanged(rate);
- return;
- }
- setPlaybackRateInternal(rate);
-}
-
-void MFPlayerSession::setPlaybackRateInternal(qreal rate)
-{
- if (rate == m_request.rate)
- return;
-
- m_pendingRate = rate;
- if (!m_rateSupport)
- return;
-
-#ifdef DEBUG_MEDIAFOUNDATION
- qDebug() << "setPlaybackRate";
-#endif
- BOOL isThin = FALSE;
-
- //from MSDN http://msdn.microsoft.com/en-us/library/aa965220%28v=vs.85%29.aspx
- //Thinning applies primarily to video streams.
- //In thinned mode, the source drops delta frames and deliver only key frames.
- //At very high playback rates, the source might skip some key frames (for example, deliver every other key frame).
-
- if (FAILED(m_rateSupport->IsRateSupported(FALSE, rate, NULL))) {
- isThin = TRUE;
- if (FAILED(m_rateSupport->IsRateSupported(isThin, rate, NULL))) {
- qWarning() << "unable to set playbackrate = " << rate;
- m_pendingRate = m_request.rate = m_state.rate;
- return;
- }
- }
- if (m_pendingState != NoPending) {
- m_request.rate = rate;
- m_request.isThin = isThin;
- // Remember the current transport state (play, paused, etc), so that we
- // can restore it after the rate change, if necessary. However, if
- // anothercommand is already pending, that one takes precedent.
- if (m_request.command == CmdNone)
- m_request.setCommand(m_state.command);
- } else {
- //No pending operation. Commit the new rate.
- commitRateChange(rate, isThin);
- }
-}
-
-void MFPlayerSession::commitRateChange(qreal rate, BOOL isThin)
-{
-#ifdef DEBUG_MEDIAFOUNDATION
- qDebug() << "commitRateChange";
-#endif
- Q_ASSERT(m_pendingState == NoPending);
- MFTIME hnsSystemTime = 0;
- MFTIME hnsClockTime = 0;
- Command cmdNow = m_state.command;
- bool resetPosition = false;
- // Allowed rate transitions:
- // Positive <-> negative: Stopped
- // Negative <-> zero: Stopped
- // Postive <-> zero: Paused or stopped
- if ((rate > 0 && m_state.rate <= 0) || (rate < 0 && m_state.rate >= 0)) {
- if (cmdNow == CmdStart) {
- // Get the current clock position. This will be the restart time.
- m_presentationClock->GetCorrelatedTime(0, &hnsClockTime, &hnsSystemTime);
- Q_ASSERT(hnsSystemTime != 0);
-
- if (rate < 0 || m_state.rate < 0)
- m_request.setCommand(CmdSeekResume);
- else if (isThin || m_state.isThin)
- m_request.setCommand(CmdStartAndSeek);
- else
- m_request.setCommand(CmdStart);
-
- // We need to stop only when dealing with negative rates
- if (rate >= 0 && m_state.rate >= 0)
- pause();
- else
- stop();
-
- // If we deal with negative rates, we stopped the session and consequently
- // reset the position to zero. We then need to resume to the current position.
- m_request.start = hnsClockTime / 10000;
- } else if (cmdNow == CmdPause) {
- if (rate < 0 || m_state.rate < 0) {
- // The current state is paused.
- // For this rate change, the session must be stopped. However, the
- // session cannot transition back from stopped to paused.
- // Therefore, this rate transition is not supported while paused.
- qWarning() << "Unable to change rate from positive to negative or vice versa in paused state";
- rate = m_state.rate;
- isThin = m_state.isThin;
- goto done;
- }
-
- // This happens when resuming playback after scrubbing in pause mode.
- // This transition requires the session to be paused. Even though our
- // internal state is set to paused, the session might not be so we need
- // to enforce it
- if (rate > 0 && m_state.rate == 0) {
- m_state.setCommand(CmdNone);
- pause();
- }
- }
- } else if (rate == 0 && m_state.rate > 0) {
- if (cmdNow != CmdPause) {
- // Transition to paused.
- // This transisition requires the paused state.
- // Pause and set the rate.
- pause();
-
- // Request: Switch back to current state.
- m_request.setCommand(cmdNow);
- }
- } else if (rate == 0 && m_state.rate < 0) {
- // Changing rate from negative to zero requires to stop the session
- m_presentationClock->GetCorrelatedTime(0, &hnsClockTime, &hnsSystemTime);
-
- m_request.setCommand(CmdSeekResume);
-
- stop();
-
- // Resume to the current position (stop() will reset the position to 0)
- m_request.start = hnsClockTime / 10000;
- } else if (!isThin && m_state.isThin) {
- if (cmdNow == CmdStart) {
- // When thinning, only key frames are read and presented. Going back
- // to normal playback requires to reset the current position to force
- // the pipeline to decode the actual frame at the current position
- // (which might be earlier than the last decoded key frame)
- resetPosition = true;
- } else if (cmdNow == CmdPause) {
- // If paused, don't reset the position until we resume, otherwise
- // a new frame will be rendered
- m_presentationClock->GetCorrelatedTime(0, &hnsClockTime, &hnsSystemTime);
- m_request.setCommand(CmdSeekResume);
- m_request.start = hnsClockTime / 10000;
- }
-
- }
-
- // Set the rate.
- if (FAILED(m_rateControl->SetRate(isThin, rate))) {
- qWarning() << "failed to set playbackrate = " << rate;
- rate = m_state.rate;
- isThin = m_state.isThin;
- goto done;
- }
-
- if (resetPosition) {
- m_presentationClock->GetCorrelatedTime(0, &hnsClockTime, &hnsSystemTime);
- setPosition(hnsClockTime / 10000);
- }
-
-done:
- // Adjust our current rate and requested rate.
- m_pendingRate = m_request.rate = m_state.rate = rate;
- if (rate != 0)
- m_state.isThin = isThin;
- emit playbackRateChanged(rate);
-}
-
-void MFPlayerSession::scrub(bool enableScrub)
-{
- if (m_scrubbing == enableScrub)
- return;
-
- m_scrubbing = enableScrub;
-
- if (!canScrub()) {
- if (!enableScrub)
- m_pendingRate = m_restoreRate;
- return;
- }
-
- if (enableScrub) {
- // Enter scrubbing mode. Cache the rate.
- m_restoreRate = m_request.rate;
- setPlaybackRateInternal(0.0f);
- } else {
- // Leaving scrubbing mode. Restore the old rate.
- setPlaybackRateInternal(m_restoreRate);
- }
-}
-
-int MFPlayerSession::volume() const
-{
- return m_volume;
-}
-
-void MFPlayerSession::setVolume(int volume)
-{
- if (m_volume == volume)
- return;
- m_volume = volume;
-
- if (!m_muted)
- setVolumeInternal(volume);
-
- emit volumeChanged(m_volume);
-}
-
-bool MFPlayerSession::isMuted() const
-{
- return m_muted;
-}
-
-void MFPlayerSession::setMuted(bool muted)
-{
- if (m_muted == muted)
- return;
- m_muted = muted;
-
- setVolumeInternal(muted ? 0 : m_volume);
-
- emit mutedChanged(m_muted);
-}
-
-void MFPlayerSession::setVolumeInternal(int volume)
-{
- if (m_volumeControl) {
- quint32 channelCount = 0;
- if (!SUCCEEDED(m_volumeControl->GetChannelCount(&channelCount))
- || channelCount == 0)
- return;
-
- float scaled = volume * 0.01f;
- for (quint32 i = 0; i < channelCount; ++i)
- m_volumeControl->SetChannelVolume(i, scaled);
- }
-}
-
-int MFPlayerSession::bufferStatus()
-{
- if (!m_netsourceStatistics)
- return 0;
- PROPVARIANT var;
- PropVariantInit(&var);
- PROPERTYKEY key;
- key.fmtid = MFNETSOURCE_STATISTICS;
- key.pid = MFNETSOURCE_BUFFERPROGRESS_ID;
- int progress = -1;
- // GetValue returns S_FALSE if the property is not available, which has
- // a value > 0. We therefore can't use the SUCCEEDED macro here.
- if (m_netsourceStatistics->GetValue(key, &var) == S_OK) {
- progress = var.lVal;
- PropVariantClear(&var);
- }
-
-#ifdef DEBUG_MEDIAFOUNDATION
- qDebug() << "bufferStatus: progress = " << progress;
-#endif
-
- return progress;
-}
-
-QMediaTimeRange MFPlayerSession::availablePlaybackRanges()
-{
- // defaults to the whole media
- qint64 start = 0;
- qint64 end = qint64(m_duration / 10000);
-
- if (m_netsourceStatistics) {
- PROPVARIANT var;
- PropVariantInit(&var);
- PROPERTYKEY key;
- key.fmtid = MFNETSOURCE_STATISTICS;
- key.pid = MFNETSOURCE_SEEKRANGESTART_ID;
- // GetValue returns S_FALSE if the property is not available, which has
- // a value > 0. We therefore can't use the SUCCEEDED macro here.
- if (m_netsourceStatistics->GetValue(key, &var) == S_OK) {
- start = qint64(var.uhVal.QuadPart / 10000);
- PropVariantClear(&var);
- PropVariantInit(&var);
- key.pid = MFNETSOURCE_SEEKRANGEEND_ID;
- if (m_netsourceStatistics->GetValue(key, &var) == S_OK) {
- end = qint64(var.uhVal.QuadPart / 10000);
- PropVariantClear(&var);
- }
- }
- }
-
- return QMediaTimeRange(start, end);
-}
-
-HRESULT MFPlayerSession::QueryInterface(REFIID riid, void** ppvObject)
-{
- if (!ppvObject)
- return E_POINTER;
- if (riid == IID_IMFAsyncCallback) {
- *ppvObject = static_cast<IMFAsyncCallback*>(this);
- } else if (riid == IID_IUnknown) {
- *ppvObject = static_cast<IUnknown*>(this);
- } else {
- *ppvObject = NULL;
- return E_NOINTERFACE;
- }
- return S_OK;
-}
-
-ULONG MFPlayerSession::AddRef(void)
-{
- return InterlockedIncrement(&m_cRef);
-}
-
-ULONG MFPlayerSession::Release(void)
-{
- LONG cRef = InterlockedDecrement(&m_cRef);
- if (cRef == 0)
- this->deleteLater();
- return cRef;
-}
-
-HRESULT MFPlayerSession::Invoke(IMFAsyncResult *pResult)
-{
- if (pResult->GetStateNoAddRef() != m_session)
- return S_OK;
-
- IMFMediaEvent *pEvent = NULL;
- // Get the event from the event queue.
- HRESULT hr = m_session->EndGetEvent(pResult, &pEvent);
- if (FAILED(hr)) {
- return S_OK;
- }
-
- MediaEventType meType = MEUnknown;
- hr = pEvent->GetType(&meType);
- if (FAILED(hr)) {
- pEvent->Release();
- return S_OK;
- }
-
- if (meType == MESessionClosed) {
- SetEvent(m_hCloseEvent);
- pEvent->Release();
- return S_OK;
- } else {
- hr = m_session->BeginGetEvent(this, m_session);
- if (FAILED(hr)) {
- pEvent->Release();
- return S_OK;
- }
- }
-
- if (!m_closing) {
- emit sessionEvent(pEvent);
- } else {
- pEvent->Release();
- }
- return S_OK;
-}
-
-void MFPlayerSession::handleSessionEvent(IMFMediaEvent *sessionEvent)
-{
- HRESULT hrStatus = S_OK;
- HRESULT hr = sessionEvent->GetStatus(&hrStatus);
- if (FAILED(hr) || !m_session) {
- sessionEvent->Release();
- return;
- }
-
- MediaEventType meType = MEUnknown;
- hr = sessionEvent->GetType(&meType);
-
-#ifdef DEBUG_MEDIAFOUNDATION
- if (FAILED(hrStatus))
- qDebug() << "handleSessionEvent: MediaEventType = " << meType << "Failed";
- else
- qDebug() << "handleSessionEvent: MediaEventType = " << meType;
-#endif
-
- switch (meType) {
- case MENonFatalError: {
- PROPVARIANT var;
- PropVariantInit(&var);
- sessionEvent->GetValue(&var);
- qWarning() << "handleSessionEvent: non fatal error = " << var.ulVal;
- PropVariantClear(&var);
- emit error(QMediaPlayer::ResourceError, tr("Media session non-fatal error."), false);
- }
- break;
- case MESourceUnknown:
- changeStatus(QMediaPlayer::InvalidMedia);
- break;
- case MEError:
- changeStatus(QMediaPlayer::UnknownMediaStatus);
- qWarning() << "handleSessionEvent: serious error = " << hrStatus;
- emit error(QMediaPlayer::ResourceError, tr("Media session serious error."), true);
- break;
- case MESessionRateChanged:
- // If the rate change succeeded, we've already got the rate
- // cached. If it failed, try to get the actual rate.
- if (FAILED(hrStatus)) {
- PROPVARIANT var;
- PropVariantInit(&var);
- if (SUCCEEDED(sessionEvent->GetValue(&var)) && (var.vt == VT_R4)) {
- m_state.rate = var.fltVal;
- }
- emit playbackRateChanged(playbackRate());
- }
- break;
- case MESessionScrubSampleComplete :
- if (m_scrubbing)
- updatePendingCommands(CmdStart);
- break;
- case MESessionStarted:
- if (m_status == QMediaPlayer::EndOfMedia
- || m_status == QMediaPlayer::LoadedMedia) {
- // If the session started, then enough data is buffered to play
- changeStatus(QMediaPlayer::BufferedMedia);
- }
-
- updatePendingCommands(CmdStart);
- // playback started, we can now set again the procAmpValues if they have been
- // changed previously (these are lost when loading a new media)
- if (m_playerService->videoWindowControl()) {
- m_playerService->videoWindowControl()->applyImageControls();
- }
- break;
- case MESessionStopped:
- if (m_status != QMediaPlayer::EndOfMedia) {
- m_varStart.vt = VT_I8;
- m_varStart.hVal.QuadPart = 0;
-
- // Reset to Loaded status unless we are loading a new media
- // or changing the playback rate to negative values (stop required)
- if (m_status != QMediaPlayer::LoadingMedia && m_request.command != CmdSeekResume)
- changeStatus(QMediaPlayer::LoadedMedia);
- }
- updatePendingCommands(CmdStop);
- break;
- case MESessionPaused:
- updatePendingCommands(CmdPause);
- break;
- case MEReconnectStart:
-#ifdef DEBUG_MEDIAFOUNDATION
- qDebug() << "MEReconnectStart" << ((hrStatus == S_OK) ? "OK" : "Failed");
-#endif
- break;
- case MEReconnectEnd:
-#ifdef DEBUG_MEDIAFOUNDATION
- qDebug() << "MEReconnectEnd" << ((hrStatus == S_OK) ? "OK" : "Failed");
-#endif
- break;
- case MESessionTopologySet:
- if (FAILED(hrStatus)) {
- changeStatus(QMediaPlayer::InvalidMedia);
- emit error(QMediaPlayer::FormatError, tr("Unsupported media, a codec is missing."), true);
- } else {
- if (m_audioSampleGrabberNode) {
- IUnknown *obj = 0;
- if (SUCCEEDED(m_audioSampleGrabberNode->GetObject(&obj))) {
- IMFStreamSink *streamSink = 0;
- if (SUCCEEDED(obj->QueryInterface(IID_PPV_ARGS(&streamSink)))) {
- IMFMediaTypeHandler *typeHandler = 0;
- if (SUCCEEDED(streamSink->GetMediaTypeHandler((&typeHandler)))) {
- IMFMediaType *mediaType = 0;
- if (SUCCEEDED(typeHandler->GetCurrentMediaType(&mediaType))) {
- m_audioSampleGrabber->setFormat(audioFormatForMFMediaType(mediaType));
- mediaType->Release();
- }
- typeHandler->Release();
- }
- streamSink->Release();
- }
- obj->Release();
- }
- }
-
- // Topology is resolved and successfuly set, this happens only after loading a new media.
- // Make sure we always start the media from the beginning
- m_varStart.vt = VT_I8;
- m_varStart.hVal.QuadPart = 0;
-
- changeStatus(QMediaPlayer::LoadedMedia);
- }
- break;
- }
-
- if (FAILED(hrStatus)) {
- sessionEvent->Release();
- return;
- }
-
- switch (meType) {
- case MEBufferingStarted:
- changeStatus(QMediaPlayer::StalledMedia);
- emit bufferStatusChanged(bufferStatus());
- break;
- case MEBufferingStopped:
- changeStatus(QMediaPlayer::BufferedMedia);
- emit bufferStatusChanged(bufferStatus());
- break;
- case MESessionEnded:
- m_pendingState = NoPending;
- m_state.command = CmdStop;
- m_state.prevCmd = CmdNone;
- m_request.command = CmdNone;
- m_request.prevCmd = CmdNone;
-
- m_varStart.vt = VT_I8;
- //keep reporting the final position after end of media
- m_varStart.hVal.QuadPart = m_duration;
- emit positionChanged(position());
-
- changeStatus(QMediaPlayer::EndOfMedia);
- break;
- case MEEndOfPresentationSegment:
- break;
- case MESessionTopologyStatus: {
- UINT32 status;
- if (SUCCEEDED(sessionEvent->GetUINT32(MF_EVENT_TOPOLOGY_STATUS, &status))) {
- if (status == MF_TOPOSTATUS_READY) {
- IMFClock* clock;
- if (SUCCEEDED(m_session->GetClock(&clock))) {
- clock->QueryInterface(IID_IMFPresentationClock, (void**)(&m_presentationClock));
- clock->Release();
- }
-
- if (SUCCEEDED(MFGetService(m_session, MF_RATE_CONTROL_SERVICE, IID_PPV_ARGS(&m_rateControl)))) {
- if (SUCCEEDED(MFGetService(m_session, MF_RATE_CONTROL_SERVICE, IID_PPV_ARGS(&m_rateSupport)))) {
- if ((m_mediaTypes & Video) == Video
- && SUCCEEDED(m_rateSupport->IsRateSupported(TRUE, 0, NULL)))
- m_canScrub = true;
- }
- BOOL isThin = FALSE;
- float rate = 1;
- if (SUCCEEDED(m_rateControl->GetRate(&isThin, &rate))) {
- if (m_pendingRate != rate) {
- m_state.rate = m_request.rate = rate;
- setPlaybackRate(m_pendingRate);
- }
- }
- }
- MFGetService(m_session, MFNETSOURCE_STATISTICS_SERVICE, IID_PPV_ARGS(&m_netsourceStatistics));
-
- if (SUCCEEDED(MFGetService(m_session, MR_STREAM_VOLUME_SERVICE, IID_PPV_ARGS(&m_volumeControl))))
- setVolumeInternal(m_muted ? 0 : m_volume);
- }
- }
- }
- break;
- default:
- break;
- }
-
- sessionEvent->Release();
-}
-
-void MFPlayerSession::updatePendingCommands(Command command)
-{
- emit positionChanged(position());
- if (m_state.command != command || m_pendingState == NoPending)
- return;
-
- // Seek while paused completed
- if (m_pendingState == SeekPending && m_state.prevCmd == CmdPause) {
- m_pendingState = NoPending;
- // A seek operation actually restarts playback. If scrubbing is possible, playback rate
- // is set to 0.0 at this point and we just need to reset the current state to Pause.
- // If scrubbing is not possible, the playback rate was not changed and we explicitly need
- // to re-pause playback.
- if (!canScrub())
- pause();
- else
- m_state.setCommand(CmdPause);
- }
-
- m_pendingState = NoPending;
-
- //First look for rate changes.
- if (m_request.rate != m_state.rate) {
- commitRateChange(m_request.rate, m_request.isThin);
- }
-
- // Now look for new requests.
- if (m_pendingState == NoPending) {
- switch (m_request.command) {
- case CmdStart:
- start();
- break;
- case CmdPause:
- pause();
- break;
- case CmdStop:
- stop();
- break;
- case CmdSeek:
- case CmdSeekResume:
- setPositionInternal(m_request.start, m_request.command);
- break;
- case CmdStartAndSeek:
- start();
- setPositionInternal(m_request.start, m_request.command);
- break;
- }
- m_request.setCommand(CmdNone);
- }
-
-}
-
-bool MFPlayerSession::canScrub() const
-{
- return m_canScrub && m_rateSupport && m_rateControl;
-}
-
-void MFPlayerSession::clear()
-{
-#ifdef DEBUG_MEDIAFOUNDATION
- qDebug() << "MFPlayerSession::clear";
-#endif
- m_mediaTypes = 0;
- m_canScrub = false;
-
- m_pendingState = NoPending;
- m_state.command = CmdStop;
- m_state.prevCmd = CmdNone;
- m_request.command = CmdNone;
- m_request.prevCmd = CmdNone;
-
- if (m_presentationClock) {
- m_presentationClock->Release();
- m_presentationClock = NULL;
- }
- if (m_rateControl) {
- m_rateControl->Release();
- m_rateControl = NULL;
- }
- if (m_rateSupport) {
- m_rateSupport->Release();
- m_rateSupport = NULL;
- }
- if (m_volumeControl) {
- m_volumeControl->Release();
- m_volumeControl = NULL;
- }
- if (m_netsourceStatistics) {
- m_netsourceStatistics->Release();
- m_netsourceStatistics = NULL;
- }
- if (m_audioSampleGrabberNode) {
- m_audioSampleGrabberNode->Release();
- m_audioSampleGrabberNode = NULL;
- }
-}
diff --git a/src/plugins/wmf/player/mfplayersession.h b/src/plugins/wmf/player/mfplayersession.h
deleted file mode 100644
index c6ffba91f..000000000
--- a/src/plugins/wmf/player/mfplayersession.h
+++ /dev/null
@@ -1,239 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt Mobility Components.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef MFPLAYERSESSION_H
-#define MFPLAYERSESSION_H
-
-#include <mfapi.h>
-#include <mfidl.h>
-
-#include "qmediaplayer.h"
-#include "qmediaservice.h"
-#include "qmediatimerange.h"
-
-#include <QtCore/qcoreevent.h>
-#include <QtCore/qmutex.h>
-#include <QtCore/qurl.h>
-#include <QtCore/qwaitcondition.h>
-#include <QtMultimedia/qaudioformat.h>
-#include <QtMultimedia/qvideosurfaceformat.h>
-
-QT_BEGIN_NAMESPACE
-class QMediaContent;
-QT_END_NAMESPACE
-
-QT_USE_NAMESPACE
-
-class SourceResolver;
-class MFAudioEndpointControl;
-class MFVideoRendererControl;
-class MFPlayerControl;
-class MFMetaDataControl;
-class MFPlayerService;
-class AudioSampleGrabberCallback;
-class MFTransform;
-class MFAudioProbeControl;
-class MFVideoProbeControl;
-
-class MFPlayerSession : public QObject, public IMFAsyncCallback
-{
- Q_OBJECT
- friend class SourceResolver;
-public:
- MFPlayerSession(MFPlayerService *playerService = 0);
- ~MFPlayerSession();
-
- STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppvObject);
-
- STDMETHODIMP_(ULONG) AddRef(void);
-
- STDMETHODIMP_(ULONG) Release(void);
-
- STDMETHODIMP Invoke(IMFAsyncResult *pResult);
-
- STDMETHODIMP GetParameters(DWORD *pdwFlags, DWORD *pdwQueue)
- {
- Q_UNUSED(pdwFlags);
- Q_UNUSED(pdwQueue);
- return E_NOTIMPL;
- }
-
- void load(const QMediaContent &media, QIODevice *stream);
- void stop(bool immediate = false);
- void start();
- void pause();
-
- QMediaPlayer::MediaStatus status() const;
- qint64 position();
- void setPosition(qint64 position);
- qreal playbackRate() const;
- void setPlaybackRate(qreal rate);
- int volume() const;
- void setVolume(int volume);
- bool isMuted() const;
- void setMuted(bool muted);
- int bufferStatus();
- QMediaTimeRange availablePlaybackRanges();
-
- void changeStatus(QMediaPlayer::MediaStatus newStatus);
-
- void close();
-
- void addProbe(MFAudioProbeControl* probe);
- void removeProbe(MFAudioProbeControl* probe);
- void addProbe(MFVideoProbeControl* probe);
- void removeProbe(MFVideoProbeControl* probe);
-
-Q_SIGNALS:
- void error(QMediaPlayer::Error error, QString errorString, bool isFatal);
- void sessionEvent(IMFMediaEvent *sessionEvent);
- void statusChanged();
- void audioAvailable();
- void videoAvailable();
- void durationUpdate(qint64 duration);
- void seekableUpdate(bool seekable);
- void positionChanged(qint64 position);
- void playbackRateChanged(qreal rate);
- void volumeChanged(int volume);
- void mutedChanged(bool muted);
- void bufferStatusChanged(int percentFilled);
-
-private Q_SLOTS:
- void handleMediaSourceReady();
- void handleSessionEvent(IMFMediaEvent *sessionEvent);
- void handleSourceError(long hr);
-
-private:
- long m_cRef;
- MFPlayerService *m_playerService;
- IMFMediaSession *m_session;
- IMFPresentationClock *m_presentationClock;
- IMFRateControl *m_rateControl;
- IMFRateSupport *m_rateSupport;
- IMFAudioStreamVolume *m_volumeControl;
- IPropertyStore *m_netsourceStatistics;
- PROPVARIANT m_varStart;
- UINT64 m_duration;
-
- enum Command
- {
- CmdNone = 0,
- CmdStop,
- CmdStart,
- CmdPause,
- CmdSeek,
- CmdSeekResume,
- CmdStartAndSeek
- };
-
- void clear();
- void setPositionInternal(qint64 position, Command requestCmd);
- void setPlaybackRateInternal(qreal rate);
- void commitRateChange(qreal rate, BOOL isThin);
- bool canScrub() const;
- void scrub(bool enableScrub);
- bool m_scrubbing;
- float m_restoreRate;
-
- SourceResolver *m_sourceResolver;
- HANDLE m_hCloseEvent;
- bool m_closing;
-
- enum MediaType
- {
- Unknown = 0,
- Audio = 1,
- Video = 2,
- };
- DWORD m_mediaTypes;
-
- enum PendingState
- {
- NoPending = 0,
- CmdPending,
- SeekPending,
- };
-
- struct SeekState
- {
- void setCommand(Command cmd) {
- prevCmd = command;
- command = cmd;
- }
- Command command;
- Command prevCmd;
- float rate; // Playback rate
- BOOL isThin; // Thinned playback?
- qint64 start; // Start position
- };
- SeekState m_state; // Current nominal state.
- SeekState m_request; // Pending request.
- PendingState m_pendingState;
- float m_pendingRate;
- void updatePendingCommands(Command command);
-
- QMediaPlayer::MediaStatus m_status;
- bool m_canScrub;
- int m_volume;
- bool m_muted;
-
- void setVolumeInternal(int volume);
-
- void createSession();
- void setupPlaybackTopology(IMFMediaSource *source, IMFPresentationDescriptor *sourcePD);
- MediaType getStreamType(IMFStreamDescriptor *stream) const;
- IMFTopologyNode* addSourceNode(IMFTopology* topology, IMFMediaSource* source,
- IMFPresentationDescriptor* presentationDesc, IMFStreamDescriptor *streamDesc);
- IMFTopologyNode* addOutputNode(MediaType mediaType, IMFTopology* topology, DWORD sinkID);
-
- bool addAudioSampleGrabberNode(IMFTopology* topology);
- bool setupAudioSampleGrabber(IMFTopology *topology, IMFTopologyNode *sourceNode, IMFTopologyNode *outputNode);
- QAudioFormat audioFormatForMFMediaType(IMFMediaType *mediaType) const;
- AudioSampleGrabberCallback *m_audioSampleGrabber;
- IMFTopologyNode *m_audioSampleGrabberNode;
-
- IMFTopology *insertMFT(IMFTopology *topology, TOPOID outputNodeId);
- bool insertResizer(IMFTopology *topology);
- void insertColorConverter(IMFTopology *topology, TOPOID outputNodeId);
- MFTransform *m_videoProbeMFT;
- QList<MFVideoProbeControl*> m_videoProbes;
-};
-
-
-#endif
diff --git a/src/plugins/wmf/player/mftvideo.cpp b/src/plugins/wmf/player/mftvideo.cpp
deleted file mode 100644
index 9dce654f2..000000000
--- a/src/plugins/wmf/player/mftvideo.cpp
+++ /dev/null
@@ -1,753 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "mftvideo.h"
-#include "mfvideoprobecontrol.h"
-#include <private/qmemoryvideobuffer_p.h>
-#include <mferror.h>
-#include <strmif.h>
-#include <uuids.h>
-#include <InitGuid.h>
-#include <d3d9.h>
-#include <qdebug.h>
-
-// This MFT sends all samples it processes to connected video probes.
-// Sample is sent to probes in ProcessInput.
-// In ProcessOutput this MFT simply returns the original sample.
-
-// The implementation is based on a boilerplate from the MF SDK example.
-
-MFTransform::MFTransform():
- m_cRef(1),
- m_inputType(0),
- m_outputType(0),
- m_sample(0),
- m_videoSinkTypeHandler(0),
- m_bytesPerLine(0)
-{
-}
-
-MFTransform::~MFTransform()
-{
- if (m_inputType)
- m_inputType->Release();
-
- if (m_outputType)
- m_outputType->Release();
-
- if (m_videoSinkTypeHandler)
- m_videoSinkTypeHandler->Release();
-}
-
-void MFTransform::addProbe(MFVideoProbeControl *probe)
-{
- QMutexLocker locker(&m_videoProbeMutex);
-
- if (m_videoProbes.contains(probe))
- return;
-
- m_videoProbes.append(probe);
-}
-
-void MFTransform::removeProbe(MFVideoProbeControl *probe)
-{
- QMutexLocker locker(&m_videoProbeMutex);
- m_videoProbes.removeOne(probe);
-}
-
-void MFTransform::setVideoSink(IUnknown *videoSink)
-{
- // This transform supports the same input types as the video sink.
- // Store its type handler interface in order to report the correct supported types.
-
- if (m_videoSinkTypeHandler) {
- m_videoSinkTypeHandler->Release();
- m_videoSinkTypeHandler = NULL;
- }
-
- if (videoSink)
- videoSink->QueryInterface(IID_PPV_ARGS(&m_videoSinkTypeHandler));
-}
-
-STDMETHODIMP MFTransform::QueryInterface(REFIID riid, void** ppv)
-{
- if (!ppv)
- return E_POINTER;
- if (riid == IID_IMFTransform) {
- *ppv = static_cast<IMFTransform*>(this);
- } else if (riid == IID_IUnknown) {
- *ppv = static_cast<IUnknown*>(this);
- } else {
- *ppv = NULL;
- return E_NOINTERFACE;
- }
- AddRef();
- return S_OK;
-}
-
-STDMETHODIMP_(ULONG) MFTransform::AddRef()
-{
- return InterlockedIncrement(&m_cRef);
-}
-
-STDMETHODIMP_(ULONG) MFTransform::Release()
-{
- ULONG cRef = InterlockedDecrement(&m_cRef);
- if (cRef == 0) {
- delete this;
- }
- return cRef;
-}
-
-STDMETHODIMP MFTransform::GetStreamLimits(DWORD *pdwInputMinimum, DWORD *pdwInputMaximum, DWORD *pdwOutputMinimum, DWORD *pdwOutputMaximum)
-{
- if (!pdwInputMinimum || !pdwInputMaximum || !pdwOutputMinimum || !pdwOutputMaximum)
- return E_POINTER;
- *pdwInputMinimum = 1;
- *pdwInputMaximum = 1;
- *pdwOutputMinimum = 1;
- *pdwOutputMaximum = 1;
- return S_OK;
-}
-
-STDMETHODIMP MFTransform::GetStreamCount(DWORD *pcInputStreams, DWORD *pcOutputStreams)
-{
- if (!pcInputStreams || !pcOutputStreams)
- return E_POINTER;
-
- *pcInputStreams = 1;
- *pcOutputStreams = 1;
- return S_OK;
-}
-
-STDMETHODIMP MFTransform::GetStreamIDs(DWORD dwInputIDArraySize, DWORD *pdwInputIDs, DWORD dwOutputIDArraySize, DWORD *pdwOutputIDs)
-{
- // streams are numbered consecutively
- Q_UNUSED(dwInputIDArraySize);
- Q_UNUSED(pdwInputIDs);
- Q_UNUSED(dwOutputIDArraySize);
- Q_UNUSED(pdwOutputIDs);
- return E_NOTIMPL;
-}
-
-STDMETHODIMP MFTransform::GetInputStreamInfo(DWORD dwInputStreamID, MFT_INPUT_STREAM_INFO *pStreamInfo)
-{
- QMutexLocker locker(&m_mutex);
-
- if (dwInputStreamID > 0)
- return MF_E_INVALIDSTREAMNUMBER;
-
- if (!pStreamInfo)
- return E_POINTER;
-
- pStreamInfo->cbSize = 0;
- pStreamInfo->hnsMaxLatency = 0;
- pStreamInfo->cbMaxLookahead = 0;
- pStreamInfo->cbAlignment = 0;
- pStreamInfo->dwFlags = MFT_INPUT_STREAM_WHOLE_SAMPLES
- | MFT_INPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
- | MFT_INPUT_STREAM_PROCESSES_IN_PLACE;
-
- return S_OK;
-}
-
-STDMETHODIMP MFTransform::GetOutputStreamInfo(DWORD dwOutputStreamID, MFT_OUTPUT_STREAM_INFO *pStreamInfo)
-{
- QMutexLocker locker(&m_mutex);
-
- if (dwOutputStreamID > 0)
- return MF_E_INVALIDSTREAMNUMBER;
-
- if (!pStreamInfo)
- return E_POINTER;
-
- pStreamInfo->cbSize = 0;
- pStreamInfo->cbAlignment = 0;
- pStreamInfo->dwFlags = MFT_OUTPUT_STREAM_WHOLE_SAMPLES
- | MFT_OUTPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
- | MFT_OUTPUT_STREAM_PROVIDES_SAMPLES
- | MFT_OUTPUT_STREAM_DISCARDABLE;
-
- return S_OK;
-}
-
-STDMETHODIMP MFTransform::GetAttributes(IMFAttributes **pAttributes)
-{
- // This MFT does not support attributes.
- Q_UNUSED(pAttributes);
- return E_NOTIMPL;
-}
-
-STDMETHODIMP MFTransform::GetInputStreamAttributes(DWORD dwInputStreamID, IMFAttributes **pAttributes)
-{
- // This MFT does not support input stream attributes.
- Q_UNUSED(dwInputStreamID);
- Q_UNUSED(pAttributes);
- return E_NOTIMPL;
-}
-
-STDMETHODIMP MFTransform::GetOutputStreamAttributes(DWORD dwOutputStreamID, IMFAttributes **pAttributes)
-{
- // This MFT does not support output stream attributes.
- Q_UNUSED(dwOutputStreamID);
- Q_UNUSED(pAttributes);
- return E_NOTIMPL;
-}
-
-STDMETHODIMP MFTransform::DeleteInputStream(DWORD dwStreamID)
-{
- // This MFT has a fixed number of input streams.
- Q_UNUSED(dwStreamID);
- return E_NOTIMPL;
-}
-
-STDMETHODIMP MFTransform::AddInputStreams(DWORD cStreams, DWORD *adwStreamIDs)
-{
- // This MFT has a fixed number of input streams.
- Q_UNUSED(cStreams);
- Q_UNUSED(adwStreamIDs);
- return E_NOTIMPL;
-}
-
-STDMETHODIMP MFTransform::GetInputAvailableType(DWORD dwInputStreamID, DWORD dwTypeIndex, IMFMediaType **ppType)
-{
- // We support the same input types as the video sink
- if (!m_videoSinkTypeHandler)
- return E_NOTIMPL;
-
- if (dwInputStreamID > 0)
- return MF_E_INVALIDSTREAMNUMBER;
-
- if (!ppType)
- return E_POINTER;
-
- return m_videoSinkTypeHandler->GetMediaTypeByIndex(dwTypeIndex, ppType);
-}
-
-STDMETHODIMP MFTransform::GetOutputAvailableType(DWORD dwOutputStreamID, DWORD dwTypeIndex, IMFMediaType **ppType)
-{
- // Since we don't modify the samples, the output type must be the same as the input type.
- // Report our input type as the only available output type.
-
- if (dwOutputStreamID > 0)
- return MF_E_INVALIDSTREAMNUMBER;
-
- if (!ppType)
- return E_POINTER;
-
- // Input type must be set first
- if (!m_inputType)
- return MF_E_TRANSFORM_TYPE_NOT_SET;
-
- if (dwTypeIndex > 0)
- return MF_E_NO_MORE_TYPES;
-
- // Return a copy to make sure our type is not modified
- if (FAILED(MFCreateMediaType(ppType)))
- return E_OUTOFMEMORY;
-
- return m_inputType->CopyAllItems(*ppType);
-}
-
-STDMETHODIMP MFTransform::SetInputType(DWORD dwInputStreamID, IMFMediaType *pType, DWORD dwFlags)
-{
- if (dwInputStreamID > 0)
- return MF_E_INVALIDSTREAMNUMBER;
-
- QMutexLocker locker(&m_mutex);
-
- if (m_sample)
- return MF_E_TRANSFORM_CANNOT_CHANGE_MEDIATYPE_WHILE_PROCESSING;
-
- if (!isMediaTypeSupported(pType))
- return MF_E_INVALIDMEDIATYPE;
-
- if (dwFlags == MFT_SET_TYPE_TEST_ONLY)
- return pType ? S_OK : E_POINTER;
-
- if (m_inputType) {
- m_inputType->Release();
- // Input type has changed, discard output type (if it's set) so it's reset later on
- DWORD flags = 0;
- if (m_outputType && m_outputType->IsEqual(pType, &flags) != S_OK) {
- m_outputType->Release();
- m_outputType = 0;
- }
- }
-
- m_inputType = pType;
-
- if (m_inputType)
- m_inputType->AddRef();
-
- return S_OK;
-}
-
-STDMETHODIMP MFTransform::SetOutputType(DWORD dwOutputStreamID, IMFMediaType *pType, DWORD dwFlags)
-{
- if (dwOutputStreamID > 0)
- return MF_E_INVALIDSTREAMNUMBER;
-
- if (dwFlags == MFT_SET_TYPE_TEST_ONLY && !pType)
- return E_POINTER;
-
- QMutexLocker locker(&m_mutex);
-
- // Input type must be set first
- if (!m_inputType)
- return MF_E_TRANSFORM_TYPE_NOT_SET;
-
- if (m_sample)
- return MF_E_TRANSFORM_CANNOT_CHANGE_MEDIATYPE_WHILE_PROCESSING;
-
- DWORD flags = 0;
- if (pType && m_inputType->IsEqual(pType, &flags) != S_OK)
- return MF_E_INVALIDMEDIATYPE;
-
- if (dwFlags == MFT_SET_TYPE_TEST_ONLY)
- return pType ? S_OK : E_POINTER;
-
- if (m_outputType)
- m_outputType->Release();
-
- m_outputType = pType;
-
- if (m_outputType) {
- m_outputType->AddRef();
- m_format = videoFormatForMFMediaType(m_outputType, &m_bytesPerLine);
- }
-
- return S_OK;
-}
-
-STDMETHODIMP MFTransform::GetInputCurrentType(DWORD dwInputStreamID, IMFMediaType **ppType)
-{
- if (dwInputStreamID > 0)
- return MF_E_INVALIDSTREAMNUMBER;
-
- if (ppType == NULL)
- return E_POINTER;
-
- QMutexLocker locker(&m_mutex);
-
- if (!m_inputType)
- return MF_E_TRANSFORM_TYPE_NOT_SET;
-
- // Return a copy to make sure our type is not modified
- if (FAILED(MFCreateMediaType(ppType)))
- return E_OUTOFMEMORY;
-
- return m_inputType->CopyAllItems(*ppType);
-}
-
-STDMETHODIMP MFTransform::GetOutputCurrentType(DWORD dwOutputStreamID, IMFMediaType **ppType)
-{
- if (dwOutputStreamID > 0)
- return MF_E_INVALIDSTREAMNUMBER;
-
- if (ppType == NULL)
- return E_POINTER;
-
- QMutexLocker locker(&m_mutex);
-
- if (!m_outputType)
- return MF_E_TRANSFORM_TYPE_NOT_SET;
-
- // Return a copy to make sure our type is not modified
- if (FAILED(MFCreateMediaType(ppType)))
- return E_OUTOFMEMORY;
-
- return m_outputType->CopyAllItems(*ppType);
-}
-
-STDMETHODIMP MFTransform::GetInputStatus(DWORD dwInputStreamID, DWORD *pdwFlags)
-{
- if (dwInputStreamID > 0)
- return MF_E_INVALIDSTREAMNUMBER;
-
- if (!pdwFlags)
- return E_POINTER;
-
- QMutexLocker locker(&m_mutex);
-
- if (!m_inputType || !m_outputType)
- return MF_E_TRANSFORM_TYPE_NOT_SET;
-
- if (m_sample)
- *pdwFlags = 0;
- else
- *pdwFlags = MFT_INPUT_STATUS_ACCEPT_DATA;
-
- return S_OK;
-}
-
-STDMETHODIMP MFTransform::GetOutputStatus(DWORD *pdwFlags)
-{
- if (!pdwFlags)
- return E_POINTER;
-
- QMutexLocker locker(&m_mutex);
-
- if (!m_inputType || !m_outputType)
- return MF_E_TRANSFORM_TYPE_NOT_SET;
-
- if (m_sample)
- *pdwFlags = MFT_OUTPUT_STATUS_SAMPLE_READY;
- else
- *pdwFlags = 0;
-
- return S_OK;
-}
-
-STDMETHODIMP MFTransform::SetOutputBounds(LONGLONG hnsLowerBound, LONGLONG hnsUpperBound)
-{
- Q_UNUSED(hnsLowerBound);
- Q_UNUSED(hnsUpperBound);
- return E_NOTIMPL;
-}
-
-STDMETHODIMP MFTransform::ProcessEvent(DWORD dwInputStreamID, IMFMediaEvent *pEvent)
-{
- // This MFT ignores all events, and the pipeline should send all events downstream.
- Q_UNUSED(dwInputStreamID);
- Q_UNUSED(pEvent);
- return E_NOTIMPL;
-}
-
-STDMETHODIMP MFTransform::ProcessMessage(MFT_MESSAGE_TYPE eMessage, ULONG_PTR ulParam)
-{
- Q_UNUSED(ulParam);
-
- HRESULT hr = S_OK;
-
- switch (eMessage)
- {
- case MFT_MESSAGE_COMMAND_FLUSH:
- hr = OnFlush();
- break;
-
- case MFT_MESSAGE_COMMAND_DRAIN:
- // Drain: Tells the MFT not to accept any more input until
- // all of the pending output has been processed. That is our
- // default behevior already, so there is nothing to do.
- break;
-
- case MFT_MESSAGE_SET_D3D_MANAGER:
- // The pipeline should never send this message unless the MFT
- // has the MF_SA_D3D_AWARE attribute set to TRUE. However, if we
- // do get this message, it's invalid and we don't implement it.
- hr = E_NOTIMPL;
- break;
-
- // The remaining messages do not require any action from this MFT.
- case MFT_MESSAGE_NOTIFY_BEGIN_STREAMING:
- case MFT_MESSAGE_NOTIFY_END_STREAMING:
- case MFT_MESSAGE_NOTIFY_END_OF_STREAM:
- case MFT_MESSAGE_NOTIFY_START_OF_STREAM:
- break;
- }
-
- return hr;
-}
-
-STDMETHODIMP MFTransform::ProcessInput(DWORD dwInputStreamID, IMFSample *pSample, DWORD dwFlags)
-{
- if (dwInputStreamID > 0)
- return MF_E_INVALIDSTREAMNUMBER;
-
- if (dwFlags != 0)
- return E_INVALIDARG; // dwFlags is reserved and must be zero.
-
- QMutexLocker locker(&m_mutex);
-
- if (!m_inputType)
- return MF_E_TRANSFORM_TYPE_NOT_SET;
-
- if (m_sample)
- return MF_E_NOTACCEPTING;
-
- // Validate the number of buffers. There should only be a single buffer to hold the video frame.
- DWORD dwBufferCount = 0;
- HRESULT hr = pSample->GetBufferCount(&dwBufferCount);
- if (FAILED(hr))
- return hr;
-
- if (dwBufferCount == 0)
- return E_FAIL;
-
- if (dwBufferCount > 1)
- return MF_E_SAMPLE_HAS_TOO_MANY_BUFFERS;
-
- m_sample = pSample;
- m_sample->AddRef();
-
- QMutexLocker lockerProbe(&m_videoProbeMutex);
-
- if (!m_videoProbes.isEmpty()) {
- QVideoFrame frame = makeVideoFrame();
-
- for (MFVideoProbeControl* probe : qAsConst(m_videoProbes))
- probe->bufferProbed(frame);
- }
-
- return S_OK;
-}
-
-STDMETHODIMP MFTransform::ProcessOutput(DWORD dwFlags, DWORD cOutputBufferCount, MFT_OUTPUT_DATA_BUFFER *pOutputSamples, DWORD *pdwStatus)
-{
- if (pOutputSamples == NULL || pdwStatus == NULL)
- return E_POINTER;
-
- if (cOutputBufferCount != 1)
- return E_INVALIDARG;
-
- QMutexLocker locker(&m_mutex);
-
- if (!m_inputType)
- return MF_E_TRANSFORM_TYPE_NOT_SET;
-
- if (!m_outputType) {
- pOutputSamples[0].dwStatus = MFT_OUTPUT_DATA_BUFFER_FORMAT_CHANGE;
- return MF_E_TRANSFORM_STREAM_CHANGE;
- }
-
- IMFMediaBuffer *input = NULL;
- IMFMediaBuffer *output = NULL;
-
- if (dwFlags == MFT_PROCESS_OUTPUT_DISCARD_WHEN_NO_BUFFER)
- goto done;
- else if (dwFlags != 0)
- return E_INVALIDARG;
-
- if (!m_sample)
- return MF_E_TRANSFORM_NEED_MORE_INPUT;
-
- // Since the MFT_OUTPUT_STREAM_PROVIDES_SAMPLES flag is set, the client
- // should not be providing samples here
- if (pOutputSamples[0].pSample != NULL)
- return E_INVALIDARG;
-
- pOutputSamples[0].pSample = m_sample;
- pOutputSamples[0].pSample->AddRef();
-
- // Send video frame to probes
- // We do it here (instead of inside ProcessInput) to make sure samples discarded by the renderer
- // are not sent.
- m_videoProbeMutex.lock();
- if (!m_videoProbes.isEmpty()) {
- QVideoFrame frame = makeVideoFrame();
-
- for (MFVideoProbeControl* probe : qAsConst(m_videoProbes))
- probe->bufferProbed(frame);
- }
- m_videoProbeMutex.unlock();
-
-done:
- pOutputSamples[0].dwStatus = 0;
- *pdwStatus = 0;
-
- m_sample->Release();
- m_sample = 0;
-
- if (input)
- input->Release();
- if (output)
- output->Release();
-
- return S_OK;
-}
-
-HRESULT MFTransform::OnFlush()
-{
- QMutexLocker locker(&m_mutex);
-
- if (m_sample) {
- m_sample->Release();
- m_sample = 0;
- }
- return S_OK;
-}
-
-QVideoFrame::PixelFormat MFTransform::formatFromSubtype(const GUID& subtype)
-{
- if (subtype == MFVideoFormat_ARGB32)
- return QVideoFrame::Format_ARGB32;
- else if (subtype == MFVideoFormat_RGB32)
- return QVideoFrame::Format_RGB32;
- else if (subtype == MFVideoFormat_RGB24)
- return QVideoFrame::Format_RGB24;
- else if (subtype == MFVideoFormat_RGB565)
- return QVideoFrame::Format_RGB565;
- else if (subtype == MFVideoFormat_RGB555)
- return QVideoFrame::Format_RGB555;
- else if (subtype == MFVideoFormat_AYUV)
- return QVideoFrame::Format_AYUV444;
- else if (subtype == MFVideoFormat_I420)
- return QVideoFrame::Format_YUV420P;
- else if (subtype == MFVideoFormat_UYVY)
- return QVideoFrame::Format_UYVY;
- else if (subtype == MFVideoFormat_YV12)
- return QVideoFrame::Format_YV12;
- else if (subtype == MFVideoFormat_NV12)
- return QVideoFrame::Format_NV12;
-
- return QVideoFrame::Format_Invalid;
-}
-
-QVideoSurfaceFormat MFTransform::videoFormatForMFMediaType(IMFMediaType *mediaType, int *bytesPerLine)
-{
- UINT32 stride;
- if (FAILED(mediaType->GetUINT32(MF_MT_DEFAULT_STRIDE, &stride))) {
- *bytesPerLine = 0;
- return QVideoSurfaceFormat();
- }
-
- *bytesPerLine = (int)stride;
-
- QSize size;
- UINT32 width, height;
- if (FAILED(MFGetAttributeSize(mediaType, MF_MT_FRAME_SIZE, &width, &height)))
- return QVideoSurfaceFormat();
-
- size.setWidth(width);
- size.setHeight(height);
-
- GUID subtype = GUID_NULL;
- if (FAILED(mediaType->GetGUID(MF_MT_SUBTYPE, &subtype)))
- return QVideoSurfaceFormat();
-
- QVideoFrame::PixelFormat pixelFormat = formatFromSubtype(subtype);
- QVideoSurfaceFormat format(size, pixelFormat);
-
- UINT32 num, den;
- if (SUCCEEDED(MFGetAttributeRatio(mediaType, MF_MT_PIXEL_ASPECT_RATIO, &num, &den))) {
- format.setPixelAspectRatio(num, den);
- }
- if (SUCCEEDED(MFGetAttributeRatio(mediaType, MF_MT_FRAME_RATE, &num, &den))) {
- format.setFrameRate(qreal(num)/den);
- }
-
- return format;
-}
-
-QVideoFrame MFTransform::makeVideoFrame()
-{
- QVideoFrame frame;
-
- if (!m_format.isValid())
- return frame;
-
- IMFMediaBuffer *buffer = 0;
-
- do {
- if (FAILED(m_sample->ConvertToContiguousBuffer(&buffer)))
- break;
-
- QByteArray array = dataFromBuffer(buffer, m_format.frameHeight(), &m_bytesPerLine);
- if (array.isEmpty())
- break;
-
- // Wrapping IMFSample or IMFMediaBuffer in a QVideoFrame is not possible because we cannot hold
- // IMFSample for a "long" time without affecting the rest of the topology.
- // If IMFSample is held for more than 5 frames decoder starts to reuse it even though it hasn't been released it yet.
- // That is why we copy data from IMFMediaBuffer here.
- frame = QVideoFrame(new QMemoryVideoBuffer(array, m_bytesPerLine), m_format.frameSize(), m_format.pixelFormat());
-
- // WMF uses 100-nanosecond units, Qt uses microseconds
- LONGLONG startTime = -1;
- if (SUCCEEDED(m_sample->GetSampleTime(&startTime))) {
- frame.setStartTime(startTime * 0.1);
-
- LONGLONG duration = -1;
- if (SUCCEEDED(m_sample->GetSampleDuration(&duration)))
- frame.setEndTime((startTime + duration) * 0.1);
- }
- } while (false);
-
- if (buffer)
- buffer->Release();
-
- return frame;
-}
-
-QByteArray MFTransform::dataFromBuffer(IMFMediaBuffer *buffer, int height, int *bytesPerLine)
-{
- QByteArray array;
- BYTE *bytes;
- DWORD length;
- HRESULT hr = buffer->Lock(&bytes, NULL, &length);
- if (SUCCEEDED(hr)) {
- array = QByteArray((const char *)bytes, (int)length);
- buffer->Unlock();
- } else {
- // try to lock as Direct3DSurface
- IDirect3DSurface9 *surface = 0;
- do {
- if (FAILED(MFGetService(buffer, MR_BUFFER_SERVICE, IID_IDirect3DSurface9, (void**)&surface)))
- break;
-
- D3DLOCKED_RECT rect;
- if (FAILED(surface->LockRect(&rect, NULL, D3DLOCK_READONLY)))
- break;
-
- if (bytesPerLine)
- *bytesPerLine = (int)rect.Pitch;
-
- array = QByteArray((const char *)rect.pBits, rect.Pitch * height);
- surface->UnlockRect();
- } while (false);
-
- if (surface) {
- surface->Release();
- surface = 0;
- }
- }
-
- return array;
-}
-
-bool MFTransform::isMediaTypeSupported(IMFMediaType *type)
-{
- // If we don't have the video sink's type handler,
- // assume it supports anything...
- if (!m_videoSinkTypeHandler || !type)
- return true;
-
- return m_videoSinkTypeHandler->IsMediaTypeSupported(type, NULL) == S_OK;
-}
diff --git a/src/plugins/wmf/player/mftvideo.h b/src/plugins/wmf/player/mftvideo.h
deleted file mode 100644
index ffcb80b32..000000000
--- a/src/plugins/wmf/player/mftvideo.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef MFTRANSFORM_H
-#define MFTRANSFORM_H
-
-#include <mfapi.h>
-#include <mfidl.h>
-#include <QtCore/qlist.h>
-#include <QtCore/qmutex.h>
-#include <QtMultimedia/qvideosurfaceformat.h>
-
-QT_USE_NAMESPACE
-
-class MFVideoProbeControl;
-
-class MFTransform: public IMFTransform
-{
-public:
- MFTransform();
- ~MFTransform();
-
- void addProbe(MFVideoProbeControl* probe);
- void removeProbe(MFVideoProbeControl* probe);
-
- void setVideoSink(IUnknown *videoSink);
-
- // IUnknown methods
- STDMETHODIMP QueryInterface(REFIID iid, void** ppv);
- STDMETHODIMP_(ULONG) AddRef();
- STDMETHODIMP_(ULONG) Release();
-
- // IMFTransform methods
- STDMETHODIMP GetStreamLimits(DWORD *pdwInputMinimum, DWORD *pdwInputMaximum, DWORD *pdwOutputMinimum, DWORD *pdwOutputMaximum);
- STDMETHODIMP GetStreamCount(DWORD *pcInputStreams, DWORD *pcOutputStreams);
- STDMETHODIMP GetStreamIDs(DWORD dwInputIDArraySize, DWORD *pdwInputIDs, DWORD dwOutputIDArraySize, DWORD *pdwOutputIDs);
- STDMETHODIMP GetInputStreamInfo(DWORD dwInputStreamID, MFT_INPUT_STREAM_INFO *pStreamInfo);
- STDMETHODIMP GetOutputStreamInfo(DWORD dwOutputStreamID, MFT_OUTPUT_STREAM_INFO *pStreamInfo);
- STDMETHODIMP GetAttributes(IMFAttributes **pAttributes);
- STDMETHODIMP GetInputStreamAttributes(DWORD dwInputStreamID, IMFAttributes **pAttributes);
- STDMETHODIMP GetOutputStreamAttributes(DWORD dwOutputStreamID, IMFAttributes **pAttributes);
- STDMETHODIMP DeleteInputStream(DWORD dwStreamID);
- STDMETHODIMP AddInputStreams(DWORD cStreams, DWORD *adwStreamIDs);
- STDMETHODIMP GetInputAvailableType(DWORD dwInputStreamID, DWORD dwTypeIndex, IMFMediaType **ppType);
- STDMETHODIMP GetOutputAvailableType(DWORD dwOutputStreamID,DWORD dwTypeIndex, IMFMediaType **ppType);
- STDMETHODIMP SetInputType(DWORD dwInputStreamID, IMFMediaType *pType, DWORD dwFlags);
- STDMETHODIMP SetOutputType(DWORD dwOutputStreamID, IMFMediaType *pType, DWORD dwFlags);
- STDMETHODIMP GetInputCurrentType(DWORD dwInputStreamID, IMFMediaType **ppType);
- STDMETHODIMP GetOutputCurrentType(DWORD dwOutputStreamID, IMFMediaType **ppType);
- STDMETHODIMP GetInputStatus(DWORD dwInputStreamID, DWORD *pdwFlags);
- STDMETHODIMP GetOutputStatus(DWORD *pdwFlags);
- STDMETHODIMP SetOutputBounds(LONGLONG hnsLowerBound, LONGLONG hnsUpperBound);
- STDMETHODIMP ProcessEvent(DWORD dwInputStreamID, IMFMediaEvent *pEvent);
- STDMETHODIMP ProcessMessage(MFT_MESSAGE_TYPE eMessage, ULONG_PTR ulParam);
- STDMETHODIMP ProcessInput(DWORD dwInputStreamID, IMFSample *pSample, DWORD dwFlags);
- STDMETHODIMP ProcessOutput(DWORD dwFlags, DWORD cOutputBufferCount, MFT_OUTPUT_DATA_BUFFER *pOutputSamples, DWORD *pdwStatus);
-
-private:
- HRESULT OnFlush();
- static QVideoFrame::PixelFormat formatFromSubtype(const GUID& subtype);
- static QVideoSurfaceFormat videoFormatForMFMediaType(IMFMediaType *mediaType, int *bytesPerLine);
- QVideoFrame makeVideoFrame();
- QByteArray dataFromBuffer(IMFMediaBuffer *buffer, int height, int *bytesPerLine);
- bool isMediaTypeSupported(IMFMediaType *type);
-
- long m_cRef;
- IMFMediaType *m_inputType;
- IMFMediaType *m_outputType;
- IMFSample *m_sample;
- QMutex m_mutex;
-
- IMFMediaTypeHandler *m_videoSinkTypeHandler;
-
- QList<MFVideoProbeControl*> m_videoProbes;
- QMutex m_videoProbeMutex;
-
- QVideoSurfaceFormat m_format;
- int m_bytesPerLine;
-};
-
-#endif
diff --git a/src/plugins/wmf/player/mfvideoprobecontrol.cpp b/src/plugins/wmf/player/mfvideoprobecontrol.cpp
deleted file mode 100644
index 13d9a1bfe..000000000
--- a/src/plugins/wmf/player/mfvideoprobecontrol.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "mfvideoprobecontrol.h"
-
-MFVideoProbeControl::MFVideoProbeControl(QObject *parent)
- : QMediaVideoProbeControl(parent)
-{
-}
-
-MFVideoProbeControl::~MFVideoProbeControl()
-{
-}
-
-void MFVideoProbeControl::bufferProbed(const QVideoFrame& frame)
-{
- QMetaObject::invokeMethod(this, "videoFrameProbed", Qt::QueuedConnection, Q_ARG(QVideoFrame, frame));
-}
diff --git a/src/plugins/wmf/player/mfvideoprobecontrol.h b/src/plugins/wmf/player/mfvideoprobecontrol.h
deleted file mode 100644
index 2b238725a..000000000
--- a/src/plugins/wmf/player/mfvideoprobecontrol.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef MFVIDEOPROBECONTROL_H
-#define MFVIDEOPROBECONTROL_H
-
-#include <qmediavideoprobecontrol.h>
-#include <QtCore/qmutex.h>
-#include <qvideoframe.h>
-
-QT_USE_NAMESPACE
-
-class MFVideoProbeControl : public QMediaVideoProbeControl
-{
- Q_OBJECT
-public:
- explicit MFVideoProbeControl(QObject *parent);
- virtual ~MFVideoProbeControl();
-
- void bufferProbed(const QVideoFrame& frame);
-};
-
-#endif
diff --git a/src/plugins/wmf/player/mfvideorenderercontrol.cpp b/src/plugins/wmf/player/mfvideorenderercontrol.cpp
deleted file mode 100644
index 7b121255f..000000000
--- a/src/plugins/wmf/player/mfvideorenderercontrol.cpp
+++ /dev/null
@@ -1,2426 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt Mobility Components.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "mfvideorenderercontrol.h"
-#include "mfactivate.h"
-
-#include "evrcustompresenter.h"
-
-#include <qabstractvideosurface.h>
-#include <qvideosurfaceformat.h>
-#include <qtcore/qtimer.h>
-#include <qtcore/qmutex.h>
-#include <qtcore/qcoreevent.h>
-#include <qtcore/qcoreapplication.h>
-#include <qtcore/qthread.h>
-#include "guiddef.h"
-#include <qtcore/qdebug.h>
-
-//#define DEBUG_MEDIAFOUNDATION
-#define PAD_TO_DWORD(x) (((x) + 3) & ~3)
-
-namespace
-{
- class MediaSampleVideoBuffer : public QAbstractVideoBuffer
- {
- public:
- MediaSampleVideoBuffer(IMFMediaBuffer *buffer, int bytesPerLine)
- : QAbstractVideoBuffer(NoHandle)
- , m_buffer(buffer)
- , m_bytesPerLine(bytesPerLine)
- , m_mapMode(NotMapped)
- {
- buffer->AddRef();
- }
-
- ~MediaSampleVideoBuffer()
- {
- m_buffer->Release();
- }
-
- uchar *map(MapMode mode, int *numBytes, int *bytesPerLine)
- {
- if (m_mapMode == NotMapped && mode != NotMapped) {
- BYTE *bytes;
- DWORD length;
- HRESULT hr = m_buffer->Lock(&bytes, NULL, &length);
- if (SUCCEEDED(hr)) {
- if (numBytes)
- *numBytes = int(length);
-
- if (bytesPerLine)
- *bytesPerLine = m_bytesPerLine;
-
- m_mapMode = mode;
- return reinterpret_cast<uchar *>(bytes);
- } else {
- qWarning("Faild to lock mf buffer!");
- }
- }
- return 0;
- }
-
- void unmap()
- {
- if (m_mapMode == NotMapped)
- return;
- m_mapMode = NotMapped;
- m_buffer->Unlock();
- }
-
- MapMode mapMode() const
- {
- return m_mapMode;
- }
-
- private:
- IMFMediaBuffer *m_buffer;
- int m_bytesPerLine;
- MapMode m_mapMode;
- };
-
- // Custom interface for handling IMFStreamSink::PlaceMarker calls asynchronously.
- MIDL_INTERFACE("a3ff32de-1031-438a-8b47-82f8acda59b7")
- IMarker : public IUnknown
- {
- virtual STDMETHODIMP GetMarkerType(MFSTREAMSINK_MARKER_TYPE *pType) = 0;
- virtual STDMETHODIMP GetMarkerValue(PROPVARIANT *pvar) = 0;
- virtual STDMETHODIMP GetContext(PROPVARIANT *pvar) = 0;
- };
-
- class Marker : public IMarker
- {
- public:
- static HRESULT Create(
- MFSTREAMSINK_MARKER_TYPE eMarkerType,
- const PROPVARIANT* pvarMarkerValue, // Can be NULL.
- const PROPVARIANT* pvarContextValue, // Can be NULL.
- IMarker **ppMarker)
- {
- if (ppMarker == NULL)
- return E_POINTER;
-
- HRESULT hr = S_OK;
- Marker *pMarker = new Marker(eMarkerType);
- if (pMarker == NULL)
- hr = E_OUTOFMEMORY;
-
- // Copy the marker data.
- if (SUCCEEDED(hr) && pvarMarkerValue)
- hr = PropVariantCopy(&pMarker->m_varMarkerValue, pvarMarkerValue);
-
- if (SUCCEEDED(hr) && pvarContextValue)
- hr = PropVariantCopy(&pMarker->m_varContextValue, pvarContextValue);
-
- if (SUCCEEDED(hr)) {
- *ppMarker = pMarker;
- (*ppMarker)->AddRef();
- }
-
- if (pMarker)
- pMarker->Release();
-
- return hr;
- }
-
- // IUnknown methods.
- STDMETHODIMP QueryInterface(REFIID iid, void** ppv)
- {
- if (!ppv)
- return E_POINTER;
- if (iid == IID_IUnknown) {
- *ppv = static_cast<IUnknown*>(this);
- } else if (iid == __uuidof(IMarker)) {
- *ppv = static_cast<IMarker*>(this);
- } else {
- *ppv = NULL;
- return E_NOINTERFACE;
- }
- AddRef();
- return S_OK;
- }
-
- STDMETHODIMP_(ULONG) AddRef()
- {
- return InterlockedIncrement(&m_cRef);
- }
-
- STDMETHODIMP_(ULONG) Release()
- {
- LONG cRef = InterlockedDecrement(&m_cRef);
- if (cRef == 0)
- delete this;
- // For thread safety, return a temporary variable.
- return cRef;
- }
-
- STDMETHODIMP GetMarkerType(MFSTREAMSINK_MARKER_TYPE *pType)
- {
- if (pType == NULL)
- return E_POINTER;
- *pType = m_eMarkerType;
- return S_OK;
- }
-
- STDMETHODIMP GetMarkerValue(PROPVARIANT *pvar)
- {
- if (pvar == NULL)
- return E_POINTER;
- return PropVariantCopy(pvar, &m_varMarkerValue);
- }
-
- STDMETHODIMP GetContext(PROPVARIANT *pvar)
- {
- if (pvar == NULL)
- return E_POINTER;
- return PropVariantCopy(pvar, &m_varContextValue);
- }
-
- protected:
- MFSTREAMSINK_MARKER_TYPE m_eMarkerType;
- PROPVARIANT m_varMarkerValue;
- PROPVARIANT m_varContextValue;
-
- private:
- long m_cRef;
-
- Marker(MFSTREAMSINK_MARKER_TYPE eMarkerType) : m_cRef(1), m_eMarkerType(eMarkerType)
- {
- PropVariantInit(&m_varMarkerValue);
- PropVariantInit(&m_varContextValue);
- }
-
- virtual ~Marker()
- {
- PropVariantClear(&m_varMarkerValue);
- PropVariantClear(&m_varContextValue);
- }
- };
-
- class MediaStream : public QObject, public IMFStreamSink, public IMFMediaTypeHandler
- {
- Q_OBJECT
- friend class MFVideoRendererControl;
- public:
- static const DWORD DEFAULT_MEDIA_STREAM_ID = 0x0;
-
- MediaStream(IMFMediaSink *parent, MFVideoRendererControl *rendererControl)
- : m_cRef(1)
- , m_eventQueue(0)
- , m_shutdown(false)
- , m_surface(0)
- , m_state(State_TypeNotSet)
- , m_currentFormatIndex(-1)
- , m_bytesPerLine(0)
- , m_workQueueId(0)
- , m_workQueueCB(this, &MediaStream::onDispatchWorkItem)
- , m_finalizeResult(0)
- , m_scheduledBuffer(0)
- , m_bufferStartTime(-1)
- , m_bufferDuration(-1)
- , m_presentationClock(0)
- , m_sampleRequested(false)
- , m_currentMediaType(0)
- , m_prerolling(false)
- , m_prerollTargetTime(0)
- , m_startTime(0)
- , m_rendererControl(rendererControl)
- , m_rate(1.f)
- {
- m_sink = parent;
-
- if (FAILED(MFCreateEventQueue(&m_eventQueue)))
- qWarning("Failed to create mf event queue!");
- if (FAILED(MFAllocateWorkQueue(&m_workQueueId)))
- qWarning("Failed to allocated mf work queue!");
- }
-
- ~MediaStream()
- {
- Q_ASSERT(m_shutdown);
- }
-
- //from IUnknown
- STDMETHODIMP QueryInterface(REFIID riid, void** ppvObject)
- {
- if (!ppvObject)
- return E_POINTER;
- if (riid == IID_IMFStreamSink) {
- *ppvObject = static_cast<IMFStreamSink*>(this);
- } else if (riid == IID_IMFMediaEventGenerator) {
- *ppvObject = static_cast<IMFMediaEventGenerator*>(this);
- } else if (riid == IID_IMFMediaTypeHandler) {
- *ppvObject = static_cast<IMFMediaTypeHandler*>(this);
- } else if (riid == IID_IUnknown) {
- *ppvObject = static_cast<IUnknown*>(static_cast<IMFStreamSink*>(this));
- } else {
- *ppvObject = NULL;
- return E_NOINTERFACE;
- }
- AddRef();
- return S_OK;
- }
-
- STDMETHODIMP_(ULONG) AddRef(void)
- {
- return InterlockedIncrement(&m_cRef);
- }
-
- STDMETHODIMP_(ULONG) Release(void)
- {
- LONG cRef = InterlockedDecrement(&m_cRef);
- if (cRef == 0)
- delete this;
- // For thread safety, return a temporary variable.
- return cRef;
- }
-
- //from IMFMediaEventGenerator
- STDMETHODIMP GetEvent(
- DWORD dwFlags,
- IMFMediaEvent **ppEvent)
- {
- // GetEvent can block indefinitely, so we don't hold the lock.
- // This requires some juggling with the event queue pointer.
- HRESULT hr = S_OK;
- IMFMediaEventQueue *queue = NULL;
-
- m_mutex.lock();
- if (m_shutdown)
- hr = MF_E_SHUTDOWN;
- if (SUCCEEDED(hr)) {
- queue = m_eventQueue;
- queue->AddRef();
- }
- m_mutex.unlock();
-
- // Now get the event.
- if (SUCCEEDED(hr)) {
- hr = queue->GetEvent(dwFlags, ppEvent);
- queue->Release();
- }
-
- return hr;
- }
-
- STDMETHODIMP BeginGetEvent(
- IMFAsyncCallback *pCallback,
- IUnknown *punkState)
- {
- QMutexLocker locker(&m_mutex);
- if (m_shutdown)
- return MF_E_SHUTDOWN;
- return m_eventQueue->BeginGetEvent(pCallback, punkState);
- }
-
- STDMETHODIMP EndGetEvent(
- IMFAsyncResult *pResult,
- IMFMediaEvent **ppEvent)
- {
- QMutexLocker locker(&m_mutex);
- if (m_shutdown)
- return MF_E_SHUTDOWN;
- return m_eventQueue->EndGetEvent(pResult, ppEvent);
- }
-
- STDMETHODIMP QueueEvent(
- MediaEventType met,
- REFGUID guidExtendedType,
- HRESULT hrStatus,
- const PROPVARIANT *pvValue)
- {
-#ifdef DEBUG_MEDIAFOUNDATION
- qDebug() << "MediaStream::QueueEvent" << met;
-#endif
- QMutexLocker locker(&m_mutex);
- if (m_shutdown)
- return MF_E_SHUTDOWN;
- return m_eventQueue->QueueEventParamVar(met, guidExtendedType, hrStatus, pvValue);
- }
-
- //from IMFStreamSink
- STDMETHODIMP GetMediaSink(
- IMFMediaSink **ppMediaSink)
- {
- QMutexLocker locker(&m_mutex);
- if (m_shutdown)
- return MF_E_SHUTDOWN;
- else if (!ppMediaSink)
- return E_INVALIDARG;
-
- m_sink->AddRef();
- *ppMediaSink = m_sink;
- return S_OK;
- }
-
- STDMETHODIMP GetIdentifier(
- DWORD *pdwIdentifier)
- {
- *pdwIdentifier = MediaStream::DEFAULT_MEDIA_STREAM_ID;
- return S_OK;
- }
-
- STDMETHODIMP GetMediaTypeHandler(
- IMFMediaTypeHandler **ppHandler)
- {
- LPVOID handler = NULL;
- HRESULT hr = QueryInterface(IID_IMFMediaTypeHandler, &handler);
- *ppHandler = (IMFMediaTypeHandler*)(handler);
- return hr;
- }
-
- STDMETHODIMP ProcessSample(
- IMFSample *pSample)
- {
- if (pSample == NULL)
- return E_INVALIDARG;
- HRESULT hr = S_OK;
- QMutexLocker locker(&m_mutex);
- if (m_shutdown)
- return MF_E_SHUTDOWN;
-
- if (!m_prerolling) {
- hr = validateOperation(OpProcessSample);
- if (FAILED(hr))
- return hr;
- }
-
- pSample->AddRef();
- m_sampleQueue.push_back(pSample);
-
- // Unless we are paused, start an async operation to dispatch the next sample.
- if (m_state != State_Paused)
- hr = queueAsyncOperation(OpProcessSample);
-
- return hr;
- }
-
- STDMETHODIMP PlaceMarker(
- MFSTREAMSINK_MARKER_TYPE eMarkerType,
- const PROPVARIANT *pvarMarkerValue,
- const PROPVARIANT *pvarContextValue)
- {
- HRESULT hr = S_OK;
- QMutexLocker locker(&m_mutex);
- IMarker *pMarker = NULL;
- if (m_shutdown)
- return MF_E_SHUTDOWN;
-
- hr = validateOperation(OpPlaceMarker);
- if (FAILED(hr))
- return hr;
-
- // Create a marker object and put it on the sample queue.
- hr = Marker::Create(eMarkerType, pvarMarkerValue, pvarContextValue, &pMarker);
- if (FAILED(hr))
- return hr;
-
- m_sampleQueue.push_back(pMarker);
-
- // Unless we are paused, start an async operation to dispatch the next sample/marker.
- if (m_state != State_Paused)
- hr = queueAsyncOperation(OpPlaceMarker); // Increments ref count on pOp.
- return hr;
- }
-
- STDMETHODIMP Flush( void)
- {
-#ifdef DEBUG_MEDIAFOUNDATION
- qDebug() << "MediaStream::Flush";
-#endif
- QMutexLocker locker(&m_mutex);
- if (m_shutdown)
- return MF_E_SHUTDOWN;
- // Note: Even though we are flushing data, we still need to send
- // any marker events that were queued.
- clearBufferCache();
- return processSamplesFromQueue(DropSamples);
- }
-
- //from IMFMediaTypeHandler
- STDMETHODIMP IsMediaTypeSupported(
- IMFMediaType *pMediaType,
- IMFMediaType **ppMediaType)
- {
- if (ppMediaType)
- *ppMediaType = NULL;
- QMutexLocker locker(&m_mutex);
- if (m_shutdown)
- return MF_E_SHUTDOWN;
-
- int index = getMediaTypeIndex(pMediaType);
- if (index < 0) {
- if (ppMediaType && m_mediaTypes.size() > 0) {
- *ppMediaType = m_mediaTypes[0];
- (*ppMediaType)->AddRef();
- }
- return MF_E_INVALIDMEDIATYPE;
- }
-
- BOOL compressed = TRUE;
- pMediaType->IsCompressedFormat(&compressed);
- if (compressed) {
- if (ppMediaType && (SUCCEEDED(MFCreateMediaType(ppMediaType)))) {
- (*ppMediaType)->CopyAllItems(pMediaType);
- (*ppMediaType)->SetUINT32(MF_MT_FIXED_SIZE_SAMPLES, TRUE);
- (*ppMediaType)->SetUINT32(MF_MT_COMPRESSED, FALSE);
- (*ppMediaType)->SetUINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE);
- }
- return MF_E_INVALIDMEDIATYPE;
- }
-
- return S_OK;
- }
-
- STDMETHODIMP GetMediaTypeCount(
- DWORD *pdwTypeCount)
- {
- if (pdwTypeCount == NULL)
- return E_INVALIDARG;
- QMutexLocker locker(&m_mutex);
- *pdwTypeCount = DWORD(m_mediaTypes.size());
- return S_OK;
- }
-
- STDMETHODIMP GetMediaTypeByIndex(
- DWORD dwIndex,
- IMFMediaType **ppType)
- {
- if (ppType == NULL)
- return E_INVALIDARG;
- HRESULT hr = S_OK;
- QMutexLocker locker(&m_mutex);
- if (m_shutdown)
- hr = MF_E_SHUTDOWN;
-
- if (SUCCEEDED(hr)) {
- if (dwIndex >= DWORD(m_mediaTypes.size()))
- hr = MF_E_NO_MORE_TYPES;
- }
-
- if (SUCCEEDED(hr)) {
- *ppType = m_mediaTypes[dwIndex];
- (*ppType)->AddRef();
- }
- return hr;
- }
-
- STDMETHODIMP SetCurrentMediaType(
- IMFMediaType *pMediaType)
- {
- HRESULT hr = S_OK;
- QMutexLocker locker(&m_mutex);
- if (m_shutdown)
- return MF_E_SHUTDOWN;
-
- DWORD flag = MF_MEDIATYPE_EQUAL_MAJOR_TYPES |
- MF_MEDIATYPE_EQUAL_FORMAT_TYPES |
- MF_MEDIATYPE_EQUAL_FORMAT_DATA;
-
- if (m_currentMediaType && (m_currentMediaType->IsEqual(pMediaType, &flag) == S_OK))
- return S_OK;
-
- hr = validateOperation(OpSetMediaType);
-
- if (SUCCEEDED(hr)) {
- int index = getMediaTypeIndex(pMediaType);
- if (index >= 0) {
- UINT64 size;
- hr = pMediaType->GetUINT64(MF_MT_FRAME_SIZE, &size);
- if (SUCCEEDED(hr)) {
- m_currentFormatIndex = index;
- int width = int(HI32(size));
- int height = int(LO32(size));
- QVideoSurfaceFormat format(QSize(width, height), m_pixelFormats[index]);
- m_surfaceFormat = format;
-
- MFVideoArea viewport;
- if (SUCCEEDED(pMediaType->GetBlob(MF_MT_GEOMETRIC_APERTURE,
- reinterpret_cast<UINT8*>(&viewport),
- sizeof(MFVideoArea),
- NULL))) {
-
- m_surfaceFormat.setViewport(QRect(viewport.OffsetX.value,
- viewport.OffsetY.value,
- viewport.Area.cx,
- viewport.Area.cy));
- }
-
- if (FAILED(pMediaType->GetUINT32(MF_MT_DEFAULT_STRIDE, (UINT32*)&m_bytesPerLine))) {
- m_bytesPerLine = getBytesPerLine(format);
- }
-
- m_state = State_Ready;
- if (m_currentMediaType)
- m_currentMediaType->Release();
- m_currentMediaType = pMediaType;
- pMediaType->AddRef();
- }
- } else {
- hr = MF_E_INVALIDREQUEST;
- }
- }
- return hr;
- }
-
- STDMETHODIMP GetCurrentMediaType(
- IMFMediaType **ppMediaType)
- {
- if (ppMediaType == NULL)
- return E_INVALIDARG;
- QMutexLocker locker(&m_mutex);
- if (m_shutdown)
- return MF_E_SHUTDOWN;
- if (m_currentFormatIndex < 0)
- return MF_E_NOT_INITIALIZED;
- *ppMediaType = m_currentMediaType;
- (*ppMediaType)->AddRef();
- return S_OK;
- }
-
- STDMETHODIMP GetMajorType(
- GUID *pguidMajorType)
- {
- if (pguidMajorType == NULL)
- return E_INVALIDARG;
- *pguidMajorType = MFMediaType_Video;
- return S_OK;
- }
-
- //
- void setSurface(QAbstractVideoSurface *surface)
- {
- m_mutex.lock();
- m_surface = surface;
- m_mutex.unlock();
- supportedFormatsChanged();
- }
-
- void setClock(IMFPresentationClock *presentationClock)
- {
- QMutexLocker locker(&m_mutex);
- if (!m_shutdown) {
- if (m_presentationClock)
- m_presentationClock->Release();
- m_presentationClock = presentationClock;
- if (m_presentationClock)
- m_presentationClock->AddRef();
- }
- }
-
- void shutdown()
- {
- QMutexLocker locker(&m_mutex);
- Q_ASSERT(!m_shutdown);
-
- if (m_currentMediaType) {
- m_currentMediaType->Release();
- m_currentMediaType = NULL;
- m_currentFormatIndex = -1;
- }
-
- if (m_eventQueue)
- m_eventQueue->Shutdown();
-
- MFUnlockWorkQueue(m_workQueueId);
-
- if (m_presentationClock) {
- m_presentationClock->Release();
- m_presentationClock = NULL;
- }
-
- clearMediaTypes();
- clearSampleQueue();
- clearBufferCache();
-
- if (m_eventQueue) {
- m_eventQueue->Release();
- m_eventQueue = NULL;
- }
-
- m_shutdown = true;
- }
-
- HRESULT startPreroll(MFTIME hnsUpcomingStartTime)
- {
- QMutexLocker locker(&m_mutex);
- HRESULT hr = validateOperation(OpPreroll);
- if (SUCCEEDED(hr)) {
- m_state = State_Prerolling;
- m_prerollTargetTime = hnsUpcomingStartTime;
- hr = queueAsyncOperation(OpPreroll);
- }
- return hr;
- }
-
- HRESULT finalize(IMFAsyncCallback *pCallback, IUnknown *punkState)
- {
- QMutexLocker locker(&m_mutex);
- HRESULT hr = S_OK;
- hr = validateOperation(OpFinalize);
- if (SUCCEEDED(hr) && m_finalizeResult != NULL)
- hr = MF_E_INVALIDREQUEST; // The operation is already pending.
-
- // Create and store the async result object.
- if (SUCCEEDED(hr))
- hr = MFCreateAsyncResult(NULL, pCallback, punkState, &m_finalizeResult);
-
- if (SUCCEEDED(hr)) {
- m_state = State_Finalized;
- hr = queueAsyncOperation(OpFinalize);
- }
- return hr;
- }
-
- HRESULT start(MFTIME start)
- {
-#ifdef DEBUG_MEDIAFOUNDATION
- qDebug() << "MediaStream::start" << start;
-#endif
- HRESULT hr = S_OK;
- QMutexLocker locker(&m_mutex);
- if (m_rate != 0)
- hr = validateOperation(OpStart);
-
- if (SUCCEEDED(hr)) {
- MFTIME sysTime;
- if (start != PRESENTATION_CURRENT_POSITION)
- m_startTime = start; // Cache the start time.
- else
- m_presentationClock->GetCorrelatedTime(0, &m_startTime, &sysTime);
- m_state = State_Started;
- hr = queueAsyncOperation(OpStart);
- }
- return hr;
- }
-
- HRESULT restart()
- {
-#ifdef DEBUG_MEDIAFOUNDATION
- qDebug() << "MediaStream::restart";
-#endif
- QMutexLocker locker(&m_mutex);
- HRESULT hr = validateOperation(OpRestart);
- if (SUCCEEDED(hr)) {
- m_state = State_Started;
- hr = queueAsyncOperation(OpRestart);
- }
- return hr;
- }
-
- HRESULT stop()
- {
-#ifdef DEBUG_MEDIAFOUNDATION
- qDebug() << "MediaStream::stop";
-#endif
- QMutexLocker locker(&m_mutex);
- HRESULT hr = validateOperation(OpStop);
- if (SUCCEEDED(hr)) {
- m_state = State_Stopped;
- hr = queueAsyncOperation(OpStop);
- }
- return hr;
- }
-
- HRESULT pause()
- {
-#ifdef DEBUG_MEDIAFOUNDATION
- qDebug() << "MediaStream::pause";
-#endif
- QMutexLocker locker(&m_mutex);
- HRESULT hr = validateOperation(OpPause);
- if (SUCCEEDED(hr)) {
- m_state = State_Paused;
- hr = queueAsyncOperation(OpPause);
- }
- return hr;
- }
-
- HRESULT setRate(float rate)
- {
-#ifdef DEBUG_MEDIAFOUNDATION
- qDebug() << "MediaStream::setRate" << rate;
-#endif
- QMutexLocker locker(&m_mutex);
- HRESULT hr = validateOperation(OpSetRate);
- if (SUCCEEDED(hr)) {
- m_rate = rate;
- hr = queueAsyncOperation(OpSetRate);
- }
- return hr;
- }
-
- void supportedFormatsChanged()
- {
- QMutexLocker locker(&m_mutex);
- m_pixelFormats.clear();
- clearMediaTypes();
- if (!m_surface)
- return;
- const QList<QVideoFrame::PixelFormat> formats = m_surface->supportedPixelFormats();
- for (QVideoFrame::PixelFormat format : formats) {
- IMFMediaType *mediaType;
- if (FAILED(MFCreateMediaType(&mediaType))) {
- qWarning("Failed to create mf media type!");
- continue;
- }
- mediaType->SetUINT32(MF_MT_FIXED_SIZE_SAMPLES, TRUE);
- mediaType->SetUINT32(MF_MT_COMPRESSED, FALSE);
- mediaType->SetUINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE);
- mediaType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video);
- switch (format) {
- case QVideoFrame::Format_ARGB32:
- case QVideoFrame::Format_ARGB32_Premultiplied:
- mediaType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_ARGB32);
- break;
- case QVideoFrame::Format_RGB32:
- mediaType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_RGB32);
- break;
- case QVideoFrame::Format_BGR24: // MFVideoFormat_RGB24 has a BGR layout
- mediaType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_RGB24);
- break;
- case QVideoFrame::Format_RGB565:
- mediaType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_RGB565);
- break;
- case QVideoFrame::Format_RGB555:
- mediaType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_RGB555);
- break;
- case QVideoFrame::Format_AYUV444:
- case QVideoFrame::Format_AYUV444_Premultiplied:
- mediaType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_AYUV);
- break;
- case QVideoFrame::Format_YUV420P:
- mediaType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_I420);
- break;
- case QVideoFrame::Format_UYVY:
- mediaType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_UYVY);
- break;
- case QVideoFrame::Format_YV12:
- mediaType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_YV12);
- break;
- case QVideoFrame::Format_NV12:
- mediaType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_NV12);
- break;
- default:
- mediaType->Release();
- continue;
- }
- // QAbstractVideoSurface::supportedPixelFormats() returns formats in descending
- // order of preference, while IMFMediaTypeHandler is supposed to return supported
- // formats in ascending order of preference. We need to reverse the list.
- m_pixelFormats.prepend(format);
- m_mediaTypes.prepend(mediaType);
- }
- }
-
- void present()
- {
- QMutexLocker locker(&m_mutex);
- if (!m_scheduledBuffer)
- return;
- QVideoFrame frame = QVideoFrame(
- new MediaSampleVideoBuffer(m_scheduledBuffer, m_bytesPerLine),
- m_surfaceFormat.frameSize(),
- m_surfaceFormat.pixelFormat());
- frame.setStartTime(m_bufferStartTime * 0.1);
- frame.setEndTime((m_bufferStartTime + m_bufferDuration) * 0.1);
- m_surface->present(frame);
- m_scheduledBuffer->Release();
- m_scheduledBuffer = NULL;
- if (m_rate != 0)
- schedulePresentation(true);
- }
-
- void clearScheduledFrame()
- {
- QMutexLocker locker(&m_mutex);
- if (m_scheduledBuffer) {
- m_scheduledBuffer->Release();
- m_scheduledBuffer = NULL;
- schedulePresentation(true);
- }
- }
-
- enum
- {
- StartSurface = QEvent::User,
- StopSurface,
- FlushSurface,
- PresentSurface
- };
-
- class PresentEvent : public QEvent
- {
- public:
- PresentEvent(MFTIME targetTime)
- : QEvent(QEvent::Type(PresentSurface))
- , m_time(targetTime)
- {
- }
-
- MFTIME targetTime()
- {
- return m_time;
- }
-
- private:
- MFTIME m_time;
- };
-
- protected:
- void customEvent(QEvent *event)
- {
- QMutexLocker locker(&m_mutex);
- if (event->type() == StartSurface) {
- if (m_state == State_WaitForSurfaceStart) {
- m_startResult = startSurface();
- queueAsyncOperation(OpStart);
- }
- } else if (event->type() == StopSurface) {
- stopSurface();
- } else {
- QObject::customEvent(event);
- }
- }
- HRESULT m_startResult;
-
- private:
- HRESULT startSurface()
- {
- if (!m_surface->isFormatSupported(m_surfaceFormat))
- return S_FALSE;
- if (!m_surface->start(m_surfaceFormat))
- return S_FALSE;
- return S_OK;
- }
-
- void stopSurface()
- {
- m_surface->stop();
- }
-
- enum FlushState
- {
- DropSamples = 0,
- WriteSamples
- };
-
- // State enum: Defines the current state of the stream.
- enum State
- {
- State_TypeNotSet = 0, // No media type is set
- State_Ready, // Media type is set, Start has never been called.
- State_Prerolling,
- State_Started,
- State_Paused,
- State_Stopped,
- State_WaitForSurfaceStart,
- State_Finalized,
- State_Count = State_Finalized + 1 // Number of states
- };
-
- // StreamOperation: Defines various operations that can be performed on the stream.
- enum StreamOperation
- {
- OpSetMediaType = 0,
- OpStart,
- OpPreroll,
- OpRestart,
- OpPause,
- OpStop,
- OpSetRate,
- OpProcessSample,
- OpPlaceMarker,
- OpFinalize,
-
- Op_Count = OpFinalize + 1 // Number of operations
- };
-
- // AsyncOperation:
- // Used to queue asynchronous operations. When we call MFPutWorkItem, we use this
- // object for the callback state (pState). Then, when the callback is invoked,
- // we can use the object to determine which asynchronous operation to perform.
- class AsyncOperation : public IUnknown
- {
- public:
- AsyncOperation(StreamOperation op)
- :m_cRef(1), m_op(op)
- {
- }
-
- StreamOperation m_op; // The operation to perform.
-
- //from IUnknown
- STDMETHODIMP QueryInterface(REFIID iid, void** ppv)
- {
- if (!ppv)
- return E_POINTER;
- if (iid == IID_IUnknown) {
- *ppv = static_cast<IUnknown*>(this);
- } else {
- *ppv = NULL;
- return E_NOINTERFACE;
- }
- AddRef();
- return S_OK;
- }
- STDMETHODIMP_(ULONG) AddRef()
- {
- return InterlockedIncrement(&m_cRef);
- }
- STDMETHODIMP_(ULONG) Release()
- {
- ULONG uCount = InterlockedDecrement(&m_cRef);
- if (uCount == 0)
- delete this;
- // For thread safety, return a temporary variable.
- return uCount;
- }
-
- private:
- long m_cRef;
- virtual ~AsyncOperation()
- {
- Q_ASSERT(m_cRef == 0);
- }
- };
-
- // ValidStateMatrix: Defines a look-up table that says which operations
- // are valid from which states.
- static BOOL ValidStateMatrix[State_Count][Op_Count];
-
- long m_cRef;
- QMutex m_mutex;
-
- IMFMediaType *m_currentMediaType;
- State m_state;
- IMFMediaSink *m_sink;
- IMFMediaEventQueue *m_eventQueue;
- DWORD m_workQueueId;
- AsyncCallback<MediaStream> m_workQueueCB;
- QList<IUnknown*> m_sampleQueue;
- IMFAsyncResult *m_finalizeResult; // Result object for Finalize operation.
- MFTIME m_startTime; // Presentation time when the clock started.
-
- bool m_shutdown;
- QList<IMFMediaType*> m_mediaTypes;
- QList<QVideoFrame::PixelFormat> m_pixelFormats;
- int m_currentFormatIndex;
- int m_bytesPerLine;
- QVideoSurfaceFormat m_surfaceFormat;
- QAbstractVideoSurface* m_surface;
- MFVideoRendererControl *m_rendererControl;
-
- void clearMediaTypes()
- {
- for (IMFMediaType* mediaType : qAsConst(m_mediaTypes))
- mediaType->Release();
- m_mediaTypes.clear();
- }
-
- int getMediaTypeIndex(IMFMediaType *mt)
- {
- GUID majorType;
- if (FAILED(mt->GetMajorType(&majorType)))
- return -1;
- if (majorType != MFMediaType_Video)
- return -1;
-
- GUID subType;
- if (FAILED(mt->GetGUID(MF_MT_SUBTYPE, &subType)))
- return -1;
-
- for (int index = 0; index < m_mediaTypes.size(); ++index) {
- GUID st;
- m_mediaTypes[index]->GetGUID(MF_MT_SUBTYPE, &st);
- if (st == subType)
- return index;
- }
- return -1;
- }
-
- int getBytesPerLine(const QVideoSurfaceFormat &format)
- {
- switch (format.pixelFormat()) {
- // 32 bpp packed formats.
- case QVideoFrame::Format_RGB32:
- case QVideoFrame::Format_AYUV444:
- return format.frameWidth() * 4;
- // 24 bpp packed formats.
- case QVideoFrame::Format_RGB24:
- case QVideoFrame::Format_BGR24:
- return PAD_TO_DWORD(format.frameWidth() * 3);
- // 16 bpp packed formats.
- case QVideoFrame::Format_RGB565:
- case QVideoFrame::Format_RGB555:
- case QVideoFrame::Format_YUYV:
- case QVideoFrame::Format_UYVY:
- return PAD_TO_DWORD(format.frameWidth() * 2);
- // Planar formats.
- case QVideoFrame::Format_IMC1:
- case QVideoFrame::Format_IMC2:
- case QVideoFrame::Format_IMC3:
- case QVideoFrame::Format_IMC4:
- case QVideoFrame::Format_YV12:
- case QVideoFrame::Format_NV12:
- case QVideoFrame::Format_YUV420P:
- return PAD_TO_DWORD(format.frameWidth());
- default:
- return 0;
- }
- }
-
- // Callback for MFPutWorkItem.
- HRESULT onDispatchWorkItem(IMFAsyncResult* pAsyncResult)
- {
- QMutexLocker locker(&m_mutex);
- if (m_shutdown)
- return MF_E_SHUTDOWN;
-
- HRESULT hr = S_OK;
- IUnknown *pState = NULL;
- hr = pAsyncResult->GetState(&pState);
- if (SUCCEEDED(hr)) {
- // The state object is an AsncOperation object.
- AsyncOperation *pOp = (AsyncOperation*)pState;
- StreamOperation op = pOp->m_op;
- switch (op) {
- case OpStart:
- endPreroll(S_FALSE);
- if (m_state == State_WaitForSurfaceStart) {
- hr = m_startResult;
- m_state = State_Started;
- } else if (!m_surface->isActive()) {
- if (thread() == QThread::currentThread()) {
- hr = startSurface();
- }
- else {
- m_state = State_WaitForSurfaceStart;
- QCoreApplication::postEvent(m_rendererControl, new QChildEvent(QEvent::Type(StartSurface), this));
- break;
- }
- }
-
- if (m_state == State_Started)
- schedulePresentation(true);
- case OpRestart:
- endPreroll(S_FALSE);
- if (SUCCEEDED(hr)) {
- // Send MEStreamSinkStarted.
- hr = queueEvent(MEStreamSinkStarted, GUID_NULL, hr, NULL);
- // Kick things off by requesting samples...
- schedulePresentation(true);
- // There might be samples queue from earlier (ie, while paused).
- if (SUCCEEDED(hr))
- hr = processSamplesFromQueue(WriteSamples);
- }
- break;
- case OpPreroll:
- beginPreroll();
- break;
- case OpStop:
- // Drop samples from queue.
- hr = processSamplesFromQueue(DropSamples);
- clearBufferCache();
- // Send the event even if the previous call failed.
- hr = queueEvent(MEStreamSinkStopped, GUID_NULL, hr, NULL);
- if (m_surface->isActive()) {
- if (thread() == QThread::currentThread()) {
- stopSurface();
- }
- else {
- QCoreApplication::postEvent(m_rendererControl, new QChildEvent(QEvent::Type(StopSurface), this));
- }
- }
- break;
- case OpPause:
- hr = queueEvent(MEStreamSinkPaused, GUID_NULL, hr, NULL);
- break;
- case OpSetRate:
- hr = queueEvent(MEStreamSinkRateChanged, GUID_NULL, S_OK, NULL);
- break;
- case OpProcessSample:
- case OpPlaceMarker:
- hr = dispatchProcessSample(pOp);
- break;
- case OpFinalize:
- endPreroll(S_FALSE);
- hr = dispatchFinalize(pOp);
- break;
- }
- }
-
- if (pState)
- pState->Release();
- return hr;
- }
-
-
- HRESULT queueEvent(MediaEventType met, REFGUID guidExtendedType, HRESULT hrStatus, const PROPVARIANT* pvValue)
- {
- HRESULT hr = S_OK;
- if (m_shutdown)
- hr = MF_E_SHUTDOWN;
- if (SUCCEEDED(hr))
- hr = m_eventQueue->QueueEventParamVar(met, guidExtendedType, hrStatus, pvValue);
- return hr;
- }
-
- HRESULT validateOperation(StreamOperation op)
- {
- Q_ASSERT(!m_shutdown);
- if (ValidStateMatrix[m_state][op])
- return S_OK;
- else
- return MF_E_INVALIDREQUEST;
- }
-
- HRESULT queueAsyncOperation(StreamOperation op)
- {
- HRESULT hr = S_OK;
- AsyncOperation *asyncOp = new AsyncOperation(op);
- if (asyncOp == NULL)
- hr = E_OUTOFMEMORY;
-
- if (SUCCEEDED(hr))
- hr = MFPutWorkItem(m_workQueueId, &m_workQueueCB, asyncOp);
-
- if (asyncOp)
- asyncOp->Release();
-
- return hr;
- }
-
- HRESULT processSamplesFromQueue(FlushState bFlushData)
- {
- HRESULT hr = S_OK;
- QList<IUnknown*>::Iterator pos = m_sampleQueue.begin();
- // Enumerate all of the samples/markers in the queue.
- while (pos != m_sampleQueue.end()) {
- IUnknown *pUnk = NULL;
- IMarker *pMarker = NULL;
- IMFSample *pSample = NULL;
- pUnk = *pos;
- // Figure out if this is a marker or a sample.
- if (SUCCEEDED(hr)) {
- hr = pUnk->QueryInterface(__uuidof(IMarker), (void**)&pMarker);
- if (hr == E_NOINTERFACE)
- hr = pUnk->QueryInterface(IID_IMFSample, (void**)&pSample);
- }
-
- // Now handle the sample/marker appropriately.
- if (SUCCEEDED(hr)) {
- if (pMarker) {
- hr = sendMarkerEvent(pMarker, bFlushData);
- } else {
- Q_ASSERT(pSample != NULL); // Not a marker, must be a sample
- if (bFlushData == WriteSamples)
- hr = processSampleData(pSample);
- }
- }
- if (pMarker)
- pMarker->Release();
- if (pSample)
- pSample->Release();
-
- if (FAILED(hr))
- break;
-
- pos++;
- }
-
- clearSampleQueue();
- return hr;
- }
-
- void beginPreroll()
- {
- if (m_prerolling)
- return;
- m_prerolling = true;
- clearSampleQueue();
- clearBufferCache();
- queueEvent(MEStreamSinkRequestSample, GUID_NULL, S_OK, NULL);
- }
-
- void endPreroll(HRESULT hrStatus)
- {
- if (!m_prerolling)
- return;
- m_prerolling = false;
- queueEvent(MEStreamSinkPrerolled, GUID_NULL, hrStatus, NULL);
- }
- MFTIME m_prerollTargetTime;
- bool m_prerolling;
-
- void clearSampleQueue() {
- for (IUnknown* sample : qAsConst(m_sampleQueue))
- sample->Release();
- m_sampleQueue.clear();
- }
-
- HRESULT sendMarkerEvent(IMarker *pMarker, FlushState FlushState)
- {
- HRESULT hr = S_OK;
- HRESULT hrStatus = S_OK; // Status code for marker event.
- if (FlushState == DropSamples)
- hrStatus = E_ABORT;
-
- PROPVARIANT var;
- PropVariantInit(&var);
-
- // Get the context data.
- hr = pMarker->GetContext(&var);
-
- if (SUCCEEDED(hr))
- hr = queueEvent(MEStreamSinkMarker, GUID_NULL, hrStatus, &var);
-
- PropVariantClear(&var);
- return hr;
- }
-
- HRESULT dispatchProcessSample(AsyncOperation* pOp)
- {
- HRESULT hr = S_OK;
- Q_ASSERT(pOp != NULL);
- Q_UNUSED(pOp);
- hr = processSamplesFromQueue(WriteSamples);
- // We are in the middle of an asynchronous operation, so if something failed, send an error.
- if (FAILED(hr))
- hr = queueEvent(MEError, GUID_NULL, hr, NULL);
-
- return hr;
- }
-
- HRESULT dispatchFinalize(AsyncOperation*)
- {
- HRESULT hr = S_OK;
- // Write any samples left in the queue...
- hr = processSamplesFromQueue(WriteSamples);
-
- // Set the async status and invoke the callback.
- m_finalizeResult->SetStatus(hr);
- hr = MFInvokeCallback(m_finalizeResult);
- return hr;
- }
-
- HRESULT processSampleData(IMFSample *pSample)
- {
- m_sampleRequested = false;
-
- LONGLONG time, duration = -1;
- HRESULT hr = pSample->GetSampleTime(&time);
- if (SUCCEEDED(hr))
- pSample->GetSampleDuration(&duration);
-
- if (m_prerolling) {
- if (SUCCEEDED(hr) && ((time - m_prerollTargetTime) * m_rate) >= 0) {
- IMFMediaBuffer *pBuffer = NULL;
- hr = pSample->ConvertToContiguousBuffer(&pBuffer);
- if (SUCCEEDED(hr)) {
- SampleBuffer sb;
- sb.m_buffer = pBuffer;
- sb.m_time = time;
- sb.m_duration = duration;
- m_bufferCache.push_back(sb);
- endPreroll(S_OK);
- }
- } else {
- queueEvent(MEStreamSinkRequestSample, GUID_NULL, S_OK, NULL);
- }
- } else {
- bool requestSample = true;
- // If the time stamp is too early, just discard this sample.
- if (SUCCEEDED(hr) && ((time - m_startTime) * m_rate) >= 0) {
- IMFMediaBuffer *pBuffer = NULL;
- hr = pSample->ConvertToContiguousBuffer(&pBuffer);
- if (SUCCEEDED(hr)) {
- SampleBuffer sb;
- sb.m_buffer = pBuffer;
- sb.m_time = time;
- sb.m_duration = duration;
- m_bufferCache.push_back(sb);
- }
- if (m_rate == 0)
- requestSample = false;
- }
- schedulePresentation(requestSample);
- }
- return hr;
- }
-
- class SampleBuffer
- {
- public:
- IMFMediaBuffer *m_buffer;
- LONGLONG m_time;
- LONGLONG m_duration;
- };
- QList<SampleBuffer> m_bufferCache;
- static const int BUFFER_CACHE_SIZE = 2;
-
- void clearBufferCache()
- {
- for (SampleBuffer sb : qAsConst(m_bufferCache))
- sb.m_buffer->Release();
- m_bufferCache.clear();
-
- if (m_scheduledBuffer) {
- m_scheduledBuffer->Release();
- m_scheduledBuffer = NULL;
- }
- }
-
- void schedulePresentation(bool requestSample)
- {
- if (m_state == State_Paused || m_state == State_Prerolling)
- return;
- if (!m_scheduledBuffer) {
- //get time from presentation time
- MFTIME currentTime = m_startTime, sysTime;
- bool timeOK = true;
- if (m_rate != 0) {
- if (FAILED(m_presentationClock->GetCorrelatedTime(0, &currentTime, &sysTime)))
- timeOK = false;
- }
- while (!m_bufferCache.isEmpty()) {
- SampleBuffer sb = m_bufferCache.takeFirst();
- if (timeOK && ((sb.m_time - currentTime) * m_rate) < 0) {
- sb.m_buffer->Release();
-#ifdef DEBUG_MEDIAFOUNDATION
- qDebug() << "currentPresentTime =" << float(currentTime / 10000) * 0.001f << " and sampleTime is" << float(sb.m_time / 10000) * 0.001f;
-#endif
- continue;
- }
- m_scheduledBuffer = sb.m_buffer;
- m_bufferStartTime = sb.m_time;
- m_bufferDuration = sb.m_duration;
- QCoreApplication::postEvent(m_rendererControl, new PresentEvent(sb.m_time));
- if (m_rate == 0)
- queueEvent(MEStreamSinkScrubSampleComplete, GUID_NULL, S_OK, NULL);
- break;
- }
- }
- if (requestSample && !m_sampleRequested && m_bufferCache.size() < BUFFER_CACHE_SIZE) {
- m_sampleRequested = true;
- queueEvent(MEStreamSinkRequestSample, GUID_NULL, S_OK, NULL);
- }
- }
- IMFMediaBuffer *m_scheduledBuffer;
- MFTIME m_bufferStartTime;
- MFTIME m_bufferDuration;
- IMFPresentationClock *m_presentationClock;
- bool m_sampleRequested;
- float m_rate;
- };
-
- BOOL MediaStream::ValidStateMatrix[MediaStream::State_Count][MediaStream::Op_Count] =
- {
- // States: Operations:
- // SetType Start Preroll, Restart Pause Stop SetRate Sample Marker Finalize
- /* NotSet */ TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
-
- /* Ready */ TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE,
-
- /* Prerolling */ TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE,
-
- /* Start */ FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE,
-
- /* Pause */ FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE,
-
- /* Stop */ FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE,
-
- /*WaitForSurfaceStart*/ FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE,
-
- /* Final */ FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE
-
- // Note about states:
- // 1. OnClockRestart should only be called from paused state.
- // 2. While paused, the sink accepts samples but does not process them.
- };
-
- class MediaSink : public IMFFinalizableMediaSink,
- public IMFClockStateSink,
- public IMFMediaSinkPreroll,
- public IMFGetService,
- public IMFRateSupport
- {
- public:
- MediaSink(MFVideoRendererControl *rendererControl)
- : m_cRef(1)
- , m_shutdown(false)
- , m_presentationClock(0)
- , m_playRate(1)
- {
- m_stream = new MediaStream(this, rendererControl);
- }
-
- ~MediaSink()
- {
- Q_ASSERT(m_shutdown);
- }
-
- void setSurface(QAbstractVideoSurface *surface)
- {
- QMutexLocker locker(&m_mutex);
- if (m_shutdown)
- return;
- m_stream->setSurface(surface);
- }
-
- void supportedFormatsChanged()
- {
- QMutexLocker locker(&m_mutex);
- if (m_shutdown)
- return;
- m_stream->supportedFormatsChanged();
- }
-
- void present()
- {
- QMutexLocker locker(&m_mutex);
- if (m_shutdown)
- return;
- m_stream->present();
- }
-
- void clearScheduledFrame()
- {
- QMutexLocker locker(&m_mutex);
- if (m_shutdown)
- return;
- m_stream->clearScheduledFrame();
- }
-
- MFTIME getTime()
- {
- QMutexLocker locker(&m_mutex);
- if (!m_presentationClock)
- return 0;
- MFTIME time, sysTime;
- m_presentationClock->GetCorrelatedTime(0, &time, &sysTime);
- return time;
- }
-
- float getPlayRate()
- {
- QMutexLocker locker(&m_mutex);
- return m_playRate;
- }
-
- //from IUnknown
- STDMETHODIMP QueryInterface(REFIID riid, void** ppvObject)
- {
- if (!ppvObject)
- return E_POINTER;
- if (riid == IID_IMFMediaSink) {
- *ppvObject = static_cast<IMFMediaSink*>(this);
- } else if (riid == IID_IMFGetService) {
- *ppvObject = static_cast<IMFGetService*>(this);
- } else if (riid == IID_IMFMediaSinkPreroll) {
- *ppvObject = static_cast<IMFMediaSinkPreroll*>(this);
- } else if (riid == IID_IMFClockStateSink) {
- *ppvObject = static_cast<IMFClockStateSink*>(this);
- } else if (riid == IID_IMFRateSupport) {
- *ppvObject = static_cast<IMFRateSupport*>(this);
- } else if (riid == IID_IUnknown) {
- *ppvObject = static_cast<IUnknown*>(static_cast<IMFFinalizableMediaSink*>(this));
- } else {
- *ppvObject = NULL;
- return E_NOINTERFACE;
- }
- AddRef();
- return S_OK;
- }
-
- STDMETHODIMP_(ULONG) AddRef(void)
- {
- return InterlockedIncrement(&m_cRef);
- }
-
- STDMETHODIMP_(ULONG) Release(void)
- {
- LONG cRef = InterlockedDecrement(&m_cRef);
- if (cRef == 0)
- delete this;
- // For thread safety, return a temporary variable.
- return cRef;
- }
-
- // IMFGetService methods
- STDMETHODIMP GetService(const GUID &guidService,
- const IID &riid,
- LPVOID *ppvObject)
- {
- if (!ppvObject)
- return E_POINTER;
-
- if (guidService != MF_RATE_CONTROL_SERVICE)
- return MF_E_UNSUPPORTED_SERVICE;
-
- return QueryInterface(riid, ppvObject);
- }
-
- //IMFMediaSinkPreroll
- STDMETHODIMP NotifyPreroll(MFTIME hnsUpcomingStartTime)
- {
- QMutexLocker locker(&m_mutex);
- if (m_shutdown)
- return MF_E_SHUTDOWN;
- return m_stream->startPreroll(hnsUpcomingStartTime);
- }
-
- //from IMFFinalizableMediaSink
- STDMETHODIMP BeginFinalize(IMFAsyncCallback *pCallback, IUnknown *punkState)
- {
- QMutexLocker locker(&m_mutex);
- if (m_shutdown)
- return MF_E_SHUTDOWN;
- return m_stream->finalize(pCallback, punkState);
- }
-
- STDMETHODIMP EndFinalize(IMFAsyncResult *pResult)
- {
- HRESULT hr = S_OK;
- // Return the status code from the async result.
- if (pResult == NULL)
- hr = E_INVALIDARG;
- else
- hr = pResult->GetStatus();
- return hr;
- }
-
- //from IMFMediaSink
- STDMETHODIMP GetCharacteristics(
- DWORD *pdwCharacteristics)
- {
- QMutexLocker locker(&m_mutex);
- if (m_shutdown)
- return MF_E_SHUTDOWN;
- *pdwCharacteristics = MEDIASINK_FIXED_STREAMS | MEDIASINK_CAN_PREROLL;
- return S_OK;
- }
-
- STDMETHODIMP AddStreamSink(
- DWORD,
- IMFMediaType *,
- IMFStreamSink **)
- {
- QMutexLocker locker(&m_mutex);
- return m_shutdown ? MF_E_SHUTDOWN : MF_E_STREAMSINKS_FIXED;
- }
-
- STDMETHODIMP RemoveStreamSink(
- DWORD)
- {
- QMutexLocker locker(&m_mutex);
- return m_shutdown ? MF_E_SHUTDOWN : MF_E_STREAMSINKS_FIXED;
- }
-
- STDMETHODIMP GetStreamSinkCount(
- DWORD *pcStreamSinkCount)
- {
- QMutexLocker locker(&m_mutex);
- if (m_shutdown)
- return MF_E_SHUTDOWN;
- *pcStreamSinkCount = 1;
- return S_OK;
- }
-
- STDMETHODIMP GetStreamSinkByIndex(
- DWORD dwIndex,
- IMFStreamSink **ppStreamSink)
- {
- QMutexLocker locker(&m_mutex);
- if (m_shutdown)
- return MF_E_SHUTDOWN;
-
- if (dwIndex != 0)
- return MF_E_INVALIDINDEX;
-
- *ppStreamSink = m_stream;
- m_stream->AddRef();
- return S_OK;
- }
-
- STDMETHODIMP GetStreamSinkById(
- DWORD dwStreamSinkIdentifier,
- IMFStreamSink **ppStreamSink)
- {
- if (ppStreamSink == NULL)
- return E_INVALIDARG;
- if (dwStreamSinkIdentifier != MediaStream::DEFAULT_MEDIA_STREAM_ID)
- return MF_E_INVALIDSTREAMNUMBER;
-
- QMutexLocker locker(&m_mutex);
- if (m_shutdown)
- return MF_E_SHUTDOWN;
-
- *ppStreamSink = m_stream;
- m_stream->AddRef();
- return S_OK;
- }
-
- STDMETHODIMP SetPresentationClock(
- IMFPresentationClock *pPresentationClock)
- {
- QMutexLocker locker(&m_mutex);
- if (m_shutdown)
- return MF_E_SHUTDOWN;
-
- if (m_presentationClock) {
- m_presentationClock->RemoveClockStateSink(this);
- m_presentationClock->Release();
- }
- m_presentationClock = pPresentationClock;
- if (m_presentationClock) {
- m_presentationClock->AddRef();
- m_presentationClock->AddClockStateSink(this);
- }
- m_stream->setClock(m_presentationClock);
- return S_OK;
- }
-
- STDMETHODIMP GetPresentationClock(
- IMFPresentationClock **ppPresentationClock)
- {
- QMutexLocker locker(&m_mutex);
- if (m_shutdown)
- return MF_E_SHUTDOWN;
- *ppPresentationClock = m_presentationClock;
- if (m_presentationClock) {
- m_presentationClock->AddRef();
- return S_OK;
- }
- return MF_E_NO_CLOCK;
- }
-
- STDMETHODIMP Shutdown(void)
- {
- QMutexLocker locker(&m_mutex);
- if (m_shutdown)
- return MF_E_SHUTDOWN;
-
- m_stream->shutdown();
- if (m_presentationClock) {
- m_presentationClock->Release();
- m_presentationClock = NULL;
- }
- m_stream->Release();
- m_stream = NULL;
- m_shutdown = true;
- return S_OK;
- }
-
- // IMFClockStateSink methods
- STDMETHODIMP OnClockStart(MFTIME, LONGLONG llClockStartOffset)
- {
- QMutexLocker locker(&m_mutex);
- if (m_shutdown)
- return MF_E_SHUTDOWN;
- return m_stream->start(llClockStartOffset);
- }
-
- STDMETHODIMP OnClockStop(MFTIME)
- {
- QMutexLocker locker(&m_mutex);
- if (m_shutdown)
- return MF_E_SHUTDOWN;
- return m_stream->stop();
- }
-
- STDMETHODIMP OnClockPause(MFTIME)
- {
- QMutexLocker locker(&m_mutex);
- if (m_shutdown)
- return MF_E_SHUTDOWN;
- return m_stream->pause();
- }
-
- STDMETHODIMP OnClockRestart(MFTIME)
- {
- QMutexLocker locker(&m_mutex);
- if (m_shutdown)
- return MF_E_SHUTDOWN;
- return m_stream->restart();
- }
-
- STDMETHODIMP OnClockSetRate(MFTIME, float flRate)
- {
- QMutexLocker locker(&m_mutex);
- if (m_shutdown)
- return MF_E_SHUTDOWN;
- m_playRate = flRate;
- return m_stream->setRate(flRate);
- }
-
- // IMFRateSupport methods
- STDMETHODIMP GetFastestRate(MFRATE_DIRECTION eDirection,
- BOOL fThin,
- float *pflRate)
- {
- if (!pflRate)
- return E_POINTER;
-
- *pflRate = (fThin ? 8.f : 2.0f) * (eDirection == MFRATE_FORWARD ? 1 : -1) ;
-
- return S_OK;
- }
-
- STDMETHODIMP GetSlowestRate(MFRATE_DIRECTION eDirection,
- BOOL fThin,
- float *pflRate)
- {
- Q_UNUSED(eDirection);
- Q_UNUSED(fThin);
-
- if (!pflRate)
- return E_POINTER;
-
- // we support any rate
- *pflRate = 0.f;
-
- return S_OK;
- }
-
- STDMETHODIMP IsRateSupported(BOOL fThin,
- float flRate,
- float *pflNearestSupportedRate)
- {
- HRESULT hr = S_OK;
-
- if (!qFuzzyIsNull(flRate)) {
- MFRATE_DIRECTION direction = flRate > 0.f ? MFRATE_FORWARD
- : MFRATE_REVERSE;
-
- float fastestRate = 0.f;
- float slowestRate = 0.f;
- GetFastestRate(direction, fThin, &fastestRate);
- GetSlowestRate(direction, fThin, &slowestRate);
-
- if (direction == MFRATE_REVERSE)
- qSwap(fastestRate, slowestRate);
-
- if (flRate < slowestRate || flRate > fastestRate) {
- hr = MF_E_UNSUPPORTED_RATE;
- if (pflNearestSupportedRate) {
- *pflNearestSupportedRate = qBound(slowestRate,
- flRate,
- fastestRate);
- }
- }
- } else if (pflNearestSupportedRate) {
- *pflNearestSupportedRate = flRate;
- }
-
- return hr;
- }
-
- private:
- long m_cRef;
- QMutex m_mutex;
- bool m_shutdown;
- IMFPresentationClock *m_presentationClock;
- MediaStream *m_stream;
- float m_playRate;
- };
-
- class VideoRendererActivate : public IMFActivate
- {
- public:
- VideoRendererActivate(MFVideoRendererControl *rendererControl)
- : m_cRef(1)
- , m_sink(0)
- , m_rendererControl(rendererControl)
- , m_attributes(0)
- , m_surface(0)
- {
- MFCreateAttributes(&m_attributes, 0);
- m_sink = new MediaSink(rendererControl);
- }
-
- ~VideoRendererActivate()
- {
- m_attributes->Release();
- }
-
- //from IUnknown
- STDMETHODIMP QueryInterface(REFIID riid, void** ppvObject)
- {
- if (!ppvObject)
- return E_POINTER;
- if (riid == IID_IMFActivate) {
- *ppvObject = static_cast<IMFActivate*>(this);
- } else if (riid == IID_IMFAttributes) {
- *ppvObject = static_cast<IMFAttributes*>(this);
- } else if (riid == IID_IUnknown) {
- *ppvObject = static_cast<IUnknown*>(static_cast<IMFActivate*>(this));
- } else {
- *ppvObject = NULL;
- return E_NOINTERFACE;
- }
- AddRef();
- return S_OK;
- }
-
- STDMETHODIMP_(ULONG) AddRef(void)
- {
- return InterlockedIncrement(&m_cRef);
- }
-
- STDMETHODIMP_(ULONG) Release(void)
- {
- LONG cRef = InterlockedDecrement(&m_cRef);
- if (cRef == 0)
- delete this;
- // For thread safety, return a temporary variable.
- return cRef;
- }
-
- //from IMFActivate
- STDMETHODIMP ActivateObject(REFIID riid, void **ppv)
- {
- if (!ppv)
- return E_INVALIDARG;
- QMutexLocker locker(&m_mutex);
- if (!m_sink) {
- m_sink = new MediaSink(m_rendererControl);
- if (m_surface)
- m_sink->setSurface(m_surface);
- }
- return m_sink->QueryInterface(riid, ppv);
- }
-
- STDMETHODIMP ShutdownObject(void)
- {
- QMutexLocker locker(&m_mutex);
- HRESULT hr = S_OK;
- if (m_sink) {
- hr = m_sink->Shutdown();
- m_sink->Release();
- m_sink = NULL;
- }
- return hr;
- }
-
- STDMETHODIMP DetachObject(void)
- {
- QMutexLocker locker(&m_mutex);
- if (m_sink) {
- m_sink->Release();
- m_sink = NULL;
- }
- return S_OK;
- }
-
- //from IMFAttributes
- STDMETHODIMP GetItem(
- REFGUID guidKey,
- PROPVARIANT *pValue)
- {
- return m_attributes->GetItem(guidKey, pValue);
- }
-
- STDMETHODIMP GetItemType(
- REFGUID guidKey,
- MF_ATTRIBUTE_TYPE *pType)
- {
- return m_attributes->GetItemType(guidKey, pType);
- }
-
- STDMETHODIMP CompareItem(
- REFGUID guidKey,
- REFPROPVARIANT Value,
- BOOL *pbResult)
- {
- return m_attributes->CompareItem(guidKey, Value, pbResult);
- }
-
- STDMETHODIMP Compare(
- IMFAttributes *pTheirs,
- MF_ATTRIBUTES_MATCH_TYPE MatchType,
- BOOL *pbResult)
- {
- return m_attributes->Compare(pTheirs, MatchType, pbResult);
- }
-
- STDMETHODIMP GetUINT32(
- REFGUID guidKey,
- UINT32 *punValue)
- {
- return m_attributes->GetUINT32(guidKey, punValue);
- }
-
- STDMETHODIMP GetUINT64(
- REFGUID guidKey,
- UINT64 *punValue)
- {
- return m_attributes->GetUINT64(guidKey, punValue);
- }
-
- STDMETHODIMP GetDouble(
- REFGUID guidKey,
- double *pfValue)
- {
- return m_attributes->GetDouble(guidKey, pfValue);
- }
-
- STDMETHODIMP GetGUID(
- REFGUID guidKey,
- GUID *pguidValue)
- {
- return m_attributes->GetGUID(guidKey, pguidValue);
- }
-
- STDMETHODIMP GetStringLength(
- REFGUID guidKey,
- UINT32 *pcchLength)
- {
- return m_attributes->GetStringLength(guidKey, pcchLength);
- }
-
- STDMETHODIMP GetString(
- REFGUID guidKey,
- LPWSTR pwszValue,
- UINT32 cchBufSize,
- UINT32 *pcchLength)
- {
- return m_attributes->GetString(guidKey, pwszValue, cchBufSize, pcchLength);
- }
-
- STDMETHODIMP GetAllocatedString(
- REFGUID guidKey,
- LPWSTR *ppwszValue,
- UINT32 *pcchLength)
- {
- return m_attributes->GetAllocatedString(guidKey, ppwszValue, pcchLength);
- }
-
- STDMETHODIMP GetBlobSize(
- REFGUID guidKey,
- UINT32 *pcbBlobSize)
- {
- return m_attributes->GetBlobSize(guidKey, pcbBlobSize);
- }
-
- STDMETHODIMP GetBlob(
- REFGUID guidKey,
- UINT8 *pBuf,
- UINT32 cbBufSize,
- UINT32 *pcbBlobSize)
- {
- return m_attributes->GetBlob(guidKey, pBuf, cbBufSize, pcbBlobSize);
- }
-
- STDMETHODIMP GetAllocatedBlob(
- REFGUID guidKey,
- UINT8 **ppBuf,
- UINT32 *pcbSize)
- {
- return m_attributes->GetAllocatedBlob(guidKey, ppBuf, pcbSize);
- }
-
- STDMETHODIMP GetUnknown(
- REFGUID guidKey,
- REFIID riid,
- LPVOID *ppv)
- {
- return m_attributes->GetUnknown(guidKey, riid, ppv);
- }
-
- STDMETHODIMP SetItem(
- REFGUID guidKey,
- REFPROPVARIANT Value)
- {
- return m_attributes->SetItem(guidKey, Value);
- }
-
- STDMETHODIMP DeleteItem(
- REFGUID guidKey)
- {
- return m_attributes->DeleteItem(guidKey);
- }
-
- STDMETHODIMP DeleteAllItems(void)
- {
- return m_attributes->DeleteAllItems();
- }
-
- STDMETHODIMP SetUINT32(
- REFGUID guidKey,
- UINT32 unValue)
- {
- return m_attributes->SetUINT32(guidKey, unValue);
- }
-
- STDMETHODIMP SetUINT64(
- REFGUID guidKey,
- UINT64 unValue)
- {
- return m_attributes->SetUINT64(guidKey, unValue);
- }
-
- STDMETHODIMP SetDouble(
- REFGUID guidKey,
- double fValue)
- {
- return m_attributes->SetDouble(guidKey, fValue);
- }
-
- STDMETHODIMP SetGUID(
- REFGUID guidKey,
- REFGUID guidValue)
- {
- return m_attributes->SetGUID(guidKey, guidValue);
- }
-
- STDMETHODIMP SetString(
- REFGUID guidKey,
- LPCWSTR wszValue)
- {
- return m_attributes->SetString(guidKey, wszValue);
- }
-
- STDMETHODIMP SetBlob(
- REFGUID guidKey,
- const UINT8 *pBuf,
- UINT32 cbBufSize)
- {
- return m_attributes->SetBlob(guidKey, pBuf, cbBufSize);
- }
-
- STDMETHODIMP SetUnknown(
- REFGUID guidKey,
- IUnknown *pUnknown)
- {
- return m_attributes->SetUnknown(guidKey, pUnknown);
- }
-
- STDMETHODIMP LockStore(void)
- {
- return m_attributes->LockStore();
- }
-
- STDMETHODIMP UnlockStore(void)
- {
- return m_attributes->UnlockStore();
- }
-
- STDMETHODIMP GetCount(
- UINT32 *pcItems)
- {
- return m_attributes->GetCount(pcItems);
- }
-
- STDMETHODIMP GetItemByIndex(
- UINT32 unIndex,
- GUID *pguidKey,
- PROPVARIANT *pValue)
- {
- return m_attributes->GetItemByIndex(unIndex, pguidKey, pValue);
- }
-
- STDMETHODIMP CopyAllItems(
- IMFAttributes *pDest)
- {
- return m_attributes->CopyAllItems(pDest);
- }
-
- /////////////////////////////////
- void setSurface(QAbstractVideoSurface *surface)
- {
- QMutexLocker locker(&m_mutex);
- if (m_surface == surface)
- return;
-
- m_surface = surface;
-
- if (!m_sink)
- return;
- m_sink->setSurface(m_surface);
- }
-
- void supportedFormatsChanged()
- {
- QMutexLocker locker(&m_mutex);
- if (!m_sink)
- return;
- m_sink->supportedFormatsChanged();
- }
-
- void present()
- {
- QMutexLocker locker(&m_mutex);
- if (!m_sink)
- return;
- m_sink->present();
- }
-
- void clearScheduledFrame()
- {
- QMutexLocker locker(&m_mutex);
- if (!m_sink)
- return;
- m_sink->clearScheduledFrame();
- }
-
- MFTIME getTime()
- {
- if (m_sink)
- return m_sink->getTime();
- return 0;
- }
-
- float getPlayRate()
- {
- if (m_sink)
- return m_sink->getPlayRate();
- return 1;
- }
-
- private:
- long m_cRef;
- bool m_shutdown;
- MediaSink *m_sink;
- MFVideoRendererControl *m_rendererControl;
- IMFAttributes *m_attributes;
- QAbstractVideoSurface *m_surface;
- QMutex m_mutex;
- };
-}
-
-
-class EVRCustomPresenterActivate : public MFAbstractActivate
-{
-public:
- EVRCustomPresenterActivate();
- ~EVRCustomPresenterActivate()
- { }
-
- STDMETHODIMP ActivateObject(REFIID riid, void **ppv);
- STDMETHODIMP ShutdownObject();
- STDMETHODIMP DetachObject();
-
- void setSurface(QAbstractVideoSurface *surface);
-
-private:
- EVRCustomPresenter *m_presenter;
- QAbstractVideoSurface *m_surface;
- QMutex m_mutex;
-};
-
-
-MFVideoRendererControl::MFVideoRendererControl(QObject *parent)
- : QVideoRendererControl(parent)
- , m_surface(0)
- , m_currentActivate(0)
- , m_callback(0)
- , m_presenterActivate(0)
-{
-}
-
-MFVideoRendererControl::~MFVideoRendererControl()
-{
- clear();
-}
-
-void MFVideoRendererControl::clear()
-{
- if (m_surface)
- m_surface->stop();
-
- if (m_presenterActivate) {
- m_presenterActivate->ShutdownObject();
- m_presenterActivate->Release();
- m_presenterActivate = NULL;
- }
-
- if (m_currentActivate) {
- m_currentActivate->ShutdownObject();
- m_currentActivate->Release();
- }
- m_currentActivate = NULL;
-}
-
-void MFVideoRendererControl::releaseActivate()
-{
- clear();
-}
-
-QAbstractVideoSurface *MFVideoRendererControl::surface() const
-{
- return m_surface;
-}
-
-void MFVideoRendererControl::setSurface(QAbstractVideoSurface *surface)
-{
- if (m_surface)
- disconnect(m_surface, SIGNAL(supportedFormatsChanged()), this, SLOT(supportedFormatsChanged()));
- m_surface = surface;
-
- if (m_surface) {
- connect(m_surface, SIGNAL(supportedFormatsChanged()), this, SLOT(supportedFormatsChanged()));
- }
-
- if (m_presenterActivate)
- m_presenterActivate->setSurface(m_surface);
- else if (m_currentActivate)
- static_cast<VideoRendererActivate*>(m_currentActivate)->setSurface(m_surface);
-}
-
-void MFVideoRendererControl::customEvent(QEvent *event)
-{
- if (m_presenterActivate)
- return;
-
- if (!m_currentActivate)
- return;
-
- if (event->type() == MediaStream::PresentSurface) {
- MFTIME targetTime = static_cast<MediaStream::PresentEvent*>(event)->targetTime();
- MFTIME currentTime = static_cast<VideoRendererActivate*>(m_currentActivate)->getTime();
- float playRate = static_cast<VideoRendererActivate*>(m_currentActivate)->getPlayRate();
- if (!qFuzzyIsNull(playRate) && targetTime != currentTime) {
- // If the scheduled frame is too late, skip it
- const int interval = ((targetTime - currentTime) / 10000) / playRate;
- if (interval < 0)
- static_cast<VideoRendererActivate*>(m_currentActivate)->clearScheduledFrame();
- else
- QTimer::singleShot(interval, this, SLOT(present()));
- } else {
- present();
- }
- return;
- }
- if (event->type() >= MediaStream::StartSurface) {
- QChildEvent *childEvent = static_cast<QChildEvent*>(event);
- static_cast<MediaStream*>(childEvent->child())->customEvent(event);
- } else {
- QObject::customEvent(event);
- }
-}
-
-void MFVideoRendererControl::supportedFormatsChanged()
-{
- if (m_presenterActivate)
- return;
-
- if (m_currentActivate)
- static_cast<VideoRendererActivate*>(m_currentActivate)->supportedFormatsChanged();
-}
-
-void MFVideoRendererControl::present()
-{
- if (m_presenterActivate)
- return;
-
- if (m_currentActivate)
- static_cast<VideoRendererActivate*>(m_currentActivate)->present();
-}
-
-IMFActivate* MFVideoRendererControl::createActivate()
-{
- Q_ASSERT(m_surface);
-
- clear();
-
- // Create the EVR media sink, but replace the presenter with our own
- if (SUCCEEDED(MFCreateVideoRendererActivate(::GetShellWindow(), &m_currentActivate))) {
- m_presenterActivate = new EVRCustomPresenterActivate;
- m_currentActivate->SetUnknown(MF_ACTIVATE_CUSTOM_VIDEO_PRESENTER_ACTIVATE, m_presenterActivate);
- } else {
- m_currentActivate = new VideoRendererActivate(this);
- }
-
- setSurface(m_surface);
-
- return m_currentActivate;
-}
-
-
-EVRCustomPresenterActivate::EVRCustomPresenterActivate()
- : MFAbstractActivate()
- , m_presenter(0)
- , m_surface(0)
-{ }
-
-HRESULT EVRCustomPresenterActivate::ActivateObject(REFIID riid, void **ppv)
-{
- if (!ppv)
- return E_INVALIDARG;
- QMutexLocker locker(&m_mutex);
- if (!m_presenter) {
- m_presenter = new EVRCustomPresenter;
- if (m_surface)
- m_presenter->setSurface(m_surface);
- }
- return m_presenter->QueryInterface(riid, ppv);
-}
-
-HRESULT EVRCustomPresenterActivate::ShutdownObject()
-{
- // The presenter does not implement IMFShutdown so
- // this function is the same as DetachObject()
- return DetachObject();
-}
-
-HRESULT EVRCustomPresenterActivate::DetachObject()
-{
- QMutexLocker locker(&m_mutex);
- if (m_presenter) {
- m_presenter->Release();
- m_presenter = 0;
- }
- return S_OK;
-}
-
-void EVRCustomPresenterActivate::setSurface(QAbstractVideoSurface *surface)
-{
- QMutexLocker locker(&m_mutex);
- if (m_surface == surface)
- return;
-
- m_surface = surface;
-
- if (m_presenter)
- m_presenter->setSurface(surface);
-}
-
-#include "moc_mfvideorenderercontrol.cpp"
-#include "mfvideorenderercontrol.moc"
diff --git a/src/plugins/wmf/player/mfvideorenderercontrol.h b/src/plugins/wmf/player/mfvideorenderercontrol.h
deleted file mode 100644
index da9e97ba9..000000000
--- a/src/plugins/wmf/player/mfvideorenderercontrol.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt Mobility Components.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef MFVIDEORENDERERCONTROL_H
-#define MFVIDEORENDERERCONTROL_H
-
-#include "qvideorenderercontrol.h"
-#include <mfapi.h>
-#include <mfidl.h>
-
-QT_USE_NAMESPACE
-
-class EVRCustomPresenterActivate;
-
-class MFVideoRendererControl : public QVideoRendererControl
-{
- Q_OBJECT
-public:
- MFVideoRendererControl(QObject *parent = 0);
- ~MFVideoRendererControl();
-
- QAbstractVideoSurface *surface() const;
- void setSurface(QAbstractVideoSurface *surface);
-
- IMFActivate* createActivate();
- void releaseActivate();
-
-protected:
- void customEvent(QEvent *event);
-
-private Q_SLOTS:
- void supportedFormatsChanged();
- void present();
-
-private:
- void clear();
-
- QAbstractVideoSurface *m_surface;
- IMFActivate *m_currentActivate;
- IMFSampleGrabberSinkCallback *m_callback;
-
- EVRCustomPresenterActivate *m_presenterActivate;
-};
-
-#endif
diff --git a/src/plugins/wmf/player/player.pri b/src/plugins/wmf/player/player.pri
deleted file mode 100644
index af2f7458b..000000000
--- a/src/plugins/wmf/player/player.pri
+++ /dev/null
@@ -1,34 +0,0 @@
-INCLUDEPATH += $$PWD
-
-LIBS += -lgdi32 -luser32
-QMAKE_USE += wmf
-
-HEADERS += \
- $$PWD/mfplayerservice.h \
- $$PWD/mfplayersession.h \
- $$PWD/mfplayercontrol.h \
- $$PWD/mfvideorenderercontrol.h \
- $$PWD/mfaudioendpointcontrol.h \
- $$PWD/mfmetadatacontrol.h \
- $$PWD/mfaudioprobecontrol.h \
- $$PWD/mfvideoprobecontrol.h \
- $$PWD/mfevrvideowindowcontrol.h \
- $$PWD/samplegrabber.h \
- $$PWD/mftvideo.h \
- $$PWD/mfactivate.h
-
-SOURCES += \
- $$PWD/mfplayerservice.cpp \
- $$PWD/mfplayersession.cpp \
- $$PWD/mfplayercontrol.cpp \
- $$PWD/mfvideorenderercontrol.cpp \
- $$PWD/mfaudioendpointcontrol.cpp \
- $$PWD/mfmetadatacontrol.cpp \
- $$PWD/mfaudioprobecontrol.cpp \
- $$PWD/mfvideoprobecontrol.cpp \
- $$PWD/mfevrvideowindowcontrol.cpp \
- $$PWD/samplegrabber.cpp \
- $$PWD/mftvideo.cpp \
- $$PWD/mfactivate.cpp
-
-include($$PWD/../../common/evr.pri)
diff --git a/src/plugins/wmf/player/samplegrabber.cpp b/src/plugins/wmf/player/samplegrabber.cpp
deleted file mode 100644
index d137335f3..000000000
--- a/src/plugins/wmf/player/samplegrabber.cpp
+++ /dev/null
@@ -1,173 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "samplegrabber.h"
-#include "mfaudioprobecontrol.h"
-
-STDMETHODIMP SampleGrabberCallback::QueryInterface(REFIID riid, void** ppv)
-{
- if (!ppv)
- return E_POINTER;
- if (riid == IID_IMFSampleGrabberSinkCallback) {
- *ppv = static_cast<IMFSampleGrabberSinkCallback*>(this);
- } else if (riid == IID_IMFClockStateSink) {
- *ppv = static_cast<IMFClockStateSink*>(this);
- } else if (riid == IID_IUnknown) {
- *ppv = static_cast<IUnknown*>(this);
- } else {
- *ppv = NULL;
- return E_NOINTERFACE;
- }
- AddRef();
- return S_OK;
-}
-
-STDMETHODIMP_(ULONG) SampleGrabberCallback::AddRef()
-{
- return InterlockedIncrement(&m_cRef);
-}
-
-STDMETHODIMP_(ULONG) SampleGrabberCallback::Release()
-{
- ULONG cRef = InterlockedDecrement(&m_cRef);
- if (cRef == 0) {
- delete this;
- }
- return cRef;
-
-}
-
-// IMFClockStateSink methods.
-
-STDMETHODIMP SampleGrabberCallback::OnClockStart(MFTIME hnsSystemTime, LONGLONG llClockStartOffset)
-{
- Q_UNUSED(hnsSystemTime);
- Q_UNUSED(llClockStartOffset);
- return S_OK;
-}
-
-STDMETHODIMP SampleGrabberCallback::OnClockStop(MFTIME hnsSystemTime)
-{
- Q_UNUSED(hnsSystemTime);
- return S_OK;
-}
-
-STDMETHODIMP SampleGrabberCallback::OnClockPause(MFTIME hnsSystemTime)
-{
- Q_UNUSED(hnsSystemTime);
- return S_OK;
-}
-
-STDMETHODIMP SampleGrabberCallback::OnClockRestart(MFTIME hnsSystemTime)
-{
- Q_UNUSED(hnsSystemTime);
- return S_OK;
-}
-
-STDMETHODIMP SampleGrabberCallback::OnClockSetRate(MFTIME hnsSystemTime, float flRate)
-{
- Q_UNUSED(hnsSystemTime);
- Q_UNUSED(flRate);
- return S_OK;
-}
-
-// IMFSampleGrabberSink methods.
-
-STDMETHODIMP SampleGrabberCallback::OnSetPresentationClock(IMFPresentationClock* pClock)
-{
- Q_UNUSED(pClock);
- return S_OK;
-}
-
-STDMETHODIMP SampleGrabberCallback::OnShutdown()
-{
- return S_OK;
-}
-
-void AudioSampleGrabberCallback::addProbe(MFAudioProbeControl* probe)
-{
- QMutexLocker locker(&m_audioProbeMutex);
-
- if (m_audioProbes.contains(probe))
- return;
-
- m_audioProbes.append(probe);
-}
-
-void AudioSampleGrabberCallback::removeProbe(MFAudioProbeControl* probe)
-{
- QMutexLocker locker(&m_audioProbeMutex);
- m_audioProbes.removeOne(probe);
-}
-
-void AudioSampleGrabberCallback::setFormat(const QAudioFormat& format)
-{
- m_format = format;
-}
-
-STDMETHODIMP AudioSampleGrabberCallback::OnProcessSample(REFGUID guidMajorMediaType, DWORD dwSampleFlags,
- LONGLONG llSampleTime, LONGLONG llSampleDuration, const BYTE * pSampleBuffer,
- DWORD dwSampleSize)
-{
- Q_UNUSED(dwSampleFlags);
- Q_UNUSED(llSampleTime);
- Q_UNUSED(llSampleDuration);
-
- if (guidMajorMediaType != GUID_NULL && guidMajorMediaType != MFMediaType_Audio)
- return S_OK;
-
- QMutexLocker locker(&m_audioProbeMutex);
-
- if (m_audioProbes.isEmpty())
- return S_OK;
-
- // Check if sample has a presentation time
- if (llSampleTime == _I64_MAX) {
- // Set default QAudioBuffer start time
- llSampleTime = -1;
- } else {
- // WMF uses 100-nanosecond units, Qt uses microseconds
- llSampleTime /= 10;
- }
-
- for (MFAudioProbeControl* probe : qAsConst(m_audioProbes))
- probe->bufferProbed((const char*)pSampleBuffer, dwSampleSize, m_format, llSampleTime);
-
- return S_OK;
-}
diff --git a/src/plugins/wmf/player/samplegrabber.h b/src/plugins/wmf/player/samplegrabber.h
deleted file mode 100644
index 9ca673a1b..000000000
--- a/src/plugins/wmf/player/samplegrabber.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef SAMPLEGRABBER_H
-#define SAMPLEGRABBER_H
-
-#include <QtCore/qmutex.h>
-#include <QtCore/qlist.h>
-#include <QtMultimedia/qaudioformat.h>
-#include <mfapi.h>
-#include <mfidl.h>
-
-class MFAudioProbeControl;
-
-class SampleGrabberCallback : public IMFSampleGrabberSinkCallback
-{
-public:
- // IUnknown methods
- STDMETHODIMP QueryInterface(REFIID iid, void** ppv);
- STDMETHODIMP_(ULONG) AddRef();
- STDMETHODIMP_(ULONG) Release();
-
- // IMFClockStateSink methods
- STDMETHODIMP OnClockStart(MFTIME hnsSystemTime, LONGLONG llClockStartOffset);
- STDMETHODIMP OnClockStop(MFTIME hnsSystemTime);
- STDMETHODIMP OnClockPause(MFTIME hnsSystemTime);
- STDMETHODIMP OnClockRestart(MFTIME hnsSystemTime);
- STDMETHODIMP OnClockSetRate(MFTIME hnsSystemTime, float flRate);
-
- // IMFSampleGrabberSinkCallback methods
- STDMETHODIMP OnSetPresentationClock(IMFPresentationClock* pClock);
- STDMETHODIMP OnShutdown();
-
-protected:
- SampleGrabberCallback() : m_cRef(1) {}
-
-public:
- virtual ~SampleGrabberCallback() {}
-
-private:
- long m_cRef;
-};
-
-class AudioSampleGrabberCallback: public SampleGrabberCallback {
-public:
- void addProbe(MFAudioProbeControl* probe);
- void removeProbe(MFAudioProbeControl* probe);
- void setFormat(const QAudioFormat& format);
-
- STDMETHODIMP OnProcessSample(REFGUID guidMajorMediaType, DWORD dwSampleFlags,
- LONGLONG llSampleTime, LONGLONG llSampleDuration, const BYTE * pSampleBuffer,
- DWORD dwSampleSize);
-
-private:
- QList<MFAudioProbeControl*> m_audioProbes;
- QMutex m_audioProbeMutex;
- QAudioFormat m_format;
-};
-
-#endif // SAMPLEGRABBER_H
diff --git a/src/plugins/wmf/sourceresolver.cpp b/src/plugins/wmf/sourceresolver.cpp
deleted file mode 100644
index 15ef6f0ab..000000000
--- a/src/plugins/wmf/sourceresolver.cpp
+++ /dev/null
@@ -1,325 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "mfstream.h"
-#include "sourceresolver.h"
-#include <mferror.h>
-#include <nserror.h>
-#include <QtCore/qfile.h>
-#include <QtCore/qdebug.h>
-#include <QtMultimedia/qmediaplayer.h>
-
-/*
- SourceResolver is separated from MFPlayerSession to handle the work of resolving a media source
- asynchronously. You call SourceResolver::load to request resolving a media source asynchronously,
- and it will emit mediaSourceReady() when resolving is done. You can call SourceResolver::cancel to
- stop the previous load operation if there is any.
-*/
-
-SourceResolver::SourceResolver()
- : m_cRef(1)
- , m_cancelCookie(0)
- , m_sourceResolver(0)
- , m_mediaSource(0)
- , m_stream(0)
-{
-}
-
-SourceResolver::~SourceResolver()
-{
- shutdown();
- if (m_mediaSource) {
- m_mediaSource->Release();
- m_mediaSource = NULL;
- }
-
- if (m_cancelCookie)
- m_cancelCookie->Release();
- if (m_sourceResolver)
- m_sourceResolver->Release();
-}
-
-STDMETHODIMP SourceResolver::QueryInterface(REFIID riid, LPVOID *ppvObject)
-{
- if (!ppvObject)
- return E_POINTER;
- if (riid == IID_IUnknown) {
- *ppvObject = static_cast<IUnknown*>(this);
- } else if (riid == IID_IMFAsyncCallback) {
- *ppvObject = static_cast<IMFAsyncCallback*>(this);
- } else {
- *ppvObject = NULL;
- return E_NOINTERFACE;
- }
- AddRef();
- return S_OK;
-}
-
-STDMETHODIMP_(ULONG) SourceResolver::AddRef(void)
-{
- return InterlockedIncrement(&m_cRef);
-}
-
-STDMETHODIMP_(ULONG) SourceResolver::Release(void)
-{
- LONG cRef = InterlockedDecrement(&m_cRef);
- if (cRef == 0)
- this->deleteLater();
- return cRef;
-}
-
-HRESULT STDMETHODCALLTYPE SourceResolver::Invoke(IMFAsyncResult *pAsyncResult)
-{
- QMutexLocker locker(&m_mutex);
-
- if (!m_sourceResolver)
- return S_OK;
-
- MF_OBJECT_TYPE ObjectType = MF_OBJECT_INVALID;
- IUnknown* pSource = NULL;
- State *state = static_cast<State*>(pAsyncResult->GetStateNoAddRef());
-
- HRESULT hr = S_OK;
- if (state->fromStream())
- hr = m_sourceResolver->EndCreateObjectFromByteStream(pAsyncResult, &ObjectType, &pSource);
- else
- hr = m_sourceResolver->EndCreateObjectFromURL(pAsyncResult, &ObjectType, &pSource);
-
- if (state->sourceResolver() != m_sourceResolver) {
- //This is a cancelled one
- return S_OK;
- }
-
- if (m_cancelCookie) {
- m_cancelCookie->Release();
- m_cancelCookie = NULL;
- }
-
- if (FAILED(hr)) {
- emit error(hr);
- return S_OK;
- }
-
- if (m_mediaSource) {
- m_mediaSource->Release();
- m_mediaSource = NULL;
- }
-
- hr = pSource->QueryInterface(IID_PPV_ARGS(&m_mediaSource));
- pSource->Release();
- if (FAILED(hr)) {
- emit error(hr);
- return S_OK;
- }
-
- emit mediaSourceReady();
-
- return S_OK;
-}
-
-HRESULT STDMETHODCALLTYPE SourceResolver::GetParameters(DWORD*, DWORD*)
-{
- return E_NOTIMPL;
-}
-
-void SourceResolver::load(const QUrl &url, QIODevice* stream)
-{
- QMutexLocker locker(&m_mutex);
- HRESULT hr = S_OK;
- if (!m_sourceResolver)
- hr = MFCreateSourceResolver(&m_sourceResolver);
-
- if (m_stream) {
- m_stream->Release();
- m_stream = NULL;
- }
-
- if (FAILED(hr)) {
- qWarning() << "Failed to create Source Resolver!";
- emit error(hr);
- } else if (stream) {
- QString urlString = url.toString();
- m_stream = new MFStream(stream, false);
- hr = m_sourceResolver->BeginCreateObjectFromByteStream(
- m_stream, urlString.isEmpty() ? 0 : reinterpret_cast<LPCWSTR>(urlString.utf16()),
- MF_RESOLUTION_MEDIASOURCE | MF_RESOLUTION_CONTENT_DOES_NOT_HAVE_TO_MATCH_EXTENSION_OR_MIME_TYPE
- , NULL, &m_cancelCookie, this, new State(m_sourceResolver, true));
- if (FAILED(hr)) {
- qWarning() << "Unsupported stream!";
- emit error(hr);
- }
- } else {
-#ifdef DEBUG_MEDIAFOUNDATION
- qDebug() << "loading :" << url;
- qDebug() << "url path =" << url.path().mid(1);
-#endif
-#ifdef TEST_STREAMING
- //Testing stream function
- if (url.scheme() == QLatin1String("file")) {
- stream = new QFile(url.path().mid(1));
- if (stream->open(QIODevice::ReadOnly)) {
- m_stream = new MFStream(stream, true);
- hr = m_sourceResolver->BeginCreateObjectFromByteStream(
- m_stream, reinterpret_cast<const OLECHAR *>(url.toString().utf16()),
- MF_RESOLUTION_MEDIASOURCE | MF_RESOLUTION_CONTENT_DOES_NOT_HAVE_TO_MATCH_EXTENSION_OR_MIME_TYPE,
- NULL, &m_cancelCookie, this, new State(m_sourceResolver, true));
- if (FAILED(hr)) {
- qWarning() << "Unsupported stream!";
- emit error(hr);
- }
- } else {
- delete stream;
- emit error(QMediaPlayer::FormatError);
- }
- } else
-#endif
- if (url.scheme() == QLatin1String("qrc")) {
- // If the canonical URL refers to a Qt resource, open with QFile and use
- // the stream playback capability to play.
- stream = new QFile(QLatin1Char(':') + url.path());
- if (stream->open(QIODevice::ReadOnly)) {
- m_stream = new MFStream(stream, true);
- hr = m_sourceResolver->BeginCreateObjectFromByteStream(
- m_stream, reinterpret_cast<const OLECHAR *>(url.toString().utf16()),
- MF_RESOLUTION_MEDIASOURCE | MF_RESOLUTION_CONTENT_DOES_NOT_HAVE_TO_MATCH_EXTENSION_OR_MIME_TYPE,
- NULL, &m_cancelCookie, this, new State(m_sourceResolver, true));
- if (FAILED(hr)) {
- qWarning() << "Unsupported stream!";
- emit error(hr);
- }
- } else {
- delete stream;
- emit error(QMediaPlayer::FormatError);
- }
- } else {
- hr = m_sourceResolver->BeginCreateObjectFromURL(
- reinterpret_cast<const OLECHAR *>(url.toString().utf16()),
- MF_RESOLUTION_MEDIASOURCE | MF_RESOLUTION_CONTENT_DOES_NOT_HAVE_TO_MATCH_EXTENSION_OR_MIME_TYPE,
- NULL, &m_cancelCookie, this, new State(m_sourceResolver, false));
- if (FAILED(hr)) {
- qWarning() << "Unsupported url scheme!";
- emit error(hr);
- }
- }
- }
-}
-
-void SourceResolver::cancel()
-{
- QMutexLocker locker(&m_mutex);
- if (m_cancelCookie) {
- m_sourceResolver->CancelObjectCreation(m_cancelCookie);
- m_cancelCookie->Release();
- m_cancelCookie = NULL;
- m_sourceResolver->Release();
- m_sourceResolver = NULL;
- }
-}
-
-void SourceResolver::shutdown()
-{
- if (m_mediaSource) {
- m_mediaSource->Shutdown();
- m_mediaSource->Release();
- m_mediaSource = NULL;
- }
-
- if (m_stream) {
- m_stream->Release();
- m_stream = NULL;
- }
-}
-
-IMFMediaSource* SourceResolver::mediaSource() const
-{
- return m_mediaSource;
-}
-
-/////////////////////////////////////////////////////////////////////////////////
-SourceResolver::State::State(IMFSourceResolver *sourceResolver, bool fromStream)
- : m_cRef(0)
- , m_sourceResolver(sourceResolver)
- , m_fromStream(fromStream)
-{
- sourceResolver->AddRef();
-}
-
-SourceResolver::State::~State()
-{
- m_sourceResolver->Release();
-}
-
-STDMETHODIMP SourceResolver::State::QueryInterface(REFIID riid, LPVOID *ppvObject)
-{
- if (!ppvObject)
- return E_POINTER;
- if (riid == IID_IUnknown) {
- *ppvObject = static_cast<IUnknown*>(this);
- } else {
- *ppvObject = NULL;
- return E_NOINTERFACE;
- }
- AddRef();
- return S_OK;
-}
-
-STDMETHODIMP_(ULONG) SourceResolver::State::AddRef(void)
-{
- return InterlockedIncrement(&m_cRef);
-}
-
-STDMETHODIMP_(ULONG) SourceResolver::State::Release(void)
-{
- LONG cRef = InterlockedDecrement(&m_cRef);
- if (cRef == 0)
- delete this;
- // For thread safety, return a temporary variable.
- return cRef;
-}
-
-IMFSourceResolver* SourceResolver::State::sourceResolver() const
-{
- return m_sourceResolver;
-}
-
-bool SourceResolver::State::fromStream() const
-{
- return m_fromStream;
-}
-
diff --git a/src/plugins/wmf/sourceresolver.h b/src/plugins/wmf/sourceresolver.h
deleted file mode 100644
index 007552cb0..000000000
--- a/src/plugins/wmf/sourceresolver.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef SOURCERESOLVER_H
-#define SOURCERESOLVER_H
-
-#include "mfstream.h"
-#include <QUrl>
-
-class SourceResolver: public QObject, public IMFAsyncCallback
-{
- Q_OBJECT
-public:
- SourceResolver();
-
- ~SourceResolver();
-
- STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppvObject);
- STDMETHODIMP_(ULONG) AddRef(void);
- STDMETHODIMP_(ULONG) Release(void);
-
- HRESULT STDMETHODCALLTYPE Invoke(IMFAsyncResult *pAsyncResult);
-
- HRESULT STDMETHODCALLTYPE GetParameters(DWORD*, DWORD*);
-
- void load(const QUrl &url, QIODevice* stream);
-
- void cancel();
-
- void shutdown();
-
- IMFMediaSource* mediaSource() const;
-
-Q_SIGNALS:
- void error(long hr);
- void mediaSourceReady();
-
-private:
- class State : public IUnknown
- {
- public:
- State(IMFSourceResolver *sourceResolver, bool fromStream);
- ~State();
-
- STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppvObject);
-
- STDMETHODIMP_(ULONG) AddRef(void);
-
- STDMETHODIMP_(ULONG) Release(void);
-
- IMFSourceResolver* sourceResolver() const;
- bool fromStream() const;
-
- private:
- long m_cRef;
- IMFSourceResolver *m_sourceResolver;
- bool m_fromStream;
- };
-
- long m_cRef;
- IUnknown *m_cancelCookie;
- IMFSourceResolver *m_sourceResolver;
- IMFMediaSource *m_mediaSource;
- MFStream *m_stream;
- QMutex m_mutex;
-};
-
-#endif
diff --git a/src/plugins/wmf/wmf.json b/src/plugins/wmf/wmf.json
deleted file mode 100644
index e70736480..000000000
--- a/src/plugins/wmf/wmf.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "Keys": ["windowsmediafoundation"],
- "Services": ["org.qt-project.qt.mediaplayer", "org.qt-project.qt.audiodecode"]
-}
diff --git a/src/plugins/wmf/wmf.pro b/src/plugins/wmf/wmf.pro
deleted file mode 100644
index 7c712233d..000000000
--- a/src/plugins/wmf/wmf.pro
+++ /dev/null
@@ -1,28 +0,0 @@
-TARGET = wmfengine
-QT += multimedia-private network
-
-win32:!qtHaveModule(opengl) {
- LIBS_PRIVATE += -lgdi32 -luser32
-}
-
-INCLUDEPATH += .
-
-HEADERS += \
- wmfserviceplugin.h \
- mfstream.h \
- sourceresolver.h
-
-SOURCES += \
- wmfserviceplugin.cpp \
- mfstream.cpp \
- sourceresolver.cpp
-
-include (player/player.pri)
-include (decoder/decoder.pri)
-
-OTHER_FILES += \
- wmf.json
-
-PLUGIN_TYPE = mediaservice
-PLUGIN_CLASS_NAME = WMFServicePlugin
-load(qt_plugin)
diff --git a/src/plugins/wmf/wmfserviceplugin.cpp b/src/plugins/wmf/wmfserviceplugin.cpp
deleted file mode 100644
index 740067600..000000000
--- a/src/plugins/wmf/wmfserviceplugin.cpp
+++ /dev/null
@@ -1,117 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtCore/qstring.h>
-#include <QtCore/qdebug.h>
-#include <QtCore/QFile>
-
-#include "wmfserviceplugin.h"
-#include "mfplayerservice.h"
-#include "mfdecoderservice.h"
-
-#include <mfapi.h>
-
-namespace
-{
-static int g_refCount = 0;
-void addRefCount()
-{
- g_refCount++;
- if (g_refCount == 1) {
- CoInitialize(NULL);
- MFStartup(MF_VERSION);
- }
-}
-
-void releaseRefCount()
-{
- g_refCount--;
- if (g_refCount == 0) {
- MFShutdown();
- CoUninitialize();
- }
-}
-
-}
-
-QMediaService* WMFServicePlugin::create(QString const& key)
-{
- if (key == QLatin1String(Q_MEDIASERVICE_MEDIAPLAYER)) {
- addRefCount();
- return new MFPlayerService;
- }
-
- if (key == QLatin1String(Q_MEDIASERVICE_AUDIODECODER)) {
- addRefCount();
- return new MFAudioDecoderService;
- }
- //qDebug() << "unsupported key:" << key;
- return 0;
-}
-
-void WMFServicePlugin::release(QMediaService *service)
-{
- delete service;
- releaseRefCount();
-}
-
-QMediaServiceProviderHint::Features WMFServicePlugin::supportedFeatures(
- const QByteArray &service) const
-{
- if (service == Q_MEDIASERVICE_MEDIAPLAYER)
- return QMediaServiceProviderHint::StreamPlayback;
- else
- return QMediaServiceProviderHint::Features();
-}
-
-QByteArray WMFServicePlugin::defaultDevice(const QByteArray &) const
-{
- return QByteArray();
-}
-
-QList<QByteArray> WMFServicePlugin::devices(const QByteArray &) const
-{
- return QList<QByteArray>();
-}
-
-QString WMFServicePlugin::deviceDescription(const QByteArray &, const QByteArray &)
-{
- return QString();
-}
-
diff --git a/src/plugins/wmf/wmfserviceplugin.h b/src/plugins/wmf/wmfserviceplugin.h
deleted file mode 100644
index 493a0b08c..000000000
--- a/src/plugins/wmf/wmfserviceplugin.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef WMFSERVICEPLUGIN_H
-#define WMFSERVICEPLUGIN_H
-
-#include <QtMultimedia/private/qtmultimediaglobal_p.h>
-#include "qmediaserviceproviderplugin.h"
-
-QT_USE_NAMESPACE
-
-class WMFServicePlugin
- : public QMediaServiceProviderPlugin
- , public QMediaServiceSupportedDevicesInterface
- , public QMediaServiceDefaultDeviceInterface
- , public QMediaServiceFeaturesInterface
-{
- Q_OBJECT
- Q_INTERFACES(QMediaServiceSupportedDevicesInterface)
- Q_INTERFACES(QMediaServiceDefaultDeviceInterface)
- Q_INTERFACES(QMediaServiceFeaturesInterface)
- Q_PLUGIN_METADATA(IID "org.qt-project.qt.mediaserviceproviderfactory/5.0" FILE "wmf.json")
-
-public:
- QMediaService* create(QString const& key);
- void release(QMediaService *service);
-
- QMediaServiceProviderHint::Features supportedFeatures(const QByteArray &service) const;
-
- QByteArray defaultDevice(const QByteArray &service) const;
- QList<QByteArray> devices(const QByteArray &service) const;
- QString deviceDescription(const QByteArray &service, const QByteArray &device);
-};
-
-#endif // WMFSERVICEPLUGIN_H