summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew den Exter <andrew.den-exter@nokia.com>2010-02-03 01:18:17 (GMT)
committerAndrew den Exter <andrew.den-exter@nokia.com>2010-02-03 01:18:17 (GMT)
commitb136d5a9c2dbb83199d61de2ce88f801637434bb (patch)
treeaee01398362026ee7f023bce04ef8a3b4458507d
parent25579113df82d0e665bb90831586b7510e52469e (diff)
downloadQt-b136d5a9c2dbb83199d61de2ce88f801637434bb.zip
Qt-b136d5a9c2dbb83199d61de2ce88f801637434bb.tar.gz
Qt-b136d5a9c2dbb83199d61de2ce88f801637434bb.tar.bz2
Handle graph events in the service thread rather than the gui thread.
This makes the service thread responsible for the last of the graph manipulation and state update tasks.
-rw-r--r--src/plugins/mediaservices/directshow/mediaplayer/directshowplayerservice.cpp382
-rw-r--r--src/plugins/mediaservices/directshow/mediaplayer/directshowplayerservice.h52
2 files changed, 201 insertions, 233 deletions
diff --git a/src/plugins/mediaservices/directshow/mediaplayer/directshowplayerservice.cpp b/src/plugins/mediaservices/directshow/mediaplayer/directshowplayerservice.cpp
index ea4b73c..d205ac1 100644
--- a/src/plugins/mediaservices/directshow/mediaplayer/directshowplayerservice.cpp
+++ b/src/plugins/mediaservices/directshow/mediaplayer/directshowplayerservice.cpp
@@ -88,6 +88,8 @@ DirectShowPlayerService::DirectShowPlayerService(QObject *parent)
, m_pendingTasks(0)
, m_executingTask(0)
, m_executedTasks(0)
+ , m_taskHandle(::CreateEvent(0, 0, 0, 0))
+ , m_eventHandle(0)
, m_graphStatus(NoMedia)
, m_stream(0)
, m_graph(0)
@@ -99,6 +101,7 @@ DirectShowPlayerService::DirectShowPlayerService(QObject *parent)
, m_duration(0)
, m_buffering(false)
, m_seekable(false)
+ , m_atEnd(false)
{
m_playerControl = new DirectShowPlayerControl(this);
m_metaDataControl = new DirectShowMetaDataControl(this);
@@ -112,8 +115,6 @@ DirectShowPlayerService::DirectShowPlayerService(QObject *parent)
connect(m_videoOutputControl, SIGNAL(outputChanged()), this, SLOT(videoOutputChanged()));
connect(m_videoRendererControl, SIGNAL(filterChanged()), this, SLOT(videoOutputChanged()));
-
- connect(&m_graphEventNotifier, SIGNAL(activated(HANDLE)), this, SLOT(graphEvent(HANDLE)));
}
DirectShowPlayerService::~DirectShowPlayerService()
@@ -121,43 +122,15 @@ DirectShowPlayerService::~DirectShowPlayerService()
{
QMutexLocker locker(&m_mutex);
- m_pendingTasks = Shutdown;
-
- if (m_graph) {
- m_graphEventNotifier.setEnabled(false);
-
- if (IAMOpenProgress *progress = com_cast<IAMOpenProgress>(m_graph)) {
- progress->AbortOperation();
- progress->Release();
- }
-
- m_graph->Abort();
+ releaseGraph();
- if (IMediaControl *control = com_cast<IMediaControl>(m_graph)) {
- control->Stop();
- OAFilterState state;
- control->GetState(INFINITE, &state);
- control->Release();
- }
- }
- m_wait.wakeAll();
-
- m_loop.wait(&m_mutex);
+ m_pendingTasks = Shutdown;
+ ::SetEvent(m_taskHandle);
}
m_taskThread->wait();
delete m_taskThread;
- if (m_graph) {
- m_graph->Release();
- m_graph = 0;
- }
-
- if (m_source) {
- m_source->Release();
- m_source = 0;
- }
-
if (m_audioOutput) {
m_audioOutput->Release();
m_audioOutput = 0;
@@ -174,6 +147,8 @@ DirectShowPlayerService::~DirectShowPlayerService()
delete m_videoOutputControl;
delete m_videoRendererControl;
delete m_videoWindowControl;
+
+ ::CloseHandle(m_taskHandle);
}
QMediaControl *DirectShowPlayerService::control(const char *name) const
@@ -198,34 +173,10 @@ void DirectShowPlayerService::load(const QMediaContent &media, QIODevice *stream
{
QMutexLocker locker(&m_mutex);
- if (m_graph) {
- m_graphEventNotifier.setEnabled(false);
-
- if (m_executingTask != 0) {
- if (IAMOpenProgress *progress = com_cast<IAMOpenProgress>(m_graph)) {
- progress->AbortOperation();
- progress->Release();
- } else {
- m_graph->Abort();
- }
-
- m_pendingTasks = Stop;
+ m_pendingTasks = 0;
- m_loop.wait(&m_mutex);
- }
- if (IMediaControl *control = com_cast<IMediaControl>(m_graph)) {
- control->Stop();
- control->Release();
- }
-
- if (m_source) {
- m_source->Release();
- m_source = 0;
- }
-
- m_graph->Release();
- m_graph = 0;
- }
+ if (m_graph)
+ releaseGraph();
m_resources = media.resources();
m_stream = stream;
@@ -234,6 +185,7 @@ void DirectShowPlayerService::load(const QMediaContent &media, QIODevice *stream
m_executedTasks = 0;
m_buffering = false;
m_seekable = false;
+ m_atEnd = false;
m_metaDataControl->updateGraph(0, 0);
if (m_resources.isEmpty() && !stream) {
@@ -246,21 +198,12 @@ void DirectShowPlayerService::load(const QMediaContent &media, QIODevice *stream
m_graph = com_new<IFilterGraph2>(CLSID_FilterGraph);
- if (IMediaEventEx *event = com_cast<IMediaEventEx>(m_graph)) {
- HANDLE handle;
- if (event->GetEventHandle(reinterpret_cast<OAEVENT *>(&handle)) == S_OK) {
- m_graphEventNotifier.setHandle(handle);
- m_graphEventNotifier.setEnabled(true);
- }
- event->Release();
- }
-
if (stream)
m_pendingTasks = SetStreamSource;
else
m_pendingTasks = SetUrlSource;
- m_wait.wakeAll();
+ ::SetEvent(m_taskHandle);
}
m_playerControl->updateMediaInfo(m_duration, m_streamTypes, m_seekable);
@@ -399,7 +342,7 @@ void DirectShowPlayerService::doRender(QMutexLocker *locker)
IBaseFilter *filter = filters[filters.size() - 1];
filters.removeLast();
- if (m_executingTask == Render && SUCCEEDED(filter->EnumPins(&pins))) {
+ if (!(m_pendingTasks & ReleaseFilters) && SUCCEEDED(filter->EnumPins(&pins))) {
int outputs = 0;
for (IPin *pin = 0; pins->Next(1, &pin, 0) == S_OK; pin->Release()) {
PIN_DIRECTION direction;
@@ -446,7 +389,7 @@ void DirectShowPlayerService::doRender(QMutexLocker *locker)
graph->Release();
- if (m_executingTask == Render) {
+ if (!(m_pendingTasks & ReleaseFilters)) {
if (rendered) {
if (!(m_executedTasks & FinalizeLoad))
m_pendingTasks |= FinalizeLoad;
@@ -475,13 +418,15 @@ void DirectShowPlayerService::doRender(QMutexLocker *locker)
m_executedTasks |= Render;
}
-
- m_loop.wake();
}
void DirectShowPlayerService::doFinalizeLoad(QMutexLocker *locker)
{
if (m_graphStatus != Loaded) {
+ if (IMediaEvent *event = com_cast<IMediaEvent>(m_graph)) {
+ event->GetEventHandle(reinterpret_cast<OAEVENT *>(&m_eventHandle));
+ event->Release();
+ }
if (IMediaSeeking *seeking = com_cast<IMediaSeeking>(m_graph)) {
LONGLONG duration = 0;
seeking->GetDuration(&duration);
@@ -508,22 +453,45 @@ void DirectShowPlayerService::doFinalizeLoad(QMutexLocker *locker)
QCoreApplication::postEvent(this, new QEvent(QEvent::Type(FinalizedLoad)));
}
-
-void DirectShowPlayerService::doUpdateDuration(QMutexLocker *)
+void DirectShowPlayerService::releaseGraph()
{
- if (IMediaSeeking *seeking = com_cast<IMediaSeeking>(m_graph)) {
- LONGLONG duration = 0;
- seeking->GetDuration(&duration);
- m_duration = duration / 10;
+ if (m_graph) {
+ if (m_executingTask != 0) {
+ if (IAMOpenProgress *progress = com_cast<IAMOpenProgress>(m_graph)) {
+ progress->AbortOperation();
+ progress->Release();
+ }
+ m_graph->Abort();
+ }
+
+ m_pendingTasks = ReleaseGraph;
- DWORD capabilities = 0;
- seeking->GetCapabilities(&capabilities);
- m_seekable = capabilities & AM_SEEKING_CanSeekAbsolute;
+ ::SetEvent(m_taskHandle);
- seeking->Release();
+ m_loop.wait(&m_mutex);
+ }
+}
- QCoreApplication::postEvent(this, new QEvent(QEvent::Type(DurationChange)));
+void DirectShowPlayerService::doReleaseGraph(QMutexLocker *locker)
+{
+ Q_UNUSED(locker);
+
+ if (IMediaControl *control = com_cast<IMediaControl>(m_graph)) {
+ control->Stop();
+ control->Release();
}
+
+ if (m_source) {
+ m_source->Release();
+ m_source = 0;
+ }
+
+ m_eventHandle = 0;
+
+ m_graph->Release();
+ m_graph = 0;
+
+ m_loop.wake();
}
int DirectShowPlayerService::findStreamTypes(IBaseFilter *source) const
@@ -611,12 +579,13 @@ void DirectShowPlayerService::play()
if (m_executedTasks & Render) {
if (m_executedTasks & Stop) {
+ m_atEnd = false;
m_position = 0;
m_pendingTasks |= Seek;
m_executedTasks ^= Stop;
}
- m_wait.wakeAll();
+ ::SetEvent(m_taskHandle);
}
}
@@ -635,7 +604,7 @@ void DirectShowPlayerService::doPlay(QMutexLocker *locker)
if (SUCCEEDED(hr)) {
m_executedTasks |= Play;
- QCoreApplication::postEvent(this, new QEvent(QEvent::Type(Started)));
+ QCoreApplication::postEvent(this, new QEvent(QEvent::Type(StatusChange)));
} else {
m_error = QMediaPlayer::ResourceError;
qWarning("DirectShowPlayerService::doPlay: Unresolved error code %x", hr);
@@ -654,12 +623,13 @@ void DirectShowPlayerService::pause()
if (m_executedTasks & Render) {
if (m_executedTasks & Stop) {
+ m_atEnd = false;
m_position = 0;
m_pendingTasks |= Seek;
m_executedTasks ^= Stop;
}
- m_wait.wakeAll();
+ ::SetEvent(m_taskHandle);
}
}
@@ -675,7 +645,7 @@ void DirectShowPlayerService::doPause(QMutexLocker *locker)
if (SUCCEEDED(hr)) {
m_executedTasks |= Pause;
- QCoreApplication::postEvent(this, new QEvent(QEvent::Type(Paused)));
+ QCoreApplication::postEvent(this, new QEvent(QEvent::Type(StatusChange)));
} else {
m_error = QMediaPlayer::ResourceError;
qWarning("DirectShowPlayerService::doPause: Unresolved error code %x", hr);
@@ -719,7 +689,7 @@ void DirectShowPlayerService::setRate(qreal rate)
m_pendingTasks |= SetRate;
if (m_executedTasks & FinalizeLoad)
- m_wait.wakeAll();
+ ::SetEvent(m_taskHandle);
}
void DirectShowPlayerService::doSetRate(QMutexLocker *locker)
@@ -804,7 +774,7 @@ void DirectShowPlayerService::seek(qint64 position)
m_pendingTasks |= Seek;
if (m_executedTasks & FinalizeLoad)
- m_wait.wakeAll();
+ ::SetEvent(m_taskHandle);
}
void DirectShowPlayerService::doSeek(QMutexLocker *locker)
@@ -856,9 +826,11 @@ void DirectShowPlayerService::setAudioOutput(IBaseFilter *filter)
if (m_graph) {
if (m_audioOutput) {
if (m_executedTasks & SetAudioOutput) {
- removeOutput(m_audioOutput);
+ m_pendingTasks |= ReleaseAudioOutput;
- m_executedTasks &= ~SetAudioOutput;
+ ::SetEvent(m_taskHandle);
+
+ m_loop.wait(&m_mutex);
}
m_audioOutput->Release();
}
@@ -876,7 +848,7 @@ void DirectShowPlayerService::setAudioOutput(IBaseFilter *filter)
if (m_executedTasks & SetSource) {
m_pendingTasks |= Render;
- m_wait.wakeAll();
+ ::SetEvent(m_taskHandle);
}
} else {
if (m_audioOutput)
@@ -891,6 +863,22 @@ void DirectShowPlayerService::setAudioOutput(IBaseFilter *filter)
m_playerControl->updateAudioOutput(m_audioOutput);
}
+void DirectShowPlayerService::doReleaseAudioOutput(QMutexLocker *locker)
+{
+ m_pendingTasks |= m_executedTasks & (Play | Pause);
+
+ if (IMediaControl *control = com_cast<IMediaControl>(m_graph)) {
+ control->Stop();
+ control->Release();
+ }
+
+ m_graph->RemoveFilter(m_audioOutput);
+
+ m_executedTasks &= ~SetAudioOutput;
+
+ m_loop.wake();
+}
+
void DirectShowPlayerService::setVideoOutput(IBaseFilter *filter)
{
QMutexLocker locker(&m_mutex);
@@ -898,9 +886,11 @@ void DirectShowPlayerService::setVideoOutput(IBaseFilter *filter)
if (m_graph) {
if (m_videoOutput) {
if (m_executedTasks & SetVideoOutput) {
- removeOutput(m_videoOutput);
+ m_pendingTasks |= ReleaseVideoOutput;
- m_executedTasks &= ~SetVideoOutput;
+ ::SetEvent(m_taskHandle);
+
+ m_loop.wait(&m_mutex);
}
m_videoOutput->Release();
}
@@ -918,7 +908,7 @@ void DirectShowPlayerService::setVideoOutput(IBaseFilter *filter)
if (m_executedTasks & SetSource) {
m_pendingTasks |= Render;
- m_wait.wakeAll();
+ ::SetEvent(m_taskHandle);
}
} else {
if (m_videoOutput)
@@ -931,11 +921,25 @@ void DirectShowPlayerService::setVideoOutput(IBaseFilter *filter)
}
}
+void DirectShowPlayerService::doReleaseVideoOutput(QMutexLocker *locker)
+{
+ m_pendingTasks |= m_executedTasks & (Play | Pause);
+
+ if (IMediaControl *control = com_cast<IMediaControl>(m_graph)) {
+ control->Stop();
+ control->Release();
+ }
+
+ m_graph->RemoveFilter(m_videoOutput);
+
+ m_executedTasks &= ~SetVideoOutput;
+
+ m_loop.wake();
+}
+
void DirectShowPlayerService::customEvent(QEvent *event)
{
if (event->type() == QEvent::Type(FinalizedLoad)) {
- event->accept();
-
QMutexLocker locker(&m_mutex);
m_playerControl->updateMediaInfo(m_duration, m_streamTypes, m_seekable);
@@ -943,8 +947,6 @@ void DirectShowPlayerService::customEvent(QEvent *event)
updateStatus();
} else if (event->type() == QEvent::Type(Error)) {
- event->accept();
-
QMediaPlayer::Error error;
{
QMutexLocker locker(&m_mutex);
@@ -958,23 +960,24 @@ void DirectShowPlayerService::customEvent(QEvent *event)
}
m_playerControl->error(error, QString());
} else if (event->type() == QEvent::Type(RateChange)) {
- event->accept();
-
QMutexLocker locker(&m_mutex);
m_playerControl->updatePlaybackRate(m_rate);
- } else if (event->type() == QEvent::Type(Started) || event->type() == QEvent::Type(Paused)) {
- event->accept();
-
+ } else if (event->type() == QEvent::Type(StatusChange)) {
QMutexLocker locker(&m_mutex);
updateStatus();
} else if (event->type() == QEvent::Type(DurationChange)) {
- event->accept();
-
QMutexLocker locker(&m_mutex);
m_playerControl->updateMediaInfo(m_duration, m_streamTypes, m_seekable);
+ } else if (event->type() == QEvent::Type(EndOfMedia)) {
+ QMutexLocker locker(&m_mutex);
+
+ if (m_atEnd) {
+ m_playerControl->updateState(QMediaPlayer::StoppedState);
+ m_playerControl->updateStatus(QMediaPlayer::EndOfMedia);
+ }
} else {
QMediaService::customEvent(event);
}
@@ -998,7 +1001,7 @@ void DirectShowPlayerService::videoOutputChanged()
setVideoOutput(videoOutput);
}
-void DirectShowPlayerService::graphEvent(HANDLE handle)
+void DirectShowPlayerService::graphEvent(QMutexLocker *locker)
{
if (IMediaEvent *event = com_cast<IMediaEvent>(m_graph)) {
long eventCode;
@@ -1008,32 +1011,32 @@ void DirectShowPlayerService::graphEvent(HANDLE handle)
while (event->GetEvent(&eventCode, &param1, &param2, 0) == S_OK) {
switch (eventCode) {
case EC_BUFFERING_DATA:
- {
- QMutexLocker locker(&m_mutex);
- m_buffering = param1;
+ m_buffering = param1;
- updateStatus();
- }
+ QCoreApplication::postEvent(this, new QEvent(QEvent::Type(StatusChange)));
break;
case EC_COMPLETE:
- {
- QMutexLocker locker(&m_mutex);
- m_executedTasks &= ~(Play | Pause);
- m_executedTasks |= Stop;
-
- m_buffering = false;
- m_playerControl->updateStatus(QMediaPlayer::EndOfMedia);
- m_playerControl->updateState(QMediaPlayer::StoppedState);
- }
+ m_executedTasks &= ~(Play | Pause);
+ m_executedTasks |= Stop;
+
+ m_buffering = false;
+ m_atEnd = true;
+
+ QCoreApplication::postEvent(this, new QEvent(QEvent::Type(EndOfMedia)));
break;
case EC_LENGTH_CHANGED:
- {
- QMutexLocker locker(&m_mutex);
- if (m_executedTasks & FinalizeLoad) {
- m_pendingTasks |= UpdateDuration;
+ if (IMediaSeeking *seeking = com_cast<IMediaSeeking>(m_graph)) {
+ LONGLONG duration = 0;
+ seeking->GetDuration(&duration);
+ m_duration = duration / 10;
- m_wait.wakeAll();
- }
+ DWORD capabilities = 0;
+ seeking->GetCapabilities(&capabilities);
+ m_seekable = capabilities & AM_SEEKING_CanSeekAbsolute;
+
+ seeking->Release();
+
+ QCoreApplication::postEvent(this, new QEvent(QEvent::Type(DurationChange)));
}
break;
default:
@@ -1073,76 +1076,6 @@ void DirectShowPlayerService::updateStatus()
}
}
-void DirectShowPlayerService::removeOutput(IBaseFilter *output)
-{
- while (m_executingTask != 0) {
- if (m_executingTask == Render) {
- m_executingTask = 0;
-
- if (IAMOpenProgress *progress = com_cast<IAMOpenProgress>(m_graph)) {
- progress->AbortOperation();
- progress->Release();
- }
- }
- m_loop.wait(&m_mutex);
- }
-
- m_pendingTasks |= m_executedTasks & (Play | Pause);
-
- if (IMediaControl *control = com_cast<IMediaControl>(m_graph)) {
- control->Stop();
- control->Release();
- }
-
- if (IFilterChain *chain = com_cast<IFilterChain>(m_graph)) {
- IBaseFilter *start = findChainStart(output);
-
- chain->RemoveChain(start, output);
-
- start->Release();
- chain->Release();
- } else {
- m_graph->RemoveFilter(output);
- }
-}
-
-IBaseFilter *DirectShowPlayerService::findChainStart(IBaseFilter *end) const
-{
- IBaseFilter *start = 0;
- end->AddRef();
-
- while (start != end) {
- start = end;
-
- IEnumPins *pins = 0;
-
- if (SUCCEEDED(end->EnumPins(&pins))) {
- for (IPin *pin = 0; pins->Next(1, &pin, 0) == S_OK; pin->Release()) {
- PIN_DIRECTION direction;
- if (SUCCEEDED(pin->QueryDirection(&direction)) && direction == PINDIR_INPUT) {
- IPin *peer = 0;
- if (SUCCEEDED(pin->ConnectedTo(&peer))) {
- PIN_INFO peerInfo;
- if (SUCCEEDED(peer->QueryPinInfo(&peerInfo))) {
- CLSID classId;
- if (SUCCEEDED(peerInfo.pFilter->GetClassID(&classId))
- && classId == CLSID_Colour) {
- end->Release();
- end = peerInfo.pFilter;
- } else {
- peerInfo.pFilter->Release();
- }
- }
- peer->Release();
- }
- }
- }
- pins->Release();
- }
- }
- return start;
-}
-
bool DirectShowPlayerService::isConnected(IBaseFilter *filter, PIN_DIRECTION direction) const
{
bool connected = false;
@@ -1170,8 +1103,45 @@ void DirectShowPlayerService::run()
{
QMutexLocker locker(&m_mutex);
- while (!(m_pendingTasks & Shutdown)) {
- if (m_pendingTasks & SetUrlSource) {
+ for (;;) {
+ ::ResetEvent(m_taskHandle);
+
+ while (m_pendingTasks == 0) {
+ DWORD result = 0;
+
+ locker.unlock();
+ if (m_eventHandle) {
+ HANDLE handles[] = { m_taskHandle, m_eventHandle };
+
+ result = ::WaitForMultipleObjects(2, handles, false, INFINITE);
+ } else {
+ result = ::WaitForSingleObject(m_taskHandle, INFINITE);
+ }
+ locker.relock();
+
+ if (result == WAIT_OBJECT_0 + 1) {
+ graphEvent(&locker);
+ }
+ }
+
+ if (m_pendingTasks & ReleaseGraph) {
+ m_pendingTasks ^= ReleaseGraph;
+ m_executingTask = ReleaseGraph;
+
+ doReleaseGraph(&locker);
+ } else if (m_pendingTasks & Shutdown) {
+ return;
+ } else if (m_pendingTasks & ReleaseAudioOutput) {
+ m_pendingTasks ^= ReleaseAudioOutput;
+ m_executingTask = ReleaseAudioOutput;
+
+ doReleaseAudioOutput(&locker);
+ } else if (m_pendingTasks & ReleaseVideoOutput) {
+ m_pendingTasks ^= ReleaseVideoOutput;
+ m_executingTask = ReleaseVideoOutput;
+
+ doReleaseVideoOutput(&locker);
+ } else if (m_pendingTasks & SetUrlSource) {
m_pendingTasks ^= SetUrlSource;
m_executingTask = SetUrlSource;
@@ -1193,11 +1163,6 @@ void DirectShowPlayerService::run()
m_executingTask = FinalizeLoad;
doFinalizeLoad(&locker);
- } else if (m_pendingTasks & UpdateDuration) {
- m_pendingTasks ^= UpdateDuration;
- m_executingTask ^= UpdateDuration;
-
- doUpdateDuration(&locker);
} else if (m_pendingTasks & SetRate) {
m_pendingTasks ^= SetRate;
m_executingTask = SetRate;
@@ -1224,12 +1189,7 @@ void DirectShowPlayerService::run()
doPlay(&locker);
}
m_executingTask = 0;
-
- if (m_pendingTasks == 0)
- m_wait.wait(&m_mutex);
}
-
- m_loop.wake();
}
QT_END_NAMESPACE
diff --git a/src/plugins/mediaservices/directshow/mediaplayer/directshowplayerservice.h b/src/plugins/mediaservices/directshow/mediaplayer/directshowplayerservice.h
index 3a01889..9ea5d7d 100644
--- a/src/plugins/mediaservices/directshow/mediaplayer/directshowplayerservice.h
+++ b/src/plugins/mediaservices/directshow/mediaplayer/directshowplayerservice.h
@@ -105,16 +105,14 @@ protected:
private Q_SLOTS:
void videoOutputChanged();
- void graphEvent(HANDLE handle);
private:
+ void releaseGraph();
void updateStatus();
int findStreamTypes(IBaseFilter *source) const;
int findStreamType(IPin *pin) const;
- void removeOutput(IBaseFilter *output);
- IBaseFilter *findChainStart(IBaseFilter *end) const;
bool isConnected(IBaseFilter *filter, PIN_DIRECTION direction) const;
void run();
@@ -127,25 +125,32 @@ private:
void doSeek(QMutexLocker *locker);
void doPlay(QMutexLocker *locker);
void doPause(QMutexLocker *locker);
- void doUpdateDuration(QMutexLocker *locker);
+ void doReleaseAudioOutput(QMutexLocker *locker);
+ void doReleaseVideoOutput(QMutexLocker *locker);
+ void doReleaseGraph(QMutexLocker *locker);
+
+ void graphEvent(QMutexLocker *locker);
enum Task
{
- Shutdown = 0x0001,
- SetUrlSource = 0x0002,
- SetStreamSource = 0x0004,
- SetSource = SetUrlSource | SetStreamSource,
- SetAudioOutput = 0x0008,
- SetVideoOutput = 0x0010,
- SetOutputs = SetAudioOutput | SetVideoOutput,
- Render = 0x0020,
- FinalizeLoad = 0x0040,
- SetRate = 0x0080,
- Seek = 0x0100,
- Play = 0x0200,
- Pause = 0x0400,
- Stop = 0x0800,
- UpdateDuration = 0x1000
+ Shutdown = 0x0001,
+ SetUrlSource = 0x0002,
+ SetStreamSource = 0x0004,
+ SetSource = SetUrlSource | SetStreamSource,
+ SetAudioOutput = 0x0008,
+ SetVideoOutput = 0x0010,
+ SetOutputs = SetAudioOutput | SetVideoOutput,
+ Render = 0x0020,
+ FinalizeLoad = 0x0040,
+ SetRate = 0x0080,
+ Seek = 0x0100,
+ Play = 0x0200,
+ Pause = 0x0400,
+ Stop = 0x0800,
+ ReleaseGraph = 0x1000,
+ ReleaseAudioOutput = 0x2000,
+ ReleaseVideoOutput = 0x4000,
+ ReleaseFilters = ReleaseGraph | ReleaseAudioOutput | ReleaseVideoOutput
};
enum Event
@@ -155,7 +160,9 @@ private:
RateChange,
Started,
Paused,
- DurationChange
+ DurationChange,
+ StatusChange,
+ EndOfMedia
};
enum GraphStatus
@@ -177,6 +184,8 @@ private:
int m_pendingTasks;
int m_executingTask;
int m_executedTasks;
+ HANDLE m_taskHandle;
+ HANDLE m_eventHandle;
GraphStatus m_graphStatus;
QMediaPlayer::Error m_error;
QIODevice *m_stream;
@@ -190,12 +199,11 @@ private:
qint64 m_duration;
bool m_buffering;
bool m_seekable;
+ bool m_atEnd;
QMediaTimeRange m_playbackRange;
QUrl m_url;
QMediaResourceList m_resources;
QMutex m_mutex;
- QWaitCondition m_wait;
- QWinEventNotifier m_graphEventNotifier;
DirectShowEventLoop m_loop;
friend class DirectShowPlayerServiceThread;