Branch: refs/heads/main
  Home:   https://github.com/WebKit/WebKit
  Commit: 21a3e6b45c05b297534a0727d2ea6dd87d6e0aa6
      
https://github.com/WebKit/WebKit/commit/21a3e6b45c05b297534a0727d2ea6dd87d6e0aa6
  Author: Jean-Yves Avenard <[email protected]>
  Date:   2026-05-17 (Sun, 17 May 2026)

  Changed paths:
    M 
LayoutTests/media/media-source/media-source-remove-decodeorder-crash-expected.txt
    M LayoutTests/media/media-source/media-source-remove-decodeorder-crash.html
    M Source/WebCore/platform/graphics/TrackBuffer.cpp
    M Source/WebCore/platform/graphics/TrackBuffer.h

  Log Message:
  -----------
  [MSE] SourceBuffer.remove() removes one extra sample, and buffered trims 
coverage still backed by retained samples
https://bugs.webkit.org/show_bug.cgi?id=314814
rdar://177065364

Reviewed by Eric Carlson.

Two defects along the SourceBuffer.remove() path:

1. Per MSE spec 3.5.9 step 3.3, only coded frames whose starting
   timestamp is "greater than or equal to start" should be removed.
   TrackBuffer::removeCodedFrames was using
   findSampleContainingOrAfterPresentationTime(start), which for
   non-divisible samples (video frames) returns the sample whose
   presentation range *contains* start - i.e. a sample with PTS <
   start - and erased it. Switch to
   findSampleStartingOnOrAfterPresentationTime to match the spec
   exactly. Divisible samples are still split at start by the prior
   divideSampleIfPossibleAtPresentationTime call, and the resulting
   "after" piece (whose PTS == start) is then correctly picked up by
   findSampleStartingOnOrAfter. Apply the same change in
   codedFramesIntervalSize so the eviction-size estimator stays
   consistent with the actual remove behaviour.

2. TrackBuffer::removeSamples' neighbour-sample handling already
   padded erasedRanges on either side when the adjacent retained
   sample left a gap (prevSample.end < erasedStart, or nextSample.PT
   > erasedEnd). The symmetric overlap cases were never handled, so
   when a retained sample's presentation interval extended into the
   erased range - which happens for WebM sub-millisecond overlaps
   allowed by contiguousFrameTolerance, and can also be manufactured
   by tests via abort()+append - erasedRanges included coverage that
   was still backed by a retained sample, and the caller's
   intersection trimmed m_buffered accordingly. The old "containing"
   remove semantics papered over this in a subsequent remove by
   aggressively pulling the overlap sample in; spec-strict remove
   does not, so the inconsistency is now observable. Extend the same
   neighbour check with overlap branches: if the previous retained
   sample ends past erasedStart, clip erasedStart to its end; if the
   next retained sample starts before erasedEnd, clip erasedEnd to
   its PTS. No extra map scans - reuses the iterators already fetched
   for the gap case.

* LayoutTests/media/media-source/media-source-remove-decodeorder-crash.html:
Change remove(1.9, 2) to remove(1, 2). This test doesn't involve
buffered-range math; the original call relied on the old "containing"
removal to erase the [1, 2) sample. Under spec-strict no sample has
PTS in [1.9, 2). remove(1, 2) still drives the decode-order
extraction path (PTS=1 has DTS=2, last in decode order) and produces
the existing expected output.

* Source/WebCore/platform/graphics/TrackBuffer.cpp:
(WebCore::TrackBuffer::removeSamples):
(WebCore::TrackBuffer::removeCodedFrames):
(WebCore::TrackBuffer::codedFramesIntervalSize):
(WebCore::TrackBuffer::tryDivideSampleAtTime):
* Source/WebCore/platform/graphics/TrackBuffer.h:

Canonical link: https://commits.webkit.org/313383@main



To unsubscribe from these emails, change your notification settings at 
https://github.com/WebKit/WebKit/settings/notifications

Reply via email to