Branch: refs/heads/main
  Home:   https://github.com/WebKit/WebKit
  Commit: 6e7720ec70a93041e32a13f0b3f53fc57efe432f
      
https://github.com/WebKit/WebKit/commit/6e7720ec70a93041e32a13f0b3f53fc57efe432f
  Author: Jean-Yves Avenard <[email protected]>
  Date:   2026-06-04 (Thu, 04 Jun 2026)

  Changed paths:
    M LayoutTests/media/media-source/media-mp4-xhe-aac.html
    M LayoutTests/media/media-source/media-source-small-gap.html
    M Source/WebCore/Modules/mediasource/MediaSourceInterfaceMainThread.cpp
    M Source/WebCore/Modules/mediasource/MediaSourceInterfaceMainThread.h
    M Source/WebCore/Modules/mediasource/MediaSourceInterfaceProxy.h
    M Source/WebCore/Modules/mediasource/MediaSourceInterfaceWorker.cpp
    M Source/WebCore/Modules/mediasource/MediaSourceInterfaceWorker.h
    M Source/WebCore/html/HTMLMediaElement.cpp
    M Source/WebCore/platform/graphics/avfoundation/AudioVideoRendererAVFObjC.mm
    M 
Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm
    M Source/WebKit/WebProcess/GPU/media/AudioVideoRendererRemote.cpp

  Log Message:
  -----------
  [MSE] notifyTimeReachedAndStall must not arm a stall behind currentTime
https://bugs.webkit.org/show_bug.cgi?id=316082
rdar://problem/178513965

Reviewed by Eric Carlson.

When a SourceBuffer's duration is truncated to (or below) currentTime while
playback is parked at the end of the buffered data, two things went wrong.

1) resetStallForTime() could ask the renderer to stall at a boundary that
was already behind the playhead. Such a boundary's observer never fires
naturally, and the rate=0 failsafe in handleEffectiveRateChanged then re-pins
the synchronizer onto that stale boundary, dragging the published time
backwards. A stall boundary must never sit behind currentTime.

2) more fundamentally, end-of-media was decided in the wrong place.
HTMLMediaElement::mediaPlayerTimeChanged() scheduled the 'ended' event
whenever the playback position had reached duration with a positive rate,
without regard for whether the media data was actually complete. For Media
Source that is incorrect: reaching the end of the currently buffered data
while the MediaSource is still 'open' is a stall ('waiting'), not
end-of-media -- 'ended' must not fire until the MediaSource transitions to
'ended' via endOfStream(). The consequence is that the 'ended' event could be
fired incorrectly any time MediaPlayer::timeChanged() happened to be called at
or past duration even though the MediaSource had not ended, which is precisely
what the stall-boundary callback does when parked at the truncated duration.

Gate the forward end-of-media transition in mediaPlayerTimeChanged() on the
media data being complete: always true for a finite resource, and for Media
Source only once the MediaSource has ended. End-of-media is then driven solely
off the MediaSource 'ended' transition (notifyEndOfMediaIfNeeded()), leaving
the renderer free to stall and report its stall time without that being
mistaken for end-of-media.

* LayoutTests/media/media-source/media-mp4-xhe-aac.html: Test incorrectly 
assumed that the ended event would fire when the MediaSource wasn't ended. 
Revealed by fixing 2) above
* LayoutTests/media/media-source/media-source-small-gap.html: Same as above.
* Source/WebCore/Modules/mediasource/MediaSourceInterfaceMainThread.cpp:
(WebCore::MediaSourceInterfaceMainThread::isEnded const):
* Source/WebCore/Modules/mediasource/MediaSourceInterfaceMainThread.h:
* Source/WebCore/Modules/mediasource/MediaSourceInterfaceProxy.h:
* Source/WebCore/Modules/mediasource/MediaSourceInterfaceWorker.cpp:
(WebCore::MediaSourceInterfaceWorker::isEnded const):
* Source/WebCore/Modules/mediasource/MediaSourceInterfaceWorker.h:
* Source/WebCore/html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::mediaPlayerTimeChanged): Only treat reaching
duration as end-of-media once the media data is complete.
* Source/WebCore/platform/graphics/avfoundation/AudioVideoRendererAVFObjC.mm:
(WebCore::AudioVideoRendererAVFObjC::notifyTimeReachedAndStall):
* 
Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm:
(WebCore::MediaPlayerPrivateMediaSourceAVFObjC::resetStallForTime):
* Source/WebKit/WebProcess/GPU/media/AudioVideoRendererRemote.cpp:
(WebKit::AudioVideoRendererRemote::notifyTimeReachedAndStall):

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Canonical link: https://commits.webkit.org/314610@main



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

Reply via email to