diff options
Diffstat (limited to 'src/plugins/wmf/player')
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 } |