Branch: refs/heads/main
  Home:   https://github.com/WebKit/WebKit
  Commit: cc6a6a6dd0da3f3c3f7c96cc77a6ffe859a1a178
      
https://github.com/WebKit/WebKit/commit/cc6a6a6dd0da3f3c3f7c96cc77a6ffe859a1a178
  Author: Jean-Yves Avenard <[email protected]>
  Date:   2026-07-07 (Tue, 07 Jul 2026)

  Changed paths:
    M 
LayoutTests/imported/w3c/web-platform-tests/media-source/mediasource-remove-expected.txt
    M 
LayoutTests/imported/w3c/web-platform-tests/media-source/mediasource-sequencemode-append-buffer.html
    M LayoutTests/platform/glib/TestExpectations
    M LayoutTests/platform/mac/TestExpectations
    M Source/WebCore/SourcesCocoa.txt
    M Source/WebCore/WebCore.xcodeproj/project.pbxproj
    M Source/WebCore/platform/graphics/SourceBufferPrivate.cpp
    M Source/WebCore/platform/graphics/SourceBufferPrivate.h
    M 
Source/WebCore/platform/graphics/avfoundation/objc/SourceBufferParserAVFObjC.h
    M 
Source/WebCore/platform/graphics/avfoundation/objc/SourceBufferParserAVFObjC.mm
    M Source/WebCore/platform/graphics/cocoa/ISOBMFFPreParser.cpp
    M Source/WebCore/platform/graphics/cocoa/ISOBMFFPreParser.h
    A Source/WebCore/platform/graphics/cocoa/ISOBMFFTrackInfoParser.cpp
    A Source/WebCore/platform/graphics/cocoa/ISOBMFFTrackInfoParser.h
    M Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj
    A Tools/TestWebKitAPI/Tests/WebCore/cocoa/ISOBMFFTrackInfoParserTests.cpp

  Log Message:
  -----------
  [MSE][Cocoa] 
imported/w3c/web-platform-tests/media-source/mediasource-sequencemode-append-buffer.html
 is a permanent failure
https://bugs.webkit.org/show_bug.cgi?id=316870
rdar://179296547

Reviewed by Youenn Fablet.

The WPT mediasource-sequencemode-append-buffer.html test exercises three
SourceBuffer.mode = "sequence" scenarios using an asset whose video track
carries an empty edit list. Three independent issues — two engine bugs and
one test-side bug — combined to make all three subtests fail on AVFoundation
baswe MSE ; this commit addresses each.

Problems
--------

1. Empty fMP4 edit list not applied to video PTS.

    The asset's video track has an `edts/elst` whose first entry is an
    empty edit (media_time = -1, segment_duration = 0.095 s in movie
    timescale). AVStreamDataParser does not honour empty edits in fMP4, so
    the CMSampleBuffers it emits have PTS = raw mdat PTS, missing the
    elst-prescribed 0.095s presentation shift. The test's segmentInfo
    bakes in the post-shift timestamps, so the engine and the test data
    disagreed by exactly that amount.

2. Frames submitted to coded-frame processing in parser-arrival order.

    MSE Coded Frame Processing step 1.3 sets `timestampOffset =
    group_start_timestamp - presentation_timestamp` on the first sample to
    enter the loop. For multi-track segments the only spec-coherent choice
    for that "first" sample is the cross-track minimum-PTS sample — any
    other choice makes samples of one track land before
    group_start_timestamp. SourceBufferPrivate was iterating
    m_pendingSamples in parser-arrival order, so step 1.3 fired on
    whichever track AVStreamDataParser happened to emit first. Once
    problem 1 was fixed, that mismatch became visible: for media[1] step
    1.3 fired on video (PTS 0.896666) when audio (PTS 0.882358) should
    have driven it. The same problem reappeared on sequence-mode
    discontinuity (step 1.6 retries step 1.3 on the discontinuity-
    triggering sample) when chaining a second segment.
    A similar workaround is implemented by Firefox.

3. Third subtest's expected post-EOS buffered range was unsatisfiable.

    The third subtest appends media[1] then media[0] in sequence mode and
    asserted the post-EOS buffered range to be a single contiguous range.
    With a single per-segment `timestampOffset` (per spec) and media[0]'s
    tracks not aligned at the same start (`timev` = 0.095, `timea` = 0 for
    this asset), placing media[0] adjacent to media[1] inevitably
    introduces a per-track gap inside the unified buffered range of width
    `media[0].timev − media[0].timea`. Firefox and Chrome both fail this
    subtest too — Firefox with the identical two-range output WebKit
    produces, Chrome with a different `timestampOffset` value — so no
    production engine satisfies the expected single-range output for this
    asset shape.

Solutions
---------

1. A new ISOBMFFTrackInfoParser walks the moov bytes (captured by the
    existing ISOBMFFPreParser before they are forwarded to
    AVStreamDataParser) and extracts any per-track empty edit.
    SourceBufferParserAVFObjC then offsets each emitted sample's PTS and
    DTS by that duration via MediaSampleAVFObjC::offsetTimestampsBy()
    before delivering the sample to the client.

2. Before iterating samples in processPendingMediaSamples, do a bounded
    look-ahead per track (16 frames for video — the H.264/H.265 max
    reorder window — 1 for non-video tracks) to identify the cross-track-
    min-PTS sample and its position in the batch. When that sample isn't
    already at position 0, drain priority-track samples in
    [0, priorityIndex] in a first pass; a second pass then iterates the
    remaining samples in arrival order, skipping the entries pass 1
    already processed. The samples vector itself is not mutated.

