Title: [269121] trunk
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
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to