Skip to content

Commit

Permalink
Cherry-pick 275306@main (19f8847). https://bugs.webkit.org/show_bug.c…
Browse files Browse the repository at this point in the history
…gi?id=270034

    [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
  • Loading branch information
jyavenard authored and aperezdc committed Apr 30, 2024
1 parent f923d49 commit 45a128e
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@

EXPECTED (source.readyState == 'closed') OK
RUN(video.src = URL.createObjectURL(source))
RUN(video.disableRemotePlayback = true)
EVENT(sourceopen)
RUN(sourceBuffer = source.addSourceBuffer("video/mock; codecs=mock"))
RUN(sourceBuffer.onbufferedchange = bufferedChange)
RUN(initSegment = makeAInit(10, [makeATrack(1, 'mock', TRACK_KIND.VIDEO)]))
RUN(sourceBuffer.appendBuffer(initSegment))
EVENT(updateend)
RUN(sourceBuffer.appendBuffer(syncSampleRun(0, 10)))
onbufferedchange called.
e.addedRanges = [0, 10)
e.removedRanges = []
EVENT(update)
RUN(sourceBuffer.appendBuffer(syncSampleRun(10, 15)))
onbufferedchange called.
e.addedRanges = [10, 15)
e.removedRanges = []
EVENT(update)
RUN(sourceBuffer.appendBuffer(syncSampleRun(15, 20)))
onbufferedchange called.
e.addedRanges = [15, 20)
e.removedRanges = []
EVENT(update)
EXPECTED (sourceBuffer.buffered.length == '1') OK
RUN(sourceBuffer.appendBuffer(syncSampleRun(22, 30)))
onbufferedchange called.
e.addedRanges = [22, 30)
e.removedRanges = []
EVENT(update)
EXPECTED (sourceBuffer.buffered.length == '2') OK
RUN(video.currentTime = 9)
EVENT(seeked)
RUN(internals.beginSimulatedMemoryPressure())
onbufferedchange called.
e.addedRanges = []
e.removedRanges = [22, 30)
EVENT(bufferedchange)
RUN(internals.endSimulatedMemoryPressure())
EXPECTED (sourceBuffer.buffered.length == '1') OK
EXPECTED (sourceBuffer.buffered.end(0) == '20') OK
END OF TEST

73 changes: 73 additions & 0 deletions LayoutTests/media/media-source/media-managedmse-eviction.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<!DOCTYPE html> <!-- webkit-test-runner [ ManagedMediaSourceEnabled=true MediaSourceEnabled=true ] -->
<html>
<head>
<title>managedmediasource-memoryPressure</title>
<script src="mock-media-source.js"></script>
<script src="../../media/video-test.js"></script>
<script src="../../media/utilities.js"></script>
<script>
var source;
var sourceBuffer;
var initsegment;

if (window.internals)
internals.initializeMockMediaSource();

function syncSampleRun(start, end, stepSync = 9999999999) {
const samples = [];
for (let time = start; time < end; time++)
samples.push(makeASample(time, time, 1, 1, 1, (time - start) % stepSync == 0 ? SAMPLE_FLAG.SYNC : SAMPLE_FLAG.NONE));
return concatenateSamples(samples);
}

function bufferedChange(e) {
consoleWrite('onbufferedchange called.')
consoleWrite(`e.addedRanges = ${ timeRangesToString(e.addedRanges) }`);
consoleWrite(`e.removedRanges = ${ timeRangesToString(e.removedRanges) }`);
};

window.addEventListener('load', async event => {
findMediaElement();

source = new ManagedMediaSource();

testExpected('source.readyState', 'closed');
run('video.src = URL.createObjectURL(source)');
run('video.disableRemotePlayback = true');
await waitFor(source, 'sourceopen');

run('sourceBuffer = source.addSourceBuffer("video/mock; codecs=mock")');
run('sourceBuffer.onbufferedchange = bufferedChange');

run("initSegment = makeAInit(10, [makeATrack(1, 'mock', TRACK_KIND.VIDEO)])");

run('sourceBuffer.appendBuffer(initSegment)');
await waitFor(sourceBuffer, 'updateend');

run('sourceBuffer.appendBuffer(syncSampleRun(0, 10))');
await waitFor(sourceBuffer, 'update');
run('sourceBuffer.appendBuffer(syncSampleRun(10, 15))');
await waitFor(sourceBuffer, 'update');
run('sourceBuffer.appendBuffer(syncSampleRun(15, 20))');
await waitFor(sourceBuffer, 'update');
testExpected('sourceBuffer.buffered.length', '1');

run('sourceBuffer.appendBuffer(syncSampleRun(22, 30))');
await waitFor(sourceBuffer, 'update');
testExpected('sourceBuffer.buffered.length', '2');

run('video.currentTime = 9');
await waitFor(video, 'seeked');
run('internals.beginSimulatedMemoryPressure()');
await waitFor(sourceBuffer, 'bufferedchange');
run('internals.endSimulatedMemoryPressure()');
testExpected('sourceBuffer.buffered.length', '1');
testExpected('sourceBuffer.buffered.end(0)', '20');
endTest();
});
</script>
</head>
<body>
<video controls></video>
</body>
</html>
1 change: 1 addition & 0 deletions LayoutTests/platform/glib/TestExpectations
Original file line number Diff line number Diff line change
Expand Up @@ -1059,6 +1059,7 @@ webkit.org/b/265919 media/track/media-source-audio-track.html [ Failure ]
# WebProcess's MemoryPressureHandler are disabled, test is nonfunctional
media/media-source/media-managedmse-memorypressure.html [ Timeout ]
media/media-source/media-managedmse-memorypressure-inactive.html [ Timeout ]
media/media-source/media-managedmse-eviction.html [ Timeout ]
# No AirPlay on glib platforms.
media/media-source/media-managedmse-airplay.html [ Skip ]

Expand Down
7 changes: 5 additions & 2 deletions Source/WebCore/platform/graphics/SourceBufferPrivate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1225,8 +1225,11 @@ bool SourceBufferPrivate::evictFrames(uint64_t newDataSize, uint64_t maximumBuff
size_t currentTimeRange = buffered.find(currentTime);
size_t startTimeRange = buffered.find(rangeStart);
if (currentTimeRange != notFound && startTimeRange == currentTimeRange) {
size_t endTimeRange = buffered.find(rangeEnd);
if (endTimeRange == currentTimeRange)
currentTimeRange++;
if (currentTimeRange == buffered.length())
break;
rangeStart = buffered.start(currentTimeRange);
if (rangeStart >= rangeEnd)
break;
}

Expand Down

0 comments on commit 45a128e

Please sign in to comment.