3. In the imported WPT test, compute the expected post-EOS buffered
    string from segmentInfo, accounting for media[0]'s per-track head
    delta when it is non-zero (giving a two-range expected) and falling
    back to the original single-range string when it is zero. To be
    upstreamed to WPT.

Add API tests, covered by existing tests.

* 
LayoutTests/imported/w3c/web-platform-tests/media-source/mediasource-remove-expected.txt:
* 
LayoutTests/imported/w3c/web-platform-tests/media-source/mediasource-sequencemode-append-buffer.html:
* LayoutTests/platform/glib/TestExpectations:
* LayoutTests/platform/mac/TestExpectations: Remove the
mediasource-sequencemode-append-buffer.html Skip entry.
Mark mediasource-getvideoplaybackquality.html as Failing due to bug 316898.

* Source/WebCore/SourcesCocoa.txt:
* Source/WebCore/WebCore.xcodeproj/project.pbxproj:
Register the new ISOBMFFTrackInfoParser source files.

* Source/WebCore/platform/graphics/SourceBufferPrivate.cpp:
(WebCore::SourceBufferPrivate::findPrioritySample const):
(WebCore::SourceBufferPrivate::processNewMediaSamples):
(WebCore::SourceBufferPrivate::processPendingMediaSamples):
Bounded per-track look-ahead identifies the cross-track-min-PTS
priority sample; a two-pass iteration drains priority-track samples
first, then the rest, without mutating m_pendingSamples.
* Source/WebCore/platform/graphics/SourceBufferPrivate.h:
* 
Source/WebCore/platform/graphics/avfoundation/objc/SourceBufferParserAVFObjC.h:
* 
Source/WebCore/platform/graphics/avfoundation/objc/SourceBufferParserAVFObjC.mm:
(WebCore::makePreParserIfNeeded):
(WebCore::SourceBufferParserAVFObjC::SourceBufferParserAVFObjC):
(WebCore::SourceBufferParserAVFObjC::resetParserState): Clear the map.
(WebCore::SourceBufferParserAVFObjC::didProvideMediaDataForTrackID):
Apply the offset to each sample before delivering it.

(WebCore::SourceBufferParserAVFObjC::setEmptyEditOffsetsFromInitSegment):
Receive per-track empty-edit offsets from the pre-parser callback and
stash them in a per-track map.
* Source/WebCore/platform/graphics/cocoa/ISOBMFFPreParser.cpp:
(WebCore::ISOBMFFPreParser::ISOBMFFPreParser):
(WebCore::ISOBMFFPreParser::reset):
(WebCore::ISOBMFFPreParser::appendData):
Take an optional TrackInfoCallback; buffer moov body bytes during the
segment scan and run the walker once the body is complete.

* Source/WebCore/platform/graphics/cocoa/ISOBMFFPreParser.h:
(WebCore::ISOBMFFPreParser::ISOBMFFPreParser):
* Source/WebCore/platform/graphics/cocoa/ISOBMFFTrackInfoParser.cpp:
(WebCore::FourCC):
(WebCore::readNextChildBox):
(WebCore::forEachChildBox):
(WebCore::readFullBoxVersion):
(WebCore::readMvhdTimescale):
(WebCore::readTkhdTrackID):
(WebCore::readElstEntry0EmptyEditDuration):
(WebCore::findEmptyEditDurationInEdts):
(WebCore::parseTrak):
(WebCore::ISOBMFFTrackInfoParser::parseMoovBody):
New BitReader-based walker returning each track's empty-edit duration.

* Source/WebCore/platform/graphics/cocoa/ISOBMFFTrackInfoParser.h:
* Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* Tools/TestWebKitAPI/Tests/WebCore/cocoa/ISOBMFFTrackInfoParserTests.cpp: 
Added.
(TestWebKitAPI::appendBE32):
(TestWebKitAPI::appendBE64):
(TestWebKitAPI::makeBox):
(TestWebKitAPI::makeMvhd):
(TestWebKitAPI::makeTkhd):
(TestWebKitAPI::makeElstV0):
(TestWebKitAPI::makeElstV1):
(TestWebKitAPI::makeEdts):
(TestWebKitAPI::makeTrak):
(TestWebKitAPI::TEST(ISOBMFFTrackInfoParser, EmptyInputReturnsNothing)):
(TestWebKitAPI::TEST(ISOBMFFTrackInfoParser, SingleTrackEmptyEditVersion0)):
(TestWebKitAPI::TEST(ISOBMFFTrackInfoParser, SingleTrackEmptyEditVersion1)):
(TestWebKitAPI::TEST(ISOBMFFTrackInfoParser, NonEmptyEditIsIgnored)):
(TestWebKitAPI::TEST(ISOBMFFTrackInfoParser, TrackWithoutEditListIsOmitted)):
(TestWebKitAPI::TEST(ISOBMFFTrackInfoParser, TrackIDZeroIsRejected)):
(TestWebKitAPI::TEST(ISOBMFFTrackInfoParser, MissingMvhdReturnsNothing)):
(TestWebKitAPI::TEST(ISOBMFFTrackInfoParser, 
OversizedEmptyEditDurationIsRejected)):
(TestWebKitAPI::TEST(ISOBMFFTrackInfoParser, TruncatedChildBoxDoesNotCrash)):
(TestWebKitAPI::TEST(ISOBMFFTrackInfoParser, MultipleEmptyEditTracks)):

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



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

Reply via email to