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:
Yoann Lopes
2015-11-01 17:17:12 +01:00
parent 315a946e40
commit 4fcf153d68
4 changed files with 28 additions and 11 deletions

View File

@@ -64,7 +64,7 @@ DirectShowPlayerControl::DirectShowPlayerControl(DirectShowPlayerService *servic
, m_streamTypes(0) , m_streamTypes(0)
, m_volume(100) , m_volume(100)
, m_muted(false) , m_muted(false)
, m_position(0) , m_emitPosition(-1)
, m_pendingPosition(-1) , m_pendingPosition(-1)
, m_duration(0) , m_duration(0)
, m_playbackRate(0) , m_playbackRate(0)
@@ -98,7 +98,7 @@ qint64 DirectShowPlayerControl::position() const
if (m_pendingPosition != -1) if (m_pendingPosition != -1)
return m_pendingPosition; return m_pendingPosition;
return const_cast<qint64 &>(m_position) = m_service->position(); return m_service->position();
} }
void DirectShowPlayerControl::setPosition(qint64 position) void DirectShowPlayerControl::setPosition(qint64 position)
@@ -215,6 +215,7 @@ const QIODevice *DirectShowPlayerControl::mediaStream() const
void DirectShowPlayerControl::setMedia(const QMediaContent &media, QIODevice *stream) void DirectShowPlayerControl::setMedia(const QMediaContent &media, QIODevice *stream)
{ {
m_pendingPosition = -1; m_pendingPosition = -1;
m_emitPosition = -1;
m_media = media; m_media = media;
m_stream = stream; m_stream = stream;
@@ -247,6 +248,7 @@ void DirectShowPlayerControl::playOrPause(QMediaPlayer::State state)
return; return;
} }
m_emitPosition = -1;
m_state = state; m_state = state;
if (m_pendingPosition != -1) if (m_pendingPosition != -1)
@@ -262,6 +264,7 @@ void DirectShowPlayerControl::playOrPause(QMediaPlayer::State state)
void DirectShowPlayerControl::stop() void DirectShowPlayerControl::stop()
{ {
m_emitPosition = -1;
m_service->stop(); m_service->stop();
emit stateChanged(m_state = QMediaPlayer::StoppedState); emit stateChanged(m_state = QMediaPlayer::StoppedState);
} }
@@ -293,8 +296,8 @@ void DirectShowPlayerControl::emitPropertyChanges()
emit videoAvailableChanged(m_streamTypes & DirectShowPlayerService::VideoStream); emit videoAvailableChanged(m_streamTypes & DirectShowPlayerService::VideoStream);
} }
if (properties & PositionProperty) if (properties & PositionProperty && m_emitPosition != -1)
emit positionChanged(m_position); emit positionChanged(m_emitPosition);
if (properties & DurationProperty) if (properties & DurationProperty)
emit durationChanged(m_duration); emit durationChanged(m_duration);
@@ -389,8 +392,8 @@ void DirectShowPlayerControl::updateError(QMediaPlayer::Error error, const QStri
void DirectShowPlayerControl::updatePosition(qint64 position) void DirectShowPlayerControl::updatePosition(qint64 position)
{ {
if (m_position != position) { if (m_emitPosition != position) {
m_position = position; m_emitPosition = position;
scheduleUpdate(PositionProperty); scheduleUpdate(PositionProperty);
} }

View File

@@ -130,7 +130,7 @@ private:
int m_streamTypes; int m_streamTypes;
int m_volume; int m_volume;
bool m_muted; bool m_muted;
qint64 m_position; qint64 m_emitPosition;
qint64 m_pendingPosition; qint64 m_pendingPosition;
qint64 m_duration; qint64 m_duration;
qreal m_playbackRate; qreal m_playbackRate;

View File

@@ -103,6 +103,7 @@ DirectShowPlayerService::DirectShowPlayerService(QObject *parent)
, m_buffering(false) , m_buffering(false)
, m_seekable(false) , m_seekable(false)
, m_atEnd(false) , m_atEnd(false)
, m_dontCacheNextSeekResult(false)
{ {
m_playerControl = new DirectShowPlayerControl(this); m_playerControl = new DirectShowPlayerControl(this);
m_metaDataControl = new DirectShowMetaDataControl(this); m_metaDataControl = new DirectShowMetaDataControl(this);
@@ -229,6 +230,7 @@ void DirectShowPlayerService::load(const QMediaContent &media, QIODevice *stream
m_buffering = false; m_buffering = false;
m_seekable = false; m_seekable = false;
m_atEnd = false; m_atEnd = false;
m_dontCacheNextSeekResult = false;
m_metaDataControl->updateGraph(0, 0); m_metaDataControl->updateGraph(0, 0);
if (m_resources.isEmpty() && !stream) { if (m_resources.isEmpty() && !stream) {
@@ -672,7 +674,9 @@ void DirectShowPlayerService::play()
if (m_executedTasks & Stop) { if (m_executedTasks & Stop) {
m_atEnd = false; m_atEnd = false;
if (m_seekPosition == -1) { if (m_seekPosition == -1) {
m_dontCacheNextSeekResult = true;
m_seekPosition = 0; m_seekPosition = 0;
m_position = 0;
m_pendingTasks |= Seek; m_pendingTasks |= Seek;
} }
m_executedTasks ^= Stop; m_executedTasks ^= Stop;
@@ -718,7 +722,9 @@ void DirectShowPlayerService::pause()
if (m_executedTasks & Stop) { if (m_executedTasks & Stop) {
m_atEnd = false; m_atEnd = false;
if (m_seekPosition == -1) { if (m_seekPosition == -1) {
m_dontCacheNextSeekResult = true;
m_seekPosition = 0; m_seekPosition = 0;
m_position = 0;
m_pendingTasks |= Seek; m_pendingTasks |= Seek;
} }
m_executedTasks ^= Stop; m_executedTasks ^= Stop;
@@ -791,6 +797,8 @@ void DirectShowPlayerService::doStop(QMutexLocker *locker)
} }
m_seekPosition = 0; m_seekPosition = 0;
m_position = 0;
m_dontCacheNextSeekResult = true;
m_pendingTasks |= Seek; m_pendingTasks |= Seek;
m_executedTasks &= ~(Play | Pause); 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 // Cache current values as we can't query IMediaSeeking during a seek due to the
// possibility of a deadlock when flushing the VideoSurfaceFilter. // possibility of a deadlock when flushing the VideoSurfaceFilter.
LONGLONG currentPosition = 0; LONGLONG currentPosition = 0;
seeking->GetCurrentPosition(&currentPosition); if (!m_dontCacheNextSeekResult) {
m_position = currentPosition / qt_directShowTimeScale; seeking->GetCurrentPosition(&currentPosition);
m_position = currentPosition / qt_directShowTimeScale;
}
LONGLONG minimum = 0; LONGLONG minimum = 0;
LONGLONG maximum = 0; LONGLONG maximum = 0;
@@ -928,8 +938,10 @@ void DirectShowPlayerService::doSeek(QMutexLocker *locker)
&seekPosition, AM_SEEKING_AbsolutePositioning, 0, AM_SEEKING_NoPositioning); &seekPosition, AM_SEEKING_AbsolutePositioning, 0, AM_SEEKING_NoPositioning);
locker->relock(); locker->relock();
seeking->GetCurrentPosition(&currentPosition); if (!m_dontCacheNextSeekResult) {
m_position = currentPosition / qt_directShowTimeScale; seeking->GetCurrentPosition(&currentPosition);
m_position = currentPosition / qt_directShowTimeScale;
}
seeking->Release(); seeking->Release();
@@ -937,6 +949,7 @@ void DirectShowPlayerService::doSeek(QMutexLocker *locker)
} }
m_seekPosition = -1; m_seekPosition = -1;
m_dontCacheNextSeekResult = false;
} }
int DirectShowPlayerService::bufferStatus() const int DirectShowPlayerService::bufferStatus() const

View File

@@ -195,6 +195,7 @@ private:
bool m_buffering; bool m_buffering;
bool m_seekable; bool m_seekable;
bool m_atEnd; bool m_atEnd;
bool m_dontCacheNextSeekResult;
QMediaTimeRange m_playbackRange; QMediaTimeRange m_playbackRange;
QUrl m_url; QUrl m_url;
QMediaResourceList m_resources; QMediaResourceList m_resources;