summaryrefslogtreecommitdiffstats
path: root/src/plugins/mediaservices
diff options
context:
space:
mode:
authorAndrew den Exter <andrew.den-exter@nokia.com>2010-02-03 01:14:49 (GMT)
committerAndrew den Exter <andrew.den-exter@nokia.com>2010-02-03 01:14:49 (GMT)
commit25579113df82d0e665bb90831586b7510e52469e (patch)
tree950062c418e11aa33b58b3bdf10d32c86b774128 /src/plugins/mediaservices
parent5a43e96062f7bd82ff9deb57e065b757d784607d (diff)
downloadQt-25579113df82d0e665bb90831586b7510e52469e.zip
Qt-25579113df82d0e665bb90831586b7510e52469e.tar.gz
Qt-25579113df82d0e665bb90831586b7510e52469e.tar.bz2
Send an EC_COMPLETE event from the video surface filter on end of stream
Otherwise the filter graph won't stop itself as it hasn't received the event from all the output filters.
Diffstat (limited to 'src/plugins/mediaservices')
-rw-r--r--src/plugins/mediaservices/directshow/mediaplayer/directshowsamplescheduler.cpp22
-rw-r--r--src/plugins/mediaservices/directshow/mediaplayer/directshowsamplescheduler.h3
-rw-r--r--src/plugins/mediaservices/directshow/mediaplayer/videosurfacefilter.cpp27
3 files changed, 49 insertions, 3 deletions
diff --git a/src/plugins/mediaservices/directshow/mediaplayer/directshowsamplescheduler.cpp b/src/plugins/mediaservices/directshow/mediaplayer/directshowsamplescheduler.cpp
index 921330c..733080e 100644
--- a/src/plugins/mediaservices/directshow/mediaplayer/directshowsamplescheduler.cpp
+++ b/src/plugins/mediaservices/directshow/mediaplayer/directshowsamplescheduler.cpp
@@ -53,6 +53,7 @@ public:
: m_next(0)
, m_sample(sample)
, m_cookie(0)
+ , m_lastSample(false)
{
m_sample->AddRef();
}
@@ -75,10 +76,14 @@ public:
bool isReady(IReferenceClock *clock) const;
+ bool isLast() const { return m_lastSample; }
+ void setLast() { m_lastSample = true; }
+
private:
DirectShowTimedSample *m_next;
IMediaSample *m_sample;
DWORD_PTR m_cookie;
+ bool m_lastSample;
};
bool DirectShowTimedSample::schedule(
@@ -355,7 +360,7 @@ void DirectShowSampleScheduler::setClock(IReferenceClock *clock)
m_clock->AddRef();
}
-IMediaSample *DirectShowSampleScheduler::takeSample()
+IMediaSample *DirectShowSampleScheduler::takeSample(bool *eos)
{
QMutexLocker locker(&m_mutex);
@@ -364,6 +369,8 @@ IMediaSample *DirectShowSampleScheduler::takeSample()
sample->AddRef();
if (m_state == Running) {
+ *eos = m_head->isLast();
+
m_head = m_head->remove();
if (!m_head)
@@ -378,6 +385,19 @@ IMediaSample *DirectShowSampleScheduler::takeSample()
}
}
+bool DirectShowSampleScheduler::scheduleEndOfStream()
+{
+ QMutexLocker locker(&m_mutex);
+
+ if (m_tail) {
+ m_tail->setLast();
+
+ return true;
+ } else {
+ return false;
+ }
+}
+
bool DirectShowSampleScheduler::event(QEvent *event)
{
if (event->type() == QEvent::WinEventAct) {
diff --git a/src/plugins/mediaservices/directshow/mediaplayer/directshowsamplescheduler.h b/src/plugins/mediaservices/directshow/mediaplayer/directshowsamplescheduler.h
index 7af9112..007fa99 100644
--- a/src/plugins/mediaservices/directshow/mediaplayer/directshowsamplescheduler.h
+++ b/src/plugins/mediaservices/directshow/mediaplayer/directshowsamplescheduler.h
@@ -97,8 +97,9 @@ public:
void setClock(IReferenceClock *clock);
bool schedule(IMediaSample *sample);
+ bool scheduleEndOfStream();
- IMediaSample *takeSample();
+ IMediaSample *takeSample(bool *eos);
bool event(QEvent *event);
diff --git a/src/plugins/mediaservices/directshow/mediaplayer/videosurfacefilter.cpp b/src/plugins/mediaservices/directshow/mediaplayer/videosurfacefilter.cpp
index a5565f1..7b4aad5 100644
--- a/src/plugins/mediaservices/directshow/mediaplayer/videosurfacefilter.cpp
+++ b/src/plugins/mediaservices/directshow/mediaplayer/videosurfacefilter.cpp
@@ -42,6 +42,7 @@
#include "videosurfacefilter.h"
#include "directshoweventloop.h"
+#include "directshowglobal.h"
#include "directshowpinenum.h"
#include "mediasamplevideobuffer.h"
@@ -442,6 +443,18 @@ HRESULT VideoSurfaceFilter::QueryInternalConnections(IPin **apPin, ULONG *nPin)
HRESULT VideoSurfaceFilter::EndOfStream()
{
+ QMutexLocker locker(&m_mutex);
+
+ if (!m_sampleScheduler.scheduleEndOfStream()) {
+ if (IMediaEventSink *sink = com_cast<IMediaEventSink>(m_graph)) {
+ sink->Notify(
+ EC_COMPLETE,
+ S_OK,
+ reinterpret_cast<LONG_PTR>(static_cast<IBaseFilter *>(this)));
+ sink->Release();
+ }
+ }
+
return S_OK;
}
@@ -584,7 +597,9 @@ void VideoSurfaceFilter::supportedFormatsChanged()
void VideoSurfaceFilter::sampleReady()
{
- IMediaSample *sample = m_sampleScheduler.takeSample();
+ bool eos = false;
+
+ IMediaSample *sample = m_sampleScheduler.takeSample(&eos);
if (sample) {
m_surface->present(QVideoFrame(
@@ -593,6 +608,16 @@ void VideoSurfaceFilter::sampleReady()
m_surfaceFormat.pixelFormat()));
sample->Release();
+
+ if (eos) {
+ if (IMediaEventSink *sink = com_cast<IMediaEventSink>(m_graph)) {
+ sink->Notify(
+ EC_COMPLETE,
+ S_OK,
+ reinterpret_cast<LONG_PTR>(static_cast<IBaseFilter *>(this)));
+ sink->Release();
+ }
+ }
}
}