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_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);
}

View File

@@ -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;

View File

@@ -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(&currentPosition);
m_position = currentPosition / qt_directShowTimeScale;
if (!m_dontCacheNextSeekResult) {
seeking->GetCurrentPosition(&currentPosition);
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(&currentPosition);
m_position = currentPosition / qt_directShowTimeScale;
if (!m_dontCacheNextSeekResult) {
seeking->GetCurrentPosition(&currentPosition);
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

View File

@@ -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;