summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJøger Hansegård <joger.hansegard@qt.io>2023-08-10 14:17:01 +0200
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2023-08-10 16:33:44 +0000
commitc52c908d94ac84a90f2d3c82564d3a7b2550b830 (patch)
tree17acb7ee06b095817867189d4edbe3cbc2f01ad3
parente41b9c4d355fa10f473f83a82dc99013801851f2 (diff)
Fix mediaplayer scroll issue if stream duration is missing
If a media file is missing per stream duration data, the mediaplayer slider operations to scroll in video would restart the video from start. The cause of the issue was that the mediaplayer duration was calculated from the stream durations and became 0. The ffmpeg demuxer already has more advanced heuristics to calculate the media file duration, and this patch fixes the issue by also taking the media file duration into account. Fixes: QTBUG-115747 Change-Id: I906f62c15ffdccadf1da07a75a109961d897b1b0 Reviewed-by: Artem Dyomin <artem.dyomin@qt.io> (cherry picked from commit 42107b9d263802d361451c00c8b623fcd45e6922) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r--src/plugins/multimedia/ffmpeg/playbackengine/qffmpegmediadataholder.cpp6
-rw-r--r--tests/auto/integration/qmediaplayerbackend/tst_qmediaplayerbackend.cpp72
2 files changed, 65 insertions, 13 deletions
diff --git a/src/plugins/multimedia/ffmpeg/playbackengine/qffmpegmediadataholder.cpp b/src/plugins/multimedia/ffmpeg/playbackengine/qffmpegmediadataholder.cpp
index 2133548f3..fdb03a806 100644
--- a/src/plugins/multimedia/ffmpeg/playbackengine/qffmpegmediadataholder.cpp
+++ b/src/plugins/multimedia/ffmpeg/playbackengine/qffmpegmediadataholder.cpp
@@ -233,6 +233,12 @@ void MediaDataHolder::updateStreams()
m_streamMap[trackType].append({ (int)i, isDefault, metaData });
}
+ // With some media files, streams may be lacking duration info. Let's
+ // get it from ffmpeg's duration estimation instead.
+ if (m_duration == 0 && m_context->duration > 0ll) {
+ m_duration = m_context->duration;
+ }
+
for (auto trackType :
{ QPlatformMediaPlayer::VideoStream, QPlatformMediaPlayer::AudioStream }) {
auto &requestedStream = m_requestedStreams[trackType];
diff --git a/tests/auto/integration/qmediaplayerbackend/tst_qmediaplayerbackend.cpp b/tests/auto/integration/qmediaplayerbackend/tst_qmediaplayerbackend.cpp
index fbf5ce2b3..0cc943818 100644
--- a/tests/auto/integration/qmediaplayerbackend/tst_qmediaplayerbackend.cpp
+++ b/tests/auto/integration/qmediaplayerbackend/tst_qmediaplayerbackend.cpp
@@ -74,6 +74,7 @@ private slots:
void multiplePlaybackRateChangingStressTest();
void multipleSeekStressTest();
void playbackRateChanging();
+ void durationDetectionIssues_data();
void durationDetectionIssues();
void finiteLoops();
void infiniteLoops();
@@ -98,8 +99,6 @@ private:
QUrl localCompressedSoundFile;
QUrl localFileWithMetadata;
QUrl localVideoFile3ColorsWithSound;
- QUrl videoWithDurationIssues; // ffmpeg detects stream an incorrect stream duration, so we take
- // the correct duration from the metadata
const std::array<QRgb, 3> video3Colors = { { 0xFF0000, 0x00FF00, 0x0000FF } };
@@ -233,9 +232,6 @@ void tst_QMediaPlayerBackend::initTestCase()
localFileWithMetadata =
MediaFileSelector::selectMediaFile(QStringList() << "qrc:/testdata/nokia-tune.mp3");
- videoWithDurationIssues = MediaFileSelector::selectMediaFile(
- QStringList() << "qrc:/testdata/duration_issues.webm");
-
qgetenv("QT_TEST_CI").toInt(&m_inCISystem,10);
}
@@ -1705,10 +1701,49 @@ void tst_QMediaPlayerBackend::position()
QVERIFY(player.position() < 550);
}
+void tst_QMediaPlayerBackend::durationDetectionIssues_data()
+{
+ QTest::addColumn<QString>("mediaFile");
+ QTest::addColumn<qint64>("expectedDuration");
+ QTest::addColumn<int>("expectedVideoTrackCount");
+ QTest::addColumn<qint64>("expectedVideoTrackDuration");
+ QTest::addColumn<int>("expectedAudioTrackCount");
+ QTest::addColumn<QVariant>("expectedAudioTrackDuration");
+
+ // clang-format off
+
+ QTest::newRow("stream-duration-in-metadata")
+ << QString{ "qrc:/testdata/duration_issues.webm" }
+ << 400ll // Total media duration
+ << 1 // Number of video tracks in file
+ << 400ll // Video stream duration
+ << 0 // Number of audio tracks in file
+ << QVariant{}; // Audio stream duration (unused)
+
+ QTest::newRow("no-stream-duration-in-metadata")
+ << QString{ "qrc:/testdata/nokia-tune.mkv" }
+ << 7531ll // Total media duration
+ << 0 // Number of video tracks in file
+ << 0ll // Video stream duration (unused)
+ << 1 // Number of audio tracks in file
+ << QVariant{}; // Audio stream duration (not present on file)
+
+ // clang-format on
+}
+
void tst_QMediaPlayerBackend::durationDetectionIssues()
{
- if (videoWithDurationIssues.isEmpty())
- QSKIP("No supported video file");
+ QFETCH(QString, mediaFile);
+ QFETCH(qint64, expectedDuration);
+ QFETCH(int, expectedVideoTrackCount);
+ QFETCH(qint64, expectedVideoTrackDuration);
+ QFETCH(int, expectedAudioTrackCount);
+ QFETCH(QVariant, expectedAudioTrackDuration);
+
+ // ffmpeg detects stream an incorrect stream duration, so we take
+ // the correct duration from the metadata
+ const QUrl videoWithDurationIssues =
+ MediaFileSelector::selectMediaFile({ mediaFile });
TestVideoSink surface(false);
QAudioOutput output;
@@ -1720,15 +1755,26 @@ void tst_QMediaPlayerBackend::durationDetectionIssues()
player.setAudioOutput(&output);
player.setSource(videoWithDurationIssues);
+ // Duration event received
QCOMPARE(durationSpy.size(), 1);
- QCOMPARE(durationSpy.front().front(), QVariant(qint64(400)));
+ QCOMPARE(durationSpy.front().front(), expectedDuration);
+
+ // Duration property
+ QCOMPARE(player.duration(), expectedDuration);
+ QCOMPARE(player.metaData().value(QMediaMetaData::Duration), expectedDuration);
+
+ // Track duration properties
+ const auto videoTracks = player.videoTracks();
+ QCOMPARE(videoTracks.size(), expectedVideoTrackCount);
+
+ if (expectedVideoTrackCount != 0)
+ QCOMPARE(videoTracks.front().value(QMediaMetaData::Duration), expectedVideoTrackDuration);
- QCOMPARE(player.duration(), 400);
- QCOMPARE(player.metaData().value(QMediaMetaData::Duration), QVariant(qint64(400)));
+ const auto audioTracks = player.audioTracks();
+ QCOMPARE(audioTracks.size(), expectedAudioTrackCount);
- auto videoTracks = player.videoTracks();
- QCOMPARE(videoTracks.size(), 1);
- QCOMPARE(videoTracks.front().value(QMediaMetaData::Duration), QVariant(qint64(400)));
+ if (expectedAudioTrackCount != 0)
+ QCOMPARE(audioTracks.front().value(QMediaMetaData::Duration), expectedAudioTrackDuration);
}
static std::vector<std::pair<qint64, qint64>>