diff options
author | Val Doroshchuk <valentyn.doroshchuk@qt.io> | 2018-11-28 16:03:46 +0100 |
---|---|---|
committer | VaL Doroshchuk <valentyn.doroshchuk@qt.io> | 2019-01-15 08:46:37 +0000 |
commit | 94921e0fd8b9904e7472ae9546fa82e3eca55407 (patch) | |
tree | a3c2166e35aaa1588584af15d4794a73cc73a1d6 /src/plugins/directshow/player | |
parent | 4eb0a083cbadca2d24d2382e159864b2980e425f (diff) |
DirectShow: Fix video and audio probes in media player
Added using ICaptureGraphBuilder2 to connect source filter and sample
grabber to probe video and audio buffers.
The capture graph builder can automatically add some intermediate filters as needed.
Video buffers are always requested in ARGB32 format.
Task-number: QTBUG-71819
Change-Id: I7382635758ba3bd76c8806cabd0895c67072be6c
Reviewed-by: Andy Shaw <andy.shaw@qt.io>
Reviewed-by: Maurice Kalinowski <maurice.kalinowski@qt.io>
Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
Diffstat (limited to 'src/plugins/directshow/player')
-rw-r--r-- | src/plugins/directshow/player/directshowplayerservice.cpp | 69 | ||||
-rw-r--r-- | src/plugins/directshow/player/directshowplayerservice.h | 1 |
2 files changed, 33 insertions, 37 deletions
diff --git a/src/plugins/directshow/player/directshowplayerservice.cpp b/src/plugins/directshow/player/directshowplayerservice.cpp index f6106724b..d48350fa2 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) @@ -326,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; @@ -673,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(); } @@ -683,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; } @@ -699,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; } @@ -764,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); diff --git a/src/plugins/directshow/player/directshowplayerservice.h b/src/plugins/directshow/player/directshowplayerservice.h index 729a189aa..a6eeb8a77 100644 --- a/src/plugins/directshow/player/directshowplayerservice.h +++ b/src/plugins/directshow/player/directshowplayerservice.h @@ -215,6 +215,7 @@ private: QMediaPlayer::Error m_error; QIODevice *m_stream; IFilterGraph2 *m_graph; + ICaptureGraphBuilder2 *m_graphBuilder; IBaseFilter *m_source; IBaseFilter *m_audioOutput; IBaseFilter *m_videoOutput; |