Fixed some crash with WMF backend
Change-Id: I721ba049e2ecafff53ee70d5b930fb52c15fbe09 Reviewed-by: Michael Goddard <michael.goddard@nokia.com>
This commit is contained in:
@@ -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,11 +83,15 @@ 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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
Reference in New Issue
Block a user