summaryrefslogtreecommitdiffstats
path: root/src/plugins/mediaservices/directshow/mediaplayer/directshowplayerservice.cpp
diff options
context:
space:
mode:
authorAndrew den Exter <andrew.den-exter@nokia.com>2010-02-08 07:50:42 (GMT)
committerAndrew den Exter <andrew.den-exter@nokia.com>2010-02-08 07:50:42 (GMT)
commitda727b5aadf64128de0eb39fc1ce26e587211272 (patch)
tree2c2334c8f2f55fe128c1655ba3aa979216b22681 /src/plugins/mediaservices/directshow/mediaplayer/directshowplayerservice.cpp
parent923af5cd17dcfa2038998addec44f70154b385d2 (diff)
downloadQt-da727b5aadf64128de0eb39fc1ce26e587211272.zip
Qt-da727b5aadf64128de0eb39fc1ce26e587211272.tar.gz
Qt-da727b5aadf64128de0eb39fc1ce26e587211272.tar.bz2
Fix stall in graph when removing video and audio outputs.
Must remove the decoder as well as the output otherwise the graph wont be able to resume because a disconnected decoder cant. And the graph must be stopped to connect a new output.
Diffstat (limited to 'src/plugins/mediaservices/directshow/mediaplayer/directshowplayerservice.cpp')
-rw-r--r--src/plugins/mediaservices/directshow/mediaplayer/directshowplayerservice.cpp107
1 files changed, 88 insertions, 19 deletions
diff --git a/src/plugins/mediaservices/directshow/mediaplayer/directshowplayerservice.cpp b/src/plugins/mediaservices/directshow/mediaplayer/directshowplayerservice.cpp
index fdbee81..3c0a43a 100644
--- a/src/plugins/mediaservices/directshow/mediaplayer/directshowplayerservice.cpp
+++ b/src/plugins/mediaservices/directshow/mediaplayer/directshowplayerservice.cpp
@@ -319,6 +319,13 @@ void DirectShowPlayerService::doSetStreamSource(QMutexLocker *locker)
void DirectShowPlayerService::doRender(QMutexLocker *locker)
{
+ m_pendingTasks |= m_executedTasks & (Play | Pause);
+
+ if (IMediaControl *control = com_cast<IMediaControl>(m_graph)) {
+ control->Stop();
+ control->Release();
+ }
+
if (m_pendingTasks & SetAudioOutput) {
m_graph->AddFilter(m_audioOutput, L"AudioOutput");
@@ -358,7 +365,7 @@ void DirectShowPlayerService::doRender(QMutexLocker *locker)
IPin *peer = 0;
if (pin->ConnectedTo(&peer) == S_OK) {
PIN_INFO peerInfo;
- if (peer->QueryPinInfo(&peerInfo) == S_OK)
+ if (SUCCEEDED(peer->QueryPinInfo(&peerInfo)))
filters.append(peerInfo.pFilter);
peer->Release();
} else {
@@ -374,13 +381,15 @@ void DirectShowPlayerService::doRender(QMutexLocker *locker)
}
}
}
+
+ pins->Release();
+
if (outputs == 0)
rendered = true;
}
filter->Release();
}
-
if (m_audioOutput && !isConnected(m_audioOutput, PINDIR_INPUT)) {
graph->RemoveFilter(m_audioOutput);
@@ -604,9 +613,6 @@ void DirectShowPlayerService::doPlay(QMutexLocker *locker)
control->Release();
- if (SUCCEEDED(hr))
- m_executedTasks |= Play;
-
if (SUCCEEDED(hr)) {
m_executedTasks |= Play;
@@ -851,14 +857,14 @@ void DirectShowPlayerService::setAudioOutput(IBaseFilter *filter)
m_audioOutput->AddRef();
m_pendingTasks |= SetAudioOutput;
- } else {
- m_pendingTasks &= ~ SetAudioOutput;
- }
- if (m_executedTasks & SetSource) {
- m_pendingTasks |= Render;
+ if (m_executedTasks & SetSource) {
+ m_pendingTasks |= Render;
- ::SetEvent(m_taskHandle);
+ ::SetEvent(m_taskHandle);
+ }
+ } else {
+ m_pendingTasks &= ~ SetAudioOutput;
}
} else {
if (m_audioOutput)
@@ -882,7 +888,20 @@ void DirectShowPlayerService::doReleaseAudioOutput(QMutexLocker *locker)
control->Release();
}
- m_graph->RemoveFilter(m_audioOutput);
+ IBaseFilter *decoder = getConnected(m_audioOutput, PINDIR_INPUT);
+ if (!decoder) {
+ decoder = m_audioOutput;
+ decoder->AddRef();
+ }
+
+ if (IFilterChain *chain = com_cast<IFilterChain>(m_graph)) {
+ chain->RemoveChain(decoder, m_audioOutput);
+ chain->Release();
+ } else {
+ m_graph->RemoveFilter(m_audioOutput);
+ }
+
+ decoder->Release();
m_executedTasks &= ~SetAudioOutput;
@@ -911,14 +930,12 @@ void DirectShowPlayerService::setVideoOutput(IBaseFilter *filter)
m_videoOutput->AddRef();
m_pendingTasks |= SetVideoOutput;
- } else {
- m_pendingTasks &= ~ SetVideoOutput;
- }
- if (m_executedTasks & SetSource) {
- m_pendingTasks |= Render;
+ if (m_executedTasks & SetSource) {
+ m_pendingTasks |= Render;
- ::SetEvent(m_taskHandle);
+ ::SetEvent(m_taskHandle);
+ }
}
} else {
if (m_videoOutput)
@@ -940,7 +957,27 @@ void DirectShowPlayerService::doReleaseVideoOutput(QMutexLocker *locker)
control->Release();
}
- m_graph->RemoveFilter(m_videoOutput);
+ IBaseFilter *intermediate = 0;
+ if (!SUCCEEDED(m_graph->FindFilterByName(L"Color Space Converter", &intermediate))) {
+ intermediate = m_videoOutput;
+ intermediate->AddRef();
+ }
+
+ IBaseFilter *decoder = getConnected(intermediate, PINDIR_INPUT);
+ if (!decoder) {
+ decoder = intermediate;
+ decoder->AddRef();
+ }
+
+ if (IFilterChain *chain = com_cast<IFilterChain>(m_graph)) {
+ chain->RemoveChain(decoder, m_videoOutput);
+ chain->Release();
+ } else {
+ m_graph->RemoveFilter(m_videoOutput);
+ }
+
+ intermediate->Release();
+ decoder->Release();
m_executedTasks &= ~SetVideoOutput;
@@ -1109,6 +1146,38 @@ bool DirectShowPlayerService::isConnected(IBaseFilter *filter, PIN_DIRECTION dir
return connected;
}
+IBaseFilter *DirectShowPlayerService::getConnected(
+ IBaseFilter *filter, PIN_DIRECTION direction) const
+{
+ IBaseFilter *connected = 0;
+
+ IEnumPins *pins = 0;
+
+ if (SUCCEEDED(filter->EnumPins(&pins))) {
+ for (IPin *pin = 0; pins->Next(1, &pin, 0) == S_OK; pin->Release()) {
+ PIN_DIRECTION dir;
+ if (SUCCEEDED(pin->QueryDirection(&dir)) && dir == direction) {
+ IPin *peer = 0;
+ if (SUCCEEDED(pin->ConnectedTo(&peer))) {
+ PIN_INFO info;
+
+ if (SUCCEEDED(peer->QueryPinInfo(&info))) {
+ if (connected) {
+ qWarning("DirectShowPlayerService::getConnected: "
+ "Multiple connected filters");
+ connected->Release();
+ }
+ connected = info.pFilter;
+ }
+ peer->Release();
+ }
+ }
+ }
+ pins->Release();
+ }
+ return connected;
+}
+
void DirectShowPlayerService::run()
{
QMutexLocker locker(&m_mutex);