Title: [283097] trunk
Revision
283097
Author
[email protected]
Date
2021-09-26 21:40:08 -0700 (Sun, 26 Sep 2021)

Log Message

[MSE] appending to the source buffer will not throw when the source buffer is full.
https://bugs.webkit.org/show_bug.cgi?id=230672
rdar://problem/83496195

Reviewed by Eric Carlson.

Source/WebCore:

Tests: media/media-source/media-source-append-buffer-full-quota-exceeded-error.html

* platform/graphics/PlatformTimeRanges.cpp:
(WebCore::PlatformTimeRanges::findWithEpsilon): add method.
(WebCore::PlatformTimeRanges::copyWithEpsilon const): add method.
* platform/graphics/PlatformTimeRanges.h:
* platform/graphics/SourceBufferPrivate.cpp:
(WebCore::SourceBufferPrivate::evictCodedFrames):

LayoutTests:

* media/media-source/media-source-append-buffer-full-quota-exceeded-error-expected.txt:
* media/media-source/media-source-append-buffer-full-quota-exceeded-error.html:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (283096 => 283097)


--- trunk/LayoutTests/ChangeLog	2021-09-27 04:25:46 UTC (rev 283096)
+++ trunk/LayoutTests/ChangeLog	2021-09-27 04:40:08 UTC (rev 283097)
@@ -1,3 +1,14 @@
+2021-09-26  Jean-Yves Avenard  <[email protected]>
+
+        [MSE] appending to the source buffer will not throw when the source buffer is full.
+        https://bugs.webkit.org/show_bug.cgi?id=230672
+        rdar://problem/83496195
+
+        Reviewed by Eric Carlson.
+
+        * media/media-source/media-source-append-buffer-full-quota-exceeded-error-expected.txt:
+        * media/media-source/media-source-append-buffer-full-quota-exceeded-error.html:
+
 2021-09-26  Lauro Moura  <[email protected]>
 
         [WPE] Rebaseline a number of text-only failures

Modified: trunk/LayoutTests/media/media-source/media-source-append-buffer-full-quota-exceeded-error-expected.txt (283096 => 283097)


--- trunk/LayoutTests/media/media-source/media-source-append-buffer-full-quota-exceeded-error-expected.txt	2021-09-27 04:25:46 UTC (rev 283096)
+++ trunk/LayoutTests/media/media-source/media-source-append-buffer-full-quota-exceeded-error-expected.txt	2021-09-27 04:40:08 UTC (rev 283097)
@@ -30,5 +30,302 @@
 EXPECTED (exception != 'QuotaExceededError: The quota has been exceeded.') OK
 Appending PTS=13-15
 EXPECTED (exception == 'QuotaExceededError: The quota has been exceeded.') OK
