diff options
author | Andrew den Exter <andrew.den-exter@nokia.com> | 2010-02-12 05:46:48 (GMT) |
---|---|---|
committer | Andrew den Exter <andrew.den-exter@nokia.com> | 2010-02-12 05:46:48 (GMT) |
commit | 476970c2a1d00cfbf3f8bd6ac4b5c835633641ca (patch) | |
tree | 695c8ff7ee2f1b13a235e223904566a6ac52b72c /src | |
parent | dc7a0b2842a5866b6248e56d41db0af05f7efbc2 (diff) | |
download | Qt-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')
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(¤tPosition); + 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 |