Branch: refs/heads/main
Home: https://github.com/WebKit/WebKit
Commit: 8f635b34ec3090727755ee926b805af8b5b6e4ba
https://github.com/WebKit/WebKit/commit/8f635b34ec3090727755ee926b805af8b5b6e4ba
Author: Jean-Yves Avenard <[email protected]>
Date: 2026-03-16 (Mon, 16 Mar 2026)
Changed paths:
M Source/WebCore/platform/graphics/cocoa/MediaPlayerPrivateWebM.h
M Source/WebCore/platform/graphics/cocoa/MediaPlayerPrivateWebM.mm
M Source/WebCore/platform/graphics/cocoa/SourceBufferParserWebM.cpp
Log Message:
-----------
Can't seek in webm while content is loading
https://bugs.webkit.org/show_bug.cgi?id=309867
rdar://172473039
Reviewed by Youenn Fablet.
We had several issues at play.
1- When the MediaPlayerPrivateWebM runs in the content process, the media parser
would return each individual MediaSample by queueing a task on the main thread
to handle that unique MediaSample. It was pegging the main thread and would
delay
the UI process seeking task sent to the video element.
2- When reading a file, where data is provided through a single chunk through
`dataReceived()`, as the buffered range wasn't updated until all data was
demuxed
and all MediaSamples processed, we wouldn't resolve the
m_waitForTimeBufferedPromise until
a possibly extensive period of time had lapsed.
3- Logging in the WebMParser was extensive, generating thousands line of logs
should Media logging was set to `info`. This also prevented, particularly on
debug build, the HTMLMediaElement::seekTask() to run.
1- We now run all media buffering, playback, seeking and feeding data to the
AudioVideoRenderer
on the same queue used by the SourceBufferParserWebM when the
AudioVideoRendererRemote is in use.
We avoid dispatching one task per sample, and instead immediately append them
to their respective
TrackBuffer.
2- We now check eagerly if the track's buffered range now covers the seek time,
recompute the full intersection and potentially resolve the promise early.
3- We remove most logging from the WebMParser. The WebMParser has been mature
for a long time now and the logging has become unnecessary.
Manually tested, CPU usage in the content process while the media is being
demuxed
has dropped to a couple of % instead of 100+% before. File can be seeked into
almost immediately even in debug builds.
Covered by existing tests.
* Source/WebCore/platform/graphics/cocoa/MediaPlayerPrivateWebM.h:
(WebCore::MediaPlayerPrivateWebM::WTF_GUARDED_BY_CAPABILITY):
(WebCore::MediaPlayerPrivateWebM::runningQueue const):
* Source/WebCore/platform/graphics/cocoa/MediaPlayerPrivateWebM.mm:
(WebCore::MediaPlayerPrivateWebM::MediaPlayerPrivateWebM):
(WebCore::MediaPlayerPrivateWebM::setPreload):
(WebCore::MediaPlayerPrivateWebM::doPreload):
(WebCore::MediaPlayerPrivateWebM::load):
(WebCore::MediaPlayerPrivateWebM::needsResourceClient const):
(WebCore::MediaPlayerPrivateWebM::createResourceClientIfNeeded):
(WebCore::MediaPlayerPrivateWebM::dataLengthReceived):
(WebCore::MediaPlayerPrivateWebM::dataReceived):
(WebCore::MediaPlayerPrivateWebM::loadFinished):
(WebCore::MediaPlayerPrivateWebM::cancelLoad):
(WebCore::MediaPlayerPrivateWebM::prepareToPlay):
(WebCore::MediaPlayerPrivateWebM::play):
(WebCore::MediaPlayerPrivateWebM::pause):
(WebCore::MediaPlayerPrivateWebM::playAtHostTime):
(WebCore::MediaPlayerPrivateWebM::pauseAtHostTime):
(WebCore::MediaPlayerPrivateWebM::playInternal):
(WebCore::MediaPlayerPrivateWebM::performTaskAtTime):
(WebCore::MediaPlayerPrivateWebM::audioOutputDeviceChanged):
(WebCore::MediaPlayerPrivateWebM::setPageIsVisible):
(WebCore::MediaPlayerPrivateWebM::duration const):
(WebCore::MediaPlayerPrivateWebM::durationOnRunningQueue const):
(WebCore::MediaPlayerPrivateWebM::naturalSize const):
(WebCore::MediaPlayerPrivateWebM::rate const):
(WebCore::MediaPlayerPrivateWebM::hasAvailableVideoFrame const):
(WebCore::MediaPlayerPrivateWebM::videoFrameMetadata):
(WebCore::MediaPlayerPrivateWebM::seekToTarget):
(WebCore::MediaPlayerPrivateWebM::seekInternal):
(WebCore::MediaPlayerPrivateWebM::startSeek):
(WebCore::MediaPlayerPrivateWebM::completeSeek):
(WebCore::MediaPlayerPrivateWebM::waitForTimeBuffered):
(WebCore::MediaPlayerPrivateWebM::resolveWaitForTimeBufferedPromiseIfPossible):
(WebCore::MediaPlayerPrivateWebM::seeking const):
(WebCore::MediaPlayerPrivateWebM::setRateDouble):
(WebCore::MediaPlayerPrivateWebM::setVolume):
(WebCore::MediaPlayerPrivateWebM::setMuted):
(WebCore::MediaPlayerPrivateWebM::setBufferedRanges):
(WebCore::MediaPlayerPrivateWebM::updateBufferedFromTrackBuffers):
(WebCore::MediaPlayerPrivateWebM::updateDurationFromTrackBuffers):
(WebCore::MediaPlayerPrivateWebM::didLoadingProgress const):
(WebCore::MediaPlayerPrivateWebM::nativeImageForCurrentTime):
(WebCore::MediaPlayerPrivateWebM::updateLastVideoFrame):
(WebCore::MediaPlayerPrivateWebM::updateLastImage):
(WebCore::MediaPlayerPrivateWebM::paint):
(WebCore::MediaPlayerPrivateWebM::paintCurrentFrameInContext):
(WebCore::MediaPlayerPrivateWebM::videoFrameForCurrentTime):
(WebCore::MediaPlayerPrivateWebM::colorSpace):
(WebCore::MediaPlayerPrivateWebM::bitmapImageForCurrentTime):
(WebCore::MediaPlayerPrivateWebM::setNaturalSize):
(WebCore::MediaPlayerPrivateWebM::effectiveRateChanged):
(WebCore::MediaPlayerPrivateWebM::setHasAudio):
(WebCore::MediaPlayerPrivateWebM::setHasVideo):
(WebCore::MediaPlayerPrivateWebM::setHasAvailableVideoFrame):
(WebCore::MediaPlayerPrivateWebM::setDuration):
(WebCore::MediaPlayerPrivateWebM::setNetworkState):
(WebCore::MediaPlayerPrivateWebM::setReadyState):
(WebCore::MediaPlayerPrivateWebM::characteristicsChanged):
(WebCore::MediaPlayerPrivateWebM::errorOccurred):
(WebCore::MediaPlayerPrivateWebM::setPreservesPitch):
(WebCore::MediaPlayerPrivateWebM::setPresentationSize):
(WebCore::MediaPlayerPrivateWebM::acceleratedRenderingStateChanged):
(WebCore::MediaPlayerPrivateWebM::createVideoFullscreenLayer):
(WebCore::MediaPlayerPrivateWebM::setVideoFullscreenLayer):
(WebCore::MediaPlayerPrivateWebM::setVideoFullscreenFrame):
(WebCore::MediaPlayerPrivateWebM::syncTextTrackBounds):
(WebCore::MediaPlayerPrivateWebM::setTextTrackRepresentation):
(WebCore::MediaPlayerPrivateWebM::setWirelessPlaybackTarget):
(WebCore::MediaPlayerPrivateWebM::setShouldPlayToPlaybackTarget):
(WebCore::MediaPlayerPrivateWebM::isCurrentPlaybackTargetWireless const):
(WebCore::MediaPlayerPrivateWebM::enqueueSample):
(WebCore::MediaPlayerPrivateWebM::reenqueSamples):
(WebCore::MediaPlayerPrivateWebM::reenqueueMediaForTime):
(WebCore::MediaPlayerPrivateWebM::notifyClientWhenReadyForMoreSamples):
(WebCore::MediaPlayerPrivateWebM::isReadyForMoreSamples):
(WebCore::MediaPlayerPrivateWebM::didBecomeReadyForMoreSamples):
(WebCore::MediaPlayerPrivateWebM::appendCompleted):
(WebCore::MediaPlayerPrivateWebM::maybeFinishLoading):
(WebCore::MediaPlayerPrivateWebM::provideMediaData):
(WebCore::MediaPlayerPrivateWebM::trackDidChangeSelected):
(WebCore::MediaPlayerPrivateWebM::trackDidChangeEnabled):
(WebCore::MediaPlayerPrivateWebM::didParseInitializationData):
(WebCore::MediaPlayerPrivateWebM::didProvideMediaDataForTrackId):
(WebCore::MediaPlayerPrivateWebM::flush):
(WebCore::MediaPlayerPrivateWebM::setAllTracksForReenqueuing):
(WebCore::MediaPlayerPrivateWebM::setTrackForReenqueuing):
(WebCore::MediaPlayerPrivateWebM::flushVideoIfNeeded):
(WebCore::MediaPlayerPrivateWebM::addTrackBuffer):
(WebCore::MediaPlayerPrivateWebM::startVideoFrameMetadataGathering):
(WebCore::MediaPlayerPrivateWebM::stopVideoFrameMetadataGathering):
(WebCore::MediaPlayerPrivateWebM::checkNewVideoFrameMetadata):
(WebCore::MediaPlayerPrivateWebM::setResourceOwner):
(WebCore::MediaPlayerPrivateWebM::isEnabledVideoTrackID const):
(WebCore::MediaPlayerPrivateWebM::hasSelectedVideo const):
(WebCore::MediaPlayerPrivateWebM::setShouldDisableHDR):
(WebCore::MediaPlayerPrivateWebM::setPlatformDynamicRangeLimit):
(WebCore::MediaPlayerPrivateWebM::playerContentBoxRectChanged):
(WebCore::MediaPlayerPrivateWebM::setShouldMaintainAspectRatio):
(WebCore::MediaPlayerPrivateWebM::defaultSpatialTrackingLabel const):
(WebCore::MediaPlayerPrivateWebM::setDefaultSpatialTrackingLabel):
(WebCore::MediaPlayerPrivateWebM::spatialTrackingLabel const):
(WebCore::MediaPlayerPrivateWebM::setSpatialTrackingLabel):
(WebCore::MediaPlayerPrivateWebM::updateSpatialTrackingLabel):
(WebCore::MediaPlayerPrivateWebM::setVideoTarget):
(WebCore::MediaPlayerPrivateWebM::sceneIdentifierDidChange):
(WebCore::MediaPlayerPrivateWebM::applicationWillResignActive):
(WebCore::MediaPlayerPrivateWebM::applicationDidBecomeActive):
(WebCore::MediaPlayerPrivateWebM::isInFullscreenOrPictureInPictureChanged):
(WebCore::MediaPlayerPrivateWebM::trackIdentifierFor const):
(WebCore::MediaPlayerPrivateWebM::maybeTrackIdentifierFor const):
(WebCore::MediaPlayerPrivateWebM::setLayerRequiresFlush):
(WebCore::MediaPlayerPrivateWebM::videoPlaybackQualityMetrics):
(WebCore::MediaPlayerPrivateWebM::hostingContext const):
(WebCore::MediaPlayerPrivateWebM::setVideoLayerSizeFenced):
(WebCore::MediaPlayerPrivateWebM::monitorReadyState):
(WebCore::MediaPlayerPrivateWebM::ensureOnRunningQueue):
(WebCore::MediaPlayerPrivateWebM::~MediaPlayerPrivateWebM): Deleted.
(WebCore::MediaPlayerPrivateWebM::cancelPendingSeek): Deleted.
(WebCore::MediaPlayerPrivateWebM::buffered const): Deleted.
(WebCore::MediaPlayerPrivateWebM::clearTracks): Deleted.
* Source/WebCore/platform/graphics/cocoa/SourceBufferParserWebM.cpp:
(WebCore::WebMParser::OnElementBegin):
(WebCore::WebMParser::OnElementEnd):
(WebCore::WebMParser::OnEbml):
(WebCore::WebMParser::OnSegmentBegin):
(WebCore::WebMParser::OnInfo):
(WebCore::WebMParser::OnClusterBegin):
(WebCore::WebMParser::OnBlockBegin):
(WebCore::WebMParser::OnBlockEnd):
(WebCore::WebMParser::OnSimpleBlockBegin):
(WebCore::WebMParser::OnSimpleBlockEnd):
(WebCore::WebMParser::OnBlockGroupBegin):
(WebCore::WebMParser::OnBlockGroupEnd):
Canonical link: https://commits.webkit.org/309373@main
To unsubscribe from these emails, change your notification settings at
https://github.com/WebKit/WebKit/settings/notifications