Diff
Modified: trunk/LayoutTests/ChangeLog (225441 => 225442)
--- trunk/LayoutTests/ChangeLog 2017-12-02 03:19:16 UTC (rev 225441)
+++ trunk/LayoutTests/ChangeLog 2017-12-02 05:39:30 UTC (rev 225442)
@@ -1,3 +1,17 @@
+2017-12-01 Alicia Boya García <[email protected]>
+
+ [MSE] Use correct range end checks in sourceBufferPrivateDidReceiveSample()
+ https://bugs.webkit.org/show_bug.cgi?id=179690
+
+ Reviewed by Jer Noble.
+
+ Added test cases for bug #179690.
+
+ * media/media-source/media-source-range-end-frame-not-removed-expected.txt: Added.
+ * media/media-source/media-source-range-end-frame-not-removed.html: Added.
+ * media/media-source/media-source-range-start-frame-replaced-expected.txt: Added.
+ * media/media-source/media-source-range-start-frame-replaced.html: Added.
+
2017-12-01 Ms2ger <[email protected]>
[WPE] Enable wpt css tests.
Added: trunk/LayoutTests/media/media-source/media-source-range-end-frame-not-removed-expected.txt (0 => 225442)
--- trunk/LayoutTests/media/media-source/media-source-range-end-frame-not-removed-expected.txt (rev 0)
+++ trunk/LayoutTests/media/media-source/media-source-range-end-frame-not-removed-expected.txt 2017-12-02 05:39:30 UTC (rev 225442)
@@ -0,0 +1,22 @@
+
+RUN(video.src = ""
+EVENT(sourceopen)
+RUN(sourceBuffer = source.addSourceBuffer("video/mock; codecs=mock"))
+RUN(sourceBuffer.appendBuffer(initSegment))
+EVENT(updateend)
+RUN(sourceBuffer.appendBuffer(samples))
+EVENT(updateend)
+RUN(sourceBuffer.appendBuffer(samples))
+EVENT(updateend)
+EXPECTED (bufferedSamples.length == '6') OK
+{PTS({0/1000 = 0.000000}), DTS({0/1000 = 0.000000}), duration({1000/1000 = 1.000000}), flags(1), generation(0)}
+{PTS({1000/1000 = 1.000000}), DTS({1000/1000 = 1.000000}), duration({1000/1000 = 1.000000}), flags(1), generation(0)}
+{PTS({2000/1000 = 2.000000}), DTS({2000/1000 = 2.000000}), duration({1000/1000 = 1.000000}), flags(1), generation(0)}
+{PTS({3000/1000 = 3.000000}), DTS({3000/1000 = 3.000000}), duration({1000/1000 = 1.000000}), flags(1), generation(0)}
+{PTS({4000/1000 = 4.000000}), DTS({4000/1000 = 4.000000}), duration({1000/1000 = 1.000000}), flags(1), generation(0)}
+{PTS({5000/1000 = 5.000000}), DTS({5000/1000 = 5.000000}), duration({1000/1000 = 1.000000}), flags(1), generation(0)}
+EXPECTED (sourceBuffer.buffered.length == '1') OK
+EXPECTED (sourceBuffer.buffered.start(0) == '0') OK
+EXPECTED (sourceBuffer.buffered.end(0) == '6') OK
+END OF TEST
+
Added: trunk/LayoutTests/media/media-source/media-source-range-end-frame-not-removed.html (0 => 225442)
--- trunk/LayoutTests/media/media-source/media-source-range-end-frame-not-removed.html (rev 0)
+++ trunk/LayoutTests/media/media-source/media-source-range-end-frame-not-removed.html 2017-12-02 05:39:30 UTC (rev 225442)
@@ -0,0 +1,72 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>media-source-range-ends</title>
+ <script src=""
+ <script src=""
+ <script>
+ var source;
+ var sourceBuffer;
+ var initSegment;
+ var samples;
+ var bufferedSamples;
+
+ if (window.internals)
+ internals.initializeMockMediaSource();
+
+ function runTest()
+ {
+ findMediaElement();
+
+ source = new MediaSource();
+ waitForEventOn(source, 'sourceopen', sourceOpen);
+ run('video.src = ""
+ }
+
+ function sourceOpen()
+ {
+ run('sourceBuffer = source.addSourceBuffer("video/mock; codecs=mock")');
+ waitForEventOn(sourceBuffer, 'updateend', loadSamples1, false, true);
+ initSegment = makeAInit(6, [makeATrack(1, 'mock', TRACK_KIND.VIDEO)]);
+ run('sourceBuffer.appendBuffer(initSegment)');
+ }
+
+ function loadSamples1()
+ {
+ samples = concatenateSamples([
+ makeASample(3, 3, 1, 1, SAMPLE_FLAG.SYNC, 0),
+ makeASample(4, 4, 1, 1, SAMPLE_FLAG.SYNC, 0),
+ makeASample(5, 5, 1, 1, SAMPLE_FLAG.SYNC, 0),
+ ]);
+ waitForEventOn(sourceBuffer, 'updateend', loadSamples2, false, true);
+ run('sourceBuffer.appendBuffer(samples)');
+ }
+
+ function loadSamples2()
+ {
+ samples = concatenateSamples([
+ makeASample(0, 0, 1, 1, SAMPLE_FLAG.SYNC, 0),
+ makeASample(1, 1, 1, 1, SAMPLE_FLAG.SYNC, 0),
+ makeASample(2, 2, 1, 1, SAMPLE_FLAG.SYNC, 0),
+ ]);
+ waitForEventOn(sourceBuffer, 'updateend', samplesAdded, false, true);
+ run('sourceBuffer.appendBuffer(samples)');
+ }
+
+ function samplesAdded()
+ {
+ bufferedSamples = internals.bufferedSamplesForTrackID(sourceBuffer, 1);
+ testExpected("bufferedSamples.length", 6);
+ bufferedSamples.forEach(consoleWrite);
+
+ testExpected("sourceBuffer.buffered.length", 1);
+ testExpected("sourceBuffer.buffered.start(0)", 0);
+ testExpected("sourceBuffer.buffered.end(0)", 6);
+
+ endTest();
+ }
+ </script>
+</head>
+<body _onload_="runTest()">
+ <video></video>
+</body>
Added: trunk/LayoutTests/media/media-source/media-source-range-start-frame-replaced-expected.txt (0 => 225442)
--- trunk/LayoutTests/media/media-source/media-source-range-start-frame-replaced-expected.txt (rev 0)
+++ trunk/LayoutTests/media/media-source/media-source-range-start-frame-replaced-expected.txt 2017-12-02 05:39:30 UTC (rev 225442)
@@ -0,0 +1,17 @@
+
+RUN(video.src = ""
+EVENT(sourceopen)
+RUN(sourceBuffer = source.addSourceBuffer("video/mock; codecs=mock"))
+RUN(sourceBuffer.appendBuffer(initSegment))
+EVENT(updateend)
+RUN(sourceBuffer.appendBuffer(samples))
+EVENT(updateend)
+RUN(sourceBuffer.appendBuffer(samples))
+EVENT(updateend)
+{PTS({0/1000 = 0.000000}), DTS({0/1000 = 0.000000}), duration({1000/1000 = 1.000000}), flags(1), generation(0)}
+{PTS({1000/1000 = 1.000000}), DTS({1000/1000 = 1.000000}), duration({2000/1000 = 2.000000}), flags(1), generation(0)}
+EXPECTED (sourceBuffer.buffered.length == '1') OK
+EXPECTED (sourceBuffer.buffered.start(0) == '0') OK
+EXPECTED (sourceBuffer.buffered.end(0) == '3') OK
+END OF TEST
+
Added: trunk/LayoutTests/media/media-source/media-source-range-start-frame-replaced.html (0 => 225442)
--- trunk/LayoutTests/media/media-source/media-source-range-start-frame-replaced.html (rev 0)
+++ trunk/LayoutTests/media/media-source/media-source-range-start-frame-replaced.html 2017-12-02 05:39:30 UTC (rev 225442)
@@ -0,0 +1,69 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>media-source-range-start-frame-replaced</title>
+ <script src=""
+ <script src=""
+ <script>
+ var source;
+ var sourceBuffer;
+ var initSegment;
+ var samples;
+ var bufferedSamples;
+
+ if (window.internals)
+ internals.initializeMockMediaSource();
+
+ function runTest()
+ {
+ findMediaElement();
+
+ source = new MediaSource();
+ waitForEventOn(source, 'sourceopen', sourceOpen);
+ run('video.src = ""
+ }
+
+ function sourceOpen()
+ {
+ run('sourceBuffer = source.addSourceBuffer("video/mock; codecs=mock")');
+ waitForEventOn(sourceBuffer, 'updateend', loadSamples1, false, true);
+ initSegment = makeAInit(3, [makeATrack(1, 'mock', TRACK_KIND.VIDEO)]);
+ run('sourceBuffer.appendBuffer(initSegment)');
+ }
+
+ function loadSamples1()
+ {
+ samples = concatenateSamples([
+ makeASample(1, 1, 1, 1, SAMPLE_FLAG.SYNC, 0),
+ ]);
+ waitForEventOn(sourceBuffer, 'updateend', loadSamples2, false, true);
+ run('sourceBuffer.appendBuffer(samples)');
+ }
+
+ function loadSamples2()
+ {
+ samples = concatenateSamples([
+ // New Coded Frame Group (DTS went backwards)
+ makeASample(0, 0, 1, 1, SAMPLE_FLAG.SYNC, 0),
+ makeASample(1, 1, 2, 1, SAMPLE_FLAG.SYNC, 0), // duration = 2
+ ]);
+ waitForEventOn(sourceBuffer, 'updateend', samplesAdded, false, true);
+ run('sourceBuffer.appendBuffer(samples)');
+ }
+
+ function samplesAdded()
+ {
+ bufferedSamples = internals.bufferedSamplesForTrackID(sourceBuffer, 1);
+ bufferedSamples.forEach(consoleWrite);
+
+ testExpected("sourceBuffer.buffered.length", 1);
+ testExpected("sourceBuffer.buffered.start(0)", 0);
+ testExpected("sourceBuffer.buffered.end(0)", 3);
+
+ endTest();
+ }
+ </script>
+</head>
+<body _onload_="runTest()">
+ <video></video>
+</body>
Modified: trunk/Source/WebCore/ChangeLog (225441 => 225442)
--- trunk/Source/WebCore/ChangeLog 2017-12-02 03:19:16 UTC (rev 225441)
+++ trunk/Source/WebCore/ChangeLog 2017-12-02 05:39:30 UTC (rev 225442)
@@ -1,3 +1,36 @@
+2017-12-01 Alicia Boya García <[email protected]>
+
+ [MSE] Use correct range end checks in sourceBufferPrivateDidReceiveSample()
+ https://bugs.webkit.org/show_bug.cgi?id=179690
+
+ Reviewed by Jer Noble.
+
+ The Coded Frame Processing algorithm as defined in
+ https://www.w3.org/TR/media-source/#sourcebuffer-coded-frame-processing states:
+
+ 1.14. Remove existing coded frames in track buffer:
+ -> If highest end timestamp for track buffer is not set:
+ [...]
+ -> If highest end timestamp for track buffer is set and less than or
+ equal to presentation timestamp:
+ Remove all coded frames from track buffer that have a
+ presentation timestamp greater than or equal to highest end
+ timestamp and less than frame end timestamp.
+
+ Note the removal range is closed-open [a, b). WebKit is actually removing
+ frames using an open-closed range (a, b], which causes frames not to be removed
+ in situations where they should and frames to be removed in situations when
+ they should not.
+
+ Tests: media/media-source/media-source-range-end-frame-not-removed.html
+ media/media-source/media-source-range-start-frame-replaced.html
+
+ * Modules/mediasource/SampleMap.cpp:
+ (WebCore::PresentationOrderSampleMap::findSamplesBetweenPresentationTimesFromEnd):
+ * Modules/mediasource/SampleMap.h:
+ * Modules/mediasource/SourceBuffer.cpp:
+ (WebCore::SourceBuffer::sourceBufferPrivateDidReceiveSample):
+
2017-12-01 Simon Fraser <[email protected]>
Reduce the number of calls to ViewportConfiguration::updateConfiguration()
Modified: trunk/Source/WebCore/Modules/mediasource/SampleMap.cpp (225441 => 225442)
--- trunk/Source/WebCore/Modules/mediasource/SampleMap.cpp 2017-12-02 03:19:16 UTC (rev 225441)
+++ trunk/Source/WebCore/Modules/mediasource/SampleMap.cpp 2017-12-02 05:39:30 UTC (rev 225442)
@@ -284,28 +284,21 @@
return { lower_bound, upper_bound };
}
-PresentationOrderSampleMap::iterator_range PresentationOrderSampleMap::findSamplesWithinPresentationRange(const MediaTime& beginTime, const MediaTime& endTime)
+PresentationOrderSampleMap::iterator_range PresentationOrderSampleMap::findSamplesBetweenPresentationTimesFromEnd(const MediaTime& beginTime, const MediaTime& endTime)
{
- // startTime is not inclusive, so use upper_bound to exclude samples which start exactly at startTime.
- // endTime is inclusive, so use upper_bound to include samples which start exactly at endTime.
- auto lower_bound = m_samples.upper_bound(beginTime);
- auto upper_bound = m_samples.upper_bound(endTime);
- if (lower_bound == upper_bound)
- return { end(), end() };
- return { lower_bound, upper_bound };
-}
-
-PresentationOrderSampleMap::iterator_range PresentationOrderSampleMap::findSamplesWithinPresentationRangeFromEnd(const MediaTime& beginTime, const MediaTime& endTime)
-{
- reverse_iterator rangeEnd = std::find_if(rbegin(), rend(), [&beginTime](auto& value) {
- return value.second->presentationTime() <= beginTime;
+ reverse_iterator rangeEnd = std::find_if(rbegin(), rend(), [&endTime](auto& value) {
+ return value.first < endTime;
});
- reverse_iterator rangeStart = std::find_if(rbegin(), rangeEnd, [&endTime](auto& value) {
- return value.second->presentationTime() <= endTime;
+ reverse_iterator rangeStart = std::find_if(rangeEnd, rend(), [&beginTime](auto& value) {
+ return value.first < beginTime;
});
- return iterator_range(rangeEnd.base(), rangeStart.base());
+ if (rangeStart == rangeEnd)
+ return { end(), end() };
+
+ // ( rangeStart, rangeEnd ] == [ rangeStart.base(), rangeEnd.base() )
+ return { rangeStart.base(), rangeEnd.base() };
}
DecodeOrderSampleMap::reverse_iterator_range DecodeOrderSampleMap::findDependentSamples(MediaSample* sample)
Modified: trunk/Source/WebCore/Modules/mediasource/SampleMap.h (225441 => 225442)
--- trunk/Source/WebCore/Modules/mediasource/SampleMap.h 2017-12-02 03:19:16 UTC (rev 225441)
+++ trunk/Source/WebCore/Modules/mediasource/SampleMap.h 2017-12-02 05:39:30 UTC (rev 225442)
@@ -63,8 +63,7 @@
WEBCORE_EXPORT reverse_iterator reverseFindSampleContainingPresentationTime(const MediaTime&);
WEBCORE_EXPORT reverse_iterator reverseFindSampleBeforePresentationTime(const MediaTime&);
WEBCORE_EXPORT iterator_range findSamplesBetweenPresentationTimes(const MediaTime&, const MediaTime&);
- WEBCORE_EXPORT iterator_range findSamplesWithinPresentationRange(const MediaTime&, const MediaTime&);
- WEBCORE_EXPORT iterator_range findSamplesWithinPresentationRangeFromEnd(const MediaTime&, const MediaTime&);
+ WEBCORE_EXPORT iterator_range findSamplesBetweenPresentationTimesFromEnd(const MediaTime&, const MediaTime&);
private:
MapType m_samples;
Modified: trunk/Source/WebCore/Modules/mediasource/SourceBuffer.cpp (225441 => 225442)
--- trunk/Source/WebCore/Modules/mediasource/SourceBuffer.cpp 2017-12-02 03:19:16 UTC (rev 225441)
+++ trunk/Source/WebCore/Modules/mediasource/SourceBuffer.cpp 2017-12-02 05:39:30 UTC (rev 225442)
@@ -1537,9 +1537,11 @@
PresentationOrderSampleMap::iterator_range range;
if (highestBufferedTime - trackBuffer.highestPresentationTimestamp < trackBuffer.lastFrameDuration)
- range = trackBuffer.samples.presentationOrder().findSamplesWithinPresentationRangeFromEnd(trackBuffer.highestPresentationTimestamp, frameEndTimestamp);
+ // If the new frame is at the end of the buffered ranges, perform a sequential scan from end (O(1)).
+ range = trackBuffer.samples.presentationOrder().findSamplesBetweenPresentationTimesFromEnd(trackBuffer.highestPresentationTimestamp, frameEndTimestamp);
else
- range = trackBuffer.samples.presentationOrder().findSamplesWithinPresentationRange(trackBuffer.highestPresentationTimestamp, frameEndTimestamp);
+ // In any other case, perform a binary search (O(log(n)).
+ range = trackBuffer.samples.presentationOrder().findSamplesBetweenPresentationTimes(trackBuffer.highestPresentationTimestamp, frameEndTimestamp);
if (range.first != trackBuffer.samples.presentationOrder().end())
erasedSamples.addRange(range.first, range.second);
Modified: trunk/Tools/TestWebKitAPI/Tests/WebCore/SampleMap.cpp (225441 => 225442)
--- trunk/Tools/TestWebKitAPI/Tests/WebCore/SampleMap.cpp 2017-12-02 03:19:16 UTC (rev 225441)
+++ trunk/Tools/TestWebKitAPI/Tests/WebCore/SampleMap.cpp 2017-12-02 05:39:30 UTC (rev 225442)
@@ -202,30 +202,30 @@
EXPECT_TRUE(presentationMap.end() == iterator_range.second);
}
-TEST_F(SampleMapTest, findSamplesWithinPresentationRange)
+TEST_F(SampleMapTest, findSamplesBetweenPresentationTimesFromEnd)
{
auto& presentationMap = map.presentationOrder();
- auto iterator_range = presentationMap.findSamplesWithinPresentationRange(MediaTime(0, 1), MediaTime(1, 1));
- EXPECT_EQ(MediaTime(1, 1), iterator_range.first->second->presentationTime());
- EXPECT_EQ(MediaTime(2, 1), iterator_range.second->second->presentationTime());
+ auto iterator_range = presentationMap.findSamplesBetweenPresentationTimesFromEnd(MediaTime(0, 1), MediaTime(1, 1));
+ EXPECT_EQ(MediaTime(0, 1), iterator_range.first->second->presentationTime());
+ EXPECT_EQ(MediaTime(1, 1), iterator_range.second->second->presentationTime());
- iterator_range = presentationMap.findSamplesWithinPresentationRange(MediaTime(1, 2), MediaTime(3, 2));
+ iterator_range = presentationMap.findSamplesBetweenPresentationTimesFromEnd(MediaTime(1, 2), MediaTime(3, 2));
EXPECT_EQ(MediaTime(1, 1), iterator_range.first->second->presentationTime());
EXPECT_EQ(MediaTime(2, 1), iterator_range.second->second->presentationTime());
- iterator_range = presentationMap.findSamplesWithinPresentationRange(MediaTime(9, 1), MediaTime(21, 1));
- EXPECT_EQ(MediaTime(11, 1), iterator_range.first->second->presentationTime());
+ iterator_range = presentationMap.findSamplesBetweenPresentationTimesFromEnd(MediaTime(9, 1), MediaTime(21, 1));
+ EXPECT_EQ(MediaTime(9, 1), iterator_range.first->second->presentationTime());
EXPECT_TRUE(presentationMap.end() == iterator_range.second);
- iterator_range = presentationMap.findSamplesWithinPresentationRange(MediaTime(-1, 1), MediaTime(0, 1));
- EXPECT_EQ(MediaTime(0, 1), iterator_range.first->second->presentationTime());
- EXPECT_EQ(MediaTime(1, 1), iterator_range.second->second->presentationTime());
+ iterator_range = presentationMap.findSamplesBetweenPresentationTimesFromEnd(MediaTime(-1, 1), MediaTime(0, 1));
+ EXPECT_TRUE(presentationMap.end() == iterator_range.first);
+ EXPECT_TRUE(presentationMap.end() == iterator_range.second);
- iterator_range = presentationMap.findSamplesWithinPresentationRange(MediaTime(10, 1), MediaTime(21, 2));
+ iterator_range = presentationMap.findSamplesBetweenPresentationTimesFromEnd(MediaTime(19, 2), MediaTime(10, 1));
EXPECT_TRUE(presentationMap.end() == iterator_range.first);
EXPECT_TRUE(presentationMap.end() == iterator_range.second);
- iterator_range = presentationMap.findSamplesWithinPresentationRange(MediaTime(20, 1), MediaTime(21, 1));
+ iterator_range = presentationMap.findSamplesBetweenPresentationTimesFromEnd(MediaTime(20, 1), MediaTime(21, 1));
EXPECT_TRUE(presentationMap.end() == iterator_range.first);
EXPECT_TRUE(presentationMap.end() == iterator_range.second);
}