Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
Add BufferedChangeEvent object
https://bugs.webkit.org/show_bug.cgi?id=256985 rdar://109532732 Reviewed by Youenn Fablet. Pass to `bufferedchange` a dictionary containing the range added and removed from the last operation on the source buffer. Fly-by: remove the need for code to be conditional on both ENABLE(MEDIA_SOURCE) and ENABLE(MANAGED_MEDIA_SOURCE), assume that if the latter is true, then so is the first, as doing otherwise would be totally nonsensical. * LayoutTests/media/media-source/media-managedmse-bufferedchange-expected.txt: * LayoutTests/media/media-source/media-managedmse-bufferedchange.html: Check that object received is of type BufferedChangeEvent * LayoutTests/media/media-source/mock-managedmse-bufferedchange-expected.txt: Added. * LayoutTests/media/media-source/mock-managedmse-bufferedchange.html: Added. * LayoutTests/media/utilities.js: (timeRangesToString): * Source/WTF/Scripts/Preferences/UnifiedWebPreferences.yaml: * Source/WebCore/CMakeLists.txt: * Source/WebCore/DerivedSources-input.xcfilelist: * Source/WebCore/DerivedSources-output.xcfilelist: * Source/WebCore/DerivedSources.make: * Source/WebCore/Modules/mediasource/BufferedChangeEvent.cpp: Copied from Source/WebCore/Modules/mediasource/ManagedSourceBuffer.cpp. (WebCore::BufferedChangeEvent::BufferedChangeEvent): (WebCore::BufferedChangeEvent::eventInterface const): * Source/WebCore/Modules/mediasource/BufferedChangeEvent.h: Copied from Source/WebCore/Modules/mediasource/ManagedSourceBuffer.h. * Source/WebCore/Modules/mediasource/BufferedChangeEvent.idl: Copied from Source/WebCore/Modules/mediasource/ManagedSourceBuffer.idl. * Source/WebCore/Modules/mediasource/ManagedMediaSource.cpp: * Source/WebCore/Modules/mediasource/ManagedMediaSource.h: * Source/WebCore/Modules/mediasource/ManagedMediaSource.idl: * Source/WebCore/Modules/mediasource/ManagedSourceBuffer.cpp: * Source/WebCore/Modules/mediasource/ManagedSourceBuffer.h: * Source/WebCore/Modules/mediasource/ManagedSourceBuffer.idl: * Source/WebCore/Modules/mediasource/MediaSource.cpp: * Source/WebCore/Modules/mediasource/MediaSource.h: * Source/WebCore/Modules/mediasource/SourceBuffer.cpp: (WebCore::SourceBuffer::buffered): (WebCore::SourceBuffer::sourceBufferPrivateBufferedChanged): * Source/WebCore/Modules/mediasource/SourceBuffer.h: * Source/WebCore/Sources.txt: * Source/WebCore/WebCore.xcodeproj/project.pbxproj: * Source/WebCore/bindings/js/WebCoreBuiltinNames.h: * Source/WebCore/dom/EventNames.in: * Source/WebCore/html/HTMLMediaElement.cpp: (WebCore::HTMLMediaElement::setBufferingPolicy): Change to be conditional on MANAGED_MEDIA_SOURCE (WebCore::HTMLMediaElement::purgeBufferedDataIfPossible): same as above * Source/WebCore/platform/graphics/PlatformTimeRanges.cpp: (WebCore::PlatformTimeRanges::operator+=): Add alias to `unionWith` method for naming consistency. (WebCore::PlatformTimeRanges::operator-=): Add operator to process calculation of range removal. * Source/WebCore/platform/graphics/PlatformTimeRanges.h: Canonical link: https://commits.webkit.org/264472@main
- Loading branch information
Showing
30 changed files
with
510 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
103 changes: 103 additions & 0 deletions
103
LayoutTests/media/media-source/mock-managedmse-bufferedchange-expected.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
|
||
EXPECTED (source.readyState == 'closed') OK | ||
RUN(sourceElement = document.createElement("source")) | ||
RUN(sourceElement.type = "video/mock; codecs=mock") | ||
RUN(sourceElement.src = URL.createObjectURL(source)) | ||
RUN(video.appendChild(sourceElement)) | ||
RUN(sourceElement = document.createElement("source")) | ||
RUN(sourceElement.src = "http://foo.com/playlist.m3u8") | ||
RUN(sourceElement.type = "application/vnd.apple.mpegurl") | ||
RUN(video.appendChild(sourceElement)) | ||
EVENT(sourceopen) | ||
RUN(sourceBuffer = source.addSourceBuffer("video/mock; codecs=mock")) | ||
RUN(sourceBuffer.appendBuffer(initSegment)) | ||
EVENT(updateend) | ||
RUN(sourceBuffer.appendBuffer(syncSampleRun(5, 10))) | ||
onbufferedchange called. | ||
e.addedRanges = [5, 10) | ||
e.removedRanges = null | ||
EVENT(update) | ||
EXPECTED (sourceBuffer.buffered.length == '1') OK | ||
RUN(sourceBuffer.appendBuffer(syncSampleRun(0, 5))) | ||
onbufferedchange called. | ||
e.addedRanges = [0, 5) | ||
e.removedRanges = null | ||
EVENT(update) | ||
EXPECTED (sourceBuffer.buffered.length == '1') OK | ||
Clean sourcebuffer of all content. | ||
RUN(sourceBuffer.remove(0, sourceBuffer.buffered.end(0))) | ||
onbufferedchange called. | ||
e.addedRanges = null | ||
e.removedRanges = [0, 10) | ||
EVENT(update) | ||
EXPECTED (sourceBuffer.buffered.length == '0') OK | ||
RUN(sourceBuffer.appendBuffer(syncSampleRun(0, 3))) | ||
onbufferedchange called. | ||
e.addedRanges = [0, 3) | ||
e.removedRanges = null | ||
EVENT(update) | ||
RUN(sourceBuffer.appendBuffer(syncSampleRun(3, 6))) | ||
onbufferedchange called. | ||
e.addedRanges = [3, 6) | ||
e.removedRanges = null | ||
EVENT(update) | ||
RUN(sourceBuffer.appendBuffer(syncSampleRun(6, 9))) | ||
onbufferedchange called. | ||
e.addedRanges = [6, 9) | ||
e.removedRanges = null | ||
EVENT(update) | ||
Re-adding the same samples does not update the buffer | ||
RUN(sourceBuffer.appendBuffer(syncSampleRun(0, 3))) | ||
EVENT(update) | ||
Removing first sync sample, remove the first 3 seconds block | ||
RUN(sourceBuffer.remove(0, 1)) | ||
onbufferedchange called. | ||
e.addedRanges = null | ||
e.removedRanges = [0, 3) | ||
EVENT(update) | ||
Removing from 8 to infinity, remove to the end of existing buffer | ||
RUN(sourceBuffer.remove(8, Infinity)) | ||
onbufferedchange called. | ||
e.addedRanges = null | ||
e.removedRanges = [8, 9) | ||
EVENT(update) | ||
Removing from empty range, does not update the buffer | ||
RUN(sourceBuffer.remove(0, 2)) | ||
EVENT(update) | ||
Removing from non-sync sample | ||
RUN(sourceBuffer.remove(4, 5)) | ||
onbufferedchange called. | ||
e.addedRanges = null | ||
e.removedRanges = [4, 6) | ||
EVENT(update) | ||
Overriding sync sample, remove following block and only update buffer for missing samples | ||
before: [3, 4)[6, 8) | ||
RUN(sourceBuffer.appendBuffer(syncSampleRun(5, 7))) | ||
onbufferedchange called. | ||
e.addedRanges = [5, 6) | ||
e.removedRanges = [7, 8) | ||
EVENT(update) | ||
after: [3, 4)[5, 7) | ||
Only report samples added in missing intervals | ||
RUN(sourceBuffer.appendBuffer(syncSampleRun(0, 10, 2))) | ||
onbufferedchange called. | ||
e.addedRanges = [0, 3)[4, 5)[7, 10) | ||
e.removedRanges = null | ||
EVENT(update) | ||
RUN(sourceBuffer.remove(2, 4)) | ||
onbufferedchange called. | ||
e.addedRanges = null | ||
e.removedRanges = [2, 4) | ||
EVENT(update) | ||
RUN(sourceBuffer.remove(6, 8)) | ||
onbufferedchange called. | ||
e.addedRanges = null | ||
e.removedRanges = [6, 8) | ||
EVENT(update) | ||
RUN(sourceBuffer.remove(0, 10)) | ||
onbufferedchange called. | ||
e.addedRanges = null | ||
e.removedRanges = [0, 2)[4, 6)[8, 10) | ||
EVENT(update) | ||
END OF TEST | ||
|
117 changes: 117 additions & 0 deletions
117
LayoutTests/media/media-source/mock-managedmse-bufferedchange.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
<!DOCTYPE html> <!-- webkit-test-runner [ ManagedMediaSourceEnabled=true MediaSourceEnabled=true ] --> | ||
<html> | ||
<head> | ||
<title>managedmediasource</title> | ||
<script src="mock-media-source.js"></script> | ||
<script src="../../media/video-test.js"></script> | ||
<script src="../../media/utilities.js"></script> | ||
<script> | ||
var loader; | ||
var source; | ||
var sourceBuffer; | ||
var bufferedChangeEvent; | ||
var sourceElement; | ||
|
||
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); | ||
} | ||
|
||
window.addEventListener('load', async event => { | ||
findMediaElement(); | ||
|
||
source = new ManagedMediaSource(); | ||
|
||
testExpected('source.readyState', 'closed'); | ||
run('sourceElement = document.createElement("source")'); | ||
run('sourceElement.type = "video/mock; codecs=mock"'); | ||
run('sourceElement.src = URL.createObjectURL(source)'); | ||
run('video.appendChild(sourceElement)'); | ||
run('sourceElement = document.createElement("source")'); | ||
run('sourceElement.src = "http://foo.com/playlist.m3u8"'); | ||
run('sourceElement.type = "application/vnd.apple.mpegurl"'); | ||
run('video.appendChild(sourceElement)'); | ||
await waitFor(source, 'sourceopen'); | ||
|
||
run('sourceBuffer = source.addSourceBuffer("video/mock; codecs=mock")'); | ||
sourceBuffer.onbufferedchange = (e) => { | ||
consoleWrite('onbufferedchange called.') | ||
consoleWrite(`e.addedRanges = ${ timeRangesToString(e.addedRanges) }`); | ||
consoleWrite(`e.removedRanges = ${ timeRangesToString(e.removedRanges) }`); | ||
}; | ||
|
||
initSegment = makeAInit(10, [makeATrack(1, 'mock', TRACK_KIND.VIDEO)]); | ||
|
||
run('sourceBuffer.appendBuffer(initSegment)'); | ||
await waitFor(sourceBuffer, 'updateend'); | ||
|
||
run('sourceBuffer.appendBuffer(syncSampleRun(5, 10))'); | ||
await waitFor(sourceBuffer, 'update'); | ||
testExpected('sourceBuffer.buffered.length', '1'); | ||
|
||
run('sourceBuffer.appendBuffer(syncSampleRun(0, 5))'); | ||
await waitFor(sourceBuffer, 'update'); | ||
testExpected('sourceBuffer.buffered.length', '1'); | ||
|
||
consoleWrite('Clean sourcebuffer of all content.'); | ||
run('sourceBuffer.remove(0, sourceBuffer.buffered.end(0))'); | ||
await waitFor(sourceBuffer, 'update'); | ||
testExpected('sourceBuffer.buffered.length', '0'); | ||
|
||
run('sourceBuffer.appendBuffer(syncSampleRun(0, 3))'); | ||
await waitFor(sourceBuffer, 'update'); | ||
run('sourceBuffer.appendBuffer(syncSampleRun(3, 6))'); | ||
await waitFor(sourceBuffer, 'update'); | ||
run('sourceBuffer.appendBuffer(syncSampleRun(6, 9))'); | ||
await waitFor(sourceBuffer, 'update'); | ||
|
||
consoleWrite('Re-adding the same samples does not update the buffer'); | ||
run('sourceBuffer.appendBuffer(syncSampleRun(0, 3))'); | ||
await waitFor(sourceBuffer, 'update'); | ||
|
||
consoleWrite('Removing first sync sample, remove the first 3 seconds block'); | ||
run('sourceBuffer.remove(0, 1)'); | ||
await waitFor(sourceBuffer, 'update'); | ||
|
||
consoleWrite('Removing from 8 to infinity, remove to the end of existing buffer'); | ||
run('sourceBuffer.remove(8, Infinity)'); | ||
await waitFor(sourceBuffer, 'update'); | ||
|
||
consoleWrite('Removing from empty range, does not update the buffer'); | ||
run('sourceBuffer.remove(0, 2)'); | ||
await waitFor(sourceBuffer, 'update'); | ||
|
||
consoleWrite('Removing from non-sync sample'); | ||
run('sourceBuffer.remove(4, 5)'); | ||
await waitFor(sourceBuffer, 'update'); | ||
|
||
consoleWrite('Overriding sync sample, remove following block and only update buffer for missing samples'); | ||
consoleWrite(`before: ${ timeRangesToString(sourceBuffer.buffered) }`); | ||
run('sourceBuffer.appendBuffer(syncSampleRun(5, 7))'); | ||
await waitFor(sourceBuffer, 'update'); | ||
consoleWrite(`after: ${ timeRangesToString(sourceBuffer.buffered) }`); | ||
|
||
consoleWrite('Only report samples added in missing intervals'); | ||
run('sourceBuffer.appendBuffer(syncSampleRun(0, 10, 2))'); | ||
await waitFor(sourceBuffer, 'update'); | ||
|
||
run('sourceBuffer.remove(2, 4)'); | ||
await waitFor(sourceBuffer, 'update'); | ||
run('sourceBuffer.remove(6, 8)'); | ||
await waitFor(sourceBuffer, 'update'); | ||
run('sourceBuffer.remove(0, 10)'); | ||
await waitFor(sourceBuffer, 'update'); | ||
|
||
endTest(); | ||
}); | ||
</script> | ||
</head> | ||
<body> | ||
<video controls></video> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
63 changes: 63 additions & 0 deletions
63
Source/WebCore/Modules/mediasource/BufferedChangeEvent.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
/* | ||
* Copyright (C) 2023 Apple Inc. All rights reserved. | ||
* | ||
* Redistribution and use in source and binary forms, with or without | ||
* modification, are permitted provided that the following conditions | ||
* are met: | ||
* 1. Redistributions of source code must retain the above copyright | ||
* notice, this list of conditions and the following disclaimer. | ||
* 2. Redistributions in binary form must reproduce the above copyright | ||
* notice, this list of conditions and the following disclaimer in the | ||
* documentation and/or other materials provided with the distribution. | ||
* | ||
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' | ||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | ||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS | ||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF | ||
* THE POSSIBILITY OF SUCH DAMAGE. | ||
*/ | ||
|
||
#include "config.h" | ||
|
||
#if ENABLE(MANAGED_MEDIA_SOURCE) | ||
#include "BufferedChangeEvent.h" | ||
|
||
#include "Event.h" | ||
#include "EventNames.h" | ||
#include "TimeRanges.h" | ||
#include <wtf/IsoMallocInlines.h> | ||
|
||
namespace WebCore { | ||
|
||
WTF_MAKE_ISO_ALLOCATED_IMPL(BufferedChangeEvent); | ||
|
||
BufferedChangeEvent::BufferedChangeEvent(RefPtr<TimeRanges>&& added, RefPtr<TimeRanges>&& removed) | ||
: Event(eventNames().bufferedchangeEvent, CanBubble::No, IsCancelable::No) | ||
, m_added(WTFMove(added)) | ||
, m_removed(WTFMove(removed)) | ||
{ | ||
} | ||
|
||
BufferedChangeEvent::BufferedChangeEvent(const AtomString& type, Init&& init) | ||
: Event(type, init, IsTrusted::No) | ||
, m_added(WTFMove(init.addedRanges)) | ||
, m_removed(WTFMove(init.removedRanges)) | ||
{ | ||
} | ||
|
||
BufferedChangeEvent::~BufferedChangeEvent() = default; | ||
|
||
EventInterface BufferedChangeEvent::eventInterface() const | ||
{ | ||
return BufferedChangeEventInterfaceType; | ||
} | ||
|
||
} // namespace WebCore | ||
|
||
#endif |
Oops, something went wrong.