+EVENT(updateend)
+Appending PTS=0
+EVENT(updateend)
+Appending PTS=1
+EVENT(updateend)
+Appending PTS=2
+EVENT(updateend)
+Appending PTS=3
+EVENT(updateend)
+Appending PTS=4
+EVENT(updateend)
+Appending PTS=5
+EVENT(updateend)
+Appending PTS=6
+EVENT(updateend)
+Appending PTS=7
+EVENT(updateend)
+Appending PTS=8
+EVENT(updateend)
+Appending PTS=9
+EVENT(updateend)
+Appending PTS=10
+EVENT(updateend)
+Appending PTS=11
+EVENT(updateend)
+Appending PTS=12
+EVENT(updateend)
+Appending PTS=13
+EVENT(updateend)
+Appending PTS=14
+EVENT(updateend)
+Appending PTS=15
+EVENT(updateend)
+Appending PTS=16
+EVENT(updateend)
+Appending PTS=17
+EVENT(updateend)
+Appending PTS=18
+EVENT(updateend)
+Appending PTS=19
+EVENT(updateend)
+Appending PTS=20
+EVENT(updateend)
+Appending PTS=21
+EVENT(updateend)
+Appending PTS=22
+EVENT(updateend)
+Appending PTS=23
+EVENT(updateend)
+Appending PTS=24
+EVENT(updateend)
+Appending PTS=25
+EVENT(updateend)
+Appending PTS=26
+EVENT(updateend)
+Appending PTS=27
+EVENT(updateend)
+Appending PTS=28
+EVENT(updateend)
+Appending PTS=29
+EVENT(updateend)
+Appending PTS=30
+EVENT(updateend)
+Appending PTS=31
+EVENT(updateend)
+Appending PTS=32
+EVENT(updateend)
+Appending PTS=33
+EVENT(updateend)
+Appending PTS=34
+EVENT(updateend)
+Appending PTS=35
+EVENT(updateend)
+Appending PTS=36
+EVENT(updateend)
+Appending PTS=37
+EVENT(updateend)
+Appending PTS=38
+EVENT(updateend)
+Appending PTS=39
+EVENT(updateend)
+Appending PTS=40
+EVENT(updateend)
+Appending PTS=41
+EVENT(updateend)
+Appending PTS=42
+EXPECTED (exception == 'QuotaExceededError: The quota has been exceeded.') OK
+EXPECTED (1 == '1') OK
+EVENT(updateend)
+Appending PTS=0.002
+EVENT(updateend)
+Appending PTS=1.002
+EVENT(updateend)
+Appending PTS=2.002
+EVENT(updateend)
+Appending PTS=3.002
+EVENT(updateend)
+Appending PTS=4.002
+EVENT(updateend)
+Appending PTS=5.002
+EVENT(updateend)
+Appending PTS=6.002
+EVENT(updateend)
+Appending PTS=7.002
+EVENT(updateend)
+Appending PTS=8.002
+EVENT(updateend)
+Appending PTS=9.002
+EVENT(updateend)
+Appending PTS=10.002
+EVENT(updateend)
+Appending PTS=11.002
+EVENT(updateend)
+Appending PTS=12.002
+EVENT(updateend)
+Appending PTS=13.002
+EVENT(updateend)
+Appending PTS=14.002
+EVENT(updateend)
+Appending PTS=15.002
+EVENT(updateend)
+Appending PTS=16.002
+EVENT(updateend)
+Appending PTS=17.002
+EVENT(updateend)
+Appending PTS=18.002
+EVENT(updateend)
+Appending PTS=19.002
+EVENT(updateend)
+Appending PTS=20.002
+EVENT(updateend)
+Appending PTS=21.002
+EVENT(updateend)
+Appending PTS=22.002
+EVENT(updateend)
+Appending PTS=23.002
+EVENT(updateend)
+Appending PTS=24.002
+EVENT(updateend)
+Appending PTS=25.002
+EVENT(updateend)
+Appending PTS=26.002
+EVENT(updateend)
+Appending PTS=27.002
+EVENT(updateend)
+Appending PTS=28.002
+EVENT(updateend)
+Appending PTS=29.002
+EVENT(updateend)
+Appending PTS=30.002
+EVENT(updateend)
+Appending PTS=31.002
+EVENT(updateend)
+Appending PTS=32.002
+EVENT(updateend)
+Appending PTS=33.002
+EVENT(updateend)
+Appending PTS=34.002
+EVENT(updateend)
+Appending PTS=35.002
+EVENT(updateend)
+Appending PTS=36.002
+EVENT(updateend)
+Appending PTS=37.002
+EVENT(updateend)
+Appending PTS=38.002
+EVENT(updateend)
+Appending PTS=39.002
+EVENT(updateend)
+Appending PTS=40.002
+EVENT(updateend)
+Appending PTS=41.002
+EVENT(updateend)
+Appending PTS=42.002
+EXPECTED (exception == 'QuotaExceededError: The quota has been exceeded.') OK
+EVENT(updateend)
+Appending PTS=0
+EVENT(updateend)
+Appending PTS=1
+EVENT(updateend)
+Appending PTS=2
+EVENT(updateend)
+Appending PTS=3
+EVENT(updateend)
+Appending PTS=4
+EVENT(updateend)
+Appending PTS=5
+EVENT(updateend)
+Appending PTS=6
+EVENT(updateend)
+Appending PTS=7
+EVENT(updateend)
+Appending PTS=8
+EVENT(updateend)
+Appending PTS=9
+EVENT(updateend)
+Appending PTS=10
+EVENT(updateend)
+Appending PTS=11
+EVENT(updateend)
+Appending PTS=12
+EVENT(updateend)
+Appending PTS=13
+EVENT(updateend)
+Appending PTS=14
+EVENT(updateend)
+Appending PTS=15
+EVENT(updateend)
+Appending PTS=16
+EVENT(updateend)
+Appending PTS=17
+EVENT(updateend)
+Appending PTS=18
+EVENT(updateend)
+Appending PTS=19
+EVENT(updateend)
+Appending PTS=20
+EVENT(updateend)
+Appending PTS=21
+EVENT(updateend)
+Appending PTS=22
+EVENT(updateend)
+Appending PTS=23
+EVENT(updateend)
+Appending PTS=24
+EVENT(updateend)
+Appending PTS=25
+EVENT(updateend)
+Appending PTS=26
+EVENT(updateend)
+Appending PTS=27
+EVENT(updateend)
+Appending PTS=28
+EVENT(updateend)
+Appending PTS=29
+EVENT(updateend)
+EXPECTED (exception != 'QuotaExceededError: The quota has been exceeded.') OK
+Appending PTS=30
+EVENT(updateend)
+Appending PTS=30.083333333333332
+EVENT(updateend)
+Appending PTS=30.166666666666668
+EVENT(updateend)
+Appending PTS=30.25
+EVENT(updateend)
+Appending PTS=30.333333333333332
+EVENT(updateend)
+Appending PTS=30.416666666666668
+EVENT(updateend)
+Appending PTS=30.5
+EVENT(updateend)
+Appending PTS=30.583333333333332
+EVENT(updateend)
+Appending PTS=30.666666666666668
+EVENT(updateend)
+Appending PTS=30.75
+EVENT(updateend)
+Appending PTS=30.833333333333332
+EVENT(updateend)
+Appending PTS=30.916666666666668
+EVENT(updateend)
+Appending PTS=31
+EVENT(updateend)
+Appending PTS=31.083333333333332
+EVENT(updateend)
+Appending PTS=31.166666666666668
+EVENT(updateend)
+Appending PTS=31.25
+EVENT(updateend)
+Appending PTS=31.333333333333332
+EVENT(updateend)
+Appending PTS=31.416666666666668
+EVENT(updateend)
+Appending PTS=31.5
+EVENT(updateend)
+Appending PTS=31.583333333333332
+EVENT(updateend)
+Appending PTS=31.666666666666668
+EVENT(updateend)
+Appending PTS=31.75
+EVENT(updateend)
+Appending PTS=31.833333333333332
+EVENT(updateend)
+Appending PTS=31.916666666666668
+EVENT(updateend)
+EXPECTED (exception != 'QuotaExceededError: The quota has been exceeded.') OK
+EXPECTED (1 == '1') OK
+EVENT(updateend)
+EXPECTED (2 == '2') OK
+Appending PTS=32
+EVENT(updateend)
+Appending PTS=33
+EVENT(updateend)
+Appending PTS=34
+EVENT(updateend)
+Appending PTS=35
+EXPECTED (exception == 'QuotaExceededError: The quota has been exceeded.') OK
 END OF TEST
 

