summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYoann Lopes <yoann.lopes@digia.com>2014-09-19 09:53:53 +0200
committerYoann Lopes <yoann.lopes@digia.com>2014-09-26 14:26:58 +0200
commitec245921865eda2bc57397c1979c92fa10adfd98 (patch)
treedefd9970f1c3f8b16b69e18ff49be445c305f642
parent5c30ed55ef41ea85232f63c7ee4fd52a4e7126e2 (diff)
downloadqtmultimedia-ec245921865eda2bc57397c1979c92fa10adfd98.tar.gz
Android: fix some problems with the media player.
- Correctly emit positionChanged signal. One of the problems with this was that QMediaPlayer automatically sends periodic position updates while playing a media. There's no need to have the same logic in the backend. - Seeking after reaching the end of the media now correctly works Auto tests included. Change-Id: I6d5ecbae6e05f94a8aac1a0834cf57427adf219b Reviewed-by: Christian Stromme <christian.stromme@digia.com>
-rw-r--r--src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtAndroidMediaPlayer.java20
-rw-r--r--src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.cpp130
-rw-r--r--src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.h1
-rw-r--r--tests/auto/integration/qmediaplayerbackend/tst_qmediaplayerbackend.cpp246
4 files changed, 294 insertions, 103 deletions
diff --git a/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtAndroidMediaPlayer.java b/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtAndroidMediaPlayer.java
index ade2517d2..5e6630de8 100644
--- a/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtAndroidMediaPlayer.java
+++ b/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtAndroidMediaPlayer.java
@@ -83,23 +83,6 @@ public class QtAndroidMediaPlayer
private volatile int mState = State.Uninitialized;
- private class ProgressWatcher
- implements Runnable
- {
- @Override
- public void run()
- {
- try {
- while ((mState & (State.Started)) != 0) {
- onProgressUpdateNative(getCurrentPosition(), mID);
- Thread.sleep(1000);
- }
- } catch (final InterruptedException e) {
- // Ignore
- }
- }
- }
-
/**
* MediaPlayer OnErrorListener
*/
@@ -257,8 +240,6 @@ public class QtAndroidMediaPlayer
try {
mMediaPlayer.start();
setState(State.Started);
- Thread progressThread = new Thread(new ProgressWatcher());
- progressThread.start();
} catch (final IllegalStateException e) {
Log.d(TAG, "" + e.getMessage());
}
@@ -309,7 +290,6 @@ public class QtAndroidMediaPlayer
try {
mMediaPlayer.seekTo(msec);
- onProgressUpdateNative(msec, mID);
} catch (final IllegalStateException e) {
Log.d(TAG, "" + e.getMessage());
}
diff --git a/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.cpp b/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.cpp
index fb1c8b72f..eae09c64f 100644
--- a/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.cpp
+++ b/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.cpp
@@ -86,6 +86,7 @@ QAndroidMediaPlayerControl::QAndroidMediaPlayerControl(QObject *parent)
mPendingSetMedia(false),
mPendingVolume(-1),
mPendingMute(-1),
+ mReloadingMedia(false),
mActiveStateChangeNotifiers(0)
{
connect(mMediaPlayer,SIGNAL(bufferingChanged(qint32)),
@@ -138,17 +139,14 @@ qint64 QAndroidMediaPlayerControl::position() const
if (mCurrentMediaStatus == QMediaPlayer::EndOfMedia)
return duration();
- if ((mState & (AndroidMediaPlayer::Idle
- | AndroidMediaPlayer::Initialized
- | AndroidMediaPlayer::Prepared
+ if ((mState & (AndroidMediaPlayer::Prepared
| AndroidMediaPlayer::Started
| AndroidMediaPlayer::Paused
- | AndroidMediaPlayer::Stopped
- | AndroidMediaPlayer::PlaybackCompleted)) == 0) {
- return (mPendingPosition == -1) ? 0 : mPendingPosition;
+ | AndroidMediaPlayer::PlaybackCompleted))) {
+ return mMediaPlayer->getCurrentPosition();
}
- return (mCurrentState == QMediaPlayer::StoppedState) ? 0 : mMediaPlayer->getCurrentPosition();
+ return (mPendingPosition == -1) ? 0 : mPendingPosition;
}
void QAndroidMediaPlayerControl::setPosition(qint64 position)
@@ -158,26 +156,25 @@ void QAndroidMediaPlayerControl::setPosition(qint64 position)
const int seekPosition = (position > INT_MAX) ? INT_MAX : position;
- if ((mState & (AndroidMediaPlayer::Prepared
- | AndroidMediaPlayer::Started
- | AndroidMediaPlayer::Paused
- | AndroidMediaPlayer::PlaybackCompleted)) == 0) {
- if (mPendingPosition != seekPosition) {
- mPendingPosition = seekPosition;
- Q_EMIT positionChanged(seekPosition);
- }
+ if (seekPosition == this->position())
return;
- }
StateChangeNotifier notifier(this);
if (mCurrentMediaStatus == QMediaPlayer::EndOfMedia)
setMediaStatus(QMediaPlayer::LoadedMedia);
- mMediaPlayer->seekTo(seekPosition);
+ if ((mState & (AndroidMediaPlayer::Prepared
+ | AndroidMediaPlayer::Started
+ | AndroidMediaPlayer::Paused
+ | AndroidMediaPlayer::PlaybackCompleted)) == 0) {
+ mPendingPosition = seekPosition;
+ } else {
+ mMediaPlayer->seekTo(seekPosition);
- if (mPendingPosition != -1) {
- mPendingPosition = -1;
+ if (mPendingPosition != -1) {
+ mPendingPosition = -1;
+ }
}
Q_EMIT positionChanged(seekPosition);
@@ -310,9 +307,9 @@ void QAndroidMediaPlayerControl::setMedia(const QMediaContent &mediaContent,
{
StateChangeNotifier notifier(this);
- const bool reloading = (mMediaContent == mediaContent);
+ mReloadingMedia = (mMediaContent == mediaContent);
- if (!reloading) {
+ if (!mReloadingMedia) {
mMediaContent = mediaContent;
mMediaStream = stream;
}
@@ -321,43 +318,45 @@ void QAndroidMediaPlayerControl::setMedia(const QMediaContent &mediaContent,
if ((mState & (AndroidMediaPlayer::Idle | AndroidMediaPlayer::Uninitialized)) == 0)
mMediaPlayer->release();
+ QString mediaPath;
+
if (mediaContent.isNull()) {
setMediaStatus(QMediaPlayer::NoMedia);
- return;
- }
-
- if (mVideoOutput && !mVideoOutput->isReady()) {
- // if a video output is set but the video texture is not ready, delay loading the media
- // since it can cause problems on some hardware
- mPendingSetMedia = true;
- return;
- }
-
- const QUrl url = mediaContent.canonicalUrl();
- QString mediaPath;
- if (url.scheme() == QLatin1String("qrc")) {
- const QString path = url.toString().mid(3);
- mTempFile.reset(QTemporaryFile::createNativeFile(path));
- if (!mTempFile.isNull())
- mediaPath = QStringLiteral("file://") + mTempFile->fileName();
} else {
- mediaPath = url.toString();
- }
+ if (mVideoOutput && !mVideoOutput->isReady()) {
+ // if a video output is set but the video texture is not ready, delay loading the media
+ // since it can cause problems on some hardware
+ mPendingSetMedia = true;
+ return;
+ }
- if (mVideoSize.isValid() && mVideoOutput)
- mVideoOutput->setVideoSize(mVideoSize);
+ const QUrl url = mediaContent.canonicalUrl();
+ if (url.scheme() == QLatin1String("qrc")) {
+ const QString path = url.toString().mid(3);
+ mTempFile.reset(QTemporaryFile::createNativeFile(path));
+ if (!mTempFile.isNull())
+ mediaPath = QStringLiteral("file://") + mTempFile->fileName();
+ } else {
+ mediaPath = url.toString();
+ }
- if ((mMediaPlayer->display() == 0) && mVideoOutput)
- mMediaPlayer->setDisplay(mVideoOutput->surfaceTexture());
- mMediaPlayer->setDataSource(mediaPath);
- mMediaPlayer->prepareAsync();
+ if (mVideoSize.isValid() && mVideoOutput)
+ mVideoOutput->setVideoSize(mVideoSize);
+
+ if ((mMediaPlayer->display() == 0) && mVideoOutput)
+ mMediaPlayer->setDisplay(mVideoOutput->surfaceTexture());
+ mMediaPlayer->setDataSource(mediaPath);
+ mMediaPlayer->prepareAsync();
+ }
- if (!reloading) {
+ if (!mReloadingMedia) {
Q_EMIT mediaChanged(mMediaContent);
Q_EMIT actualMediaLocationChanged(mediaPath);
}
resetBufferingProgress();
+
+ mReloadingMedia = false;
}
void QAndroidMediaPlayerControl::setVideoOutput(QObject *videoOutput)
@@ -567,7 +566,8 @@ void QAndroidMediaPlayerControl::onStateChanged(qint32 state)
case AndroidMediaPlayer::Initialized:
break;
case AndroidMediaPlayer::Preparing:
- setMediaStatus(QMediaPlayer::LoadingMedia);
+ if (!mReloadingMedia)
+ setMediaStatus(QMediaPlayer::LoadingMedia);
break;
case AndroidMediaPlayer::Prepared:
setMediaStatus(QMediaPlayer::LoadedMedia);
@@ -588,6 +588,7 @@ void QAndroidMediaPlayerControl::onStateChanged(qint32 state)
} else {
setMediaStatus(QMediaPlayer::BufferedMedia);
}
+ Q_EMIT positionChanged(position());
break;
case AndroidMediaPlayer::Paused:
setState(QMediaPlayer::PausedState);
@@ -596,27 +597,32 @@ void QAndroidMediaPlayerControl::onStateChanged(qint32 state)
setState(QMediaPlayer::StoppedState);
setMediaStatus(QMediaPlayer::UnknownMediaStatus);
mMediaPlayer->release();
+ Q_EMIT positionChanged(0);
break;
case AndroidMediaPlayer::Stopped:
setState(QMediaPlayer::StoppedState);
setMediaStatus(QMediaPlayer::LoadedMedia);
- setPosition(0);
+ Q_EMIT positionChanged(0);
break;
case AndroidMediaPlayer::PlaybackCompleted:
setState(QMediaPlayer::StoppedState);
- setPosition(0);
setMediaStatus(QMediaPlayer::EndOfMedia);
break;
case AndroidMediaPlayer::Uninitialized:
- // reset some properties
- resetBufferingProgress();
- mPendingPosition = -1;
- mPendingSetMedia = false;
- mPendingState = -1;
-
- setAudioAvailable(false);
- setVideoAvailable(false);
- setSeekable(true);
+ // reset some properties (unless we reload the same media)
+ if (!mReloadingMedia) {
+ resetBufferingProgress();
+ mPendingPosition = -1;
+ mPendingSetMedia = false;
+ mPendingState = -1;
+
+ Q_EMIT durationChanged(0);
+ Q_EMIT positionChanged(0);
+
+ setAudioAvailable(false);
+ setVideoAvailable(false);
+ setSeekable(true);
+ }
break;
default:
break;
@@ -655,13 +661,13 @@ void QAndroidMediaPlayerControl::setMediaStatus(QMediaPlayer::MediaStatus status
if (mCurrentMediaStatus == status)
return;
+ mCurrentMediaStatus = status;
+
if (status == QMediaPlayer::NoMedia || status == QMediaPlayer::InvalidMedia)
Q_EMIT durationChanged(0);
if (status == QMediaPlayer::EndOfMedia)
- Q_EMIT durationChanged(duration());
-
- mCurrentMediaStatus = status;
+ Q_EMIT positionChanged(position());
updateBufferStatus();
}
diff --git a/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.h b/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.h
index 7de0c2dcf..64b88f49e 100644
--- a/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.h
+++ b/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.h
@@ -111,6 +111,7 @@ private:
bool mPendingSetMedia;
int mPendingVolume;
int mPendingMute;
+ bool mReloadingMedia;
QScopedPointer<QTemporaryFile> mTempFile;
int mActiveStateChangeNotifiers;
diff --git a/tests/auto/integration/qmediaplayerbackend/tst_qmediaplayerbackend.cpp b/tests/auto/integration/qmediaplayerbackend/tst_qmediaplayerbackend.cpp
index 5109d305b..b4e2f1f17 100644
--- a/tests/auto/integration/qmediaplayerbackend/tst_qmediaplayerbackend.cpp
+++ b/tests/auto/integration/qmediaplayerbackend/tst_qmediaplayerbackend.cpp
@@ -71,6 +71,7 @@ private slots:
void volumeAcrossFiles();
void initialVolume();
void seekPauseSeek();
+ void seekInStoppedState();
void subsequentPlayback();
void probes();
void playlist();
@@ -79,10 +80,11 @@ private slots:
private:
QMediaContent selectVideoFile(const QStringList& mediaCandidates);
- QMediaContent selectSoundFile(const QStringList& mediaCandidates);
+ QMediaContent selectMediaFile(const QStringList& mediaCandidates);
//one second local wav file
QMediaContent localWavFile;
+ QMediaContent localWavFile2;
QMediaContent localVideoFile;
QMediaContent localCompressedSoundFile;
@@ -169,17 +171,17 @@ QMediaContent tst_QMediaPlayerBackend::selectVideoFile(const QStringList& mediaC
return QMediaContent();
}
-QMediaContent tst_QMediaPlayerBackend::selectSoundFile(const QStringList& mediaCandidates)
+QMediaContent tst_QMediaPlayerBackend::selectMediaFile(const QStringList& mediaCandidates)
{
QMediaPlayer player;
QSignalSpy errorSpy(&player, SIGNAL(error(QMediaPlayer::Error)));
foreach (QString s, mediaCandidates) {
- QFileInfo soundFile(s);
- if (!soundFile.exists())
+ QFileInfo mediaFile(s);
+ if (!mediaFile.exists())
continue;
- QMediaContent media = QMediaContent(QUrl::fromLocalFile(soundFile.absoluteFilePath()));
+ QMediaContent media = QMediaContent(QUrl::fromLocalFile(mediaFile.absoluteFilePath()));
player.setMedia(media);
player.play();
@@ -205,17 +207,24 @@ void tst_QMediaPlayerBackend::initTestCase()
localWavFile = QMediaContent(QUrl::fromLocalFile(wavFile.absoluteFilePath()));
+ const QString testFileName2 = QFINDTESTDATA("testdata/_test.wav");
+ QFileInfo wavFile2(testFileName2);
+
+ QVERIFY(wavFile2.exists());
+
+ localWavFile2 = QMediaContent(QUrl::fromLocalFile(wavFile2.absoluteFilePath()));
+
qRegisterMetaType<QMediaContent>();
QStringList mediaCandidates;
mediaCandidates << QFINDTESTDATA("testdata/colors.ogv");
mediaCandidates << QFINDTESTDATA("testdata/colors.mp4");
- localVideoFile = selectVideoFile(mediaCandidates);
+ localVideoFile = selectMediaFile(mediaCandidates);
mediaCandidates.clear();
mediaCandidates << QFINDTESTDATA("testdata/nokia-tune.mkv");
mediaCandidates << QFINDTESTDATA("testdata/nokia-tune.mp3");
- localCompressedSoundFile = selectSoundFile(mediaCandidates);
+ localCompressedSoundFile = selectMediaFile(mediaCandidates);
qgetenv("QT_TEST_CI").toInt(&m_inCISystem,10);
}
@@ -239,6 +248,7 @@ void tst_QMediaPlayerBackend::loadMedia()
QSignalSpy stateSpy(&player, SIGNAL(stateChanged(QMediaPlayer::State)));
QSignalSpy statusSpy(&player, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)));
QSignalSpy mediaSpy(&player, SIGNAL(mediaChanged(QMediaContent)));
+ QSignalSpy currentMediaSpy(&player, SIGNAL(currentMediaChanged(QMediaContent)));
player.setMedia(localWavFile);
@@ -247,11 +257,13 @@ void tst_QMediaPlayerBackend::loadMedia()
QVERIFY(player.mediaStatus() != QMediaPlayer::NoMedia);
QVERIFY(player.mediaStatus() != QMediaPlayer::InvalidMedia);
QVERIFY(player.media() == localWavFile);
+ QVERIFY(player.currentMedia() == localWavFile);
QCOMPARE(stateSpy.count(), 0);
QVERIFY(statusSpy.count() > 0);
QCOMPARE(mediaSpy.count(), 1);
QCOMPARE(mediaSpy.last()[0].value<QMediaContent>(), localWavFile);
+ QCOMPARE(currentMediaSpy.last()[0].value<QMediaContent>(), localWavFile);
QTRY_COMPARE(player.mediaStatus(), QMediaPlayer::LoadedMedia);
@@ -267,6 +279,7 @@ void tst_QMediaPlayerBackend::unloadMedia()
QSignalSpy stateSpy(&player, SIGNAL(stateChanged(QMediaPlayer::State)));
QSignalSpy statusSpy(&player, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)));
QSignalSpy mediaSpy(&player, SIGNAL(mediaChanged(QMediaContent)));
+ QSignalSpy currentMediaSpy(&player, SIGNAL(currentMediaChanged(QMediaContent)));
QSignalSpy positionSpy(&player, SIGNAL(positionChanged(qint64)));
QSignalSpy durationSpy(&player, SIGNAL(positionChanged(qint64)));
@@ -285,6 +298,7 @@ void tst_QMediaPlayerBackend::unloadMedia()
stateSpy.clear();
statusSpy.clear();
mediaSpy.clear();
+ currentMediaSpy.clear();
positionSpy.clear();
durationSpy.clear();
@@ -295,10 +309,12 @@ void tst_QMediaPlayerBackend::unloadMedia()
QCOMPARE(player.state(), QMediaPlayer::StoppedState);
QCOMPARE(player.mediaStatus(), QMediaPlayer::NoMedia);
QCOMPARE(player.media(), QMediaContent());
+ QCOMPARE(player.currentMedia(), QMediaContent());
QVERIFY(!stateSpy.isEmpty());
QVERIFY(!statusSpy.isEmpty());
QVERIFY(!mediaSpy.isEmpty());
+ QVERIFY(!currentMediaSpy.isEmpty());
QVERIFY(!positionSpy.isEmpty());
}
@@ -327,7 +343,7 @@ void tst_QMediaPlayerBackend::playPauseStop()
QTRY_VERIFY(statusSpy.count() > 0 &&
statusSpy.last()[0].value<QMediaPlayer::MediaStatus>() == QMediaPlayer::BufferedMedia);
- QTRY_VERIFY(player.position() > 0);
+ QTRY_VERIFY(player.position() > 100);
QVERIFY(player.duration() > 0);
QVERIFY(positionSpy.count() > 0);
QVERIFY(positionSpy.last()[0].value<qint64>() > 0);
@@ -361,6 +377,63 @@ void tst_QMediaPlayerBackend::playPauseStop()
QCOMPARE(player.position(), qint64(0));
QCOMPARE(positionSpy.last()[0].value<qint64>(), qint64(0));
QVERIFY(player.duration() > 0);
+
+ stateSpy.clear();
+ statusSpy.clear();
+ positionSpy.clear();
+
+ player.play();
+
+ QCOMPARE(player.state(), QMediaPlayer::PlayingState);
+ QTRY_COMPARE(player.mediaStatus(), QMediaPlayer::BufferedMedia);
+ QCOMPARE(stateSpy.count(), 1);
+ QCOMPARE(stateSpy.last()[0].value<QMediaPlayer::State>(), QMediaPlayer::PlayingState);
+ QCOMPARE(statusSpy.count(), 1); // Should not go through Loading again when play -> stop -> play
+ QCOMPARE(statusSpy.last()[0].value<QMediaPlayer::MediaStatus>(), QMediaPlayer::BufferedMedia);
+
+ player.stop();
+ stateSpy.clear();
+ statusSpy.clear();
+ positionSpy.clear();
+
+ player.setMedia(localWavFile2);
+
+ QTRY_VERIFY(statusSpy.count() > 0);
+ QTRY_COMPARE(player.mediaStatus(), QMediaPlayer::LoadedMedia);
+ QCOMPARE(statusSpy.last()[0].value<QMediaPlayer::MediaStatus>(), QMediaPlayer::LoadedMedia);
+ QCOMPARE(player.state(), QMediaPlayer::StoppedState);
+ QCOMPARE(stateSpy.count(), 0);
+
+ player.play();
+
+ QTRY_VERIFY(player.position() > 100);
+
+ player.setMedia(localWavFile);
+
+ QTRY_COMPARE(player.mediaStatus(), QMediaPlayer::LoadedMedia);
+ QCOMPARE(statusSpy.last()[0].value<QMediaPlayer::MediaStatus>(), QMediaPlayer::LoadedMedia);
+ QCOMPARE(player.state(), QMediaPlayer::StoppedState);
+ QCOMPARE(stateSpy.last()[0].value<QMediaPlayer::State>(), QMediaPlayer::StoppedState);
+ QCOMPARE(player.position(), 0);
+ QCOMPARE(positionSpy.last()[0].value<qint64>(), 0);
+
+ stateSpy.clear();
+ statusSpy.clear();
+ positionSpy.clear();
+
+ player.play();
+
+ QTRY_VERIFY(player.position() > 100);
+
+ player.setMedia(QMediaContent());
+
+ QTRY_COMPARE(player.mediaStatus(), QMediaPlayer::NoMedia);
+ QCOMPARE(statusSpy.last()[0].value<QMediaPlayer::MediaStatus>(), QMediaPlayer::NoMedia);
+ QCOMPARE(player.state(), QMediaPlayer::StoppedState);
+ QCOMPARE(stateSpy.last()[0].value<QMediaPlayer::State>(), QMediaPlayer::StoppedState);
+ QCOMPARE(player.position(), 0);
+ QCOMPARE(positionSpy.last()[0].value<qint64>(), 0);
+ QCOMPARE(player.duration(), 0);
}
@@ -383,17 +456,25 @@ void tst_QMediaPlayerBackend::processEOS()
QVERIFY(statusSpy.count() > 0);
QCOMPARE(statusSpy.last()[0].value<QMediaPlayer::MediaStatus>(), QMediaPlayer::EndOfMedia);
+ QCOMPARE(player.state(), QMediaPlayer::StoppedState);
+ QCOMPARE(stateSpy.count(), 2);
+ QCOMPARE(stateSpy.last()[0].value<QMediaPlayer::State>(), QMediaPlayer::StoppedState);
//at EOS the position stays at the end of file
- QVERIFY(player.position() > 900);
+ QCOMPARE(player.position(), player.duration());
+ QVERIFY(positionSpy.count() > 0);
+ QCOMPARE(positionSpy.last()[0].value<qint64>(), player.duration());
stateSpy.clear();
statusSpy.clear();
+ positionSpy.clear();
player.play();
//position is reset to start
QTRY_VERIFY(player.position() < 100);
+ QVERIFY(positionSpy.count() > 0);
+ QCOMPARE(positionSpy.first()[0].value<qint64>(), 0);
QCOMPARE(player.state(), QMediaPlayer::PlayingState);
QTRY_COMPARE(player.mediaStatus(), QMediaPlayer::BufferedMedia);
@@ -406,13 +487,16 @@ void tst_QMediaPlayerBackend::processEOS()
player.setPosition(900);
//wait up to 5 seconds for EOS
QTRY_COMPARE(player.mediaStatus(), QMediaPlayer::EndOfMedia);
+ QVERIFY(statusSpy.count() > 0);
+ QCOMPARE(statusSpy.last()[0].value<QMediaPlayer::MediaStatus>(), QMediaPlayer::EndOfMedia);
+ QCOMPARE(player.state(), QMediaPlayer::StoppedState);
+ QCOMPARE(stateSpy.count(), 2);
+ QCOMPARE(stateSpy.last()[0].value<QMediaPlayer::State>(), QMediaPlayer::StoppedState);
- //ensure the positionChanged() signal is emitted
- QVERIFY(positionSpy.count() > 0);
-
- QCOMPARE(player.mediaStatus(), QMediaPlayer::EndOfMedia);
//position stays at the end of file
- QVERIFY(player.position() > 900);
+ QCOMPARE(player.position(), player.duration());
+ QVERIFY(positionSpy.count() > 0);
+ QCOMPARE(positionSpy.last()[0].value<qint64>(), player.duration());
//after setPosition EndOfMedia status should be reset to Loaded
stateSpy.clear();
@@ -608,7 +692,7 @@ void tst_QMediaPlayerBackend::initialVolume()
void tst_QMediaPlayerBackend::seekPauseSeek()
{
if (localVideoFile.isNull())
- QSKIP("Video format is not supported");
+ QSKIP("No supported video file");
QMediaPlayer player;
@@ -674,6 +758,125 @@ void tst_QMediaPlayerBackend::seekPauseSeek()
}
}
+void tst_QMediaPlayerBackend::seekInStoppedState()
+{
+ if (localVideoFile.isNull())
+ QSKIP("No supported video file");
+
+ QMediaPlayer player;
+ player.setNotifyInterval(500);
+
+ QSignalSpy stateSpy(&player, SIGNAL(stateChanged(QMediaPlayer::State)));
+ QSignalSpy positionSpy(&player, SIGNAL(positionChanged(qint64)));
+
+ player.setMedia(localVideoFile);
+ QTRY_COMPARE(player.mediaStatus(), QMediaPlayer::LoadedMedia);
+ QCOMPARE(player.state(), QMediaPlayer::StoppedState);
+ QCOMPARE(player.position(), 0);
+ QVERIFY(player.isSeekable());
+
+ stateSpy.clear();
+ positionSpy.clear();
+
+ qint64 position = 5000;
+ player.setPosition(position);
+
+ QTRY_VERIFY(qAbs(player.position() - position) < qint64(500));
+ QCOMPARE(positionSpy.count(), 1);
+ QVERIFY(qAbs(positionSpy.last()[0].value<qint64>() - position) < qint64(500));
+
+ QCOMPARE(player.state(), QMediaPlayer::StoppedState);
+ QCOMPARE(stateSpy.count(), 0);
+
+ QCOMPARE(player.mediaStatus(), QMediaPlayer::LoadedMedia);
+
+ positionSpy.clear();
+
+ player.play();
+
+ QCOMPARE(player.state(), QMediaPlayer::PlayingState);
+ QTRY_COMPARE(player.mediaStatus(), QMediaPlayer::BufferedMedia);
+ QVERIFY(qAbs(player.position() - position) < qint64(500));
+
+ QTest::qWait(2000);
+ // Check that it never played from the beginning
+ QVERIFY(player.position() > (position - 500));
+ for (int i = 0; i < positionSpy.count(); ++i)
+ QVERIFY(positionSpy.at(i)[0].value<qint64>() > (position - 500));
+
+ // ------
+ // Same tests but after play() --> stop()
+
+ player.stop();
+ QCOMPARE(player.state(), QMediaPlayer::StoppedState);
+ QTRY_COMPARE(player.mediaStatus(), QMediaPlayer::LoadedMedia);
+ QCOMPARE(player.position(), 0);
+
+ stateSpy.clear();
+ positionSpy.clear();
+
+ player.setPosition(position);
+
+ QTRY_VERIFY(qAbs(player.position() - position) < qint64(500));
+ QCOMPARE(positionSpy.count(), 1);
+ QVERIFY(qAbs(positionSpy.last()[0].value<qint64>() - position) < qint64(500));
+
+ QCOMPARE(player.state(), QMediaPlayer::StoppedState);
+ QCOMPARE(stateSpy.count(), 0);
+
+ QCOMPARE(player.mediaStatus(), QMediaPlayer::LoadedMedia);
+
+ positionSpy.clear();
+
+ player.play();
+
+ QCOMPARE(player.state(), QMediaPlayer::PlayingState);
+ QTRY_COMPARE(player.mediaStatus(), QMediaPlayer::BufferedMedia);
+ QVERIFY(qAbs(player.position() - position) < qint64(500));
+
+ QTest::qWait(2000);
+ // Check that it never played from the beginning
+ QVERIFY(player.position() > (position - 500));
+ for (int i = 0; i < positionSpy.count(); ++i)
+ QVERIFY(positionSpy.at(i)[0].value<qint64>() > (position - 500));
+
+ // ------
+ // Same tests but after reaching the end of the media
+
+ player.setPosition(player.duration() - 500);
+ QTRY_COMPARE(player.mediaStatus(), QMediaPlayer::EndOfMedia);
+ QCOMPARE(player.state(), QMediaPlayer::StoppedState);
+ QCOMPARE(player.position(), player.duration());
+
+ stateSpy.clear();
+ positionSpy.clear();
+
+ player.setPosition(position);
+
+ QTRY_VERIFY(qAbs(player.position() - position) < qint64(500));
+ QCOMPARE(positionSpy.count(), 1);
+ QVERIFY(qAbs(positionSpy.last()[0].value<qint64>() - position) < qint64(500));
+
+ QCOMPARE(player.state(), QMediaPlayer::StoppedState);
+ QCOMPARE(stateSpy.count(), 0);
+
+ QCOMPARE(player.mediaStatus(), QMediaPlayer::LoadedMedia);
+
+ positionSpy.clear();
+
+ player.play();
+
+ QCOMPARE(player.state(), QMediaPlayer::PlayingState);
+ QTRY_COMPARE(player.mediaStatus(), QMediaPlayer::BufferedMedia);
+ QVERIFY(qAbs(player.position() - position) < qint64(500));
+
+ QTest::qWait(2000);
+ // Check that it never played from the beginning
+ QVERIFY(player.position() > (position - 500));
+ for (int i = 0; i < positionSpy.count(); ++i)
+ QVERIFY(positionSpy.at(i)[0].value<qint64>() > (position - 500));
+}
+
void tst_QMediaPlayerBackend::subsequentPlayback()
{
#ifdef Q_OS_LINUX
@@ -717,7 +920,7 @@ void tst_QMediaPlayerBackend::subsequentPlayback()
void tst_QMediaPlayerBackend::probes()
{
if (localVideoFile.isNull())
- QSKIP("Video format is not supported");
+ QSKIP("No supported video file");
QMediaPlayer *player = new QMediaPlayer;
@@ -733,8 +936,9 @@ void tst_QMediaPlayerBackend::probes()
connect(audioProbe, SIGNAL(audioBufferProbed(QAudioBuffer)), &probeHandler, SLOT(processBuffer(QAudioBuffer)));
connect(audioProbe, SIGNAL(flush()), &probeHandler, SLOT(flushAudio()));
- QVERIFY(videoProbe->setSource(player));
- QVERIFY(audioProbe->setSource(player));
+ if (!videoProbe->setSource(player))
+ QSKIP("QVideoProbe is not supported");
+ audioProbe->setSource(player);
player->setMedia(localVideoFile);
QTRY_COMPARE(player->mediaStatus(), QMediaPlayer::LoadedMedia);
@@ -831,7 +1035,7 @@ void tst_QMediaPlayerBackend::playlist()
errorSpy.clear();
// <<< Invalid2 - 1st pass >>>
- fileInfo.setFile((QFINDTESTDATA("testdata/invalid_media2.m3u")));
+ fileInfo.setFile(QFINDTESTDATA("/testdata/invalid_media2.m3u"));
player.setMedia(QUrl::fromLocalFile(fileInfo.absoluteFilePath()));
player.play();
@@ -864,7 +1068,7 @@ void tst_QMediaPlayerBackend::playlist()
errorSpy.clear();
// <<< Recursive - 1st pass >>>
- fileInfo.setFile((QFINDTESTDATA("testdata/recursive_master.m3u")));
+ fileInfo.setFile(QFINDTESTDATA("testdata/recursive_master.m3u"));
player.setMedia(QUrl::fromLocalFile(fileInfo.absoluteFilePath()));
player.play();
@@ -929,7 +1133,7 @@ void tst_QMediaPlayerBackend::surfaceTest()
{
// 25 fps video file
if (localVideoFile.isNull())
- QSKIP("Video format is not supported");
+ QSKIP("No supported video file");
QFETCH(QList<QVideoFrame::PixelFormat>, formatsList);