summaryrefslogtreecommitdiffstats
path: root/src/plugins/directshow/player/directshowplayerservice.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/directshow/player/directshowplayerservice.cpp')
-rw-r--r--src/plugins/directshow/player/directshowplayerservice.cpp93
1 files changed, 58 insertions, 35 deletions
diff --git a/src/plugins/directshow/player/directshowplayerservice.cpp b/src/plugins/directshow/player/directshowplayerservice.cpp
index 67aea6e9a..8e9e50cbf 100644
--- a/src/plugins/directshow/player/directshowplayerservice.cpp
+++ b/src/plugins/directshow/player/directshowplayerservice.cpp
@@ -38,8 +38,10 @@
#include "directshowmetadatacontrol.h"
#include "directshowplayercontrol.h"
#include "directshowvideorenderercontrol.h"
-#if defined(HAVE_WIDGETS) && !defined(Q_WS_SIMULATOR)
#include "vmr9videowindowcontrol.h"
+
+#ifdef HAVE_EVR
+#include "directshowevrvideowindowcontrol.h"
#endif
#ifndef QT_NO_WMSDK
@@ -79,9 +81,7 @@ DirectShowPlayerService::DirectShowPlayerService(QObject *parent)
, m_playerControl(0)
, m_metaDataControl(0)
, m_videoRendererControl(0)
-#if defined(HAVE_WIDGETS) && !defined(Q_WS_SIMULATOR)
, m_videoWindowControl(0)
-#endif
, m_audioEndpointControl(0)
, m_taskThread(0)
, m_loop(qt_directShowEventLoop())
@@ -98,10 +98,12 @@ DirectShowPlayerService::DirectShowPlayerService(QObject *parent)
, m_videoOutput(0)
, m_rate(1.0)
, m_position(0)
+ , m_seekPosition(-1)
, m_duration(0)
, m_buffering(false)
, m_seekable(false)
, m_atEnd(false)
+ , m_dontCacheNextSeekResult(false)
{
m_playerControl = new DirectShowPlayerControl(this);
m_metaDataControl = new DirectShowMetaDataControl(this);
@@ -139,9 +141,7 @@ DirectShowPlayerService::~DirectShowPlayerService()
delete m_audioEndpointControl;
delete m_metaDataControl;
delete m_videoRendererControl;
-#if defined(HAVE_WIDGETS) && !defined(Q_WS_SIMULATOR)
delete m_videoWindowControl;
-#endif
::CloseHandle(m_taskHandle);
}
@@ -155,11 +155,7 @@ QMediaControl *DirectShowPlayerService::requestControl(const char *name)
} else if (qstrcmp(name, QMetaDataReaderControl_iid) == 0) {
return m_metaDataControl;
} else if (qstrcmp(name, QVideoRendererControl_iid) == 0) {
-#if defined(HAVE_WIDGETS) && !defined(Q_WS_SIMULATOR)
if (!m_videoRendererControl && !m_videoWindowControl) {
-#else
- if (!m_videoRendererControl) {
-#endif
m_videoRendererControl = new DirectShowVideoRendererControl(m_loop);
connect(m_videoRendererControl, SIGNAL(filterChanged()),
@@ -167,16 +163,28 @@ QMediaControl *DirectShowPlayerService::requestControl(const char *name)
return m_videoRendererControl;
}
-#if defined(HAVE_WIDGETS) && !defined(Q_WS_SIMULATOR)
} else if (qstrcmp(name, QVideoWindowControl_iid) == 0) {
if (!m_videoRendererControl && !m_videoWindowControl) {
- m_videoWindowControl = new Vmr9VideoWindowControl;
+ IBaseFilter *filter;
- setVideoOutput(m_videoWindowControl->filter());
+#ifdef HAVE_EVR
+ DirectShowEvrVideoWindowControl *evrControl = new DirectShowEvrVideoWindowControl;
+ if ((filter = evrControl->filter()))
+ m_videoWindowControl = evrControl;
+ else
+ delete evrControl;
+#endif
+ // Fall back to the VMR9 if the EVR is not available
+ if (!m_videoWindowControl) {
+ Vmr9VideoWindowControl *vmr9Control = new Vmr9VideoWindowControl;
+ filter = vmr9Control->filter();
+ m_videoWindowControl = vmr9Control;
+ }
+
+ setVideoOutput(filter);
return m_videoWindowControl;
}
-#endif
}
return 0;
}
@@ -192,14 +200,12 @@ void DirectShowPlayerService::releaseControl(QMediaControl *control)
delete m_videoRendererControl;
m_videoRendererControl = 0;
-#if defined(HAVE_WIDGETS) && !defined(Q_WS_SIMULATOR)
} else if (control == m_videoWindowControl) {
setVideoOutput(0);
delete m_videoWindowControl;
m_videoWindowControl = 0;
-#endif
}
}
@@ -217,13 +223,15 @@ void DirectShowPlayerService::load(const QMediaContent &media, QIODevice *stream
m_error = QMediaPlayer::NoError;
m_errorString = QString();
m_position = 0;
+ m_seekPosition = -1;
m_duration = 0;
m_streamTypes = 0;
m_executedTasks = 0;
m_buffering = false;
m_seekable = false;
m_atEnd = false;
- m_metaDataControl->updateGraph(0, 0);
+ m_dontCacheNextSeekResult = false;
+ m_metaDataControl->reset();
if (m_resources.isEmpty() && !stream) {
m_pendingTasks = 0;
@@ -273,8 +281,7 @@ void DirectShowPlayerService::doSetUrlSource(QMutexLocker *locker)
static const GUID iid_IFileSourceFilter = {
0x56a868a6, 0x0ad4, 0x11ce, {0xb0, 0x3a, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70} };
- if (IFileSourceFilter *fileSource = com_new<IFileSourceFilter>(
- clsid_WMAsfReader, iid_IFileSourceFilter)) {
+ if (IFileSourceFilter *fileSource = com_new<IFileSourceFilter>(clsid_WMAsfReader, iid_IFileSourceFilter)) {
locker->unlock();
hr = fileSource->Load(reinterpret_cast<const OLECHAR *>(m_url.toString().utf16()), 0);
@@ -322,6 +329,7 @@ void DirectShowPlayerService::doSetUrlSource(QMutexLocker *locker)
m_error = QMediaPlayer::FormatError;
m_errorString = QString();
break;
+ case E_FAIL:
case E_OUTOFMEMORY:
case VFW_E_CANNOT_LOAD_SOURCE_FILTER:
case VFW_E_NOT_FOUND:
@@ -562,9 +570,6 @@ void DirectShowPlayerService::doReleaseGraph(QMutexLocker *locker)
control->Release();
}
- //release m_headerInfo -> decrease ref counter of m_source
- m_metaDataControl->updateGraph(0, 0);
-
if (m_source) {
m_source->Release();
m_source = 0;
@@ -665,8 +670,12 @@ void DirectShowPlayerService::play()
if (m_executedTasks & Render) {
if (m_executedTasks & Stop) {
m_atEnd = false;
- m_position = 0;
- m_pendingTasks |= Seek;
+ if (m_seekPosition == -1) {
+ m_dontCacheNextSeekResult = true;
+ m_seekPosition = 0;
+ m_position = 0;
+ m_pendingTasks |= Seek;
+ }
m_executedTasks ^= Stop;
}
@@ -709,8 +718,12 @@ void DirectShowPlayerService::pause()
if (m_executedTasks & Render) {
if (m_executedTasks & Stop) {
m_atEnd = false;
- m_position = 0;
- m_pendingTasks |= Seek;
+ if (m_seekPosition == -1) {
+ m_dontCacheNextSeekResult = true;
+ m_seekPosition = 0;
+ m_position = 0;
+ m_pendingTasks |= Seek;
+ }
m_executedTasks ^= Stop;
}
@@ -780,7 +793,9 @@ void DirectShowPlayerService::doStop(QMutexLocker *locker)
control->Release();
}
+ m_seekPosition = 0;
m_position = 0;
+ m_dontCacheNextSeekResult = true;
m_pendingTasks |= Seek;
m_executedTasks &= ~(Play | Pause);
@@ -884,7 +899,7 @@ void DirectShowPlayerService::seek(qint64 position)
{
QMutexLocker locker(&m_mutex);
- m_position = position;
+ m_seekPosition = position;
m_pendingTasks |= Seek;
@@ -894,14 +909,19 @@ void DirectShowPlayerService::seek(qint64 position)
void DirectShowPlayerService::doSeek(QMutexLocker *locker)
{
+ if (m_seekPosition == -1)
+ return;
+
if (IMediaSeeking *seeking = com_cast<IMediaSeeking>(m_graph, IID_IMediaSeeking)) {
- LONGLONG seekPosition = LONGLONG(m_position) * qt_directShowTimeScale;
+ LONGLONG seekPosition = LONGLONG(m_seekPosition) * qt_directShowTimeScale;
// Cache current values as we can't query IMediaSeeking during a seek due to the
// possibility of a deadlock when flushing the VideoSurfaceFilter.
LONGLONG currentPosition = 0;
- seeking->GetCurrentPosition(&currentPosition);
- m_position = currentPosition / qt_directShowTimeScale;
+ if (!m_dontCacheNextSeekResult) {
+ seeking->GetCurrentPosition(&currentPosition);
+ m_position = currentPosition / qt_directShowTimeScale;
+ }
LONGLONG minimum = 0;
LONGLONG maximum = 0;
@@ -915,15 +935,18 @@ void DirectShowPlayerService::doSeek(QMutexLocker *locker)
&seekPosition, AM_SEEKING_AbsolutePositioning, 0, AM_SEEKING_NoPositioning);
locker->relock();
- seeking->GetCurrentPosition(&currentPosition);
- m_position = currentPosition / qt_directShowTimeScale;
+ if (!m_dontCacheNextSeekResult) {
+ seeking->GetCurrentPosition(&currentPosition);
+ m_position = currentPosition / qt_directShowTimeScale;
+ }
seeking->Release();
- } else {
- m_position = 0;
+
+ QCoreApplication::postEvent(this, new QEvent(QEvent::Type(PositionChange)));
}
- QCoreApplication::postEvent(this, new QEvent(QEvent::Type(PositionChange)));
+ m_seekPosition = -1;
+ m_dontCacheNextSeekResult = false;
}
int DirectShowPlayerService::bufferStatus() const
@@ -1112,7 +1135,7 @@ void DirectShowPlayerService::customEvent(QEvent *event)
QMutexLocker locker(&m_mutex);
m_playerControl->updateMediaInfo(m_duration, m_streamTypes, m_seekable);
- m_metaDataControl->updateGraph(m_graph, m_source, m_url.toString());
+ m_metaDataControl->updateMetadata(m_graph, m_source, m_url.toString());
updateStatus();
} else if (event->type() == QEvent::Type(Error)) {