Modified: trunk/LayoutTests/media/media-source/media-source-append-buffer-full-quota-exceeded-error.html (283096 => 283097)


--- trunk/LayoutTests/media/media-source/media-source-append-buffer-full-quota-exceeded-error.html	2021-09-27 04:25:46 UTC (rev 283096)
+++ trunk/LayoutTests/media/media-source/media-source-append-buffer-full-quota-exceeded-error.html	2021-09-27 04:40:08 UTC (rev 283097)
@@ -10,12 +10,14 @@
     var initSegment;
     var exception;
 
-    async function appendPtsRange(firstPts, lastPts) {
+    async function appendPtsRange(firstPts, lastPts, timescale = 1, gap = 0, step = null) {
         var resultException = null;
-        for (var pts = firstPts; pts <= lastPts; pts++) {
+        if (step == null)
+            step = timescale;
+        for (var pts = firstPts; pts <= lastPts; pts += step) {
             try {
-                consoleWrite('Appending PTS='+pts);
-                sourceBuffer.appendBuffer(makeASample(pts, pts, 1, 1, 1, SAMPLE_FLAG.SYNC, 1));
+                consoleWrite('Appending PTS='+pts / timescale);
+                sourceBuffer.appendBuffer(makeASample(pts, pts, step - gap, timescale, 1, SAMPLE_FLAG.SYNC, 1));
                 await waitFor(sourceBuffer, 'updateend');
             } catch (e) {
                 resultException = e;
@@ -70,6 +72,43 @@
         exception = await appendConcatenateSamples(13, 15);
         testExpected('exception', 'QuotaExceededError: The quota has been exceeded.', '==');
 
+        // To exercise eviction ahead of current time we must add over 30s of data.
+        internals.settings.setMaximumSourceBufferSize(3000);
+
+        // Ensure that small gaps that would be ignored during playback are also ignored by eviction.
+        // We use a gap of 2/1000 as gaps of 1/1000th are removed and 2002/24000 is the maximum gap ignored during playback.
+        sourceBuffer.remove(0, Infinity);
+        await waitFor(sourceBuffer, 'updateend');
+        exception = await appendPtsRange(0, 60000, 1000, 2);
+        testExpected('exception', 'QuotaExceededError: The quota has been exceeded.', '==');
+        // Check that appendBuffer removed all the small gaps in the data less than the threshold.
+        testExpected(sourceBuffer.buffered.length, '1', '==');
+
+        // Ensure that if current time is close enough to the buffered data that the nearest range isn't evicted.
+        sourceBuffer.remove(0, Infinity);
+        await waitFor(sourceBuffer, 'updateend');
+        exception = await appendPtsRange(2, 60002, 1000);
+        testExpected('exception', 'QuotaExceededError: The quota has been exceeded.', '==');
+
+        internals.settings.setMaximumSourceBufferSize(4000);
+        // Ensure that small gaps that would be ignored during playback are also ignored by eviction.
+        // We use a gap of 2000/24000 which is less than the 2002/24000 gap ignored during playback.
+        // Gaps are removed during append, so we remove data to create a gap <= 2000/24000.
+        sourceBuffer.remove(0, Infinity);
+        await waitFor(sourceBuffer, 'updateend');
+        exception = await appendPtsRange(0, 29);
+        testExpected('exception', 'QuotaExceededError: The quota has been exceeded.', '!=');
+        // Add 30 to 32s in smaller granularity.
+        exception = await appendPtsRange(720000, 768000 - 1, 24000, 0, 2000);
+        testExpected('exception', 'QuotaExceededError: The quota has been exceeded.', '!=');
+        testExpected(sourceBuffer.buffered.length, '1', '==');
+        // Create a small 2000/24000 gap in the data at 31s.
+        sourceBuffer.remove(744000 / 24000, (744000 + 2000) / 24000);
+        await waitFor(sourceBuffer, 'updateend');
+        testExpected(sourceBuffer.buffered.length, '2', '==');
+        exception = await appendPtsRange(32, 60);
+        testExpected('exception', 'QuotaExceededError: The quota has been exceeded.', '==');
+
         endTest();
     });
     </script>

Modified: trunk/Source/WebCore/ChangeLog (283096 => 283097)


--- trunk/Source/WebCore/ChangeLog	2021-09-27 04:25:46 UTC (rev 283096)
+++ trunk/Source/WebCore/ChangeLog	2021-09-27 04:40:08 UTC (rev 283097)
@@ -1,3 +1,20 @@
+2021-09-26  Jean-Yves Avenard  <[email protected]>
+
+        [MSE] appending to the source buffer will not throw when the source buffer is full.
+        https://bugs.webkit.org/show_bug.cgi?id=230672
+        rdar://problem/83496195
+
+        Reviewed by Eric Carlson.
+
+        Tests: media/media-source/media-source-append-buffer-full-quota-exceeded-error.html
+
+        * platform/graphics/PlatformTimeRanges.cpp:
+        (WebCore::PlatformTimeRanges::findWithEpsilon): add method.
+        (WebCore::PlatformTimeRanges::copyWithEpsilon const): add method.
+        * platform/graphics/PlatformTimeRanges.h:
+        * platform/graphics/SourceBufferPrivate.cpp:
+        (WebCore::SourceBufferPrivate::evictCodedFrames):
+
 2021-09-26  Antti Koivisto  <[email protected]>
 
         Line iterator firstRun/lastRun may return runs from wrong lines

Modified: trunk/Source/WebCore/platform/graphics/PlatformTimeRanges.cpp (283096 => 283097)


--- trunk/Source/WebCore/platform/graphics/PlatformTimeRanges.cpp	2021-09-27 04:25:46 UTC (rev 283096)
+++ trunk/Source/WebCore/platform/graphics/PlatformTimeRanges.cpp	2021-09-27 04:40:08 UTC (rev 283097)
@@ -203,6 +203,33 @@
     return notFound;
 }
 
+size_t PlatformTimeRanges::findWithEpsilon(const MediaTime& time, const MediaTime& epsilon)
+{
+    bool ignoreInvalid;
+    for (unsigned n = 0; n < length(); n++) {
+        if (time + epsilon >= start(n, ignoreInvalid) && time < end(n, ignoreInvalid))
+            return n;
+    }
+    return notFound;
+}
+
+PlatformTimeRanges PlatformTimeRanges::copyWithEpsilon(const MediaTime& epsilon) const
+{
+    if (length() <= 1)
+        return *this;
+    Vector<Range> ranges;
+    unsigned n1 = 0;
+    for (unsigned n2 = 1; n2 < length(); n2++) {
+        auto& previousRangeEnd = m_ranges[n2 - 1].m_end;
+        if (previousRangeEnd + epsilon < m_ranges[n2].m_start) {
+            ranges.append({ m_ranges[n1].m_start, previousRangeEnd });
+            n1 = n2;
+        }
+    }
+    ranges.append({ m_ranges[n1].m_start, m_ranges[length() - 1].m_end });
+    return ranges;
+}
+
 MediaTime PlatformTimeRanges::nearest(const MediaTime& time) const
 {
     MediaTime closestDelta = MediaTime::positiveInfiniteTime();

Modified: trunk/Source/WebCore/platform/graphics/PlatformTimeRanges.h (283096 => 283097)


--- trunk/Source/WebCore/platform/graphics/PlatformTimeRanges.h	2021-09-27 04:25:46 UTC (rev 283096)
+++ trunk/Source/WebCore/platform/graphics/PlatformTimeRanges.h	2021-09-27 04:40:08 UTC (rev 283097)
@@ -42,6 +42,8 @@
     explicit PlatformTimeRanges() { }
     PlatformTimeRanges(const MediaTime& start, const MediaTime& end);
 
+    PlatformTimeRanges copyWithEpsilon(const MediaTime&) const;
+
     MediaTime start(unsigned index) const;
     MediaTime start(unsigned index, bool& valid) const;
     MediaTime end(unsigned index) const;
@@ -61,6 +63,7 @@
     bool contain(const MediaTime&) const;
 
     size_t find(const MediaTime&) const;
+    size_t findWithEpsilon(const MediaTime&, const MediaTime& epsilon);
     
     MediaTime nearest(const MediaTime&) const;
 

Modified: trunk/Source/WebCore/platform/graphics/SourceBufferPrivate.cpp (283096 => 283097)


--- trunk/Source/WebCore/platform/graphics/SourceBufferPrivate.cpp	2021-09-27 04:25:46 UTC (rev 283096)
+++ trunk/Source/WebCore/platform/graphics/SourceBufferPrivate.cpp	2021-09-27 04:40:08 UTC (rev 283097)
@@ -692,8 +692,8 @@
     // If there still isn't enough free space and there buffers in time ranges after the current range (ie. there is a gap after
     // the current buffered range), delete 30 seconds at a time from duration back to the current time range or 30 seconds after
     // currenTime whichever we hit first.
-    auto buffered = m_buffered->ranges();
-    uint64_t currentTimeRange = buffered.find(currentTime);
+    auto buffered = m_buffered->ranges().copyWithEpsilon(timeFudgeFactor());
+    uint64_t currentTimeRange = buffered.findWithEpsilon(currentTime, timeFudgeFactor());
     if (!buffered.length() || currentTimeRange == buffered.length() - 1) {
 #if !RELEASE_LOG_DISABLED
         ERROR_LOG(LOGIDENTIFIER, "FAILED to free enough after evicting ", initialBufferedSize - totalTrackBufferSizeInBytes());
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to