Branch: refs/heads/main
Home: https://github.com/WebKit/WebKit
Commit: 49f240763dcf90d9be128418bed0a863343f5f94
https://github.com/WebKit/WebKit/commit/49f240763dcf90d9be128418bed0a863343f5f94
Author: Jean-Yves Avenard <[email protected]>
Date: 2026-05-26 (Tue, 26 May 2026)
Changed paths:
A
LayoutTests/media/media-source/media-source-seek-across-gap-stall-reset-expected.txt
A
LayoutTests/media/media-source/media-source-seek-across-gap-stall-reset.html
M
Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.h
M
Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm
M Source/WebKit/WebProcess/GPU/media/AudioVideoRendererRemote.cpp
M Source/WebKit/WebProcess/GPU/media/AudioVideoRendererRemote.h
Log Message:
-----------
[MSE|Cocoa] currentTime can go beyond duration or gap following a seek.
https://bugs.webkit.org/show_bug.cgi?id=315551
rdar://177926288
Reviewed by Youenn Fablet.
MediaPlayerPrivateMediaSourceAVFObjC programs an AVFoundation boundary-time
observer ("stall cap") on the synchronizer that fires when synchronizer time
crosses the next gap end (or duration). The cap was computed in
bufferedChanged()
from the current buffered ranges and the current playhead.
bufferedChanged() is only invoked by MediaSource::updateBufferedIfNeeded when
the aggregated buffered ranges actually change. A seek does NOT change buffered
ranges, so before the fix the cap remained programmed against the pre-seek
playhead. If that boundary lies behind the post-seek synchronizer time, the
synchronizer plays forward and never crosses it, so the renderer kept
advancing past the next gap.
Should the currentTime changed following a seek, this wasn't reset and the
stall stop would become stale.
A second cache of the stall cap exists in AudioVideoRendererRemote's
TimeProgressEstimator: it mirrors the boundary so currentTime() can clamp to it
locally without waiting for the GPU stall IPC to round-trip. After a forward
seek past the cap, that cached value describes a position behind the playhead
and the estimator would clamp currentTime() backwards to it.
clearStallCapIfBefore() drops the cached cap when prepareToSeek moves the
playhead past it; the player then computes a fresh cap via resetStallForTime on
the post-seek time, which reprograms both the GPU-side boundary observer and
the WebContent-side cache.
Test added.
*
LayoutTests/media/media-source/media-source-seek-across-gap-stall-reset-expected.txt:
Added.
* LayoutTests/media/media-source/media-source-seek-across-gap-stall-reset.html:
Added.
*
Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.h:
*
Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm:
(WebCore::MediaPlayerPrivateMediaSourceAVFObjC::reenqueueMediaForTimeAndFinishSeek):
(WebCore::MediaPlayerPrivateMediaSourceAVFObjC::bufferedChanged):
(WebCore::MediaPlayerPrivateMediaSourceAVFObjC::resetStallForTime):
(WebCore::MediaPlayerPrivateMediaSourceAVFObjC::durationChanged):
(WebCore::MediaPlayerPrivateMediaSourceAVFObjC::notifyEndOfMediaIfNeeded):
* Source/WebKit/WebProcess/GPU/media/AudioVideoRendererRemote.cpp:
(WebKit::AudioVideoRendererRemote::TimeProgressEstimator::clearStallCapIfBefore):
(WebKit::AudioVideoRendererRemote::prepareToSeek):
* Source/WebKit/WebProcess/GPU/media/AudioVideoRendererRemote.h:
Canonical link: https://commits.webkit.org/313936@main
To unsubscribe from these emails, change your notification settings at
https://github.com/WebKit/WebKit/settings/notifications