- Revision
- 269121
- Author
- [email protected]
- Date
- 2020-10-28 13:42:59 -0700 (Wed, 28 Oct 2020)
Log Message
[MSE] Handle trackId changing across Initialization Segments
https://bugs.webkit.org/show_bug.cgi?id=218294
<rdar://problem/70771306>
Reviewed by Eric Carlson.
Source/WebCore:
Test: media/media-source/media-source-trackid-change.html
When appending an initialization segment after the receivedFirstInitializationSegment flag is
true, and when the number of video or audio tracks is 1, the trackId is allowed to change across
initialiaztion segments. When this occurs, move the TrackBuffer inside the trackBufferMap to
refer to the new trackId, so that when MediaSamples are parsed, they're put into the correct
TrackBuffer.
* Modules/mediasource/SourceBuffer.cpp:
(WebCore::SourceBuffer::sourceBufferPrivateDidReceiveInitializationSegment):
* html/track/AudioTrack.cpp:
(WebCore::AudioTrack::setPrivate):
* html/track/InbandTextTrack.cpp:
(WebCore::InbandTextTrack::setPrivate):
* html/track/VideoTrack.cpp:
(WebCore::VideoTrack::setPrivate):
LayoutTests:
* media/media-source/media-source-trackid-change-expected.txt: Added.
* media/media-source/media-source-trackid-change.html: Added.
Modified Paths
Added Paths
Diff
Modified: trunk/LayoutTests/ChangeLog (269120 => 269121)
--- trunk/LayoutTests/ChangeLog 2020-10-28 20:39:42 UTC (rev 269120)
+++ trunk/LayoutTests/ChangeLog 2020-10-28 20:42:59 UTC (rev 269121)
@@ -1,3 +1,14 @@
+2020-10-28 Jer Noble <[email protected]>
+
+ [MSE] Handle trackId changing across Initialization Segments
+ https://bugs.webkit.org/show_bug.cgi?id=218294
+ <rdar://problem/70771306>
+
+ Reviewed by Eric Carlson.
+
+ * media/media-source/media-source-trackid-change-expected.txt: Added.
+ * media/media-source/media-source-trackid-change.html: Added.
+
2020-10-28 Sam Weinig <[email protected]>
Reduce Preference Override Methods: TabsToLinks/SpatialNavigation
Added: trunk/LayoutTests/media/media-source/media-source-trackid-change-expected.txt (0 => 269121)
--- trunk/LayoutTests/media/media-source/media-source-trackid-change-expected.txt (rev 0)
+++ trunk/LayoutTests/media/media-source/media-source-trackid-change-expected.txt 2020-10-28 20:42:59 UTC (rev 269121)
@@ -0,0 +1,43 @@
+This tests the ability of the SourceBuffer to change trackIds when a single videoTrack with a different trackId is appended.
+
+RUN(video.src = ""
+EVENT(sourceopen)
+RUN(source.duration = loader.duration())
+RUN(sourceBuffer = source.addSourceBuffer(loader.type()))
+RUN(sourceBuffer.appendBuffer(loader.initSegment()))
+EVENT(update)
+Append a media segment.
+RUN(sourceBuffer.appendBuffer(loader.mediaSegment(0)))
+EVENT(update)
+Get the current buffered range
+RUN(initialBufferedEnd = sourceBuffer.buffered.end(0))
+Modify an Init Segment to have a different trackID
+RUN(modifiedInitSegment = loader.initSegment().slice(0))
+RUN(initSegmentView = new DataView(modifiedInitSegment))
+EXPECTED (initSegmentView.getInt32(180) == '1') OK
+RUN(initSegmentView.setInt32(180, 3))
+EXPECTED (initSegmentView.getInt32(693) == '2') OK
+RUN(initSegmentView.setInt32(693, 4))
+EXPECTED (initSegmentView.getInt32(1109) == '1') OK
+RUN(initSegmentView.setInt32(1109, 3))
+EXPECTED (initSegmentView.getInt32(1141) == '2') OK
+RUN(initSegmentView.setInt32(1141, 4))
+Append the modified Init Segment
+RUN(sourceBuffer.appendBuffer(modifiedInitSegment))
+EVENT(update)
+EXPECTED (video.videoTracks[0].id == '3') OK
+EXPECTED (video.audioTracks[0].id == '4') OK
+Modify a Media Segment to have a different trackID
+RUN(modifiedMediaSegment = loader.mediaSegment(0).slice(0))
+RUN(mediaSegmentView = new DataView(modifiedMediaSegment))
+EXPECTED (mediaSegmentView.getInt32(44) == '1') OK
+RUN(mediaSegmentView.setInt32(44, 3))
+EXPECTED (mediaSegmentView.getInt32(324) == '2') OK
+RUN(mediaSegmentView.setInt32(324, 4))
+RUN(sourceBuffer.timestampOffset = sourceBuffer.buffered.end(0))
+Append a media segment.
+RUN(sourceBuffer.appendBuffer(modifiedMediaSegment))
+EVENT(update)
+EXPECTED (sourceBuffer.buffered.end(0) > '1') OK
+END OF TEST
+
Added: trunk/LayoutTests/media/media-source/media-source-trackid-change.html (0 => 269121)
--- trunk/LayoutTests/media/media-source/media-source-trackid-change.html (rev 0)
+++ trunk/LayoutTests/media/media-source/media-source-trackid-change.html 2020-10-28 20:42:59 UTC (rev 269121)
@@ -0,0 +1,96 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>media-source-trackid-change</title>
+ <script src=""
+ <script src=""
+ <script>
+ var loader;
+ var source;
+ var sourceBuffer;
+ var modifiedInitSegment;
+ var modifiedMediaSegment;
+
+ function loaderPromise(loader) {
+ return new Promise((resolve, reject) => {
+ loader._onload_ = resolve;
+ loader._onerror_ = reject;
+ });
+ }
+
+ window.addEventListener('load', async event => {
+ try {
+ findMediaElement();
+ loader = new MediaSourceLoader('content/test-fragmented-manifest.json');
+ await loaderPromise(loader);
+
+ source = new MediaSource();
+ run('video.src = ""
+ await waitFor(source, 'sourceopen');
+ waitFor(source, 'error').then(endTest);
+ waitForEventAndFail('error');
+
+ run('source.duration = loader.duration()');
+ run('sourceBuffer = source.addSourceBuffer(loader.type())');
+ run('sourceBuffer.appendBuffer(loader.initSegment())');
+
+ await waitFor(sourceBuffer, 'update');
+
+ consoleWrite('Append a media segment.')
+ run('sourceBuffer.appendBuffer(loader.mediaSegment(0))');
+
+ await waitFor(sourceBuffer, 'update');
+
+ consoleWrite('Get the current buffered range');
+ run('initialBufferedEnd = sourceBuffer.buffered.end(0)');
+
+ consoleWrite('Modify an Init Segment to have a different trackID');
+ run('modifiedInitSegment = loader.initSegment().slice(0)');
+ run('initSegmentView = new DataView(modifiedInitSegment)');
+ testExpected('initSegmentView.getInt32(180)', 1);
+ run('initSegmentView.setInt32(180, 3)');
+ testExpected('initSegmentView.getInt32(693)', 2);
+ run('initSegmentView.setInt32(693, 4)');
+ testExpected('initSegmentView.getInt32(1109)', 1);
+ run('initSegmentView.setInt32(1109, 3)');
+ testExpected('initSegmentView.getInt32(1141)', 2);
+ run('initSegmentView.setInt32(1141, 4)');
+
+ consoleWrite('Append the modified Init Segment')
+ run('sourceBuffer.appendBuffer(modifiedInitSegment)');
+ await waitFor(sourceBuffer, 'update');
+
+ testExpected('video.videoTracks[0].id', 3);
+ testExpected('video.audioTracks[0].id', 4);
+
+ consoleWrite('Modify a Media Segment to have a different trackID');
+ run('modifiedMediaSegment = loader.mediaSegment(0).slice(0)');
+ run('mediaSegmentView = new DataView(modifiedMediaSegment)');
+ testExpected('mediaSegmentView.getInt32(44)', 1);
+ run('mediaSegmentView.setInt32(44, 3)');
+ testExpected('mediaSegmentView.getInt32(324)', 2);
+ run('mediaSegmentView.setInt32(324, 4)');
+
+ run('sourceBuffer.timestampOffset = sourceBuffer.buffered.end(0)');
+
+ consoleWrite('Append a media segment.')
+ run('sourceBuffer.appendBuffer(modifiedMediaSegment)');
+
+ await waitFor(sourceBuffer, 'update');
+
+ testExpected('sourceBuffer.buffered.end(0)', initialBufferedEnd, '>');
+
+ endTest();
+ } catch (e) {
+ failTest(`Caught exception: "${e}"`);
+ }
+ });
+ </script>
+</head>
+<body>
+ <div>
+ This tests the ability of the SourceBuffer to change trackIds when a single videoTrack with a different trackId is appended.
+ </div>
+ <video controls></video>
+</body>
+</html>
\ No newline at end of file
Modified: trunk/Source/WebCore/ChangeLog (269120 => 269121)
--- trunk/Source/WebCore/ChangeLog 2020-10-28 20:39:42 UTC (rev 269120)
+++ trunk/Source/WebCore/ChangeLog 2020-10-28 20:42:59 UTC (rev 269121)
@@ -1,3 +1,28 @@
+2020-10-28 Jer Noble <[email protected]>
+
+ [MSE] Handle trackId changing across Initialization Segments
+ https://bugs.webkit.org/show_bug.cgi?id=218294
+ <rdar://problem/70771306>
+
+ Reviewed by Eric Carlson.
+
+ Test: media/media-source/media-source-trackid-change.html
+
+ When appending an initialization segment after the receivedFirstInitializationSegment flag is
+ true, and when the number of video or audio tracks is 1, the trackId is allowed to change across
+ initialiaztion segments. When this occurs, move the TrackBuffer inside the trackBufferMap to
+ refer to the new trackId, so that when MediaSamples are parsed, they're put into the correct
+ TrackBuffer.
+
+ * Modules/mediasource/SourceBuffer.cpp:
+ (WebCore::SourceBuffer::sourceBufferPrivateDidReceiveInitializationSegment):
+ * html/track/AudioTrack.cpp:
+ (WebCore::AudioTrack::setPrivate):
+ * html/track/InbandTextTrack.cpp:
+ (WebCore::InbandTextTrack::setPrivate):
+ * html/track/VideoTrack.cpp:
+ (WebCore::VideoTrack::setPrivate):
+
2020-10-28 Tim Horton <[email protected]>
macCatalyst WebGL on Apple Silicon devices is using a software renderer
Modified: trunk/Source/WebCore/Modules/mediasource/SourceBuffer.cpp (269120 => 269121)
--- trunk/Source/WebCore/Modules/mediasource/SourceBuffer.cpp 2020-10-28 20:39:42 UTC (rev 269120)
+++ trunk/Source/WebCore/Modules/mediasource/SourceBuffer.cpp 2020-10-28 20:42:59 UTC (rev 269121)
@@ -1111,11 +1111,21 @@
appendError(true);
return;
}
+
+ Vector<std::pair<AtomString, TrackBuffer>> newTrackBuffers;
+
// 3.2 Add the appropriate track descriptions from this initialization segment to each of the track buffers.
ASSERT(segment.audioTracks.size() == audioTracks().length());
for (auto& audioTrackInfo : segment.audioTracks) {
if (audioTracks().length() == 1) {
- audioTracks().item(0)->setPrivate(*audioTrackInfo.track);
+ auto* track = audioTracks().item(0);
+ auto oldId = track->id();
+ auto newId = audioTrackInfo.track->id();
+ track->setPrivate(*audioTrackInfo.track);
+ if (newId != oldId) {
+ auto trackBuffer = m_trackBufferMap.take(oldId);
+ newTrackBuffers.append(std::make_pair(newId, WTFMove(trackBuffer)));
+ }
break;
}
@@ -1127,7 +1137,14 @@
ASSERT(segment.videoTracks.size() == videoTracks().length());
for (auto& videoTrackInfo : segment.videoTracks) {
if (videoTracks().length() == 1) {
- videoTracks().item(0)->setPrivate(*videoTrackInfo.track);
+ auto* track = videoTracks().item(0);
+ auto oldId = track->id();
+ auto newId = videoTrackInfo.track->id();
+ track->setPrivate(*videoTrackInfo.track);
+ if (newId != oldId) {
+ auto trackBuffer = m_trackBufferMap.take(oldId);
+ newTrackBuffers.append(std::make_pair(newId, WTFMove(trackBuffer)));
+ }
break;
}
@@ -1139,7 +1156,14 @@
ASSERT(segment.textTracks.size() == textTracks().length());
for (auto& textTrackInfo : segment.textTracks) {
if (textTracks().length() == 1) {
- downcast<InbandTextTrack>(*textTracks().item(0)).setPrivate(*textTrackInfo.track);
+ auto* track = downcast<InbandTextTrack>(textTracks().item(0));
+ auto oldId = track->id();
+ auto newId = textTrackInfo.track->id();
+ track->setPrivate(*textTrackInfo.track);
+ if (newId != oldId) {
+ auto trackBuffer = m_trackBufferMap.take(oldId);
+ newTrackBuffers.append(std::make_pair(newId, WTFMove(trackBuffer)));
+ }
break;
}
@@ -1148,6 +1172,11 @@
downcast<InbandTextTrack>(*textTrack).setPrivate(*textTrackInfo.track);
}
+ while (!newTrackBuffers.isEmpty()) {
+ auto trackPair = newTrackBuffers.takeLast();
+ m_trackBufferMap.add(trackPair.first, WTFMove(trackPair.second));
+ }
+
// 3.3 Set the need random access point flag on all track buffers to true.
for (auto& trackBuffer : m_trackBufferMap.values())
trackBuffer.needRandomAccessFlag = true;
Modified: trunk/Source/WebCore/html/track/AudioTrack.cpp (269120 => 269121)
--- trunk/Source/WebCore/html/track/AudioTrack.cpp 2020-10-28 20:39:42 UTC (rev 269120)
+++ trunk/Source/WebCore/html/track/AudioTrack.cpp 2020-10-28 20:42:59 UTC (rev 269121)
@@ -104,6 +104,7 @@
#endif
updateKindFromPrivate();
+ setId(m_private->id());
}
bool AudioTrack::isValidKind(const AtomString& value) const
Modified: trunk/Source/WebCore/html/track/InbandTextTrack.cpp (269120 => 269121)
--- trunk/Source/WebCore/html/track/InbandTextTrack.cpp 2020-10-28 20:39:42 UTC (rev 269120)
+++ trunk/Source/WebCore/html/track/InbandTextTrack.cpp 2020-10-28 20:42:59 UTC (rev 269121)
@@ -77,6 +77,7 @@
setModeInternal(mode());
updateKindFromPrivate();
+ setId(m_private->id());
}
void InbandTextTrack::setMode(Mode mode)
Modified: trunk/Source/WebCore/html/track/VideoTrack.cpp (269120 => 269121)
--- trunk/Source/WebCore/html/track/VideoTrack.cpp 2020-10-28 20:39:42 UTC (rev 269120)
+++ trunk/Source/WebCore/html/track/VideoTrack.cpp 2020-10-28 20:42:59 UTC (rev 269121)
@@ -109,6 +109,7 @@
m_private->setSelected(m_selected);
updateKindFromPrivate();
+ setId(m_private->id());
}
bool VideoTrack::isValidKind(const AtomString& value) const