From: Lev Zelenskiy Date: Wed, 11 Jul 2012 05:06:40 +0000 (+1000) Subject: Audioprobe implementation for wmf backend. X-Git-Tag: upstream/5.2.95+rc1~283 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=afe12ea4de29500530b1e1fabef39e79e047053e;p=platform%2Fupstream%2Fqtmultimedia.git Audioprobe implementation for wmf backend. Change-Id: I63af91af870cb92c838c1ab5d4752815aa60a03f Reviewed-by: Ling Hu --- diff --git a/src/plugins/wmf/player/mfaudioprobecontrol.cpp b/src/plugins/wmf/player/mfaudioprobecontrol.cpp new file mode 100644 index 0000000..c76ab91 --- /dev/null +++ b/src/plugins/wmf/player/mfaudioprobecontrol.cpp @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $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 new file mode 100644 index 0000000..878d00d --- /dev/null +++ b/src/plugins/wmf/player/mfaudioprobecontrol.h @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef MFAUDIOPROBECONTROL_H +#define MFAUDIOPROBECONTROL_H + +#include +#include +#include + +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/mfplayerservice.cpp b/src/plugins/wmf/player/mfplayerservice.cpp index 3372055..aad1abe 100644 --- a/src/plugins/wmf/player/mfplayerservice.cpp +++ b/src/plugins/wmf/player/mfplayerservice.cpp @@ -49,6 +49,7 @@ #endif #include "mfvideorenderercontrol.h" #include "mfaudioendpointcontrol.h" +#include "mfaudioprobecontrol.h" #include "mfplayerservice.h" #include "mfplayersession.h" #include "mfmetadatacontrol.h" @@ -105,6 +106,13 @@ QMediaControl* MFPlayerService::requestControl(const char *name) return m_videoWindowControl; } #endif + } else if (qstrcmp(name,QMediaAudioProbeControl_iid) == 0) { + if (m_session) { + MFAudioProbeControl *probe = new MFAudioProbeControl(this); + m_session->addProbe(probe); + return probe; + } + return 0; } return 0; @@ -125,6 +133,14 @@ void MFPlayerService::releaseControl(QMediaControl *control) m_videoWindowControl = 0; #endif } + + MFAudioProbeControl* audioProbe = qobject_cast(control); + if (audioProbe) { + if (m_session) + m_session->removeProbe(audioProbe); + delete audioProbe; + return; + } } MFAudioEndpointControl* MFPlayerService::audioEndpointControl() const diff --git a/src/plugins/wmf/player/mfplayersession.cpp b/src/plugins/wmf/player/mfplayersession.cpp index 2d56aff..bd51bba 100644 --- a/src/plugins/wmf/player/mfplayersession.cpp +++ b/src/plugins/wmf/player/mfplayersession.cpp @@ -63,6 +63,7 @@ #include #include #include "sourceresolver.h" +#include "samplegrabber.h" //#define DEBUG_MEDIAFOUNDATION //#define TEST_STREAMING @@ -416,6 +417,8 @@ MFPlayerSession::MFPlayerSession(MFPlayerService *playerService) , m_scrubbing(false) , m_restoreRate(1) , m_mediaTypes(0) + , m_audioSampleGrabber(0) + , m_audioSampleGrabberNode(0) { m_hCloseEvent = CreateEvent(NULL, FALSE, FALSE, NULL); m_sourceResolver = new SourceResolver(); @@ -437,6 +440,8 @@ MFPlayerSession::MFPlayerSession(MFPlayerService *playerService) PropVariantInit(&m_varStart); m_varStart.vt = VT_I8; m_varStart.uhVal.QuadPart = 0; + + m_audioSampleGrabber = new AudioSampleGrabberCallback; } void MFPlayerSession::close() @@ -470,8 +475,19 @@ void MFPlayerSession::close() CloseHandle(m_hCloseEvent); } +void MFPlayerSession::addProbe(MFAudioProbeControl *probe) +{ + m_audioSampleGrabber->addProbe(probe); +} + +void MFPlayerSession::removeProbe(MFAudioProbeControl *probe) +{ + m_audioSampleGrabber->removeProbe(probe); +} + MFPlayerSession::~MFPlayerSession() { + m_audioSampleGrabber->Release(); } @@ -579,7 +595,12 @@ void MFPlayerSession::setupPlaybackTopology(IMFMediaSource *source, IMFPresentat if (sourceNode) { IMFTopologyNode *outputNode = addOutputNode(streamDesc, mediaType, topology, 0); if (outputNode) { - hr = sourceNode->ConnectOutput(0, outputNode, 0); + // Only install audio sample grabber for the first audio stream. + if (mediaType != Audio || m_audioSampleGrabberNode || !setupAudioSampleGrabber(topology, sourceNode, outputNode)) { + hr = sourceNode->ConnectOutput(0, outputNode, 0); + } else { + hr = S_OK; + } if (FAILED(hr)) { emit error(QMediaPlayer::FormatError, tr("Unable to play some stream"), false); } @@ -689,6 +710,133 @@ IMFTopologyNode* MFPlayerSession::addOutputNode(IMFStreamDescriptor *streamDesc, return NULL; } +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); + format.setSampleType(QAudioFormat::SignedInt); + + CoTaskMemFree(wfx); + return format; +} + void MFPlayerSession::stop(bool immediate) { #ifdef DEBUG_MEDIAFOUNDATION @@ -1270,6 +1418,15 @@ void MFPlayerSession::handleSessionEvent(IMFMediaEvent *sessionEvent) } break; case MESessionTopologySet: { + if (m_audioSampleGrabberNode) { + IMFMediaType *mediaType = 0; + hr = MFGetTopoNodeCurrentType(m_audioSampleGrabberNode, 0, FALSE, &mediaType); + if (SUCCEEDED(hr)) { + m_audioSampleGrabber->setFormat(audioFormatForMFMediaType(mediaType)); + mediaType->Release(); + } + } + if (SUCCEEDED(MFGetService(m_session, MR_POLICY_VOLUME_SERVICE, IID_PPV_ARGS(&m_volumeControl)))) { m_volumeControl->SetMasterVolume(m_volume); m_volumeControl->SetMute(m_muted); @@ -1402,4 +1559,8 @@ void MFPlayerSession::clear() 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 index 70ce925..969fd24 100644 --- a/src/plugins/wmf/player/mfplayersession.h +++ b/src/plugins/wmf/player/mfplayersession.h @@ -54,6 +54,7 @@ #include #include #include +#include QT_BEGIN_NAMESPACE class QMediaContent; @@ -70,6 +71,8 @@ class MFVideoRendererControl; class MFPlayerControl; class MFMetaDataControl; class MFPlayerService; +class AudioSampleGrabberCallback; +class MFAudioProbeControl; class MFPlayerSession : public QObject, public IMFAsyncCallback { @@ -115,6 +118,9 @@ public: void close(); + void addProbe(MFAudioProbeControl* probe); + void removeProbe(MFAudioProbeControl* probe); + Q_SIGNALS: void error(QMediaPlayer::Error error, QString errorString, bool isFatal); void sessionEvent(IMFMediaEvent *sessionEvent); @@ -211,6 +217,12 @@ private: IMFTopologyNode* addSourceNode(IMFTopology* topology, IMFMediaSource* source, IMFPresentationDescriptor* presentationDesc, IMFStreamDescriptor *streamDesc); IMFTopologyNode* addOutputNode(IMFStreamDescriptor *streamDesc, 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; }; diff --git a/src/plugins/wmf/player/player.pri b/src/plugins/wmf/player/player.pri index 733c790..8f28b52 100644 --- a/src/plugins/wmf/player/player.pri +++ b/src/plugins/wmf/player/player.pri @@ -10,7 +10,8 @@ HEADERS += \ $$PWD/mfplayercontrol.h \ $$PWD/mfvideorenderercontrol.h \ $$PWD/mfaudioendpointcontrol.h \ - $$PWD/mfmetadatacontrol.h + $$PWD/mfmetadatacontrol.h \ + $$PWD/mfaudioprobecontrol.h SOURCES += \ $$PWD/mfplayerservice.cpp \ @@ -18,7 +19,8 @@ SOURCES += \ $$PWD/mfplayercontrol.cpp \ $$PWD/mfvideorenderercontrol.cpp \ $$PWD/mfaudioendpointcontrol.cpp \ - $$PWD/mfmetadatacontrol.cpp + $$PWD/mfmetadatacontrol.cpp \ + $$PWD/mfaudioprobecontrol.cpp !isEmpty(QT.widgets.name):!simulator { HEADERS += $$PWD/evr9videowindowcontrol.h diff --git a/src/plugins/wmf/samplegrabber.cpp b/src/plugins/wmf/samplegrabber.cpp new file mode 100644 index 0000000..98757b6 --- /dev/null +++ b/src/plugins/wmf/samplegrabber.cpp @@ -0,0 +1,172 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $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(this); + } else if (riid == IID_IMFClockStateSink) { + *ppv = static_cast(this); + } else if (riid == IID_IUnknown) { + *ppv = static_cast(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; + } + + foreach (MFAudioProbeControl* probe, m_audioProbes) + probe->bufferProbed((const char*)pSampleBuffer, dwSampleSize, m_format, llSampleTime); + + return S_OK; +} diff --git a/src/plugins/wmf/samplegrabber.h b/src/plugins/wmf/samplegrabber.h new file mode 100644 index 0000000..e639eac --- /dev/null +++ b/src/plugins/wmf/samplegrabber.h @@ -0,0 +1,95 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef SAMPLEGRABBER_H +#define SAMPLEGRABBER_H + +#include +#include +#include +#include +#include + +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) {} + +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 m_audioProbes; + QMutex m_audioProbeMutex; + QAudioFormat m_format; +}; + +#endif // SAMPLEGRABBER_H diff --git a/src/plugins/wmf/wmf.pro b/src/plugins/wmf/wmf.pro index d7f596d..87555dd 100644 --- a/src/plugins/wmf/wmf.pro +++ b/src/plugins/wmf/wmf.pro @@ -18,12 +18,14 @@ INCLUDEPATH += . HEADERS += \ wmfserviceplugin.h \ mfstream.h \ - sourceresolver.h + sourceresolver.h \ + samplegrabber.h SOURCES += \ wmfserviceplugin.cpp \ mfstream.cpp \ - sourceresolver.cpp + sourceresolver.cpp \ + samplegrabber.cpp include (player/player.pri) include (decoder/decoder.pri)