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 ade2517d258523ca5090d5b7d44fee4b427d78d4..5e6630de84172d740f18d7b6c12b9526abfe3899 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 fb1c8b72f1422b20a9350ec8db2e02f0f68b6c75..eae09c64fccfa4f5b54d2de6f953c2cd94fcd801 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 7de0c2dcf7b6a0c5e6deeaee229e380e5135f733..64b88f49ecdedf141b5946807041a79fe47f0855 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 5109d305b5c5d5a979be683cd4bba8ddf6f32b75..b4e2f1f1725bca93e12f39759954beef07ea7e3c 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);