summaryrefslogtreecommitdiffstats
path: root/src/plugins/wmf/player
diff options
context:
space:
mode:
authorChristian Strømme <christian.stromme@theqtcompany.com>2016-01-15 17:27:32 +0100
committerChristian Strømme <christian.stromme@theqtcompany.com>2016-01-15 17:28:17 +0100
commit84e426c3af2a3bb1b7f916e54263aea758db38d0 (patch)
tree4fe09a8da5b15ba466e5771239d06f29a6c123da /src/plugins/wmf/player
parent84aaa48fdfc1f35c9870518a3d4b6f08a1f99449 (diff)
parent924dc7f48c7003b46079623738ae531f34aed903 (diff)
Merge remote-tracking branch 'origin/5.6' into dev
Conflicts: src/plugins/android/src/mediacapture/qandroidcamerasession.cpp src/plugins/wmf/mftvideo.cpp Change-Id: I78868b416ea4baec89ca3e2dc9eb4712db16d5fc
Diffstat (limited to 'src/plugins/wmf/player')
-rw-r--r--src/plugins/wmf/player/mfplayersession.cpp181
-rw-r--r--src/plugins/wmf/player/mfplayersession.h3
-rw-r--r--src/plugins/wmf/player/mfvideorenderercontrol.cpp111
-rw-r--r--src/plugins/wmf/player/mfvideorenderercontrol.h6
4 files changed, 174 insertions, 127 deletions
diff --git a/src/plugins/wmf/player/mfplayersession.cpp b/src/plugins/wmf/player/mfplayersession.cpp
index e4c498b76..0ac1c3d66 100644
--- a/src/plugins/wmf/player/mfplayersession.cpp
+++ b/src/plugins/wmf/player/mfplayersession.cpp
@@ -266,6 +266,25 @@ void MFPlayerSession::handleMediaSourceReady()
}
}
+MFPlayerSession::MediaType MFPlayerSession::getStreamType(IMFStreamDescriptor *stream) const
+{
+ if (!stream)
+ return Unknown;
+
+ IMFMediaTypeHandler *typeHandler = NULL;
+ if (SUCCEEDED(stream->GetMediaTypeHandler(&typeHandler))) {
+ GUID guidMajorType;
+ if (SUCCEEDED(typeHandler->GetMajorType(&guidMajorType))) {
+ if (guidMajorType == MFMediaType_Audio)
+ return Audio;
+ else if (guidMajorType == MFMediaType_Video)
+ return Video;
+ }
+ }
+
+ return Unknown;
+}
+
void MFPlayerSession::setupPlaybackTopology(IMFMediaSource *source, IMFPresentationDescriptor *sourcePD)
{
HRESULT hr = S_OK;
@@ -294,45 +313,58 @@ void MFPlayerSession::setupPlaybackTopology(IMFMediaSource *source, IMFPresentat
for (DWORD i = 0; i < cSourceStreams; i++)
{
BOOL fSelected = FALSE;
+ bool streamAdded = false;
IMFStreamDescriptor *streamDesc = NULL;
HRESULT hr = sourcePD->GetStreamDescriptorByIndex(i, &fSelected, &streamDesc);
if (SUCCEEDED(hr)) {
- MediaType mediaType = Unknown;
- IMFTopologyNode *sourceNode = addSourceNode(topology, source, sourcePD, streamDesc);
- if (sourceNode) {
- IMFTopologyNode *outputNode = addOutputNode(streamDesc, mediaType, topology, 0);
- if (outputNode) {
- bool connected = false;
- if (mediaType == Audio) {
- if (!m_audioSampleGrabberNode)
- connected = setupAudioSampleGrabber(topology, sourceNode, outputNode);
- } else if (mediaType == Video && outputNodeId == -1) {
- // Remember video output node ID.
- outputNode->GetTopoNodeID(&outputNodeId);
- }
+ // The media might have multiple audio and video streams,
+ // only use one of each kind, and only if it is selected by default.
+ MediaType mediaType = getStreamType(streamDesc);
+ if (mediaType != Unknown
+ && ((m_mediaTypes & mediaType) == 0) // Check if this type isn't already added
+ && fSelected) {
+
+ IMFTopologyNode *sourceNode = addSourceNode(topology, source, sourcePD, streamDesc);
+ if (sourceNode) {
+ IMFTopologyNode *outputNode = addOutputNode(mediaType, topology, 0);
+ if (outputNode) {
+ bool connected = false;
+ if (mediaType == Audio) {
+ if (!m_audioSampleGrabberNode)
+ connected = setupAudioSampleGrabber(topology, sourceNode, outputNode);
+ } else if (mediaType == Video && outputNodeId == -1) {
+ // Remember video output node ID.
+ outputNode->GetTopoNodeID(&outputNodeId);
+ }
- if (!connected)
- hr = sourceNode->ConnectOutput(0, outputNode, 0);
- if (FAILED(hr)) {
- emit error(QMediaPlayer::FormatError, tr("Unable to play any stream."), false);
- }
- else {
- succeededCount++;
- m_mediaTypes |= mediaType;
- switch (mediaType) {
- case Audio:
- emit audioAvailable();
- break;
- case Video:
- emit videoAvailable();
- break;
+ if (!connected)
+ hr = sourceNode->ConnectOutput(0, outputNode, 0);
+
+ if (FAILED(hr)) {
+ emit error(QMediaPlayer::FormatError, tr("Unable to play any stream."), false);
+ } else {
+ streamAdded = true;
+ succeededCount++;
+ m_mediaTypes |= mediaType;
+ switch (mediaType) {
+ case Audio:
+ emit audioAvailable();
+ break;
+ case Video:
+ emit videoAvailable();
+ break;
+ }
}
+ outputNode->Release();
}
- outputNode->Release();
+ sourceNode->Release();
}
- sourceNode->Release();
}
+
+ if (fSelected && !streamAdded)
+ sourcePD->DeselectStream(i);
+
streamDesc->Release();
}
}
@@ -377,56 +409,38 @@ IMFTopologyNode* MFPlayerSession::addSourceNode(IMFTopology* topology, IMFMediaS
return NULL;
}
-IMFTopologyNode* MFPlayerSession::addOutputNode(IMFStreamDescriptor *streamDesc, MediaType& mediaType, IMFTopology* topology, DWORD sinkID)
+IMFTopologyNode* MFPlayerSession::addOutputNode(MediaType mediaType, IMFTopology* topology, DWORD sinkID)
{
IMFTopologyNode *node = NULL;
- HRESULT hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &node);
- if (FAILED(hr))
+ if (FAILED(MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &node)))
return NULL;
- node->SetUINT32(MF_TOPONODE_NOSHUTDOWN_ON_REMOVE, FALSE);
- mediaType = Unknown;
- IMFMediaTypeHandler *handler = NULL;
- hr = streamDesc->GetMediaTypeHandler(&handler);
- if (SUCCEEDED(hr)) {
- GUID guidMajorType;
- hr = handler->GetMajorType(&guidMajorType);
- if (SUCCEEDED(hr)) {
- IMFActivate *activate = NULL;
- if (MFMediaType_Audio == guidMajorType) {
- mediaType = Audio;
- activate = m_playerService->audioEndpointControl()->createActivate();
- } else if (MFMediaType_Video == guidMajorType) {
- mediaType = Video;
- if (m_playerService->videoRendererControl()) {
- activate = m_playerService->videoRendererControl()->createActivate();
- } else if (m_playerService->videoWindowControl()) {
- activate = m_playerService->videoWindowControl()->createActivate();
- } else {
- qWarning() << "no videoWindowControl or videoRendererControl, unable to add output node for video data";
- }
- } else {
- // Unknown stream type.
- emit error(QMediaPlayer::FormatError, tr("Unknown stream type."), false);
- }
-
- if (activate) {
- hr = node->SetObject(activate);
- if (SUCCEEDED(hr)) {
- hr = node->SetUINT32(MF_TOPONODE_STREAMID, sinkID);
- if (SUCCEEDED(hr)) {
- if (SUCCEEDED(topology->AddNode(node))) {
- handler->Release();
- return node;
- }
- }
- }
- }
+ IMFActivate *activate = NULL;
+ if (mediaType == Audio) {
+ activate = m_playerService->audioEndpointControl()->createActivate();
+ } else if (mediaType == Video) {
+ if (m_playerService->videoRendererControl()) {
+ activate = m_playerService->videoRendererControl()->createActivate();
+ } else if (m_playerService->videoWindowControl()) {
+ activate = m_playerService->videoWindowControl()->createActivate();
+ } else {
+ qWarning() << "no videoWindowControl or videoRendererControl, unable to add output node for video data";
}
- handler->Release();
+ } else {
+ // Unknown stream type.
+ emit error(QMediaPlayer::FormatError, tr("Unknown stream type."), false);
}
- node->Release();
- return NULL;
+
+ if (!activate
+ || FAILED(node->SetObject(activate))
+ || FAILED(node->SetUINT32(MF_TOPONODE_STREAMID, sinkID))
+ || FAILED(node->SetUINT32(MF_TOPONODE_NOSHUTDOWN_ON_REMOVE, FALSE))
+ || FAILED(topology->AddNode(node))) {
+ node->Release();
+ node = NULL;
+ }
+
+ return node;
}
bool MFPlayerSession::addAudioSampleGrabberNode(IMFTopology *topology)
@@ -692,7 +706,6 @@ IMFTopology *MFPlayerSession::insertMFT(IMFTopology *topology, TOPOID outputNode
IUnknown *element = 0;
IMFTopologyNode *node = 0;
IUnknown *outputObject = 0;
- IMFMediaTypeHandler *videoSink = 0;
IMFTopologyNode *inputNode = 0;
IMFTopologyNode *mftNode = 0;
bool mftAdded = false;
@@ -711,22 +724,10 @@ IMFTopology *MFPlayerSession::insertMFT(IMFTopology *topology, TOPOID outputNode
if (id != outputNodeId)
break;
- // Use output supported media types for the MFT
if (FAILED(node->GetObject(&outputObject)))
break;
- if (FAILED(outputObject->QueryInterface(IID_IMFMediaTypeHandler, (void**)&videoSink)))
- break;
-
- DWORD mtCount;
- if (FAILED(videoSink->GetMediaTypeCount(&mtCount)))
- break;
-
- for (DWORD i = 0; i < mtCount; ++i) {
- IMFMediaType *type = 0;
- if (SUCCEEDED(videoSink->GetMediaTypeByIndex(i, &type)))
- m_videoProbeMFT->addSupportedMediaType(type);
- }
+ m_videoProbeMFT->setVideoSink(outputObject);
// Insert MFT between the output node and the node connected to it.
DWORD outputIndex = 0;
@@ -760,13 +761,13 @@ IMFTopology *MFPlayerSession::insertMFT(IMFTopology *topology, TOPOID outputNode
node->Release();
if (element)
element->Release();
- if (videoSink)
- videoSink->Release();
if (outputObject)
outputObject->Release();
if (mftAdded)
break;
+ else
+ m_videoProbeMFT->setVideoSink(NULL);
}
} while (false);
diff --git a/src/plugins/wmf/player/mfplayersession.h b/src/plugins/wmf/player/mfplayersession.h
index 1d136ba55..5bbf8e212 100644
--- a/src/plugins/wmf/player/mfplayersession.h
+++ b/src/plugins/wmf/player/mfplayersession.h
@@ -215,9 +215,10 @@ private:
void createSession();
void setupPlaybackTopology(IMFMediaSource *source, IMFPresentationDescriptor *sourcePD);
+ MediaType getStreamType(IMFStreamDescriptor *stream) const;
IMFTopologyNode* addSourceNode(IMFTopology* topology, IMFMediaSource* source,
IMFPresentationDescriptor* presentationDesc, IMFStreamDescriptor *streamDesc);
- IMFTopologyNode* addOutputNode(IMFStreamDescriptor *streamDesc, MediaType& mediaType, IMFTopology* topology, DWORD sinkID);
+ IMFTopologyNode* addOutputNode(MediaType mediaType, IMFTopology* topology, DWORD sinkID);
bool addAudioSampleGrabberNode(IMFTopology* topology);
bool setupAudioSampleGrabber(IMFTopology *topology, IMFTopologyNode *sourceNode, IMFTopologyNode *outputNode);
diff --git a/src/plugins/wmf/player/mfvideorenderercontrol.cpp b/src/plugins/wmf/player/mfvideorenderercontrol.cpp
index 683dd4b71..222d74ef2 100644
--- a/src/plugins/wmf/player/mfvideorenderercontrol.cpp
+++ b/src/plugins/wmf/player/mfvideorenderercontrol.cpp
@@ -32,15 +32,9 @@
****************************************************************************/
#include "mfvideorenderercontrol.h"
-#include "mfglobal.h"
+#include "mfactivate.h"
-#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)
-#define MAYBE_ANGLE
-#endif
-
-#ifdef MAYBE_ANGLE
#include "evrcustompresenter.h"
-#endif
#include <qabstractvideosurface.h>
#include <qvideosurfaceformat.h>
@@ -2226,6 +2220,27 @@ namespace
};
}
+
+class EVRCustomPresenterActivate : public MFAbstractActivate
+{
+public:
+ EVRCustomPresenterActivate();
+ ~EVRCustomPresenterActivate()
+ { }
+
+ STDMETHODIMP ActivateObject(REFIID riid, void **ppv);
+ STDMETHODIMP ShutdownObject();
+ STDMETHODIMP DetachObject();
+
+ void setSurface(QAbstractVideoSurface *surface);
+
+private:
+ EVRCustomPresenter *m_presenter;
+ QAbstractVideoSurface *m_surface;
+ QMutex m_mutex;
+};
+
+
MFVideoRendererControl::MFVideoRendererControl(QObject *parent)
: QVideoRendererControl(parent)
, m_surface(0)
@@ -2245,13 +2260,11 @@ void MFVideoRendererControl::clear()
if (m_surface)
m_surface->stop();
-#ifdef MAYBE_ANGLE
if (m_presenterActivate) {
m_presenterActivate->ShutdownObject();
m_presenterActivate->Release();
m_presenterActivate = NULL;
}
-#endif
if (m_currentActivate) {
m_currentActivate->ShutdownObject();
@@ -2280,12 +2293,9 @@ void MFVideoRendererControl::setSurface(QAbstractVideoSurface *surface)
connect(m_surface, SIGNAL(supportedFormatsChanged()), this, SLOT(supportedFormatsChanged()));
}
-#ifdef MAYBE_ANGLE
if (m_presenterActivate)
m_presenterActivate->setSurface(m_surface);
- else
-#endif
- if (m_currentActivate)
+ else if (m_currentActivate)
static_cast<VideoRendererActivate*>(m_currentActivate)->setSurface(m_surface);
}
@@ -2323,11 +2333,9 @@ void MFVideoRendererControl::customEvent(QEvent *event)
void MFVideoRendererControl::supportedFormatsChanged()
{
-#ifdef MAYBE_ANGLE
if (m_presenterActivate)
- m_presenterActivate->supportedFormatsChanged();
- else
-#endif
+ return;
+
if (m_currentActivate)
static_cast<VideoRendererActivate*>(m_currentActivate)->supportedFormatsChanged();
}
@@ -2347,26 +2355,67 @@ IMFActivate* MFVideoRendererControl::createActivate()
clear();
-#ifdef MAYBE_ANGLE
- // We can use the EVR with our custom presenter only if the surface supports OpenGL
- // texture handles. We also require ANGLE (due to the D3D interop).
- if (!m_surface->supportedPixelFormats(QAbstractVideoBuffer::GLTextureHandle).isEmpty()
- && QMediaOpenGLHelper::isANGLE()) {
- // 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);
- }
- }
-#endif
-
- if (!m_currentActivate)
+ // 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);
+ } else {
m_currentActivate = new VideoRendererActivate(this);
+ }
setSurface(m_surface);
return m_currentActivate;
}
+
+EVRCustomPresenterActivate::EVRCustomPresenterActivate()
+ : MFAbstractActivate()
+ , m_presenter(0)
+ , m_surface(0)
+{ }
+
+HRESULT EVRCustomPresenterActivate::ActivateObject(REFIID riid, void **ppv)
+{
+ if (!ppv)
+ return E_INVALIDARG;
+ QMutexLocker locker(&m_mutex);
+ if (!m_presenter) {
+ m_presenter = new EVRCustomPresenter;
+ if (m_surface)
+ m_presenter->setSurface(m_surface);
+ }
+ return m_presenter->QueryInterface(riid, ppv);
+}
+
+HRESULT EVRCustomPresenterActivate::ShutdownObject()
+{
+ // The presenter does not implement IMFShutdown so
+ // this function is the same as DetachObject()
+ return DetachObject();
+}
+
+HRESULT EVRCustomPresenterActivate::DetachObject()
+{
+ QMutexLocker locker(&m_mutex);
+ if (m_presenter) {
+ m_presenter->Release();
+ m_presenter = 0;
+ }
+ return S_OK;
+}
+
+void EVRCustomPresenterActivate::setSurface(QAbstractVideoSurface *surface)
+{
+ QMutexLocker locker(&m_mutex);
+ if (m_surface == surface)
+ return;
+
+ m_surface = surface;
+
+ if (m_presenter)
+ m_presenter->setSurface(surface);
+}
+
#include "moc_mfvideorenderercontrol.cpp"
#include "mfvideorenderercontrol.moc"
diff --git a/src/plugins/wmf/player/mfvideorenderercontrol.h b/src/plugins/wmf/player/mfvideorenderercontrol.h
index ca3b95d10..224fcea51 100644
--- a/src/plugins/wmf/player/mfvideorenderercontrol.h
+++ b/src/plugins/wmf/player/mfvideorenderercontrol.h
@@ -38,14 +38,10 @@
#include <mfapi.h>
#include <mfidl.h>
-QT_BEGIN_NAMESPACE
+QT_USE_NAMESPACE
class EVRCustomPresenterActivate;
-QT_END_NAMESPACE
-
-QT_USE_NAMESPACE
-
class MFVideoRendererControl : public QVideoRendererControl
{
Q_OBJECT