Fixed some crash with WMF backend

Change-Id: I721ba049e2ecafff53ee70d5b930fb52c15fbe09
Reviewed-by: Michael Goddard <michael.goddard@nokia.com>
This commit is contained in:
Ling Hu
2012-06-21 16:18:05 +10:00
committed by Qt by Nokia
parent 6d301388e1
commit 1b7da9e0ad
6 changed files with 51 additions and 25 deletions

View File

@@ -52,6 +52,7 @@
#include "mfplayerservice.h" #include "mfplayerservice.h"
#include "mfplayersession.h" #include "mfplayersession.h"
#include "mfmetadatacontrol.h" #include "mfmetadatacontrol.h"
int MFPlayerService::s_refCount = 0;
MFPlayerService::MFPlayerService(QObject *parent) MFPlayerService::MFPlayerService(QObject *parent)
: QMediaService(parent) : QMediaService(parent)
@@ -61,17 +62,19 @@ MFPlayerService::MFPlayerService(QObject *parent)
#endif #endif
, m_videoRendererControl(0) , m_videoRendererControl(0)
{ {
s_refCount++;
if (s_refCount == 1) {
CoInitialize(NULL); CoInitialize(NULL);
MFStartup(MF_VERSION); MFStartup(MF_VERSION);
}
m_audioEndpointControl = new MFAudioEndpointControl(this);
m_session = new MFPlayerSession(this); m_session = new MFPlayerSession(this);
m_player = new MFPlayerControl(m_session); m_player = new MFPlayerControl(m_session);
m_audioEndpointControl = new MFAudioEndpointControl(this);
m_metaDataControl = new MFMetaDataControl(this); m_metaDataControl = new MFMetaDataControl(this);
} }
MFPlayerService::~MFPlayerService() MFPlayerService::~MFPlayerService()
{ {
#ifndef Q_WS_SIMULATOR #ifndef Q_WS_SIMULATOR
if (m_videoWindowControl) if (m_videoWindowControl)
delete m_videoWindowControl; delete m_videoWindowControl;
@@ -80,10 +83,14 @@ MFPlayerService::~MFPlayerService()
if (m_videoRendererControl) if (m_videoRendererControl)
delete m_videoRendererControl; delete m_videoRendererControl;
delete m_session; m_session->close();
m_session->Release();
s_refCount--;
if (s_refCount == 0) {
MFShutdown(); MFShutdown();
CoUninitialize(); CoUninitialize();
}
} }
QMediaControl* MFPlayerService::requestControl(const char *name) QMediaControl* MFPlayerService::requestControl(const char *name)

View File

@@ -91,6 +91,7 @@ private:
#endif #endif
MFPlayerControl *m_player; MFPlayerControl *m_player;
MFMetaDataControl *m_metaDataControl; MFMetaDataControl *m_metaDataControl;
static int s_refCount;
}; };
#endif #endif

View File

