Title: [255025] branches/safari-609-branch
Revision
255025
Author
[email protected]
Date
2020-01-23 13:44:24 -0800 (Thu, 23 Jan 2020)

Log Message

Cherry-pick r254761. rdar://problem/58807932

    [MSE] Decode glitches when watching videos on CNN.com
    https://bugs.webkit.org/show_bug.cgi?id=206412
    <rdar://problem/55685630>

    Reviewed by Xabier Rodriguez-Calvar.

    Source/WebCore:

    Test: media/media-source/media-source-samples-out-of-order.html

    The "Coded frame processing" algorithm has a known shortcoming <https://github.com/w3c/media-source/issues/187>
    when dealing appends of with "SAP Type 2" content, or in general terms, appending data where the resulting samples
    have presentation times that do not increase monotonically. When this occurs, the ordering of samples in presentation
    time will be different from the ordering of samples in decode time. The decoder requires samples to be enqueued in
    decode time order, but the MSE specification only checks for overlapping samples in presentation time order. During
    appends of out-of-order samples, this can lead to new samples being inserted between a previously appended sample and
    the sample on which that sample depends.

    To resolve this, add a new step in the implementation of the "coded frame processing" algorithm in
    SourceBuffer::sourceBufferPrivateDidReceiveSample(). When the incoming frame is a sync sample, search forward
    in the TrackBuffer for all previous samples in between the new sync sample, and the next sync sample. All the
    samples found in this step would fail to decode correctly if enqueued after the new (possibly different resolution)
    sync sample, so they are removed in this step.

    * Modules/mediasource/SampleMap.cpp:
    (WebCore::DecodeOrderSampleMap::findSampleAfterDecodeKey):
    * Modules/mediasource/SampleMap.h:
    * Modules/mediasource/SourceBuffer.cpp:
    (WebCore::SourceBuffer::sourceBufferPrivateDidReceiveSample):

    LayoutTests:

    * media/media-source/media-source-samples-out-of-order-expected.txt: Added.
    * media/media-source/media-source-samples-out-of-order.html: Added.

    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@254761 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Modified Paths

Added Paths

Diff

Modified: branches/safari-609-branch/LayoutTests/ChangeLog (255024 => 255025)


--- branches/safari-609-branch/LayoutTests/ChangeLog	2020-01-23 21:44:21 UTC (rev 255024)
+++ branches/safari-609-branch/LayoutTests/ChangeLog	2020-01-23 21:44:24 UTC (rev 255025)
@@ -1,5 +1,58 @@
 2020-01-23  Russell Epstein  <[email protected]>
 
+        Cherry-pick r254761. rdar://problem/58807932
+
+    [MSE] Decode glitches when watching videos on CNN.com
+    https://bugs.webkit.org/show_bug.cgi?id=206412
+    <rdar://problem/55685630>
+    
+    Reviewed by Xabier Rodriguez-Calvar.
+    
+    Source/WebCore:
+    
+    Test: media/media-source/media-source-samples-out-of-order.html
+    
+    The "Coded frame processing" algorithm has a known shortcoming <https://github.com/w3c/media-source/issues/187>
+    when dealing appends of with "SAP Type 2" content, or in general terms, appending data where the resulting samples
+    have presentation times that do not increase monotonically. When this occurs, the ordering of samples in presentation
+    time will be different from the ordering of samples in decode time. The decoder requires samples to be enqueued in
+    decode time order, but the MSE specification only checks for overlapping samples in presentation time order. During
+    appends of out-of-order samples, this can lead to new samples being inserted between a previously appended sample and
+    the sample on which that sample depends.
+    
+    To resolve this, add a new step in the implementation of the "coded frame processing" algorithm in
+    SourceBuffer::sourceBufferPrivateDidReceiveSample(). When the incoming frame is a sync sample, search forward
+    in the TrackBuffer for all previous samples in between the new sync sample, and the next sync sample. All the
+    samples found in this step would fail to decode correctly if enqueued after the new (possibly different resolution)
+    sync sample, so they are removed in this step.
+    
+    * Modules/mediasource/SampleMap.cpp:
+    (WebCore::DecodeOrderSampleMap::findSampleAfterDecodeKey):
+    * Modules/mediasource/SampleMap.h:
+    * Modules/mediasource/SourceBuffer.cpp:
+    (WebCore::SourceBuffer::sourceBufferPrivateDidReceiveSample):
+    
+    LayoutTests:
+    
+    * media/media-source/media-source-samples-out-of-order-expected.txt: Added.
+    * media/media-source/media-source-samples-out-of-order.html: Added.
+    
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@254761 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    2020-01-17  Jer Noble  <[email protected]>
+
+            [MSE] Decode glitches when watching videos on CNN.com
+            https://bugs.webkit.org/show_bug.cgi?id=206412
+            <rdar://problem/55685630>
+
+            Reviewed by Xabier Rodriguez-Calvar.
+
+            * media/media-source/media-source-samples-out-of-order-expected.txt: Added.
+            * media/media-source/media-source-samples-out-of-order.html: Added.
+
+2020-01-23  Russell Epstein  <[email protected]>
+
         Cherry-pick r254722. rdar://problem/58811423
 
     REGRESSION (r251110): Crash on https://developer.apple.com/tutorials/swiftui/creating-and-combining-views

