DirectShow: fix media player's positionChanged() signal.
The signal was not emitted at the right time or with incorrect values under certain circumstances. Change-Id: Ib8b1d38381d908399752856db7b0a987c4422bb1 Reviewed-by: Christian Stromme <christian.stromme@theqtcompany.com>
This commit is contained in:
@@ -64,7 +64,7 @@ DirectShowPlayerControl::DirectShowPlayerControl(DirectShowPlayerService *servic
|
||||
, m_streamTypes(0)
|
||||
, m_volume(100)
|
||||
, m_muted(false)
|
||||
, m_position(0)
|
||||
, m_emitPosition(-1)
|
||||
, m_pendingPosition(-1)
|
||||
, m_duration(0)
|
||||
, m_playbackRate(0)
|
||||
@@ -98,7 +98,7 @@ qint64 DirectShowPlayerControl::position() const
|
||||
if (m_pendingPosition != -1)
|
||||
return m_pendingPosition;
|
||||
|
||||
return const_cast<qint64 &>(m_position) = m_service->position();
|
||||
return m_service->position();
|
||||
}
|
||||
|
||||
void DirectShowPlayerControl::setPosition(qint64 position)
|
||||
@@ -215,6 +215,7 @@ const QIODevice *DirectShowPlayerControl::mediaStream() const
|
||||
void DirectShowPlayerControl::setMedia(const QMediaContent &media, QIODevice *stream)
|
||||
{
|
||||
m_pendingPosition = -1;
|
||||
m_emitPosition = -1;
|
||||
|
||||
m_media = media;
|
||||
m_stream = stream;
|
||||
@@ -247,6 +248,7 @@ void DirectShowPlayerControl::playOrPause(QMediaPlayer::State state)
|
||||
return;
|
||||
}
|
||||
|
||||
m_emitPosition = -1;
|
||||
m_state = state;
|
||||
|
||||
if (m_pendingPosition != -1)
|
||||
@@ -262,6 +264,7 @@ void DirectShowPlayerControl::playOrPause(QMediaPlayer::State state)
|
||||
|
||||
void DirectShowPlayerControl::stop()
|
||||
{
|
||||
m_emitPosition = -1;
|
||||
m_service->stop();
|
||||
emit stateChanged(m_state = QMediaPlayer::StoppedState);
|
||||
}
|
||||
@@ -293,8 +296,8 @@ void DirectShowPlayerControl::emitPropertyChanges()
|
||||
emit videoAvailableChanged(m_streamTypes & DirectShowPlayerService::VideoStream);
|
||||
}
|
||||
|
||||
if (properties & PositionProperty)
|
||||
emit positionChanged(m_position);
|
||||
if (properties & PositionProperty && m_emitPosition != -1)
|
||||
emit positionChanged(m_emitPosition);
|
||||
|
||||
if (properties & DurationProperty)
|
||||
emit durationChanged(m_duration);
|
||||
@@ -389,8 +392,8 @@ void DirectShowPlayerControl::updateError(QMediaPlayer::Error error, const QStri
|
||||
|
||||
void DirectShowPlayerControl::updatePosition(qint64 position)
|
||||
{
|
||||
if (m_position != position) {
|
||||
m_position = position;
|
||||
if (m_emitPosition != position) {
|
||||
m_emitPosition = position;
|
||||
|
||||
scheduleUpdate(PositionProperty);
|
||||
}
|
||||
|
||||
@@ -130,7 +130,7 @@ private:
|
||||
int m_streamTypes;
|
||||
int m_volume;
|
||||
bool m_muted;
|
||||
qint64 m_position;
|
||||
qint64 m_emitPosition;
|
||||
qint64 m_pendingPosition;
|
||||
qint64 m_duration;
|
||||
qreal m_playbackRate;
|
||||
|
||||
@@ -103,6 +103,7 @@ DirectShowPlayerService::DirectShowPlayerService(QObject *parent)
|
||||
, m_buffering(false)
|
||||
, m_seekable(false)
|
||||
, m_atEnd(false)
|
||||
, m_dontCacheNextSeekResult(false)
|
||||
{
|
||||
m_playerControl = new DirectShowPlayerControl(this);
|
||||
m_metaDataControl = new DirectShowMetaDataControl(this);
|
||||
@@ -229,6 +230,7 @@ void DirectShowPlayerService::load(const QMediaContent &media, QIODevice *stream
|
||||
m_buffering = false;
|
||||
m_seekable = false;
|
||||
m_atEnd = false;
|
||||
m_dontCacheNextSeekResult = false;
|
||||
m_metaDataControl->updateGraph(0, 0);
|
||||
|
||||
if (m_resources.isEmpty() && !stream) {
|
||||
@@ -672,7 +674,9 @@ void DirectShowPlayerService::play()
|
||||
if (m_executedTasks & Stop) {
|
||||
m_atEnd = false;
|
||||
if (m_seekPosition == -1) {
|
||||
m_dontCacheNextSeekResult = true;
|
||||
m_seekPosition = 0;
|
||||
m_position = 0;
|
||||
m_pendingTasks |= Seek;
|
||||
}
|
||||
m_executedTasks ^= Stop;
|
||||
@@ -718,7 +722,9 @@ void DirectShowPlayerService::pause()
|
||||
if (m_executedTasks & Stop) {
|
||||
m_atEnd = false;
|
||||
if (m_seekPosition == -1) {
|
||||
m_dontCacheNextSeekResult = true;
|
||||
m_seekPosition = 0;
|
||||
m_position = 0;
|
||||
m_pendingTasks |= Seek;
|
||||
}
|
||||
m_executedTasks ^= Stop;
|
||||
@@ -791,6 +797,8 @@ void DirectShowPlayerService::doStop(QMutexLocker *locker)
|
||||
}
|
||||
|
||||
m_seekPosition = 0;
|
||||
m_position = 0;
|
||||
m_dontCacheNextSeekResult = true;
|
||||
m_pendingTasks |= Seek;
|
||||
|
||||
m_executedTasks &= ~(Play | Pause);
|
||||
@@ -913,8 +921,10 @@ void DirectShowPlayerService::doSeek(QMutexLocker *locker)
|
||||
// Cache current values as we can't query IMediaSeeking during a seek due to the
|
||||
// possibility of a deadlock when flushing the VideoSurfaceFilter.
|
||||
LONGLONG currentPosition = 0;
|
||||
seeking->GetCurrentPosition(¤tPosition);
|
||||
m_position = currentPosition / qt_directShowTimeScale;
|
||||
if (!m_dontCacheNextSeekResult) {
|
||||
seeking->GetCurrentPosition(¤tPosition);
|
||||
m_position = currentPosition / qt_directShowTimeScale;
|
||||
}
|
||||
|
||||
LONGLONG minimum = 0;
|
||||
LONGLONG maximum = 0;
|
||||
@@ -928,8 +938,10 @@ void DirectShowPlayerService::doSeek(QMutexLocker *locker)
|
||||
&seekPosition, AM_SEEKING_AbsolutePositioning, 0, AM_SEEKING_NoPositioning);
|
||||
locker->relock();
|
||||
|
||||
seeking->GetCurrentPosition(¤tPosition);
|
||||
m_position = currentPosition / qt_directShowTimeScale;
|
||||
if (!m_dontCacheNextSeekResult) {
|
||||
seeking->GetCurrentPosition(¤tPosition);
|
||||
m_position = currentPosition / qt_directShowTimeScale;
|
||||
}
|
||||
|
||||
seeking->Release();
|
||||
|
||||
@@ -937,6 +949,7 @@ void DirectShowPlayerService::doSeek(QMutexLocker *locker)
|
||||
}
|
||||
|
||||
m_seekPosition = -1;
|
||||
m_dontCacheNextSeekResult = false;
|
||||
}
|
||||
|
||||
int DirectShowPlayerService::bufferStatus() const
|
||||
|
||||
@@ -195,6 +195,7 @@ private:
|
||||
bool m_buffering;
|
||||
bool m_seekable;
|
||||
bool m_atEnd;
|
||||
bool m_dontCacheNextSeekResult;
|
||||
QMediaTimeRange m_playbackRange;
|
||||
QUrl m_url;
|
||||
QMediaResourceList m_resources;
|
||||
|
||||
Reference in New Issue
Block a user