Skip to content

Commit 45a128e

Browse files
jyavenardaperezdc
authored andcommitted
[MSE] Media from the TimeRange containing currentTime can be evicted when it shouldn't https://bugs.webkit.org/show_bug.cgi?id=270034 rdar://problem/123556056 Reviewed by Eric Carlson. We want none of the data contiguous from the currentTime to the next discontinuity to be evicted to ensure continuous playback. This is inline with Google's proposal for having Eviction Policies. The comments in the eviction code indicated as such, but a logic error would have made the end of the current range be truncated if it was followed by another range after a discontinuity. * LayoutTests/media/media-source/media-managedmse-eviction-expected.txt: Added. * LayoutTests/media/media-source/media-managedmse-eviction.html: Added. * LayoutTests/platform/glib/TestExpectations: * Source/WebCore/platform/graphics/SourceBufferPrivate.cpp: (WebCore::SourceBufferPrivate::evictFrames): Canonical link: https://commits.webkit.org/275306@main Canonical link: https://commits.webkit.org/274313.185@webkitglib/2.44
1 parent f923d49 commit 45a128e

File tree

4 files changed

+123
-2
lines changed

4 files changed

+123
-2
lines changed
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
2+
EXPECTED (source.readyState == 'closed') OK
3+
RUN(video.src = URL.createObjectURL(source))
4+
RUN(video.disableRemotePlayback = true)
5+
EVENT(sourceopen)
6+
RUN(sourceBuffer = source.addSourceBuffer("video/mock; codecs=mock"))
7+
RUN(sourceBuffer.onbufferedchange = bufferedChange)
8+
RUN(initSegment = makeAInit(10, [makeATrack(1, 'mock', TRACK_KIND.VIDEO)]))
9+
RUN(sourceBuffer.appendBuffer(initSegment))
10+
EVENT(updateend)
11+
RUN(sourceBuffer.appendBuffer(syncSampleRun(0, 10)))
12+
onbufferedchange called.
13+
e.addedRanges = [0, 10)
14+
e.removedRanges = []
15+
EVENT(update)
16+
RUN(sourceBuffer.appendBuffer(syncSampleRun(10, 15)))
17+
onbufferedchange called.
18+
e.addedRanges = [10, 15)
19+
e.removedRanges = []
20+
EVENT(update)
21+
RUN(sourceBuffer.appendBuffer(syncSampleRun(15, 20)))
22+
onbufferedchange called.
23+
e.addedRanges = [15, 20)
24+
e.removedRanges = []
25+
EVENT(update)
26+
EXPECTED (sourceBuffer.buffered.length == '1') OK
27+
RUN(sourceBuffer.appendBuffer(syncSampleRun(22, 30)))
28+
onbufferedchange called.
29+
e.addedRanges = [22, 30)
30+
e.removedRanges = []
31+
EVENT(update)
32+
EXPECTED (sourceBuffer.buffered.length == '2') OK
33+
RUN(video.currentTime = 9)
34+
EVENT(seeked)
35+
RUN(internals.beginSimulatedMemoryPressure())
36+
onbufferedchange called.
37+
e.addedRanges = []
38+
e.removedRanges = [22, 30)
39+
EVENT(bufferedchange)
40+
RUN(internals.endSimulatedMemoryPressure())
41+
EXPECTED (sourceBuffer.buffered.length == '1') OK
42+
EXPECTED (sourceBuffer.buffered.end(0) == '20') OK
43+
END OF TEST
44+
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
<!DOCTYPE html> <!-- webkit-test-runner [ ManagedMediaSourceEnabled=true MediaSourceEnabled=true ] -->
2+
<html>
3+
<head>
4+
<title>managedmediasource-memoryPressure</title>
5+
<script src="mock-media-source.js"></script>
6+
<script src="../../media/video-test.js"></script>
7+
<script src="../../media/utilities.js"></script>
8+
<script>
9+
var source;
10+
var sourceBuffer;
11+
var initsegment;
12+
13+
if (window.internals)
14+
internals.initializeMockMediaSource();
15+
16+
function syncSampleRun(start, end, stepSync = 9999999999) {
17+
const samples = [];
18+
for (let time = start; time < end; time++)
19+
samples.push(makeASample(time, time, 1, 1, 1, (time - start) % stepSync == 0 ? SAMPLE_FLAG.SYNC : SAMPLE_FLAG.NONE));
20+
return concatenateSamples(samples);
21+
}
22+
23+
function bufferedChange(e) {
24+
consoleWrite('onbufferedchange called.')
25+
consoleWrite(`e.addedRanges = ${ timeRangesToString(e.addedRanges) }`);
26+
consoleWrite(`e.removedRanges = ${ timeRangesToString(e.removedRanges) }`);
27+
};
28+
29+
window.addEventListener('load', async event => {
30+
findMediaElement();
31+
32+
source = new ManagedMediaSource();
33+
34+
testExpected('source.readyState', 'closed');
35+
run('video.src = URL.createObjectURL(source)');
36+
run('video.disableRemotePlayback = true');
37+
await waitFor(source, 'sourceopen');
38+
39+
run('sourceBuffer = source.addSourceBuffer("video/mock; codecs=mock")');
40+
run('sourceBuffer.onbufferedchange = bufferedChange');
41+
42+
run("initSegment = makeAInit(10, [makeATrack(1, 'mock', TRACK_KIND.VIDEO)])");
43+
44+
run('sourceBuffer.appendBuffer(initSegment)');
45+
await waitFor(sourceBuffer, 'updateend');
46+
47+
run('sourceBuffer.appendBuffer(syncSampleRun(0, 10))');
48+
await waitFor(sourceBuffer, 'update');
49+
run('sourceBuffer.appendBuffer(syncSampleRun(10, 15))');
50+
await waitFor(sourceBuffer, 'update');
51+
run('sourceBuffer.appendBuffer(syncSampleRun(15, 20))');
52+
await waitFor(sourceBuffer, 'update');
53+
testExpected('sourceBuffer.buffered.length', '1');
54+
55+
run('sourceBuffer.appendBuffer(syncSampleRun(22, 30))');
56+
await waitFor(sourceBuffer, 'update');
57+
testExpected('sourceBuffer.buffered.length', '2');
58+
59+
run('video.currentTime = 9');
60+
await waitFor(video, 'seeked');
61+
run('internals.beginSimulatedMemoryPressure()');
62+
await waitFor(sourceBuffer, 'bufferedchange');
63+
run('internals.endSimulatedMemoryPressure()');
64+
testExpected('sourceBuffer.buffered.length', '1');
65+
testExpected('sourceBuffer.buffered.end(0)', '20');
66+
endTest();
67+
});
68+
</script>
69+
</head>
70+
<body>
71+
<video controls></video>
72+
</body>
73+
</html>

