summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorArtem Dyomin <artem.dyomin@qt.io>2023-03-30 18:54:44 +0200
committerArtem Dyomin <artem.dyomin@qt.io>2023-04-12 13:20:49 +0200
commit57ebebae16d9b4d984709541a1b37e711f48b14d (patch)
tree8f9f66cf7af6cb6c6284fc0234d2fe51210d4c22 /tests
parentbfae176fd3297089fb723cd1555b1ac981fed15a (diff)
Implement seamless ffmpeg playback looping
Users need seamless looping, in other words, looping without little delays on jumping from the media end to the start. The only way to make it seamles and smooth is to intrude into the playback engine. As result, we have just a regular delay between frames on shifting. Also, a bunch of adjuscent small improvements have been introduced: - simplify criteria of the demuxer's buffer size, it was more complex and a bit not relevant before. Actually, we need to check only max buffering time. - Improve handling of media with streams of different length. - Fix setting of the playback rate before opening sources. - Add new auto tests for looping. - Add debug logs. Pick-to: 6.5 Task-number: QTBUG-112305 Change-Id: Ic9073d77535f5aae19f9ea48d4e745c9f2fa9ea3 Reviewed-by: Lars Knoll <lars@knoll.priv.no>
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/integration/qmediaplayerbackend/tst_qmediaplayerbackend.cpp117
1 files changed, 106 insertions, 11 deletions
diff --git a/tests/auto/integration/qmediaplayerbackend/tst_qmediaplayerbackend.cpp b/tests/auto/integration/qmediaplayerbackend/tst_qmediaplayerbackend.cpp
index b734acad6..27c15c3c3 100644
--- a/tests/auto/integration/qmediaplayerbackend/tst_qmediaplayerbackend.cpp
+++ b/tests/auto/integration/qmediaplayerbackend/tst_qmediaplayerbackend.cpp
@@ -74,7 +74,9 @@ private slots:
void playbackRateChanging();
void durationDetectionIssues();
void finiteLoops();
- void infiteLoops();
+ void infiniteLoops();
+ void seekOnLoops();
+ void changeLoopsOnTheFly();
void lazyLoadVideo();
private:
@@ -1322,15 +1324,16 @@ void tst_QMediaPlayerBackend::playbackRateChanging()
player.setVideoOutput(&surface);
player.setSource(localVideoFile3ColorsWithSound);
- QImage frameImage;
- connect(&surface, &QVideoSink::videoFrameChanged, [&frameImage](const QVideoFrame& frame) {
- frameImage = frame.toImage();
+ std::optional<QRgb> color;
+ connect(&surface, &QVideoSink::videoFrameChanged, [&](const QVideoFrame& frame) {
+ auto image = frame.toImage();
+ color = image.isNull() ? std::optional<QRgb>{} : image.pixel(1, 1);
});
auto checkColorAndPosition = [&](int colorIndex, QString errorTag) {
- QVERIFY(!frameImage.isNull());
+ QVERIFY(color);
const auto expectedColor = video3Colors[colorIndex];
- const auto actualColor = frameImage.pixel(1, 1);
+ const auto actualColor = *color;
auto errorPrintingGuard = qScopeGuard([&]() {
qDebug() << "Error Tag:" << errorTag;
@@ -1677,10 +1680,8 @@ void tst_QMediaPlayerBackend::finiteLoops()
QCOMPARE(intervals.size(), 3u);
QCOMPARE_GT(intervals[0].first, 0);
QCOMPARE(intervals[0].second, player.duration());
- QCOMPARE(intervals[1].first, 0);
- QCOMPARE(intervals[1].second, player.duration());
- QCOMPARE(intervals[2].first, 0);
- QCOMPARE(intervals[2].second, player.duration());
+ QCOMPARE(intervals[1], std::make_pair(qint64(0), player.duration()));
+ QCOMPARE(intervals[2], std::make_pair(qint64(0), player.duration()));
QCOMPARE(player.mediaStatus(), QMediaPlayer::EndOfMedia);
@@ -1697,7 +1698,7 @@ void tst_QMediaPlayerBackend::finiteLoops()
}
}
-void tst_QMediaPlayerBackend::infiteLoops()
+void tst_QMediaPlayerBackend::infiniteLoops()
{
if (localVideoFile2.isEmpty())
QSKIP("Video format is not supported");
@@ -1742,6 +1743,100 @@ void tst_QMediaPlayerBackend::infiteLoops()
QCOMPARE(player.playbackState(), QMediaPlayer::StoppedState);
}
+void tst_QMediaPlayerBackend::seekOnLoops()
+{
+ if (localVideoFile3ColorsWithSound.isEmpty())
+ QSKIP("Video format is not supported");
+
+#ifdef Q_OS_MACOS
+ if (qEnvironmentVariable("QTEST_ENVIRONMENT").toLower() == "ci")
+ QSKIP("The test accidently gets crashed on macOS CI, not reproduced locally. To be "
+ "investigated: QTBUG-111744");
+#endif
+
+ TestVideoSink surface(false);
+ QMediaPlayer player;
+
+ QSignalSpy positionSpy(&player, &QMediaPlayer::positionChanged);
+
+ player.setVideoOutput(&surface);
+ player.setLoops(3);
+ player.setPlaybackRate(2);
+
+ player.setSource(localVideoFile3ColorsWithSound);
+
+ player.play();
+ surface.waitForFrame();
+
+ // seek in the 1st loop
+ player.setPosition(player.duration() * 4 / 5);
+
+ // wait for the 2nd loop and seek
+ surface.waitForFrame();
+ QTRY_VERIFY(player.position() < player.duration() / 2);
+ player.setPosition(player.duration() * 8 / 9);
+
+ // wait for the 3rd loop and seek
+ surface.waitForFrame();
+ QTRY_VERIFY(player.position() < player.duration() / 2);
+ player.setPosition(player.duration() * 4 / 5);
+
+ QTRY_COMPARE(player.playbackState(), QMediaPlayer::StoppedState);
+
+ auto intervals = positionChangingIntervals(positionSpy);
+
+ QCOMPARE(intervals.size(), 3);
+ QCOMPARE_GT(intervals[0].first, 0);
+ QCOMPARE(intervals[0].second, player.duration());
+ QCOMPARE(intervals[1], std::make_pair(qint64(0), player.duration()));
+ QCOMPARE(intervals[2], std::make_pair(qint64(0), player.duration()));
+
+ QCOMPARE(player.mediaStatus(), QMediaPlayer::EndOfMedia);
+}
+
+void tst_QMediaPlayerBackend::changeLoopsOnTheFly()
+{
+ if (localVideoFile3ColorsWithSound.isEmpty())
+ QSKIP("Video format is not supported");
+
+#ifdef Q_OS_MACOS
+ if (qEnvironmentVariable("QTEST_ENVIRONMENT").toLower() == "ci")
+ QSKIP("The test accidently gets crashed on macOS CI, not reproduced locally. To be "
+ "investigated: QTBUG-111744");
+#endif
+
+ TestVideoSink surface(false);
+ QMediaPlayer player;
+
+ QSignalSpy positionSpy(&player, &QMediaPlayer::positionChanged);
+
+ player.setVideoOutput(&surface);
+ player.setLoops(4);
+ player.setPlaybackRate(5);
+
+ player.setSource(localVideoFile3ColorsWithSound);
+
+ player.play();
+ surface.waitForFrame();
+
+ player.setPosition(player.duration() * 4 / 5);
+
+ // wait for the 2nd loop
+ surface.waitForFrame();
+ QTRY_VERIFY(player.position() < player.duration() / 2);
+ player.setPosition(player.duration() * 8 / 9);
+
+ player.setLoops(1);
+
+ QTRY_COMPARE(player.playbackState(), QMediaPlayer::StoppedState);
+ QCOMPARE(player.mediaStatus(), QMediaPlayer::EndOfMedia);
+
+ auto intervals = positionChangingIntervals(positionSpy);
+ QCOMPARE(intervals.size(), 2);
+
+ QCOMPARE(intervals[1], std::make_pair(qint64(0), player.duration()));
+}
+
void tst_QMediaPlayerBackend::lazyLoadVideo()
{
QQmlEngine engine;