summaryrefslogtreecommitdiffstats
path: root/src/plugins/mediaservices/directshow
diff options
context:
space:
mode:
authorAndrew den Exter <andrew.den-exter@nokia.com>2010-02-12 05:46:48 (GMT)
committerAndrew den Exter <andrew.den-exter@nokia.com>2010-02-12 05:46:48 (GMT)
commit476970c2a1d00cfbf3f8bd6ac4b5c835633641ca (patch)
tree695c8ff7ee2f1b13a235e223904566a6ac52b72c /src/plugins/mediaservices/directshow
parentdc7a0b2842a5866b6248e56d41db0af05f7efbc2 (diff)
downloadQt-476970c2a1d00cfbf3f8bd6ac4b5c835633641ca.zip
Qt-476970c2a1d00cfbf3f8bd6ac4b5c835633641ca.tar.gz
Qt-476970c2a1d00cfbf3f8bd6ac4b5c835633641ca.tar.bz2
Emit positionChanged signals whenever playback is interrupted.
When stopped, paused, at the end of media, and after a seek. This prevents progress bars stopping just short of the end because the last timed progress updates was 300ms before the end of playback.
Diffstat (limited to 'src/plugins/mediaservices/directshow')
-rw-r--r--src/plugins/mediaservices/directshow/mediaplayer/directshowplayercontrol.cpp15
-rw-r--r--src/plugins/mediaservices/directshow/mediaplayer/directshowplayercontrol.h5
-rw-r--r--src/plugins/mediaservices/directshow/mediaplayer/directshowplayerservice.cpp88
-rw-r--r--src/plugins/mediaservices/directshow/mediaplayer/directshowplayerservice.h4
4 files changed, 94 insertions, 18 deletions
diff --git a/src/plugins/mediaservices/directshow/mediaplayer/directshowplayercontrol.cpp b/src/plugins/mediaservices/directshow/mediaplayer/directshowplayercontrol.cpp
index 587f4b1..b024557 100644
--- a/src/plugins/mediaservices/directshow/mediaplayer/directshowplayercontrol.cpp
+++ b/src/plugins/mediaservices/directshow/mediaplayer/directshowplayercontrol.cpp
@@ -85,6 +85,7 @@ DirectShowPlayerControl::DirectShowPlayerControl(DirectShowPlayerService *servic
, m_error(QMediaPlayer::NoError)
, m_streamTypes(0)
, m_muteVolume(-1)
+ , m_position(0)
, m_duration(0)
, m_playbackRate(0)
, m_seekable(false)
@@ -114,7 +115,7 @@ qint64 DirectShowPlayerControl::duration() const
qint64 DirectShowPlayerControl::position() const
{
- return m_service->position();
+ return const_cast<qint64 &>(m_position) = m_service->position();
}
void DirectShowPlayerControl::setPosition(qint64 position)
@@ -289,6 +290,9 @@ void DirectShowPlayerControl::emitPropertyChanges()
emit videoAvailableChanged(m_streamTypes & DirectShowPlayerService::VideoStream);
}
+ if (properties & PositionProperty)
+ emit positionChanged(m_position);
+
if (properties & DurationProperty)
emit durationChanged(m_duration);
@@ -379,4 +383,13 @@ void DirectShowPlayerControl::updateError(QMediaPlayer::Error error, const QStri
scheduleUpdate(ErrorProperty);
}
+void DirectShowPlayerControl::updatePosition(qint64 position)
+{
+ if (m_position != position) {
+ m_position = position;
+
+ scheduleUpdate(PositionProperty);
+ }
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/mediaservices/directshow/mediaplayer/directshowplayercontrol.h b/src/plugins/mediaservices/directshow/mediaplayer/directshowplayercontrol.h
index 6706bab..dd25d30 100644
--- a/src/plugins/mediaservices/directshow/mediaplayer/directshowplayercontrol.h
+++ b/src/plugins/mediaservices/directshow/mediaplayer/directshowplayercontrol.h
@@ -102,6 +102,7 @@ public:
void updatePlaybackRate(qreal rate);
void updateAudioOutput(IBaseFilter *filter);
void updateError(QMediaPlayer::Error error, const QString &errorString);
+ void updatePosition(qint64 position);
protected:
void customEvent(QEvent *event);
@@ -115,7 +116,8 @@ private:
DurationProperty = 0x08,
PlaybackRateProperty = 0x10,
SeekableProperty = 0x20,
- ErrorProperty = 0x40
+ ErrorProperty = 0x40,
+ PositionProperty = 0x80
};
enum Event
@@ -135,6 +137,7 @@ private:
QMediaPlayer::Error m_error;
int m_streamTypes;
int m_muteVolume;
+ qint64 m_position;
qint64 m_duration;
qreal m_playbackRate;
bool m_seekable;
diff --git a/src/plugins/mediaservices/directshow/mediaplayer/directshowplayerservice.cpp b/src/plugins/mediaservices/directshow/mediaplayer/directshowplayerservice.cpp
index 6e6b2f2..57f4bec 100644
--- a/src/plugins/mediaservices/directshow/mediaplayer/directshowplayerservice.cpp
+++ b/src/plugins/mediaservices/directshow/mediaplayer/directshowplayerservice.cpp
@@ -184,6 +184,7 @@ void DirectShowPlayerService::load(const QMediaContent &media, QIODevice *stream
m_stream = stream;
m_error = QMediaPlayer::NoError;
m_errorString = QString();
+ m_position = 0;
m_duration = 0;
m_streamTypes = 0;
m_executedTasks = 0;
@@ -217,6 +218,7 @@ void DirectShowPlayerService::load(const QMediaContent &media, QIODevice *stream
m_playerControl->updateError(m_error, m_errorString);
m_playerControl->updateMediaInfo(m_duration, m_streamTypes, m_seekable);
m_playerControl->updateState(QMediaPlayer::StoppedState);
+ m_playerControl->updatePosition(m_position);
updateStatus();
}
@@ -678,6 +680,17 @@ void DirectShowPlayerService::doPause(QMutexLocker *locker)
control->Release();
if (SUCCEEDED(hr)) {
+ if (IMediaSeeking *seeking = com_cast<IMediaSeeking>(m_graph)) {
+ LONGLONG position = 0;
+
+ seeking->GetCurrentPosition(&position);
+ seeking->Release();
+
+ m_position = position / 10;
+ } else {
+ m_position = 0;
+ }
+
m_executedTasks |= Pause;
QCoreApplication::postEvent(this, new QEvent(QEvent::Type(StatusChange)));
@@ -697,23 +710,43 @@ void DirectShowPlayerService::stop()
m_pendingTasks &= ~(Play | Pause | Seek);
- if (m_executedTasks & Render) {
- if (m_executingTask & (Play | Pause | Seek)) {
- m_pendingTasks |= Stop;
+ if ((m_executingTask | m_executedTasks) & (Play | Pause | Seek)) {
+ m_pendingTasks |= Stop;
+
+ ::SetEvent(m_taskHandle);
+
+ m_loop->wait(&m_mutex);
+ }
+
+}
- m_loop->wait(&m_mutex);
+void DirectShowPlayerService::doStop(QMutexLocker *locker)
+{
+ if (m_executedTasks & (Play | Pause)) {
+ if (IMediaControl *control = com_cast<IMediaControl>(m_graph)) {
+ control->Stop();
+ control->Release();
}
- if (m_executedTasks & (Play | Pause)) {
- if (IMediaControl *control = com_cast<IMediaControl>(m_graph)) {
- control->Stop();
- control->Release();
- }
- m_executedTasks &= ~(Play | Pause);
+ if (IMediaSeeking *seeking = com_cast<IMediaSeeking>(m_graph)) {
+ LONGLONG position = 0;
+
+ seeking->GetCurrentPosition(&position);
+ seeking->Release();
+
+ m_position = position / 10;
+ } else {
+ m_position = 0;
}
+
+ m_executedTasks &= ~(Play | Pause);
+
+ QCoreApplication::postEvent(this, new QEvent(QEvent::Type(StatusChange)));
}
m_executedTasks |= Stop;
+
+ m_loop->wake();
}
void DirectShowPlayerService::setRate(qreal rate)
@@ -774,7 +807,9 @@ qint64 DirectShowPlayerService::position() const
seeking->GetCurrentPosition(&position);
seeking->Release();
- return position / 10;
+ const_cast<qint64 &>(m_position) = position / 10;
+
+ return m_position;
}
}
return 0;
@@ -835,8 +870,15 @@ void DirectShowPlayerService::doSeek(QMutexLocker *locker)
&seekPosition, AM_SEEKING_AbsolutePositioning, 0, AM_SEEKING_NoPositioning);
locker->relock();
+ seeking->GetCurrentPosition(&currentPosition);
+ m_position = currentPosition / 10;
+
seeking->Release();
+ } else {
+ m_position = 0;
}
+
+ QCoreApplication::postEvent(this, new QEvent(QEvent::Type(PositionChange)));
}
int DirectShowPlayerService::bufferStatus() const
@@ -1034,6 +1076,7 @@ void DirectShowPlayerService::customEvent(QEvent *event)
QMutexLocker locker(&m_mutex);
updateStatus();
+ m_playerControl->updatePosition(m_position);
} else if (event->type() == QEvent::Type(DurationChange)) {
QMutexLocker locker(&m_mutex);
@@ -1044,7 +1087,12 @@ void DirectShowPlayerService::customEvent(QEvent *event)
if (m_atEnd) {
m_playerControl->updateState(QMediaPlayer::StoppedState);
m_playerControl->updateStatus(QMediaPlayer::EndOfMedia);
+ m_playerControl->updatePosition(m_position);
}
+ } else if (event->type() == QEvent::Type(PositionChange)) {
+ QMutexLocker locker(&m_mutex);
+
+ m_playerControl->updatePosition(m_position);
} else {
QMediaService::customEvent(event);
}
@@ -1089,6 +1137,15 @@ void DirectShowPlayerService::graphEvent(QMutexLocker *locker)
m_buffering = false;
m_atEnd = true;
+ if (IMediaSeeking *seeking = com_cast<IMediaSeeking>(m_graph)) {
+ LONGLONG position = 0;
+
+ seeking->GetCurrentPosition(&position);
+ seeking->Release();
+
+ m_position = position / 10;
+ }
+
QCoreApplication::postEvent(this, new QEvent(QEvent::Type(EndOfMedia)));
break;
case EC_LENGTH_CHANGED:
@@ -1262,15 +1319,16 @@ void DirectShowPlayerService::run()
m_executingTask = FinalizeLoad;
doFinalizeLoad(&locker);
+ } else if (m_pendingTasks & Stop) {
+ m_pendingTasks ^= Stop;
+ m_executingTask = Stop;
+
+ doStop(&locker);
} else if (m_pendingTasks & SetRate) {
m_pendingTasks ^= SetRate;
m_executingTask = SetRate;
doSetRate(&locker);
- } else if (m_pendingTasks & Stop) {
- m_pendingTasks ^= Stop;
-
- m_loop->wake();
} else if (m_pendingTasks & Pause) {
m_pendingTasks ^= Pause;
m_executingTask = Pause;
diff --git a/src/plugins/mediaservices/directshow/mediaplayer/directshowplayerservice.h b/src/plugins/mediaservices/directshow/mediaplayer/directshowplayerservice.h
index f9d3232..a5da9a4 100644
--- a/src/plugins/mediaservices/directshow/mediaplayer/directshowplayerservice.h
+++ b/src/plugins/mediaservices/directshow/mediaplayer/directshowplayerservice.h
@@ -126,6 +126,7 @@ private:
void doSeek(QMutexLocker *locker);
void doPlay(QMutexLocker *locker);
void doPause(QMutexLocker *locker);
+ void doStop(QMutexLocker *locker);
void doReleaseAudioOutput(QMutexLocker *locker);
void doReleaseVideoOutput(QMutexLocker *locker);
void doReleaseGraph(QMutexLocker *locker);
@@ -163,7 +164,8 @@ private:
Paused,
DurationChange,
StatusChange,
- EndOfMedia
+ EndOfMedia,
+ PositionChange
};
enum GraphStatus