Bug 225800 - [MSE] MediaSample that need to be removed with SourceBufferPrivate::evictCodedFrames() may not be removed.
Summary: [MSE] MediaSample that need to be removed with SourceBufferPrivate::evictCode...
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: Media (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Nobody
URL:
Keywords: InRadar
Depends on:
Blocks: 230672
  Show dependency treegraph
 
Reported: 2021-05-13 23:12 PDT by Toshio Ogasawara
Modified: 2021-09-23 02:26 PDT (History)
13 users (show)

See Also:


Attachments
patch (8.59 KB, text/plain)
2021-05-13 23:57 PDT, Toshio Ogasawara
jer.noble: review-
ews-feeder: commit-queue-
Details
patch (9.00 KB, patch)
2021-05-26 02:48 PDT, Toshio Ogasawara
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Toshio Ogasawara 2021-05-13 23:12:48 PDT
Repeating appendBuffer and seek may result in a buffer full.
When buffer full occurs in appnedBuffer, MediaSample after the CurrnetTime + 30s needs to be removed by SourceBufferPrivate::evictCodedFrames(), but it may not be removed depending on the buffered status.
Comment 1 Toshio Ogasawara 2021-05-13 23:57:48 PDT
Created attachment 428607 [details]
patch

This patch removes MediaSample after CurrentTime + 30s that need to be removed with SourceBufferPrivate::evictCodedFrames().
Comment 2 Jer Noble 2021-05-17 14:31:23 PDT
Comment on attachment 428607 [details]
patch

View in context: https://bugs.webkit.org/attachment.cgi?id=428607&action=review

> Source/WebCore/platform/graphics/SourceBufferPrivate.cpp:703
> -    while (rangeStart > minimumRangeStart) {
> +    while (rangeEnd > minimumRangeStart) {

Comparing `rangeEnd` to `mininimumRangeStart` feels wrong here.  Perhaps we just need to restructure this code to correctly set `minimumRangeStart` to the beginning of the next buffered range, if that time is > `minimumRangeStart`.  Then this while loop can look identical to the while loop above.
Comment 3 Toshio Ogasawara 2021-05-19 02:05:21 PDT
>Comparing `rangeEnd` to `mininimumRangeStart` feels wrong here. 

I think it is correct to compare with rangeEnd.

At the end of this while loop, there is a process to subtract thirtySeconds from rangeStart and rangeEnd.
If this process is repeated, rangeStart may become less than minimumRangeStart before rangeEnd.
If rangeStart is less than minimumRangeStart and rangeEnd is greater than minimumRangeStart, this while loop will not be processed.
Therefore, removable MediaSamples in the range from minimumRangeStart to rangeEnd are not removed.
Comment 4 Toshio Ogasawara 2021-05-19 02:06:56 PDT
>Then this while loop can look identical to the while loop above.

In the first while loop of evictCodedFrame, there is a process to add thirtySeconds to rangeStart and rangeEnd.
Even if this process is repeated, rangeStart will not be larger than maximumRangeEnd before rangeEnd.
Therefore, the removable MediaSamples in the range from rangeStart to maximumRangeEnd is removed.

I think it is correct to compare the end of the range(rangeEnd) when processing in descending order, and the start of the range(startRange) when processing in ascending order.
Comment 5 Radar WebKit Bug Importer 2021-05-20 23:13:15 PDT
<rdar://problem/78296352>
Comment 6 Jer Noble 2021-05-20 23:59:17 PDT
Comment on attachment 428607 [details]
patch

> >Comparing `rangeEnd` to `mininimumRangeStart` feels wrong here. 
> 
> I think it is correct to compare with rangeEnd.

No, it's definitely not. You can see why it's wrong here:

-            rangeEnd = buffered.start(endTimeRange);
+            if (endTimeRange == notFound)
+                rangeStart = buffered.end(startTimeRange);
+            else
+                rangeEnd = buffered.start(endTimeRange);

If that comparison was correct, this change would be unnecessary. This just adds a complicated calculation to an already overcomplicated while loop.

The correct fix would look more like this:

@@ -689,7 +689,7 @@ void SourceBufferPrivate::evictCodedFrames(uint64_t newDataSize, uint64_t pendin
         return;
     }
 
-    MediaTime minimumRangeStart = currentTime + thirtySeconds;
+    MediaTime minimumRangeStart = std::min(currentTime + thirtySeconds, buffered.end(currentTimeRange));
 
     rangeEnd = duration;
     if (!rangeEnd.isFinite()) {

This sets up minimumRangeStart correctly to be located at the end of the current range, or 30s after currentTime, whichever is lower.

@@ -701,16 +701,6 @@ void SourceBufferPrivate::evictCodedFrames(uint64_t newDataSize, uint64_t pendin
 
     rangeStart = rangeEnd - thirtySeconds;
     while (rangeStart > minimumRangeStart) {
-        // Do not evict data from the time range that contains currentTime.
-        uint64_t startTimeRange = buffered.find(rangeStart);
-        if (currentTimeRange != notFound && startTimeRange == currentTimeRange) {
-            uint64_t endTimeRange = buffered.find(rangeEnd);
-            if (currentTimeRange != notFound && endTimeRange == currentTimeRange)
-                break;
-
-            rangeEnd = buffered.start(endTimeRange);
-        }
-

And now we don't need to do a complicated recalculation at every step through the loop. It just walks back in 30s increments until it reaches minimumRangeStart.
Comment 7 Jer Noble 2021-05-21 00:21:58 PDT
(In reply to Jer Noble from comment #6)
> -    MediaTime minimumRangeStart = currentTime + thirtySeconds;
> +    MediaTime minimumRangeStart = std::min(currentTime + thirtySeconds,
> buffered.end(currentTimeRange));

Whoops, this should be max, not min.

(In reply to Toshio Ogasawara from comment #4)
> I think it is correct to compare the end of the range(rangeEnd) when
> processing in descending order, and the start of the range(startRange) when
> processing in ascending order.

I take back my earlier comment, you're right about this comparison, because rangeStart isn't actually used inside the loop without doing `max(minimumRangeStart, rangeStart)` first.

Still, the entire first section of the while() loop can be removed to solve this problem, rather than adding more calculations.
Comment 8 Toshio Ogasawara 2021-05-26 02:43:05 PDT
(In reply to Jer Noble from comment #7)
> (In reply to Jer Noble from comment #6)
> > -    MediaTime minimumRangeStart = currentTime + thirtySeconds;
> > +    MediaTime minimumRangeStart = std::min(currentTime + thirtySeconds,
> > buffered.end(currentTimeRange));
> 
> Whoops, this should be max, not min.
> 
> (In reply to Toshio Ogasawara from comment #4)
> > I think it is correct to compare the end of the range(rangeEnd) when
> > processing in descending order, and the start of the range(startRange) when
> > processing in ascending order.
> 
> I take back my earlier comment, you're right about this comparison, because
> rangeStart isn't actually used inside the loop without doing
> `max(minimumRangeStart, rangeStart)` first.
> 
> Still, the entire first section of the while() loop can be removed to solve
> this problem, rather than adding more calculations.

I was able to confirm with your fix that minimumRangeStart is set to be correctly placed at the end of the current range, or 30 seconds after the currentTime, whichever is higher.
Now we don't need to do complicated recalculation.
Thank you.


> Source/WebCore/platform/graphics/SourceBufferPrivate.cpp:703
> -    while (rangeStart > minimumRangeStart) {
> +    while (rangeEnd > minimumRangeStart) {
I will add this fix to take into account the following conditions.

When "rangeStart < minimumRangeStart, rangeEnd > minimumRangeStart", remove between minimumRangeStart and rangeEnd.
Comment 9 Toshio Ogasawara 2021-05-26 02:48:44 PDT
Created attachment 429743 [details]
patch

Fixed patch.
Comment 10 Jer Noble 2021-05-26 17:10:10 PDT
Comment on attachment 429743 [details]
patch

r=me. Thanks for continuing to work on this with me!
Comment 11 Toshio Ogasawara 2021-05-26 17:32:09 PDT
(In reply to Jer Noble from comment #10)
> Comment on attachment 429743 [details]
> patch
> 
> r=me. Thanks for continuing to work on this with me!

Thank you for the review.
Comment 12 EWS 2021-05-26 21:35:25 PDT
Committed r278147 (238191@main): <https://commits.webkit.org/238191@main>

All reviewed patches have been landed. Closing bug and clearing flags on attachment 429743 [details].