Skip to content

Commit eb6ae0a

Browse files
committed
[MSE][GStreamer] allow fallback to seeked position on seek finish
https://bugs.webkit.org/show_bug.cgi?id=275104 Reviewed by Philippe Normand. MediaPlayerPrivateGStreamer may report incorrect position (last cached) immediately after seek. This can happen when didPreroll is called on async-done with pipeline still in async transition to playing state: current: PAUSED, pending: PLAYING, result: ASYNC. r277541 disables querying position from the sinks in this case resulting in last cached value (before seek) to be returned. Which confuses some tests from YouTube WV SFR/HFR suite, and makes it trigger multiple seeks one after another. The proposed change works around the problem by allowing fall back to last seeked position until pipeline preroll completes. Similar to MediaPlayerPrivateGStreamer::finishSeek(). Patch by Eugene Mutavchi <Ievgen_Mutavchi@comcast.com>. * LayoutTests/media/media-source/media-source-seek-back-after-ended-expected.txt: Added. * LayoutTests/media/media-source/media-source-seek-back-after-ended.html: Added. * LayoutTests/platform/mac-wk1/TestExpectations: * Source/WebCore/platform/graphics/gstreamer/mse/MediaPlayerPrivateGStreamerMSE.cpp: (WebCore::MediaPlayerPrivateGStreamerMSE::didPreroll): Canonical link: https://commits.webkit.org/279901@main
1 parent a38e31b commit eb6ae0a

4 files changed

Lines changed: 1450 additions & 466 deletions

File tree

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
This tests that a SourceBuffer can accept an initialization segment and a media segment and fire "update" events, the element can play and seek back properly when it's ended.
2+
3+
RUN(video.src = URL.createObjectURL(source))
4+
EVENT(sourceopen)
5+
RUN(source.duration = loader.duration())
6+
RUN(sourceBuffer = source.addSourceBuffer(loader.type()))
7+
RUN(sourceBuffer.appendBuffer(loader.initSegment()))
8+
EVENT(update)
9+
RUN(sourceBuffer.appendBuffer(loader.mediaSegment(0)))
10+
EVENT(update)
11+
RUN(source.endOfStream())
12+
RUN(await video.play())
13+
EXPECTED (video.paused == 'false') OK
14+
EVENT(ended)
15+
RUN(video.currentTime = 0)
16+
EVENT(seeked)
17+
RUN(await video.play())
18+
EXPECTED (video.paused == 'false') OK
19+
EXPECTED (video.currentTime > '1') OK
20+
END OF TEST
21+
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<title>media-source-seek-back-after-ended</title>
5+
<script src="media-source-loader.js"></script>
6+
<script src="../video-test.js"></script>
7+
<script>
8+
var loader;
9+
var source;
10+
var sourceBuffer;
11+
12+
function loaderPromise(loader) {
13+
return new Promise((resolve, reject) => {
14+
loader.onload = resolve;
15+
loader.onerror = reject;
16+
});
17+
}
18+
19+
function timeUpdatePromise(video) {
20+
return new Promise(resolve => {
21+
video.addEventListener('timeupdate', event => {
22+
if (!video.paused && video.currentTime > 1) {
23+
testExpected("video.paused", false);
24+
testExpected("video.currentTime", 1, ">");
25+
resolve();
26+
}
27+
});
28+
});
29+
}
30+
31+
window.addEventListener('load', async event => {
32+
try {
33+
findMediaElement();
34+
35+
loader = new MediaSourceLoader('content/test-vp9-manifest.json');
36+
await loaderPromise(loader);
37+
38+
source = new MediaSource();
39+
run('video.src = URL.createObjectURL(source)');
40+
await waitFor(source, 'sourceopen');
41+
waitForEventAndFail('error');
42+
43+
run('source.duration = loader.duration()');
44+
run('sourceBuffer = source.addSourceBuffer(loader.type())');
45+
run('sourceBuffer.appendBuffer(loader.initSegment())');
46+
await waitFor(sourceBuffer, 'update');
47+
48+
run('sourceBuffer.appendBuffer(loader.mediaSegment(0))');
49+
await waitFor(sourceBuffer, 'update');
50+
run('source.endOfStream()');
51+
52+
await video.play();
53+
consoleWrite("RUN(await video.play())");
54+
testExpected("video.paused", false);
55+
56+
await waitFor(video, 'ended');
57+
58+
run('video.currentTime = 0');
59+
await waitFor(video, 'seeked');
60+
await video.play();
61+
consoleWrite("RUN(await video.play())");
62+
63+
await timeUpdatePromise(video);
64+
65+
endTest();
66+
} catch (e) {
67+
failTest(`Caught exception: "${e}"`);
68+
}
69+
});
70+
</script>
71+
</head>
72+
<body>
73+
<div>
74+
This tests that a SourceBuffer can accept an initialization segment and a media segment and fire "update" events,
75+
the element can play and seek back properly when it's ended.
76+
</div>
77+
<video controls></video>
78+
</body>
79+
</html>

0 commit comments

Comments
 (0)