summaryrefslogtreecommitdiffstats
path: root/src/plugins/wmf/player
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/wmf/player')
-rw-r--r--src/plugins/wmf/player/evr9videowindowcontrol.cpp2
-rw-r--r--src/plugins/wmf/player/evr9videowindowcontrol.h2
-rw-r--r--src/plugins/wmf/player/mfaudioendpointcontrol.cpp2
-rw-r--r--src/plugins/wmf/player/mfaudioendpointcontrol.h2
-rw-r--r--src/plugins/wmf/player/mfaudioprobecontrol.cpp2
-rw-r--r--src/plugins/wmf/player/mfaudioprobecontrol.h2
-rw-r--r--src/plugins/wmf/player/mfmetadatacontrol.cpp2
-rw-r--r--src/plugins/wmf/player/mfmetadatacontrol.h2
-rw-r--r--src/plugins/wmf/player/mfplayercontrol.cpp2
-rw-r--r--src/plugins/wmf/player/mfplayercontrol.h2
-rw-r--r--src/plugins/wmf/player/mfplayerservice.cpp2
-rw-r--r--src/plugins/wmf/player/mfplayerservice.h2
-rw-r--r--src/plugins/wmf/player/mfplayersession.cpp250
-rw-r--r--src/plugins/wmf/player/mfplayersession.h4
-rw-r--r--src/plugins/wmf/player/mfvideoprobecontrol.cpp2
-rw-r--r--src/plugins/wmf/player/mfvideoprobecontrol.h2
-rw-r--r--src/plugins/wmf/player/mfvideorenderercontrol.cpp126
-rw-r--r--src/plugins/wmf/player/mfvideorenderercontrol.h14
-rw-r--r--src/plugins/wmf/player/player.pri2
19 files changed, 310 insertions, 114 deletions
diff --git a/src/plugins/wmf/player/evr9videowindowcontrol.cpp b/src/plugins/wmf/player/evr9videowindowcontrol.cpp
index b15eef15e..5cafb8848 100644
--- a/src/plugins/wmf/player/evr9videowindowcontrol.cpp
+++ b/src/plugins/wmf/player/evr9videowindowcontrol.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Mobility Components.
diff --git a/src/plugins/wmf/player/evr9videowindowcontrol.h b/src/plugins/wmf/player/evr9videowindowcontrol.h
index 01a9c42fa..9963f7882 100644
--- a/src/plugins/wmf/player/evr9videowindowcontrol.h
+++ b/src/plugins/wmf/player/evr9videowindowcontrol.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Mobility Components.
diff --git a/src/plugins/wmf/player/mfaudioendpointcontrol.cpp b/src/plugins/wmf/player/mfaudioendpointcontrol.cpp
index 7639f4f9e..39fc41c5f 100644
--- a/src/plugins/wmf/player/mfaudioendpointcontrol.cpp
+++ b/src/plugins/wmf/player/mfaudioendpointcontrol.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Mobility Components.
diff --git a/src/plugins/wmf/player/mfaudioendpointcontrol.h b/src/plugins/wmf/player/mfaudioendpointcontrol.h
index 53c6657cb..8be1d1c78 100644
--- a/src/plugins/wmf/player/mfaudioendpointcontrol.h
+++ b/src/plugins/wmf/player/mfaudioendpointcontrol.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Mobility Components.
diff --git a/src/plugins/wmf/player/mfaudioprobecontrol.cpp b/src/plugins/wmf/player/mfaudioprobecontrol.cpp
index 0c477f357..e89b0e393 100644
--- a/src/plugins/wmf/player/mfaudioprobecontrol.cpp
+++ b/src/plugins/wmf/player/mfaudioprobecontrol.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Toolkit.
diff --git a/src/plugins/wmf/player/mfaudioprobecontrol.h b/src/plugins/wmf/player/mfaudioprobecontrol.h
index 1b82eaa76..9db79f7bf 100644
--- a/src/plugins/wmf/player/mfaudioprobecontrol.h
+++ b/src/plugins/wmf/player/mfaudioprobecontrol.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Toolkit.
diff --git a/src/plugins/wmf/player/mfmetadatacontrol.cpp b/src/plugins/wmf/player/mfmetadatacontrol.cpp
index 142b8650b..f27370ed2 100644
--- a/src/plugins/wmf/player/mfmetadatacontrol.cpp
+++ b/src/plugins/wmf/player/mfmetadatacontrol.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Mobility Components.
diff --git a/src/plugins/wmf/player/mfmetadatacontrol.h b/src/plugins/wmf/player/mfmetadatacontrol.h
index 38ee8bad0..f3955f570 100644
--- a/src/plugins/wmf/player/mfmetadatacontrol.h
+++ b/src/plugins/wmf/player/mfmetadatacontrol.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Mobility Components.
diff --git a/src/plugins/wmf/player/mfplayercontrol.cpp b/src/plugins/wmf/player/mfplayercontrol.cpp
index bdd28fc94..68ffa7b6f 100644
--- a/src/plugins/wmf/player/mfplayercontrol.cpp
+++ b/src/plugins/wmf/player/mfplayercontrol.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Mobility Components.
diff --git a/src/plugins/wmf/player/mfplayercontrol.h b/src/plugins/wmf/player/mfplayercontrol.h
index d0625ffc0..3a841c62d 100644
--- a/src/plugins/wmf/player/mfplayercontrol.h
+++ b/src/plugins/wmf/player/mfplayercontrol.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Mobility Components.
diff --git a/src/plugins/wmf/player/mfplayerservice.cpp b/src/plugins/wmf/player/mfplayerservice.cpp
index ea06031ff..92025a79b 100644
--- a/src/plugins/wmf/player/mfplayerservice.cpp
+++ b/src/plugins/wmf/player/mfplayerservice.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Mobility Components.
diff --git a/src/plugins/wmf/player/mfplayerservice.h b/src/plugins/wmf/player/mfplayerservice.h
index 827702c3b..0d39edc16 100644
--- a/src/plugins/wmf/player/mfplayerservice.h
+++ b/src/plugins/wmf/player/mfplayerservice.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Mobility Components.
diff --git a/src/plugins/wmf/player/mfplayersession.cpp b/src/plugins/wmf/player/mfplayersession.cpp
index 7c7320228..c52498f63 100644
--- a/src/plugins/wmf/player/mfplayersession.cpp
+++ b/src/plugins/wmf/player/mfplayersession.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Mobility Components.
@@ -65,6 +65,7 @@
#include "sourceresolver.h"
#include "samplegrabber.h"
#include "mftvideo.h"
+#include <wmcodecdsp.h>
//#define DEBUG_MEDIAFOUNDATION
//#define TEST_STREAMING
@@ -1004,8 +1005,16 @@ IMFTopology *MFPlayerSession::insertMFT(IMFTopology *topology, TOPOID outputNode
if (FAILED(MFCreateTopoLoader(&topoLoader)))
break;
- if (FAILED(topoLoader->Load(topology, &resolvedTopology, NULL)))
- break;
+ if (FAILED(topoLoader->Load(topology, &resolvedTopology, NULL))) {
+ // Topology could not be resolved, adding ourselves a color converter
+ // to the topology might solve the problem
+ insertColorConverter(topology, outputNodeId);
+ if (FAILED(topoLoader->Load(topology, &resolvedTopology, NULL)))
+ break;
+ }
+
+ if (insertResizer(resolvedTopology))
+ isNewTopology = true;
// Get all output nodes and search for video output node.
if (FAILED(resolvedTopology->GetOutputNodeCollection(&outputNodes)))
@@ -1022,6 +1031,7 @@ IMFTopology *MFPlayerSession::insertMFT(IMFTopology *topology, TOPOID outputNode
IMFMediaTypeHandler *videoSink = 0;
IMFTopologyNode *inputNode = 0;
IMFTopologyNode *mftNode = 0;
+ bool mftAdded = false;
do {
if (FAILED(outputNodes->GetElement(n, &element)))
@@ -1074,6 +1084,7 @@ IMFTopology *MFPlayerSession::insertMFT(IMFTopology *topology, TOPOID outputNode
if (FAILED(mftNode->ConnectOutput(0, node, 0)))
break;
+ mftAdded = true;
isNewTopology = true;
} while (false);
@@ -1090,7 +1101,7 @@ IMFTopology *MFPlayerSession::insertMFT(IMFTopology *topology, TOPOID outputNode
if (outputObject)
outputObject->Release();
- if (isNewTopology)
+ if (mftAdded)
break;
}
} while (false);
@@ -1112,6 +1123,177 @@ IMFTopology *MFPlayerSession::insertMFT(IMFTopology *topology, TOPOID outputNode
return topology;
}
+// This method checks if the topology contains a color converter transform (CColorConvertDMO),
+// if it does it inserts a resizer transform (CResizerDMO) to handle dynamic frame size change
+// of the video stream.
+// Returns true if it inserted a resizer
+bool MFPlayerSession::insertResizer(IMFTopology *topology)
+{
+ bool inserted = false;
+ WORD elementCount = 0;
+ IMFTopologyNode *node = 0;
+ IUnknown *object = 0;
+ IWMColorConvProps *colorConv = 0;
+ IMFTransform *resizer = 0;
+ IMFTopologyNode *resizerNode = 0;
+ IMFTopologyNode *inputNode = 0;
+
+ HRESULT hr = topology->GetNodeCount(&elementCount);
+ if (FAILED(hr))
+ return false;
+
+ for (WORD i = 0; i < elementCount; ++i) {
+ if (node) {
+ node->Release();
+ node = 0;
+ }
+ if (object) {
+ object->Release();
+ object = 0;
+ }
+
+ if (FAILED(topology->GetNode(i, &node)))
+ break;
+
+ MF_TOPOLOGY_TYPE nodeType;
+ if (FAILED(node->GetNodeType(&nodeType)))
+ break;
+
+ if (nodeType != MF_TOPOLOGY_TRANSFORM_NODE)
+ continue;
+
+ if (FAILED(node->GetObject(&object)))
+ break;
+
+ if (FAILED(object->QueryInterface(&colorConv)))
+ continue;
+
+ if (FAILED(CoCreateInstance(CLSID_CResizerDMO, NULL, CLSCTX_INPROC_SERVER, IID_IMFTransform, (void**)&resizer)))
+ break;
+
+ if (FAILED(MFCreateTopologyNode(MF_TOPOLOGY_TRANSFORM_NODE, &resizerNode)))
+ break;
+
+ if (FAILED(resizerNode->SetObject(resizer)))
+ break;
+
+ if (FAILED(topology->AddNode(resizerNode)))
+ break;
+
+ DWORD outputIndex = 0;
+ if (FAILED(node->GetInput(0, &inputNode, &outputIndex))) {
+ topology->RemoveNode(resizerNode);
+ break;
+ }
+
+ if (FAILED(inputNode->ConnectOutput(0, resizerNode, 0))) {
+ topology->RemoveNode(resizerNode);
+ break;
+ }
+
+ if (FAILED(resizerNode->ConnectOutput(0, node, 0))) {
+ inputNode->ConnectOutput(0, node, 0);
+ topology->RemoveNode(resizerNode);
+ break;
+ }
+
+ inserted = true;
+ break;
+ }
+
+ if (node)
+ node->Release();
+ if (object)
+ object->Release();
+ if (colorConv)
+ colorConv->Release();
+ if (resizer)
+ resizer->Release();
+ if (resizerNode)
+ resizerNode->Release();
+ if (inputNode)
+ inputNode->Release();
+
+ return inserted;
+}
+
+// This method inserts a color converter (CColorConvertDMO) in the topology,
+// typically to convert to RGB format.
+// Usually this converter is automatically inserted when the topology is resolved but
+// for some reason it fails to do so in some cases, we then do it ourselves.
+void MFPlayerSession::insertColorConverter(IMFTopology *topology, TOPOID outputNodeId)
+{
+ IMFCollection *outputNodes = 0;
+
+ if (FAILED(topology->GetOutputNodeCollection(&outputNodes)))
+ return;
+
+ DWORD elementCount = 0;
+ if (FAILED(outputNodes->GetElementCount(&elementCount)))
+ goto done;
+
+ for (DWORD n = 0; n < elementCount; n++) {
+ IUnknown *element = 0;
+ IMFTopologyNode *node = 0;
+ IMFTopologyNode *inputNode = 0;
+ IMFTopologyNode *mftNode = 0;
+ IMFTransform *converter = 0;
+
+ do {
+ if (FAILED(outputNodes->GetElement(n, &element)))
+ break;
+
+ if (FAILED(element->QueryInterface(IID_IMFTopologyNode, (void**)&node)))
+ break;
+
+ TOPOID id;
+ if (FAILED(node->GetTopoNodeID(&id)))
+ break;
+
+ if (id != outputNodeId)
+ break;
+
+ DWORD outputIndex = 0;
+ if (FAILED(node->GetInput(0, &inputNode, &outputIndex)))
+ break;
+
+ if (FAILED(MFCreateTopologyNode(MF_TOPOLOGY_TRANSFORM_NODE, &mftNode)))
+ break;
+
+ if (FAILED(CoCreateInstance(CLSID_CColorConvertDMO, NULL, CLSCTX_INPROC_SERVER, IID_IMFTransform, (void**)&converter)))
+ break;
+
+ if (FAILED(mftNode->SetObject(converter)))
+ break;
+
+ if (FAILED(topology->AddNode(mftNode)))
+ break;
+
+ if (FAILED(inputNode->ConnectOutput(0, mftNode, 0)))
+ break;
+
+ if (FAILED(mftNode->ConnectOutput(0, node, 0)))
+ break;
+
+ } while (false);
+
+ if (mftNode)
+ mftNode->Release();
+ if (inputNode)
+ inputNode->Release();
+ if (node)
+ node->Release();
+ if (element)
+ element->Release();
+ if (converter)
+ converter->Release();
+ }
+
+done:
+ if (outputNodes)
+ outputNodes->Release();
+}
+
void MFPlayerSession::stop(bool immediate)
{
#ifdef DEBUG_MEDIAFOUNDATION
@@ -1376,29 +1558,41 @@ void MFPlayerSession::commitRateChange(qreal rate, BOOL isThin)
// Negative <-> zero: Stopped
// Postive <-> zero: Paused or stopped
if ((rate > 0 && m_state.rate <= 0) || (rate < 0 && m_state.rate >= 0)) {
- // Transition to stopped.
if (cmdNow == CmdStart) {
// Get the current clock position. This will be the restart time.
m_presentationClock->GetCorrelatedTime(0, &hnsClockTime, &hnsSystemTime);
Q_ASSERT(hnsSystemTime != 0);
- // Stop and set the rate
- stop();
+ // We need to stop only when dealing with negative rates
+ if (rate >= 0 && m_state.rate >= 0)
+ pause();
+ else
+ stop();
- //Cache Request: Restart from stop.
- m_request.setCommand(CmdSeekResume);
+ // If we deal with negative rates, we stopped the session and consequently
+ // reset the position to zero. We then need to resume to the current position.
+ m_request.setCommand(rate < 0 || m_state.rate < 0 ? CmdSeekResume : CmdStart);
m_request.start = hnsClockTime / 10000;
} else if (cmdNow == CmdPause) {
- // The current state is paused.
- // For this rate change, the session must be stopped. However, the
- // session cannot transition back from stopped to paused.
- // Therefore, this rate transition is not supported while paused.
if (rate < 0 || m_state.rate < 0) {
+ // The current state is paused.
+ // For this rate change, the session must be stopped. However, the
+ // session cannot transition back from stopped to paused.
+ // Therefore, this rate transition is not supported while paused.
qWarning() << "Unable to change rate from positive to negative or vice versa in paused state";
return;
}
+
+ // This happens when resuming playback after scrubbing in pause mode.
+ // This transition requires the session to be paused. Even though our
+ // internal state is set to paused, the session might not be so we need
+ // to enforce it
+ if (rate > 0 && m_state.rate == 0) {
+ m_state.setCommand(CmdNone);
+ pause();
+ }
}
- } else if (rate == 0 && m_state.rate != 0) {
+ } else if (rate == 0 && m_state.rate > 0) {
if (cmdNow != CmdPause) {
// Transition to paused.
// This transisition requires the paused state.
@@ -1408,6 +1602,15 @@ void MFPlayerSession::commitRateChange(qreal rate, BOOL isThin)
// Request: Switch back to current state.
m_request.setCommand(cmdNow);
}
+ } else if (rate == 0 && m_state.rate < 0) {
+ // Changing rate from negative to zero requires to stop the session
+ m_presentationClock->GetCorrelatedTime(0, &hnsClockTime, &hnsSystemTime);
+
+ stop();
+
+ // Resumte to the current position (stop() will reset the position to 0)
+ m_request.setCommand(CmdSeekResume);
+ m_request.start = hnsClockTime / 10000;
}
// Set the rate.
@@ -1634,8 +1837,7 @@ void MFPlayerSession::handleSessionEvent(IMFMediaEvent *sessionEvent)
updatePendingCommands(CmdStart);
break;
case MESessionStarted:
- if (!m_scrubbing)
- updatePendingCommands(CmdStart);
+ 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)
@@ -1649,10 +1851,10 @@ void MFPlayerSession::handleSessionEvent(IMFMediaEvent *sessionEvent)
m_varStart.vt = VT_I8;
m_varStart.hVal.QuadPart = 0;
- //only change to loadedMedia when not loading a new media source
- if (m_status != QMediaPlayer::LoadingMedia) {
+ // Reset to Loaded status unless we are loading a new media
+ // or if the media is buffered (to avoid restarting the video surface)
+ if (m_status != QMediaPlayer::LoadingMedia && m_status != QMediaPlayer::BufferedMedia)
changeStatus(QMediaPlayer::LoadedMedia);
- }
}
updatePendingCommands(CmdStop);
break;
@@ -1795,15 +1997,7 @@ void MFPlayerSession::updatePendingCommands(Command command)
// The current pending command has completed.
if (m_pendingState == SeekPending && m_state.prevCmd == CmdPause) {
m_pendingState = NoPending;
- //if we have pending seek request,
- //then we just keep current state to paused and continue the seek request,
- //otherwise we will restore to pause state
- if (m_request.command == CmdSeek) {
- m_state.setCommand(CmdPause);
- } else {
- pause();
- return;
- }
+ m_state.setCommand(CmdPause);
}
m_pendingState = NoPending;
diff --git a/src/plugins/wmf/player/mfplayersession.h b/src/plugins/wmf/player/mfplayersession.h
index 21efbf6a7..e7f8dcffa 100644
--- a/src/plugins/wmf/player/mfplayersession.h
+++ b/src/plugins/wmf/player/mfplayersession.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Mobility Components.
@@ -231,6 +231,8 @@ private:
IMFTopologyNode *m_audioSampleGrabberNode;
IMFTopology *insertMFT(IMFTopology *topology, TOPOID outputNodeId);
+ bool insertResizer(IMFTopology *topology);
+ void insertColorConverter(IMFTopology *topology, TOPOID outputNodeId);
MFTransform *m_videoProbeMFT;
QList<MFVideoProbeControl*> m_videoProbes;
};
diff --git a/src/plugins/wmf/player/mfvideoprobecontrol.cpp b/src/plugins/wmf/player/mfvideoprobecontrol.cpp
index 3db169fba..85d5de1ec 100644
--- a/src/plugins/wmf/player/mfvideoprobecontrol.cpp
+++ b/src/plugins/wmf/player/mfvideoprobecontrol.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Toolkit.
diff --git a/src/plugins/wmf/player/mfvideoprobecontrol.h b/src/plugins/wmf/player/mfvideoprobecontrol.h
index 4980004bc..fa2f06dc2 100644
--- a/src/plugins/wmf/player/mfvideoprobecontrol.h
+++ b/src/plugins/wmf/player/mfvideoprobecontrol.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Toolkit.
diff --git a/src/plugins/wmf/player/mfvideorenderercontrol.cpp b/src/plugins/wmf/player/mfvideorenderercontrol.cpp
index 28fcb5b19..6baa3716e 100644
--- a/src/plugins/wmf/player/mfvideorenderercontrol.cpp
+++ b/src/plugins/wmf/player/mfvideorenderercontrol.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Mobility Components.
@@ -40,7 +40,10 @@
****************************************************************************/
#include "mfvideorenderercontrol.h"
-#include <mferror.h>
+#include "mfglobal.h"
+#ifdef QT_OPENGL_ES_2_ANGLE
+#include "evrcustompresenter.h"
+#endif
#include <qabstractvideosurface.h>
#include <qvideosurfaceformat.h>
#include <qtcore/qtimer.h>
@@ -114,67 +117,6 @@ namespace
MapMode m_mapMode;
};
- template<class T>
- class AsyncCallback : public IMFAsyncCallback
- {
- public:
- typedef HRESULT (T::*InvokeFn)(IMFAsyncResult *pAsyncResult);
-
- AsyncCallback(T *pParent, InvokeFn fn) : m_pParent(pParent), m_pInvokeFn(fn)
- {
- }
-
- // IUnknown
- STDMETHODIMP QueryInterface(REFIID iid, void** ppv)
- {
- if (!ppv)
- {
- return E_POINTER;
- }
- if (iid == __uuidof(IUnknown))
- {
- *ppv = static_cast<IUnknown*>(static_cast<IMFAsyncCallback*>(this));
- }
- else if (iid == __uuidof(IMFAsyncCallback))
- {
- *ppv = static_cast<IMFAsyncCallback*>(this);
- }
- else
- {
- *ppv = NULL;
- return E_NOINTERFACE;
- }
- AddRef();
- return S_OK;
- }
- STDMETHODIMP_(ULONG) AddRef()
- {
- // Delegate to parent class.
- return m_pParent->AddRef();
- }
- STDMETHODIMP_(ULONG) Release()
- {
- // Delegate to parent class.
- return m_pParent->Release();
- }
-
- // IMFAsyncCallback methods
- STDMETHODIMP GetParameters(DWORD*, DWORD*)
- {
- // Implementation of this method is optional.
- return E_NOTIMPL;
- }
-
- STDMETHODIMP Invoke(IMFAsyncResult* pAsyncResult)
- {
- return (m_pParent->*m_pInvokeFn)(pAsyncResult);
- }
-
- T *m_pParent;
- InvokeFn m_pInvokeFn;
- };
-
-
// Custom interface for handling IMFStreamSink::PlaceMarker calls asynchronously.
MIDL_INTERFACE("a3ff32de-1031-438a-8b47-82f8acda59b7")
IMarker : public IUnknown
@@ -2134,6 +2076,9 @@ MFVideoRendererControl::MFVideoRendererControl(QObject *parent)
, m_surface(0)
, m_currentActivate(0)
, m_callback(0)
+#ifdef QT_OPENGL_ES_2_ANGLE
+ , m_presenterActivate(0)
+#endif
{
}
@@ -2147,6 +2092,14 @@ void MFVideoRendererControl::clear()
if (m_surface)
m_surface->stop();
+#ifdef QT_OPENGL_ES_2_ANGLE
+ if (m_presenterActivate) {
+ m_presenterActivate->ShutdownObject();
+ m_presenterActivate->Release();
+ m_presenterActivate = NULL;
+ }
+#endif
+
if (m_currentActivate) {
m_currentActivate->ShutdownObject();
m_currentActivate->Release();
@@ -2174,12 +2127,22 @@ void MFVideoRendererControl::setSurface(QAbstractVideoSurface *surface)
connect(m_surface, SIGNAL(supportedFormatsChanged()), this, SLOT(supportedFormatsChanged()));
}
+#ifdef QT_OPENGL_ES_2_ANGLE
+ if (m_presenterActivate)
+ m_presenterActivate->setSurface(m_surface);
+ else
+#endif
if (m_currentActivate)
static_cast<VideoRendererActivate*>(m_currentActivate)->setSurface(m_surface);
}
void MFVideoRendererControl::customEvent(QEvent *event)
{
+#ifdef QT_OPENGL_ES_2_ANGLE
+ if (m_presenterActivate)
+ return;
+#endif
+
if (!m_currentActivate)
return;
@@ -2193,33 +2156,58 @@ void MFVideoRendererControl::customEvent(QEvent *event)
present();
return;
}
- QChildEvent *childEvent = dynamic_cast<QChildEvent*>(event);
- if (!childEvent) {
+ if (event->type() >= MediaStream::StartSurface) {
+ QChildEvent *childEvent = static_cast<QChildEvent*>(event);
+ static_cast<MediaStream*>(childEvent->child())->customEvent(event);
+ } else {
QObject::customEvent(event);
- return;
}
- static_cast<MediaStream*>(childEvent->child())->customEvent(event);
}
void MFVideoRendererControl::supportedFormatsChanged()
{
+#ifdef QT_OPENGL_ES_2_ANGLE
+ if (m_presenterActivate)
+ m_presenterActivate->supportedFormatsChanged();
+ else
+#endif
if (m_currentActivate)
static_cast<VideoRendererActivate*>(m_currentActivate)->supportedFormatsChanged();
}
void MFVideoRendererControl::present()
{
+#ifdef QT_OPENGL_ES_2_ANGLE
+ if (m_presenterActivate)
+ return;
+#endif
+
if (m_currentActivate)
static_cast<VideoRendererActivate*>(m_currentActivate)->present();
}
IMFActivate* MFVideoRendererControl::createActivate()
{
+ Q_ASSERT(m_surface);
+
clear();
+#ifdef QT_OPENGL_ES_2_ANGLE
+ // We can use the EVR with our custom presenter only if the surface supports OpenGL
+ // texture handles
+ if (!m_surface->supportedPixelFormats(QAbstractVideoBuffer::GLTextureHandle).isEmpty()) {
+ // Create the EVR media sink, but replace the presenter with our own
+ if (SUCCEEDED(MFCreateVideoRendererActivate(::GetShellWindow(), &m_currentActivate))) {
+ m_presenterActivate = new EVRCustomPresenterActivate;
+ m_currentActivate->SetUnknown(MF_ACTIVATE_CUSTOM_VIDEO_PRESENTER_ACTIVATE, m_presenterActivate);
+ }
+ }
+
+ if (!m_currentActivate)
+#endif
m_currentActivate = new VideoRendererActivate(this);
- if (m_surface)
- setSurface(m_surface);
+
+ setSurface(m_surface);
return m_currentActivate;
}
diff --git a/src/plugins/wmf/player/mfvideorenderercontrol.h b/src/plugins/wmf/player/mfvideorenderercontrol.h
index 0829e732d..d796ce36d 100644
--- a/src/plugins/wmf/player/mfvideorenderercontrol.h
+++ b/src/plugins/wmf/player/mfvideorenderercontrol.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Mobility Components.
@@ -46,6 +46,14 @@
#include <mfapi.h>
#include <mfidl.h>
+QT_BEGIN_NAMESPACE
+
+#ifdef QT_OPENGL_ES_2_ANGLE
+class EVRCustomPresenterActivate;
+#endif
+
+QT_END_NAMESPACE
+
QT_USE_NAMESPACE
class MFVideoRendererControl : public QVideoRendererControl
@@ -74,6 +82,10 @@ private:
QAbstractVideoSurface *m_surface;
IMFActivate *m_currentActivate;
IMFSampleGrabberSinkCallback *m_callback;
+
+#ifdef QT_OPENGL_ES_2_ANGLE
+ EVRCustomPresenterActivate *m_presenterActivate;
+#endif
};
#endif
diff --git a/src/plugins/wmf/player/player.pri b/src/plugins/wmf/player/player.pri
index ac8dc9f05..a72708b3f 100644
--- a/src/plugins/wmf/player/player.pri
+++ b/src/plugins/wmf/player/player.pri
@@ -24,7 +24,7 @@ SOURCES += \
$$PWD/mfaudioprobecontrol.cpp \
$$PWD/mfvideoprobecontrol.cpp
-!isEmpty(QT.widgets.name):!simulator {
+qtHaveModule(widgets):!simulator {
HEADERS += $$PWD/evr9videowindowcontrol.h
SOURCES += $$PWD/evr9videowindowcontrol.cpp
}