@@ -399,8 +399,9 @@ namespace
} }
MFPlayerSession::MFPlayerSession(QObject *parent) MFPlayerSession::MFPlayerSession(MFPlayerService *playerService)
: QObject(parent) : m_playerService(playerService)
, m_cRef(1)
, m_session(0) , m_session(0)
, m_presentationClock(0) , m_presentationClock(0)
, m_rateControl(0) , m_rateControl(0)
@@ -438,9 +439,8 @@ MFPlayerSession::MFPlayerSession(QObject *parent)
m_varStart.uhVal.QuadPart = 0; m_varStart.uhVal.QuadPart = 0;
} }
MFPlayerSession::~MFPlayerSession() void MFPlayerSession::close()
{ {
m_sourceResolver->Release();
clear(); clear();
HRESULT hr = S_OK; HRESULT hr = S_OK;
if (m_session) { if (m_session) {
@@ -454,17 +454,22 @@ MFPlayerSession::~MFPlayerSession()
} }
if (SUCCEEDED(hr)) { if (SUCCEEDED(hr)) {
m_sourceResolver->shutdown();
if (m_session) if (m_session)
m_session->Shutdown(); m_session->Shutdown();
m_sourceResolver->shutdown();
} }
m_sourceResolver->Release();
if (m_session) if (m_session)
m_session->Release(); m_session->Release();
m_session = 0;
CloseHandle(m_hCloseEvent); CloseHandle(m_hCloseEvent);
} }
MFPlayerSession::~MFPlayerSession()
{
}
void MFPlayerSession::load(const QMediaContent &media, QIODevice *stream) void MFPlayerSession::load(const QMediaContent &media, QIODevice *stream)
{ {
@@ -525,7 +530,7 @@ void MFPlayerSession::handleMediaSourceReady()
hr = mediaSource->CreatePresentationDescriptor(&sourcePD); hr = mediaSource->CreatePresentationDescriptor(&sourcePD);
if (SUCCEEDED(hr)) { if (SUCCEEDED(hr)) {
m_duration = 0; m_duration = 0;
static_cast<MFPlayerService*>(this->parent())->metaDataControl()->updateSource(sourcePD, mediaSource); m_playerService->metaDataControl()->updateSource(sourcePD, mediaSource);
sourcePD->GetUINT64(MF_PD_DURATION, &m_duration); sourcePD->GetUINT64(MF_PD_DURATION, &m_duration);
//convert from 100 nanosecond to milisecond //convert from 100 nanosecond to milisecond
emit durationUpdate(qint64(m_duration / 10000)); emit durationUpdate(qint64(m_duration / 10000));
@@ -645,17 +650,16 @@ IMFTopologyNode* MFPlayerSession::addOutputNode(IMFStreamDescriptor *streamDesc,
hr = handler->GetMajorType(&guidMajorType); hr = handler->GetMajorType(&guidMajorType);
if (SUCCEEDED(hr)) { if (SUCCEEDED(hr)) {
IMFActivate *activate = NULL; IMFActivate *activate = NULL;
MFPlayerService *service = static_cast<MFPlayerService*>(this->parent());
if (MFMediaType_Audio == guidMajorType) { if (MFMediaType_Audio == guidMajorType) {
mediaType = Audio; mediaType = Audio;
activate = service->audioEndpointControl()->currentActivate(); activate = m_playerService->audioEndpointControl()->currentActivate();
} else if (MFMediaType_Video == guidMajorType) { } else if (MFMediaType_Video == guidMajorType) {
mediaType = Video; mediaType = Video;
if (service->videoRendererControl()) { if (m_playerService->videoRendererControl()) {
activate = service->videoRendererControl()->currentActivate(); activate = m_playerService->videoRendererControl()->currentActivate();
#ifndef Q_WS_SIMULATOR #ifndef Q_WS_SIMULATOR
} else if (service->videoWindowControl()) { } else if (m_playerService->videoWindowControl()) {
activate = service->videoWindowControl()->currentActivate(); activate = m_playerService->videoWindowControl()->currentActivate();
#endif #endif
} else { } else {
qWarning() << "no videoWindowControl or videoRendererControl, unable to add output node for video data"; qWarning() << "no videoWindowControl or videoRendererControl, unable to add output node for video data";
@@ -1085,12 +1089,15 @@ HRESULT MFPlayerSession::QueryInterface(REFIID riid, void** ppvObject)
ULONG MFPlayerSession::AddRef(void) ULONG MFPlayerSession::AddRef(void)
{ {
return 1; return InterlockedIncrement(&m_cRef);
} }
ULONG MFPlayerSession::Release(void) ULONG MFPlayerSession::Release(void)
{ {
return 1; LONG cRef = InterlockedDecrement(&m_cRef);
if (cRef == 0)
this->deleteLater();
return cRef;
} }
HRESULT MFPlayerSession::Invoke(IMFAsyncResult *pResult) HRESULT MFPlayerSession::Invoke(IMFAsyncResult *pResult)
@@ -1114,6 +1121,7 @@ HRESULT MFPlayerSession::Invoke(IMFAsyncResult *pResult)
if (meType == MESessionClosed) { if (meType == MESessionClosed) {
SetEvent(m_hCloseEvent); SetEvent(m_hCloseEvent);
pEvent->Release();
return S_OK; return S_OK;
} else { } else {
hr = m_session->BeginGetEvent(this, m_session); hr = m_session->BeginGetEvent(this, m_session);

View File

@@ -69,13 +69,14 @@ class MFAudioEndpointControl;
class MFVideoRendererControl; class MFVideoRendererControl;
class MFPlayerControl; class MFPlayerControl;
class MFMetaDataControl; class MFMetaDataControl;
class MFPlayerService;
class MFPlayerSession : public QObject, public IMFAsyncCallback class MFPlayerSession : public QObject, public IMFAsyncCallback
{ {
Q_OBJECT Q_OBJECT
friend class SourceResolver; friend class SourceResolver;
public: public:
MFPlayerSession(QObject *parent = 0); MFPlayerSession(MFPlayerService *playerService = 0);
~MFPlayerSession(); ~MFPlayerSession();
STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppvObject); STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppvObject);
@@ -112,6 +113,8 @@ public:
void changeStatus(QMediaPlayer::MediaStatus newStatus); void changeStatus(QMediaPlayer::MediaStatus newStatus);
void close();
Q_SIGNALS: Q_SIGNALS:
void error(QMediaPlayer::Error error, QString errorString, bool isFatal); void error(QMediaPlayer::Error error, QString errorString, bool isFatal);
void sessionEvent(IMFMediaEvent *sessionEvent); void sessionEvent(IMFMediaEvent *sessionEvent);
@@ -132,6 +135,8 @@ private Q_SLOTS:
void handleSourceError(long hr); void handleSourceError(long hr);
private: private:
long m_cRef;
MFPlayerService *m_playerService;
IMFMediaSession *m_session; IMFMediaSession *m_session;
IMFPresentationClock *m_presentationClock; IMFPresentationClock *m_presentationClock;
IMFRateControl *m_rateControl; IMFRateControl *m_rateControl;

View File

@@ -836,6 +836,8 @@ namespace
QMutexLocker locker(&m_mutex); QMutexLocker locker(&m_mutex);
m_pixelFormats.clear(); m_pixelFormats.clear();
clearMediaTypes(); clearMediaTypes();
if (!m_surface)
return;
QList<QVideoFrame::PixelFormat> formats = m_surface->supportedPixelFormats(); QList<QVideoFrame::PixelFormat> formats = m_surface->supportedPixelFormats();
foreach (QVideoFrame::PixelFormat format, formats) { foreach (QVideoFrame::PixelFormat format, formats) {
IMFMediaType *mediaType; IMFMediaType *mediaType;

View File

@@ -66,6 +66,11 @@ SourceResolver::SourceResolver(QObject *parent)
SourceResolver::~SourceResolver() SourceResolver::~SourceResolver()
{ {
shutdown(); shutdown();
if (m_mediaSource) {
m_mediaSource->Release();
m_mediaSource = NULL;
}
if (m_cancelCookie) if (m_cancelCookie)
m_cancelCookie->Release(); m_cancelCookie->Release();
if (m_sourceResolver) if (m_sourceResolver)
@@ -249,8 +254,6 @@ void SourceResolver::shutdown()
{ {
if (m_mediaSource) { if (m_mediaSource) {
m_mediaSource->Shutdown(); m_mediaSource->Shutdown();
m_mediaSource->Release();
m_mediaSource = NULL;
} }
if (m_stream) { if (m_stream) {