Added: branches/safari-609-branch/LayoutTests/media/media-source/media-source-samples-out-of-order-expected.txt (0 => 255025)


--- branches/safari-609-branch/LayoutTests/media/media-source/media-source-samples-out-of-order-expected.txt	                        (rev 0)
+++ branches/safari-609-branch/LayoutTests/media/media-source/media-source-samples-out-of-order-expected.txt	2020-01-23 21:44:24 UTC (rev 255025)
@@ -0,0 +1,20 @@
+
+RUN(video.src = ""
+EVENT(sourceopen)
+RUN(sourceBuffer = source.addSourceBuffer("video/mock; codecs=mock"))
+First segment has normal, monotonically increasing samples.
+RUN(sourceBuffer.appendBuffer(mediaSegment))
+EVENT(updateend)
+EXPECTED (bufferedSamples.length == '3') OK
+{PTS({1/1 = 1.000000}), DTS({1/1 = 1.000000}), duration({1/1 = 1.000000}), flags(1), generation(0)}
+{PTS({2/1 = 2.000000}), DTS({2/1 = 2.000000}), duration({1/1 = 1.000000}), flags(0), generation(0)}
+{PTS({3/1 = 3.000000}), DTS({3/1 = 3.000000}), duration({1/1 = 1.000000}), flags(0), generation(0)}
+Second, overlapping segment has out-of-display-order samples. This append should replace the last sample from the previous append.
+RUN(sourceBuffer.appendBuffer(mediaSegment))
+EVENT(updateend)
+EXPECTED (bufferedSamples.length == '3') OK
+{PTS({1/1 = 1.000000}), DTS({1/1 = 1.000000}), duration({1/1 = 1.000000}), flags(1), generation(0)}
+{PTS({2/1 = 2.000000}), DTS({2/1 = 2.000000}), duration({1/1 = 1.000000}), flags(0), generation(0)}
+{PTS({4/1 = 4.000000}), DTS({2/1 = 2.000000}), duration({1/1 = 1.000000}), flags(1), generation(1)}
+END OF TEST
+

Added: branches/safari-609-branch/LayoutTests/media/media-source/media-source-samples-out-of-order.html (0 => 255025)


--- branches/safari-609-branch/LayoutTests/media/media-source/media-source-samples-out-of-order.html	                        (rev 0)
+++ branches/safari-609-branch/LayoutTests/media/media-source/media-source-samples-out-of-order.html	2020-01-23 21:44:24 UTC (rev 255025)
@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title>media-source-samples-out-of-order</title>
+    <script src=""
+    <script src=""
+    <script>
+    var source;
+    var sourceBuffer;
+    var initSegment;
+    var mediaSegment;
+
+    if (window.internals)
+        internals.initializeMockMediaSource();
+
+    window.addEventListener('load', async event => {
+        findMediaElement();
+
+        source = new MediaSource();
+        run('video.src = ""
+        await waitFor(source, 'sourceopen');
+
+        run('sourceBuffer = source.addSourceBuffer("video/mock; codecs=mock")');
+        consoleWrite('First segment has normal, monotonically increasing samples.')
+        mediaSegment = concatenateSamples([
+            makeAInit(2, [makeATrack(1, 'mock', TRACK_KIND.AUDIO)]), 
+            makeASample(1, 1, 1, 1, 1, SAMPLE_FLAG.SYNC, 0),
+            makeASample(2, 2, 1, 1, 1, SAMPLE_FLAG.NONE, 0),
+            makeASample(3, 3, 1, 1, 1, SAMPLE_FLAG.NONE, 0),
+        ]);
+        run('sourceBuffer.appendBuffer(mediaSegment)');
+        await waitFor(sourceBuffer, 'updateend');
+
+        bufferedSamples = internals.bufferedSamplesForTrackID(sourceBuffer, 1);
+        testExpected("bufferedSamples.length", 3);
+        bufferedSamples.forEach(consoleWrite);
+
+        consoleWrite('Second, overlapping segment has out-of-display-order samples. This append should replace the last sample from the previous append.')
+        mediaSegment = concatenateSamples([
+            makeAInit(2, [makeATrack(1, 'mock', TRACK_KIND.AUDIO)]), 
+            makeASample(4, 2, 1, 1, 1, SAMPLE_FLAG.SYNC, 1),
+        ]);
+        run('sourceBuffer.appendBuffer(mediaSegment)');
+        await waitFor(sourceBuffer, 'updateend');
+
+        bufferedSamples = internals.bufferedSamplesForTrackID(sourceBuffer, 1);
+        testExpected("bufferedSamples.length", 3);
+        bufferedSamples.forEach(consoleWrite);
+
+        endTest();
+    });
+    </script>
+</head>
+<body>
+    <video></video>
+</body>
+</html>

Modified: branches/safari-609-branch/Source/WebCore/ChangeLog (255024 => 255025)


--- branches/safari-609-branch/Source/WebCore/ChangeLog	2020-01-23 21:44:21 UTC (rev 255024)
+++ branches/safari-609-branch/Source/WebCore/ChangeLog	2020-01-23 21:44:24 UTC (rev 255025)
@@ -1,5 +1,77 @@
 2020-01-23  Russell Epstein  <[email protected]>
 
+        Cherry-pick r254761. rdar://problem/58807932
+
+    [MSE] Decode glitches when watching videos on CNN.com
+    https://bugs.webkit.org/show_bug.cgi?id=206412
+    <rdar://problem/55685630>
+    
+    Reviewed by Xabier Rodriguez-Calvar.
+    
+    Source/WebCore:
+    
+    Test: media/media-source/media-source-samples-out-of-order.html
+    
+    The "Coded frame processing" algorithm has a known shortcoming <https://github.com/w3c/media-source/issues/187>
+    when dealing appends of with "SAP Type 2" content, or in general terms, appending data where the resulting samples
+    have presentation times that do not increase monotonically. When this occurs, the ordering of samples in presentation
+    time will be different from the ordering of samples in decode time. The decoder requires samples to be enqueued in
+    decode time order, but the MSE specification only checks for overlapping samples in presentation time order. During
+    appends of out-of-order samples, this can lead to new samples being inserted between a previously appended sample and
+    the sample on which that sample depends.
+    
+    To resolve this, add a new step in the implementation of the "coded frame processing" algorithm in
+    SourceBuffer::sourceBufferPrivateDidReceiveSample(). When the incoming frame is a sync sample, search forward
+    in the TrackBuffer for all previous samples in between the new sync sample, and the next sync sample. All the
+    samples found in this step would fail to decode correctly if enqueued after the new (possibly different resolution)
+    sync sample, so they are removed in this step.
+    
+    * Modules/mediasource/SampleMap.cpp:
+    (WebCore::DecodeOrderSampleMap::findSampleAfterDecodeKey):
+    * Modules/mediasource/SampleMap.h:
+    * Modules/mediasource/SourceBuffer.cpp:
+    (WebCore::SourceBuffer::sourceBufferPrivateDidReceiveSample):
+    
+    LayoutTests:
+    
+    * media/media-source/media-source-samples-out-of-order-expected.txt: Added.
+    * media/media-source/media-source-samples-out-of-order.html: Added.
+    
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@254761 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    2020-01-17  Jer Noble  <[email protected]>
+
+            [MSE] Decode glitches when watching videos on CNN.com
+            https://bugs.webkit.org/show_bug.cgi?id=206412
+            <rdar://problem/55685630>
+
+            Reviewed by Xabier Rodriguez-Calvar.
+
+            Test: media/media-source/media-source-samples-out-of-order.html
+
+            The "Coded frame processing" algorithm has a known shortcoming <https://github.com/w3c/media-source/issues/187>
+            when dealing appends of with "SAP Type 2" content, or in general terms, appending data where the resulting samples
+            have presentation times that do not increase monotonically. When this occurs, the ordering of samples in presentation
+            time will be different from the ordering of samples in decode time. The decoder requires samples to be enqueued in
+            decode time order, but the MSE specification only checks for overlapping samples in presentation time order. During
+            appends of out-of-order samples, this can lead to new samples being inserted between a previously appended sample and
+            the sample on which that sample depends.
+
+            To resolve this, add a new step in the implementation of the "coded frame processing" algorithm in
+            SourceBuffer::sourceBufferPrivateDidReceiveSample(). When the incoming frame is a sync sample, search forward
+            in the TrackBuffer for all previous samples in between the new sync sample, and the next sync sample. All the
+            samples found in this step would fail to decode correctly if enqueued after the new (possibly different resolution)
+            sync sample, so they are removed in this step.
+
+            * Modules/mediasource/SampleMap.cpp:
+            (WebCore::DecodeOrderSampleMap::findSampleAfterDecodeKey):
+            * Modules/mediasource/SampleMap.h:
+            * Modules/mediasource/SourceBuffer.cpp:
+            (WebCore::SourceBuffer::sourceBufferPrivateDidReceiveSample):
+
+2020-01-23  Russell Epstein  <[email protected]>
+
         Cherry-pick r254722. rdar://problem/58811423
 
     REGRESSION (r251110): Crash on https://developer.apple.com/tutorials/swiftui/creating-and-combining-views

Modified: branches/safari-609-branch/Source/WebCore/Modules/mediasource/SampleMap.cpp (255024 => 255025)


--- branches/safari-609-branch/Source/WebCore/Modules/mediasource/SampleMap.cpp	2020-01-23 21:44:21 UTC (rev 255024)
+++ branches/safari-609-branch/Source/WebCore/Modules/mediasource/SampleMap.cpp	2020-01-23 21:44:24 UTC (rev 255025)
@@ -188,6 +188,11 @@
     return m_samples.find(key);
 }
 
+DecodeOrderSampleMap::iterator DecodeOrderSampleMap::findSampleAfterDecodeKey(const KeyType& key)
+{
+    return m_samples.upper_bound(key);
+}
+
 PresentationOrderSampleMap::reverse_iterator PresentationOrderSampleMap::reverseFindSampleContainingPresentationTime(const MediaTime& time)
 {
     auto range = std::equal_range(rbegin(), rend(), time, SampleIsGreaterThanMediaTimeComparator<MapType>());

Modified: branches/safari-609-branch/Source/WebCore/Modules/mediasource/SampleMap.h (255024 => 255025)


--- branches/safari-609-branch/Source/WebCore/Modules/mediasource/SampleMap.h	2020-01-23 21:44:21 UTC (rev 255024)
+++ branches/safari-609-branch/Source/WebCore/Modules/mediasource/SampleMap.h	2020-01-23 21:44:24 UTC (rev 255025)
@@ -93,6 +93,7 @@
     const_reverse_iterator rend() const { return m_samples.rend(); }
 
     WEBCORE_EXPORT iterator findSampleWithDecodeKey(const KeyType&);
+    WEBCORE_EXPORT iterator findSampleAfterDecodeKey(const KeyType&);
     WEBCORE_EXPORT reverse_iterator reverseFindSampleWithDecodeKey(const KeyType&);
     WEBCORE_EXPORT reverse_iterator findSyncSamplePriorToPresentationTime(const MediaTime&, const MediaTime& threshold = MediaTime::positiveInfiniteTime());
     WEBCORE_EXPORT reverse_iterator findSyncSamplePriorToDecodeIterator(reverse_iterator);

Modified: branches/safari-609-branch/Source/WebCore/Modules/mediasource/SourceBuffer.cpp (255024 => 255025)


--- branches/safari-609-branch/Source/WebCore/Modules/mediasource/SourceBuffer.cpp	2020-01-23 21:44:21 UTC (rev 255024)
+++ branches/safari-609-branch/Source/WebCore/Modules/mediasource/SourceBuffer.cpp	2020-01-23 21:44:24 UTC (rev 255025)
@@ -1677,6 +1677,29 @@
                 erasedSamples.addRange(iter_pair.first, iter_pair.second);
         }
 
+        // When appending media containing B-frames (media whose samples' presentation timestamps
+        // do not increase monotonically, the prior erase steps could leave a sample in the trackBuffer
+        // which will be disconnected from its previous I-frame. If the incoming frame is an I-frame,
+        // remove all samples in decode order between the incoming I-frame's decode timestamp and the
+        // next I-frame. See <https://github.com/w3c/media-source/issues/187> for a discussion of what
+        // the how the MSE specification should handlie this secnario.
+        do {
+            if (!sample.isSync())
+                break;
+
+            DecodeOrderSampleMap::KeyType decodeKey(sample.decodeTime(), sample.presentationTime());
+            auto nextSampleInDecodeOrder = trackBuffer.samples.decodeOrder().findSampleAfterDecodeKey(decodeKey);
+            if (nextSampleInDecodeOrder == trackBuffer.samples.decodeOrder().end())
+                break;
+
+            if (nextSampleInDecodeOrder->second->isSync())
+                break;
+
+            auto nextSyncSample = trackBuffer.samples.decodeOrder().findSyncSampleAfterDecodeIterator(nextSampleInDecodeOrder);
+            INFO_LOG(LOGIDENTIFIER, "Discovered out-of-order frames, from: ", *nextSampleInDecodeOrder->second, " to: ", (nextSyncSample == trackBuffer.samples.decodeOrder().end() ? "[end]"_s : toString(*nextSyncSample->second)));
+            erasedSamples.addRange(nextSampleInDecodeOrder, nextSyncSample);
+        } while (false);
+
         // There are many files out there where the frame times are not perfectly contiguous and may have small overlaps
         // between the beginning of a frame and the end of the previous one; therefore a tolerance is needed whenever
         // durations are considered.
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to