summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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();
+ }
+ }
}
}