diff options
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(); + } + } } } |