summaryrefslogtreecommitdiffstats
path: root/src/plugins/wmf
diff options
context:
space:
mode:
authorYoann Lopes <yoann.lopes@digia.com>2012-12-06 16:00:06 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2012-12-07 13:06:16 +0100
commit06b63e99e4b86db1fbbed154316ada1dc7385ad3 (patch)
tree7c5b53150ed306ba54a6ecaed1729db3ea5df45a /src/plugins/wmf
parentad835347361c16b662f73680cbaa0444c1ec4064 (diff)
WMF: Recreate the MFMediaSession when loading a new media.
MFMediaSession doesn't seem to handle correctly the change of media source, causing the playback not to work afterwards. A single MFMediaSession was created and used for every loaded media, we now create a new one whenever we load a new media (releasing the old one beforehand). Task-number: QTBUG-26819 Change-Id: Id99c9dd54e161823d9580933e063f16240806529 Reviewed-by: Samuel Rødal <samuel.rodal@digia.com> Reviewed-by: Jason Barron <jason@cutehacks.com>
Diffstat (limited to 'src/plugins/wmf')
-rw-r--r--src/plugins/wmf/player/evr9videowindowcontrol.cpp54
-rw-r--r--src/plugins/wmf/player/evr9videowindowcontrol.h6
-rw-r--r--src/plugins/wmf/player/mfaudioendpointcontrol.cpp17
-rw-r--r--src/plugins/wmf/player/mfaudioendpointcontrol.h3
-rw-r--r--src/plugins/wmf/player/mfplayersession.cpp61
-rw-r--r--src/plugins/wmf/player/mfplayersession.h1
-rw-r--r--src/plugins/wmf/player/mfvideorenderercontrol.cpp34
-rw-r--r--src/plugins/wmf/player/mfvideorenderercontrol.h4
8 files changed, 133 insertions, 47 deletions
diff --git a/src/plugins/wmf/player/evr9videowindowcontrol.cpp b/src/plugins/wmf/player/evr9videowindowcontrol.cpp
index 0a50114dd..7f1c71332 100644
--- a/src/plugins/wmf/player/evr9videowindowcontrol.cpp
+++ b/src/plugins/wmf/player/evr9videowindowcontrol.cpp
@@ -57,27 +57,17 @@ Evr9VideoWindowControl::Evr9VideoWindowControl(QObject *parent)
, m_currentActivate(0)
, m_evrSink(0)
, m_displayControl(0)
+ , m_processor(0)
{
- if (FAILED(MFCreateVideoRendererActivate(0, &m_currentActivate))) {
- qWarning() << "Failed to create evr video renderer activate!";
- return;
- }
- if (FAILED(m_currentActivate->ActivateObject(IID_IMFMediaSink, (LPVOID*)(&m_evrSink)))) {
- qWarning() << "Failed to activate evr media sink!";
- return;
- }
- if (FAILED(MFGetService(m_evrSink, MR_VIDEO_RENDER_SERVICE, IID_PPV_ARGS(&m_displayControl)))) {
- qWarning() << "Failed to get display control from evr media sink!";
- return;
- }
- if (FAILED(MFGetService(m_evrSink, MR_VIDEO_MIXER_SERVICE, IID_PPV_ARGS(&m_processor)))) {
- qWarning() << "Failed to get video processor from evr media sink!";
- return;
- }
}
Evr9VideoWindowControl::~Evr9VideoWindowControl()
{
+ clear();
+}
+
+void Evr9VideoWindowControl::clear()
+{
if (m_processor)
m_processor->Release();
if (m_displayControl)
@@ -88,8 +78,12 @@ Evr9VideoWindowControl::~Evr9VideoWindowControl()
m_currentActivate->ShutdownObject();
m_currentActivate->Release();
}
-}
+ m_processor = NULL;
+ m_displayControl = NULL;
+ m_evrSink = NULL;
+ m_currentActivate = NULL;
+}
WId Evr9VideoWindowControl::winId() const
{
@@ -307,8 +301,32 @@ void Evr9VideoWindowControl::setSaturation(int saturation)
emit saturationChanged(saturation);
}
-IMFActivate* Evr9VideoWindowControl::currentActivate() const
+IMFActivate* Evr9VideoWindowControl::createActivate()
{
+ clear();
+
+ if (FAILED(MFCreateVideoRendererActivate(0, &m_currentActivate))) {
+ qWarning() << "Failed to create evr video renderer activate!";
+ return 0;
+ }
+ if (FAILED(m_currentActivate->ActivateObject(IID_IMFMediaSink, (LPVOID*)(&m_evrSink)))) {
+ qWarning() << "Failed to activate evr media sink!";
+ return 0;
+ }
+ if (FAILED(MFGetService(m_evrSink, MR_VIDEO_RENDER_SERVICE, IID_PPV_ARGS(&m_displayControl)))) {
+ qWarning() << "Failed to get display control from evr media sink!";
+ return 0;
+ }
+ if (FAILED(MFGetService(m_evrSink, MR_VIDEO_MIXER_SERVICE, IID_PPV_ARGS(&m_processor)))) {
+ qWarning() << "Failed to get video processor from evr media sink!";
+ return 0;
+ }
+
+ setWinId(m_windowId);
+ setDisplayRect(m_displayRect);
+ setAspectRatioMode(m_aspectRatioMode);
+ m_dirtyValues = DXVA2_ProcAmp_Brightness | DXVA2_ProcAmp_Contrast | DXVA2_ProcAmp_Hue | DXVA2_ProcAmp_Saturation;
+
return m_currentActivate;
}
diff --git a/src/plugins/wmf/player/evr9videowindowcontrol.h b/src/plugins/wmf/player/evr9videowindowcontrol.h
index d64447fdb..ea4bae56d 100644
--- a/src/plugins/wmf/player/evr9videowindowcontrol.h
+++ b/src/plugins/wmf/player/evr9videowindowcontrol.h
@@ -85,10 +85,12 @@ public:
int saturation() const;
void setSaturation(int saturation);
- IMFActivate* currentActivate() const;
+ IMFActivate* createActivate();
-private:
void setProcAmpValues();
+
+private:
+ void clear();
DXVA2_Fixed32 scaleProcAmpValue(DWORD prop, int value) const;
WId m_windowId;
diff --git a/src/plugins/wmf/player/mfaudioendpointcontrol.cpp b/src/plugins/wmf/player/mfaudioendpointcontrol.cpp
index 6d421fd06..7639f4f9e 100644
--- a/src/plugins/wmf/player/mfaudioendpointcontrol.cpp
+++ b/src/plugins/wmf/player/mfaudioendpointcontrol.cpp
@@ -46,17 +46,23 @@ MFAudioEndpointControl::MFAudioEndpointControl(QObject *parent)
: QAudioOutputSelectorControl(parent)
, m_currentActivate(0)
{
- updateEndpoints();
- setActiveOutput(m_defaultEndpoint);
}
MFAudioEndpointControl::~MFAudioEndpointControl()
{
+ clear();
+}
+
+void MFAudioEndpointControl::clear()
+{
+ m_activeEndpoint.clear();
+
foreach (LPWSTR wstrID, m_devices)
CoTaskMemFree(wstrID);
if (m_currentActivate)
m_currentActivate->Release();
+ m_currentActivate = NULL;
}
QList<QString> MFAudioEndpointControl::availableOutputs() const
@@ -119,8 +125,13 @@ void MFAudioEndpointControl::setActiveOutput(const QString &name)
m_activeEndpoint = name;
}
-IMFActivate* MFAudioEndpointControl::currentActivate() const
+IMFActivate* MFAudioEndpointControl::createActivate()
{
+ clear();
+
+ updateEndpoints();
+ setActiveOutput(m_defaultEndpoint);
+
return m_currentActivate;
}
diff --git a/src/plugins/wmf/player/mfaudioendpointcontrol.h b/src/plugins/wmf/player/mfaudioendpointcontrol.h
index 1e7fc58be..53c6657cb 100644
--- a/src/plugins/wmf/player/mfaudioendpointcontrol.h
+++ b/src/plugins/wmf/player/mfaudioendpointcontrol.h
@@ -68,9 +68,10 @@ public:
void setActiveOutput(const QString& name);
- IMFActivate* currentActivate() const;
+ IMFActivate* createActivate();
private:
+ void clear();
void updateEndpoints();
QString m_defaultEndpoint;
diff --git a/src/plugins/wmf/player/mfplayersession.cpp b/src/plugins/wmf/player/mfplayersession.cpp
index 150958660..7b35af43a 100644
--- a/src/plugins/wmf/player/mfplayersession.cpp
+++ b/src/plugins/wmf/player/mfplayersession.cpp
@@ -411,6 +411,7 @@ MFPlayerSession::MFPlayerSession(MFPlayerService *playerService)
, m_volumeControl(0)
, m_netsourceStatistics(0)
, m_hCloseEvent(0)
+ , m_closing(false)
, m_pendingRate(1)
, m_volume(1)
, m_muted(false)
@@ -422,10 +423,6 @@ MFPlayerSession::MFPlayerSession(MFPlayerService *playerService)
, m_audioSampleGrabberNode(0)
, m_videoProbeMFT(0)
{
- m_hCloseEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
- m_sourceResolver = new SourceResolver();
- QObject::connect(m_sourceResolver, SIGNAL(mediaSourceReady()), this, SLOT(handleMediaSourceReady()));
- QObject::connect(m_sourceResolver, SIGNAL(error(long)), this, SLOT(handleSourceError(long)));
QObject::connect(this, SIGNAL(sessionEvent(IMFMediaEvent *)), this, SLOT(handleSessionEvent(IMFMediaEvent *)));
m_pendingState = NoPending;
@@ -438,20 +435,23 @@ MFPlayerSession::MFPlayerSession(MFPlayerService *playerService)
m_request.prevCmd = CmdNone;
m_request.rate = 1.0f;
- createSession();
- PropVariantInit(&m_varStart);
- m_varStart.vt = VT_I8;
- m_varStart.uhVal.QuadPart = 0;
-
m_audioSampleGrabber = new AudioSampleGrabberCallback;
m_videoProbeMFT = new MFTransform;
}
void MFPlayerSession::close()
{
+#ifdef DEBUG_MEDIAFOUNDATION
+ qDebug() << "close";
+#endif
+
clear();
+ if (!m_session)
+ return;
+
HRESULT hr = S_OK;
if (m_session) {
+ m_closing = true;
hr = m_session->Close();
if (SUCCEEDED(hr)) {
DWORD dwWaitResult = WaitForSingleObject(m_hCloseEvent, 100);
@@ -459,6 +459,7 @@ void MFPlayerSession::close()
qWarning() << "session close time out!";
}
}
+ m_closing = false;
}
if (SUCCEEDED(hr)) {
@@ -475,7 +476,9 @@ void MFPlayerSession::close()
if (m_session)
m_session->Release();
m_session = 0;
- CloseHandle(m_hCloseEvent);
+ if (m_hCloseEvent)
+ CloseHandle(m_hCloseEvent);
+ m_hCloseEvent = 0;
}
void MFPlayerSession::addProbe(MFAudioProbeControl *probe)
@@ -522,6 +525,7 @@ void MFPlayerSession::load(const QMediaContent &media, QIODevice *stream)
changeStatus(QMediaPlayer::InvalidMedia);
emit error(QMediaPlayer::ResourceError, tr("Invalid stream source."), true);
} else {
+ createSession();
changeStatus(QMediaPlayer::LoadingMedia);
m_sourceResolver->load(resources, stream);
}
@@ -638,6 +642,7 @@ void MFPlayerSession::setupPlaybackTopology(IMFMediaSource *source, IMFPresentat
break;
}
}
+ outputNode->Release();
}
sourceNode->Release();
}
@@ -703,14 +708,14 @@ IMFTopologyNode* MFPlayerSession::addOutputNode(IMFStreamDescriptor *streamDesc,
IMFActivate *activate = NULL;
if (MFMediaType_Audio == guidMajorType) {
mediaType = Audio;
- activate = m_playerService->audioEndpointControl()->currentActivate();
+ activate = m_playerService->audioEndpointControl()->createActivate();
} else if (MFMediaType_Video == guidMajorType) {
mediaType = Video;
if (m_playerService->videoRendererControl()) {
- activate = m_playerService->videoRendererControl()->currentActivate();
+ activate = m_playerService->videoRendererControl()->createActivate();
#ifndef Q_WS_SIMULATOR
} else if (m_playerService->videoWindowControl()) {
- activate = m_playerService->videoWindowControl()->currentActivate();
+ activate = m_playerService->videoWindowControl()->createActivate();
#endif
} else {
qWarning() << "no videoWindowControl or videoRendererControl, unable to add output node for video data";
@@ -1136,6 +1141,7 @@ void MFPlayerSession::pause()
} else {
if (m_state.command == CmdPause)
return;
+
if (SUCCEEDED(m_session->Pause())) {
m_state.setCommand(CmdPause);
m_pendingState = CmdPending;
@@ -1163,6 +1169,14 @@ QMediaPlayer::MediaStatus MFPlayerSession::status() const
void MFPlayerSession::createSession()
{
+ close();
+
+ m_hCloseEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+
+ m_sourceResolver = new SourceResolver();
+ QObject::connect(m_sourceResolver, SIGNAL(mediaSourceReady()), this, SLOT(handleMediaSourceReady()));
+ QObject::connect(m_sourceResolver, SIGNAL(error(long)), this, SLOT(handleSourceError(long)));
+
Q_ASSERT(m_session == NULL);
HRESULT hr = MFCreateMediaSession(NULL, &m_session);
if (FAILED(hr)) {
@@ -1176,6 +1190,10 @@ void MFPlayerSession::createSession()
changeStatus(QMediaPlayer::UnknownMediaStatus);
emit error(QMediaPlayer::ResourceError, tr("Unable to pull session events."), false);
}
+
+ PropVariantInit(&m_varStart);
+ m_varStart.vt = VT_I8;
+ m_varStart.hVal.QuadPart = 0;
}
qint64 MFPlayerSession::position()
@@ -1511,7 +1529,8 @@ HRESULT MFPlayerSession::Invoke(IMFAsyncResult *pResult)
}
}
- emit sessionEvent(pEvent);
+ if (!m_closing)
+ emit sessionEvent(pEvent);
return S_OK;
}
@@ -1569,6 +1588,13 @@ void MFPlayerSession::handleSessionEvent(IMFMediaEvent *sessionEvent)
case MESessionStarted:
if (!m_scrubbing)
updatePendingCommands(CmdStart);
+#ifndef Q_WS_SIMULATOR
+ // playback started, we can now set again the procAmpValues if they have been
+ // changed previously (these are lost when loading a new media)
+ if (m_playerService->videoWindowControl()) {
+ m_playerService->videoWindowControl()->setProcAmpValues();
+ }
+#endif
break;
case MESessionStopped:
if (m_status != QMediaPlayer::EndOfMedia) {
@@ -1659,9 +1685,16 @@ void MFPlayerSession::handleSessionEvent(IMFMediaEvent *sessionEvent)
m_volumeControl->SetMasterVolume(m_volume);
m_volumeControl->SetMute(m_muted);
}
+
DWORD dwCharacteristics = 0;
m_sourceResolver->mediaSource()->GetCharacteristics(&dwCharacteristics);
emit seekableUpdate(MFMEDIASOURCE_CAN_SEEK & dwCharacteristics);
+
+ // Topology is resolved and successfuly set, this happens only after loading a new media.
+ // Make sure we always start the media from the beginning
+ m_varStart.vt = VT_I8;
+ m_varStart.hVal.QuadPart = 0;
+
changeStatus(QMediaPlayer::LoadedMedia);
}
break;
diff --git a/src/plugins/wmf/player/mfplayersession.h b/src/plugins/wmf/player/mfplayersession.h
index b050ad09f..b8b6f085e 100644
--- a/src/plugins/wmf/player/mfplayersession.h
+++ b/src/plugins/wmf/player/mfplayersession.h
@@ -178,6 +178,7 @@ private:
SourceResolver *m_sourceResolver;
HANDLE m_hCloseEvent;
+ bool m_closing;
enum MediaType
{
diff --git a/src/plugins/wmf/player/mfvideorenderercontrol.cpp b/src/plugins/wmf/player/mfvideorenderercontrol.cpp
index 8d47b1aac..c3c5c1ae4 100644
--- a/src/plugins/wmf/player/mfvideorenderercontrol.cpp
+++ b/src/plugins/wmf/player/mfvideorenderercontrol.cpp
@@ -2130,17 +2130,23 @@ namespace
MFVideoRendererControl::MFVideoRendererControl(QObject *parent)
: QVideoRendererControl(parent)
, m_surface(0)
+ , m_currentActivate(0)
, m_callback(0)
{
- m_currentActivate = new VideoRendererActivate(this);
}
MFVideoRendererControl::~MFVideoRendererControl()
{
+ clear();
+}
+
+void MFVideoRendererControl::clear()
+{
if (m_currentActivate) {
m_currentActivate->ShutdownObject();
m_currentActivate->Release();
}
+ m_currentActivate = NULL;
}
QAbstractVideoSurface *MFVideoRendererControl::surface() const
@@ -2150,9 +2156,6 @@ QAbstractVideoSurface *MFVideoRendererControl::surface() const
void MFVideoRendererControl::setSurface(QAbstractVideoSurface *surface)
{
- if (m_surface == surface)
- return;
-
if (m_surface)
disconnect(m_surface, SIGNAL(supportedFormatsChanged()), this, SLOT(supportedFormatsChanged()));
m_surface = surface;
@@ -2160,11 +2163,16 @@ void MFVideoRendererControl::setSurface(QAbstractVideoSurface *surface)
if (m_surface) {
connect(m_surface, SIGNAL(supportedFormatsChanged()), this, SLOT(supportedFormatsChanged()));
}
- static_cast<VideoRendererActivate*>(m_currentActivate)->setSurface(m_surface);
+
+ if (m_currentActivate)
+ static_cast<VideoRendererActivate*>(m_currentActivate)->setSurface(m_surface);
}
void MFVideoRendererControl::customEvent(QEvent *event)
{
+ if (!m_currentActivate)
+ return;
+
if (event->type() == MediaStream::PresentSurface) {
MFTIME targetTime = static_cast<MediaStream::PresentEvent*>(event)->targetTime();
MFTIME currentTime = static_cast<VideoRendererActivate*>(m_currentActivate)->getTime();
@@ -2185,16 +2193,26 @@ void MFVideoRendererControl::customEvent(QEvent *event)
void MFVideoRendererControl::supportedFormatsChanged()
{
- static_cast<VideoRendererActivate*>(m_currentActivate)->supportedFormatsChanged();
+ if (m_currentActivate)
+ static_cast<VideoRendererActivate*>(m_currentActivate)->supportedFormatsChanged();
}
void MFVideoRendererControl::present()
{
- static_cast<VideoRendererActivate*>(m_currentActivate)->present();
+ if (m_currentActivate)
+ static_cast<VideoRendererActivate*>(m_currentActivate)->present();
}
-IMFActivate* MFVideoRendererControl::currentActivate() const
+IMFActivate* MFVideoRendererControl::createActivate()
{
+ clear();
+
+ m_currentActivate = new VideoRendererActivate(this);
+ if (m_surface) {
+ setSurface(m_surface);
+ supportedFormatsChanged();
+ }
+
return m_currentActivate;
}
diff --git a/src/plugins/wmf/player/mfvideorenderercontrol.h b/src/plugins/wmf/player/mfvideorenderercontrol.h
index 25adcf269..ba04e73b7 100644
--- a/src/plugins/wmf/player/mfvideorenderercontrol.h
+++ b/src/plugins/wmf/player/mfvideorenderercontrol.h
@@ -58,7 +58,7 @@ public:
QAbstractVideoSurface *surface() const;
void setSurface(QAbstractVideoSurface *surface);
- IMFActivate* currentActivate() const;
+ IMFActivate* createActivate();
protected:
void customEvent(QEvent *event);
@@ -68,6 +68,8 @@ private Q_SLOTS:
void present();
private:
+ void clear();
+
QAbstractVideoSurface *m_surface;
IMFActivate *m_currentActivate;
IMFSampleGrabberSinkCallback *m_callback;