Audioprobe implementation for wmf backend.

Change-Id: I63af91af870cb92c838c1ab5d4752815aa60a03f
Reviewed-by: Ling Hu <ling.hu@nokia.com>
This commit is contained in:
Lev Zelenskiy
2012-07-11 15:06:40 +10:00
committed by Qt by Nokia
parent 4d13a15bae
commit afe12ea4de
9 changed files with 610 additions and 5 deletions

View File

@@ -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);
}

View File

@@ -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 <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

View File

@@ -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<MFAudioProbeControl*>(control);
if (audioProbe) {
if (m_session)
m_session->removeProbe(audioProbe);
delete audioProbe;
return;
}
}
MFAudioEndpointControl* MFPlayerService::audioEndpointControl() const

View File

@@ -63,6 +63,7 @@
#include <Mferror.h>
#include <nserror.h>
#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;
}
}

View File

@@ -54,6 +54,7 @@
#include <QtCore/qmutex.h>
#include <QtCore/qurl.h>
#include <QtCore/qwaitcondition.h>
#include <QtMultimedia/qaudioformat.h>
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;
};

View File

@@ -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

View File

@@ -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<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;
}
foreach (MFAudioProbeControl* probe, m_audioProbes)
probe->bufferProbed((const char*)pSampleBuffer, dwSampleSize, m_format, llSampleTime);
return S_OK;
}

View File

@@ -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 <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) {}
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

View File

@@ -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)