LayoutTests/platform/glib/TestExpectations

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1059,6 +1059,7 @@ webkit.org/b/265919 media/track/media-source-audio-track.html [ Failure ]
10591059
# WebProcess's MemoryPressureHandler are disabled, test is nonfunctional
10601060
media/media-source/media-managedmse-memorypressure.html [ Timeout ]
10611061
media/media-source/media-managedmse-memorypressure-inactive.html [ Timeout ]
1062+
media/media-source/media-managedmse-eviction.html [ Timeout ]
10621063
# No AirPlay on glib platforms.
10631064
media/media-source/media-managedmse-airplay.html [ Skip ]
10641065

Source/WebCore/platform/graphics/SourceBufferPrivate.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1225,8 +1225,11 @@ bool SourceBufferPrivate::evictFrames(uint64_t newDataSize, uint64_t maximumBuff
12251225
size_t currentTimeRange = buffered.find(currentTime);
12261226
size_t startTimeRange = buffered.find(rangeStart);
12271227
if (currentTimeRange != notFound && startTimeRange == currentTimeRange) {
1228-
size_t endTimeRange = buffered.find(rangeEnd);
1229-
if (endTimeRange == currentTimeRange)
1228+
currentTimeRange++;
1229+
if (currentTimeRange == buffered.length())
1230+
break;
1231+
rangeStart = buffered.start(currentTimeRange);
1232+
if (rangeStart >= rangeEnd)
12301233
break;
12311234
}
12321235

0 commit comments

Comments
 (0)