summaryrefslogtreecommitdiffstats
path: root/src/plugins/directshow/player
diff options
context:
space:
mode:
authorVal Doroshchuk <valentyn.doroshchuk@qt.io>2018-11-28 16:03:46 +0100
committerVaL Doroshchuk <valentyn.doroshchuk@qt.io>2019-01-15 08:46:37 +0000
commit94921e0fd8b9904e7472ae9546fa82e3eca55407 (patch)
treea3c2166e35aaa1588584af15d4794a73cc73a1d6 /src/plugins/directshow/player
parent4eb0a083cbadca2d24d2382e159864b2980e425f (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.cpp69
-rw-r--r--src/plugins/directshow/player/directshowplayerservice.h1
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;