diff options
Diffstat (limited to 'src/plugins/directshow/player/directshowplayerservice.cpp')
-rw-r--r-- | src/plugins/directshow/player/directshowplayerservice.cpp | 93 |
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(¤tPosition); - m_position = currentPosition / qt_directShowTimeScale; + if (!m_dontCacheNextSeekResult) { + seeking->GetCurrentPosition(¤tPosition); + 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(¤tPosition); - m_position = currentPosition / qt_directShowTimeScale; + if (!m_dontCacheNextSeekResult) { + seeking->GetCurrentPosition(¤tPosition); + 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)) { |