diff options
Diffstat (limited to 'src/plugins/directshow/player/directshowplayerservice.cpp')
-rw-r--r-- | src/plugins/directshow/player/directshowplayerservice.cpp | 94 |
1 files changed, 46 insertions, 48 deletions
diff --git a/src/plugins/directshow/player/directshowplayerservice.cpp b/src/plugins/directshow/player/directshowplayerservice.cpp index 3974c59a5..3f7346227 100644 --- a/src/plugins/directshow/player/directshowplayerservice.cpp +++ b/src/plugins/directshow/player/directshowplayerservice.cpp @@ -142,6 +142,7 @@ DirectShowPlayerService::DirectShowPlayerService(QObject *parent) , m_graphStatus(NoMedia) , m_stream(0) , m_graph(0) + , m_graphBuilder(nullptr) , m_source(0) , m_audioOutput(0) , m_videoOutput(0) @@ -297,7 +298,7 @@ void DirectShowPlayerService::load(const QMediaContent &media, QIODevice *stream if (m_graph) releaseGraph(); - m_resources = media.resources(); + m_url = media.canonicalUrl(); m_stream = stream; m_error = QMediaPlayer::NoError; m_errorString = QString(); @@ -310,13 +311,11 @@ void DirectShowPlayerService::load(const QMediaContent &media, QIODevice *stream m_seekable = false; m_atEnd = false; m_dontCacheNextSeekResult = false; - m_metaDataControl->reset(); + m_metaDataControl->setMetadata(QVariantMap()); - if (m_resources.isEmpty() && !stream) { + if (m_url.isEmpty() && !stream) { m_pendingTasks = 0; m_graphStatus = NoMedia; - - m_url.clear(); } else if (stream && (!stream->isReadable() || stream->isSequential())) { m_pendingTasks = 0; m_graphStatus = InvalidMedia; @@ -328,6 +327,15 @@ void DirectShowPlayerService::load(const QMediaContent &media, QIODevice *stream m_graphStatus = Loading; m_graph = com_new<IFilterGraph2>(CLSID_FilterGraph, iid_IFilterGraph2); + m_graphBuilder = com_new<ICaptureGraphBuilder2>(CLSID_CaptureGraphBuilder2, IID_ICaptureGraphBuilder2); + + // Attach the filter graph to the capture graph. + HRESULT hr = m_graphBuilder->SetFiltergraph(m_graph); + if (FAILED(hr)) { + qCWarning(qtDirectShowPlugin, "[0x%x] Failed to attach filter to capture graph", hr); + m_graphBuilder->Release(); + m_graphBuilder = nullptr; + } if (stream) m_pendingTasks = SetStreamSource; @@ -348,9 +356,6 @@ void DirectShowPlayerService::doSetUrlSource(QMutexLocker *locker) { IBaseFilter *source = 0; - QMediaResource resource = m_resources.takeFirst(); - m_url = resource.url(); - HRESULT hr = E_FAIL; if (m_url.scheme() == QLatin1String("http") || m_url.scheme() == QLatin1String("https")) { static const GUID clsid_WMAsfReader = { @@ -403,7 +408,7 @@ void DirectShowPlayerService::doSetUrlSource(QMutexLocker *locker) m_pendingTasks |= SetRate; m_source = source; - } else if (!m_resources.isEmpty()) { + } else if (!m_url.isEmpty()) { m_pendingTasks |= SetUrlSource; } else { m_graphStatus = InvalidMedia; @@ -596,7 +601,6 @@ void DirectShowPlayerService::doRender(QMutexLocker *locker) void DirectShowPlayerService::doFinalizeLoad(QMutexLocker *locker) { - Q_UNUSED(locker) if (m_graphStatus != Loaded) { if (IMediaEvent *event = com_cast<IMediaEvent>(m_graph, IID_IMediaEvent)) { event->GetEventHandle(reinterpret_cast<OAEVENT *>(&m_eventHandle)); @@ -625,6 +629,11 @@ void DirectShowPlayerService::doFinalizeLoad(QMutexLocker *locker) m_graphStatus = Loaded; + // Do not block gui thread while updating metadata from file. + locker->unlock(); + DirectShowMetaDataControl::updateMetadata(m_url.toString(), m_metadata); + locker->relock(); + QCoreApplication::postEvent(this, new QEvent(QEvent::Type(FinalizedLoad))); } @@ -674,6 +683,11 @@ void DirectShowPlayerService::doReleaseGraph(QMutexLocker *locker) m_graph->Release(); m_graph = 0; + if (m_graphBuilder) { + m_graphBuilder->Release(); + m_graphBuilder = nullptr; + } + m_loop->wake(); } @@ -684,7 +698,7 @@ void DirectShowPlayerService::doSetVideoProbe(QMutexLocker *locker) { Q_UNUSED(locker); - if (!m_graph) { + if (!m_graph || !m_graphBuilder) { qCWarning(qtDirectShowPlugin, "Attempting to set a video probe without a valid graph!"); return; } @@ -700,41 +714,14 @@ void DirectShowPlayerService::doSetVideoProbe(QMutexLocker *locker) return; } - // TODO: Make util function for getting this, so it's easy to keep it in sync. - static const GUID subtypes[] = { MEDIASUBTYPE_ARGB32, - MEDIASUBTYPE_RGB32, - MEDIASUBTYPE_RGB24, - MEDIASUBTYPE_RGB565, - MEDIASUBTYPE_RGB555, - MEDIASUBTYPE_AYUV, - MEDIASUBTYPE_I420, - MEDIASUBTYPE_IYUV, - MEDIASUBTYPE_YV12, - MEDIASUBTYPE_UYVY, - MEDIASUBTYPE_YUYV, - MEDIASUBTYPE_YUY2, - MEDIASUBTYPE_NV12, - MEDIASUBTYPE_MJPG, - MEDIASUBTYPE_IMC1, - MEDIASUBTYPE_IMC2, - MEDIASUBTYPE_IMC3, - MEDIASUBTYPE_IMC4 }; - - // Negotiate the subtype - DirectShowMediaType mediaType(AM_MEDIA_TYPE { MEDIATYPE_Video }); - const int items = (sizeof subtypes / sizeof(GUID)); - bool connected = false; - for (int i = 0; i != items; ++i) { - mediaType->subtype = subtypes[i]; - m_videoSampleGrabber->setMediaType(&mediaType); - if (DirectShowUtils::connectFilters(m_graph, m_source, m_videoSampleGrabber->filter(), true)) { - connected = true; - break; - } - } + DirectShowMediaType mediaType({ MEDIATYPE_Video, MEDIASUBTYPE_ARGB32 }); + m_videoSampleGrabber->setMediaType(&mediaType); - if (!connected) { - qCWarning(qtDirectShowPlugin, "Unable to connect the video probe!"); + // Connect source filter to sample grabber filter. + HRESULT hr = m_graphBuilder->RenderStream(nullptr, &MEDIATYPE_Video, + m_source, nullptr, m_videoSampleGrabber->filter()); + if (FAILED(hr)) { + qCWarning(qtDirectShowPlugin, "[0x%x] Failed to connect the video sample grabber", hr); return; } @@ -765,8 +752,15 @@ void DirectShowPlayerService::doSetAudioProbe(QMutexLocker *locker) } if (!DirectShowUtils::connectFilters(m_graph, m_source, m_audioSampleGrabber->filter(), true)) { - qCWarning(qtDirectShowPlugin, "Failed to connect the audio sample grabber"); - return; + // Connect source filter to sample grabber filter. + HRESULT hr = m_graphBuilder + ? m_graphBuilder->RenderStream(nullptr, &MEDIATYPE_Audio, + m_source, nullptr, m_audioSampleGrabber->filter()) + : E_FAIL; + if (FAILED(hr)) { + qCWarning(qtDirectShowPlugin, "[0x%x] Failed to connect the audio sample grabber", hr); + return; + } } m_audioSampleGrabber->start(DirectShowSampleGrabber::CallbackMethod::BufferCB); @@ -1407,7 +1401,11 @@ void DirectShowPlayerService::customEvent(QEvent *event) QMutexLocker locker(&m_mutex); m_playerControl->updateMediaInfo(m_duration, m_streamTypes, m_seekable); - m_metaDataControl->updateMetadata(m_graph, m_source, m_url.toString()); + if (m_metadata.isEmpty()) + DirectShowMetaDataControl::updateMetadata(m_graph, m_source, m_metadata); + + m_metaDataControl->setMetadata(m_metadata); + m_metadata.clear(); updateStatus(); } else if (event->type() == QEvent::Type(Error)) { |