From 1b7da9e0adf8a2638061d75e2697177be20ddc72 Mon Sep 17 00:00:00 2001 From: Ling Hu Date: Thu, 21 Jun 2012 16:18:05 +1000 Subject: Fixed some crash with WMF backend Change-Id: I721ba049e2ecafff53ee70d5b930fb52c15fbe09 Reviewed-by: Michael Goddard --- src/plugins/wmf/player/mfplayerservice.cpp | 21 ++++++++----- src/plugins/wmf/player/mfplayerservice.h | 1 + src/plugins/wmf/player/mfplayersession.cpp | 38 ++++++++++++++--------- src/plugins/wmf/player/mfplayersession.h | 7 ++++- src/plugins/wmf/player/mfvideorenderercontrol.cpp | 2 ++ src/plugins/wmf/player/sourceresolver.cpp | 7 +++-- 6 files changed, 51 insertions(+), 25 deletions(-) diff --git a/src/plugins/wmf/player/mfplayerservice.cpp b/src/plugins/wmf/player/mfplayerservice.cpp index c5f24cc30..c4c3fbda6 100644 --- a/src/plugins/wmf/player/mfplayerservice.cpp +++ b/src/plugins/wmf/player/mfplayerservice.cpp @@ -52,6 +52,7 @@ #include "mfplayerservice.h" #include "mfplayersession.h" #include "mfmetadatacontrol.h" +int MFPlayerService::s_refCount = 0; MFPlayerService::MFPlayerService(QObject *parent) : QMediaService(parent) @@ -61,17 +62,19 @@ MFPlayerService::MFPlayerService(QObject *parent) #endif , m_videoRendererControl(0) { - CoInitialize(NULL); - MFStartup(MF_VERSION); + s_refCount++; + if (s_refCount == 1) { + CoInitialize(NULL); + MFStartup(MF_VERSION); + } + m_audioEndpointControl = new MFAudioEndpointControl(this); m_session = new MFPlayerSession(this); m_player = new MFPlayerControl(m_session); - m_audioEndpointControl = new MFAudioEndpointControl(this); m_metaDataControl = new MFMetaDataControl(this); } MFPlayerService::~MFPlayerService() { - #ifndef Q_WS_SIMULATOR if (m_videoWindowControl) delete m_videoWindowControl; @@ -80,10 +83,14 @@ MFPlayerService::~MFPlayerService() if (m_videoRendererControl) delete m_videoRendererControl; - delete m_session; + m_session->close(); + m_session->Release(); - MFShutdown(); - CoUninitialize(); + s_refCount--; + if (s_refCount == 0) { + MFShutdown(); + CoUninitialize(); + } } QMediaControl* MFPlayerService::requestControl(const char *name) diff --git a/src/plugins/wmf/player/mfplayerservice.h b/src/plugins/wmf/player/mfplayerservice.h index 587e5925f..65f3b34d5 100644 --- a/src/plugins/wmf/player/mfplayerservice.h +++ b/src/plugins/wmf/player/mfplayerservice.h @@ -91,6 +91,7 @@ private: #endif MFPlayerControl *m_player; MFMetaDataControl *m_metaDataControl; + static int s_refCount; }; #endif diff --git a/src/plugins/wmf/player/mfplayersession.cpp b/src/plugins/wmf/player/mfplayersession.cpp index 3b96b83bc..c8c99e29a 100644 --- a/src/plugins/wmf/player/mfplayersession.cpp +++ b/src/plugins/wmf/player/mfplayersession.cpp @@ -399,8 +399,9 @@ namespace } -MFPlayerSession::MFPlayerSession(QObject *parent) - : QObject(parent) +MFPlayerSession::MFPlayerSession(MFPlayerService *playerService) + : m_playerService(playerService) + , m_cRef(1) , m_session(0) , m_presentationClock(0) , m_rateControl(0) @@ -438,9 +439,8 @@ MFPlayerSession::MFPlayerSession(QObject *parent) m_varStart.uhVal.QuadPart = 0; } -MFPlayerSession::~MFPlayerSession() +void MFPlayerSession::close() { - m_sourceResolver->Release(); clear(); HRESULT hr = S_OK; if (m_session) { @@ -454,17 +454,22 @@ MFPlayerSession::~MFPlayerSession() } if (SUCCEEDED(hr)) { - m_sourceResolver->shutdown(); if (m_session) m_session->Shutdown(); + m_sourceResolver->shutdown(); } + m_sourceResolver->Release(); if (m_session) m_session->Release(); - + m_session = 0; CloseHandle(m_hCloseEvent); } +MFPlayerSession::~MFPlayerSession() +{ +} + void MFPlayerSession::load(const QMediaContent &media, QIODevice *stream) { @@ -525,7 +530,7 @@ void MFPlayerSession::handleMediaSourceReady() hr = mediaSource->CreatePresentationDescriptor(&sourcePD); if (SUCCEEDED(hr)) { m_duration = 0; - static_cast(this->parent())->metaDataControl()->updateSource(sourcePD, mediaSource); + 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)); @@ -645,17 +650,16 @@ IMFTopologyNode* MFPlayerSession::addOutputNode(IMFStreamDescriptor *streamDesc, hr = handler->GetMajorType(&guidMajorType); if (SUCCEEDED(hr)) { IMFActivate *activate = NULL; - MFPlayerService *service = static_cast(this->parent()); if (MFMediaType_Audio == guidMajorType) { mediaType = Audio; - activate = service->audioEndpointControl()->currentActivate(); + activate = m_playerService->audioEndpointControl()->currentActivate(); } else if (MFMediaType_Video == guidMajorType) { mediaType = Video; - if (service->videoRendererControl()) { - activate = service->videoRendererControl()->currentActivate(); + if (m_playerService->videoRendererControl()) { + activate = m_playerService->videoRendererControl()->currentActivate(); #ifndef Q_WS_SIMULATOR - } else if (service->videoWindowControl()) { - activate = service->videoWindowControl()->currentActivate(); + } else if (m_playerService->videoWindowControl()) { + activate = m_playerService->videoWindowControl()->currentActivate(); #endif } else { 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) { - return 1; + return InterlockedIncrement(&m_cRef); } ULONG MFPlayerSession::Release(void) { - return 1; + LONG cRef = InterlockedDecrement(&m_cRef); + if (cRef == 0) + this->deleteLater(); + return cRef; } HRESULT MFPlayerSession::Invoke(IMFAsyncResult *pResult) @@ -1114,6 +1121,7 @@ HRESULT MFPlayerSession::Invoke(IMFAsyncResult *pResult) if (meType == MESessionClosed) { SetEvent(m_hCloseEvent); + pEvent->Release(); return S_OK; } else { hr = m_session->BeginGetEvent(this, m_session); diff --git a/src/plugins/wmf/player/mfplayersession.h b/src/plugins/wmf/player/mfplayersession.h index 911230e9b..70ce92562 100644 --- a/src/plugins/wmf/player/mfplayersession.h +++ b/src/plugins/wmf/player/mfplayersession.h @@ -69,13 +69,14 @@ class MFAudioEndpointControl; class MFVideoRendererControl; class MFPlayerControl; class MFMetaDataControl; +class MFPlayerService; class MFPlayerSession : public QObject, public IMFAsyncCallback { Q_OBJECT friend class SourceResolver; public: - MFPlayerSession(QObject *parent = 0); + MFPlayerSession(MFPlayerService *playerService = 0); ~MFPlayerSession(); STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppvObject); @@ -112,6 +113,8 @@ public: void changeStatus(QMediaPlayer::MediaStatus newStatus); + void close(); + Q_SIGNALS: void error(QMediaPlayer::Error error, QString errorString, bool isFatal); void sessionEvent(IMFMediaEvent *sessionEvent); @@ -132,6 +135,8 @@ private Q_SLOTS: void handleSourceError(long hr); private: + long m_cRef; + MFPlayerService *m_playerService; IMFMediaSession *m_session; IMFPresentationClock *m_presentationClock; IMFRateControl *m_rateControl; diff --git a/src/plugins/wmf/player/mfvideorenderercontrol.cpp b/src/plugins/wmf/player/mfvideorenderercontrol.cpp index 74ac715b8..56228e9c3 100644 --- a/src/plugins/wmf/player/mfvideorenderercontrol.cpp +++ b/src/plugins/wmf/player/mfvideorenderercontrol.cpp @@ -836,6 +836,8 @@ namespace QMutexLocker locker(&m_mutex); m_pixelFormats.clear(); clearMediaTypes(); + if (!m_surface) + return; QList formats = m_surface->supportedPixelFormats(); foreach (QVideoFrame::PixelFormat format, formats) { IMFMediaType *mediaType; diff --git a/src/plugins/wmf/player/sourceresolver.cpp b/src/plugins/wmf/player/sourceresolver.cpp index fe304afa7..8db973a24 100644 --- a/src/plugins/wmf/player/sourceresolver.cpp +++ b/src/plugins/wmf/player/sourceresolver.cpp @@ -66,6 +66,11 @@ SourceResolver::SourceResolver(QObject *parent) SourceResolver::~SourceResolver() { shutdown(); + if (m_mediaSource) { + m_mediaSource->Release(); + m_mediaSource = NULL; + } + if (m_cancelCookie) m_cancelCookie->Release(); if (m_sourceResolver) @@ -249,8 +254,6 @@ void SourceResolver::shutdown() { if (m_mediaSource) { m_mediaSource->Shutdown(); - m_mediaSource->Release(); - m_mediaSource = NULL; } if (m_stream) { -- cgit v1.2.3