diff options
author | Andrew den Exter <andrew.den-exter@nokia.com> | 2010-02-03 01:14:49 (GMT) |
---|---|---|
committer | Andrew den Exter <andrew.den-exter@nokia.com> | 2010-02-03 01:14:49 (GMT) |
commit | 25579113df82d0e665bb90831586b7510e52469e (patch) | |
tree | 950062c418e11aa33b58b3bdf10d32c86b774128 /src/plugins/mediaservices | |
parent | 5a43e96062f7bd82ff9deb57e065b757d784607d (diff) | |
download | Qt-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')
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(); + } + } } } |