summaryrefslogtreecommitdiff
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.cpp94
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)) {