Introduce SharedTimebase and stop sending time updates every 100ms
WebKit's multi-process model puts media decoding in the GPU process and JS in the WebContent process; every video.currentTime query must answer synchronously without an IPC round-trip. Previously the GPU sent MediaTimeUpdateData anchors ~4×/sec; TimeProgressEstimator cached and extrapolated. The new SharedTimebase maps a small SharedMemory region into both processes — GPU holds the writer, WebContent holds the SharedTimebaseReader, and reads are lock-free via SequenceLocked<T> (a seqlock).
Source/WebCore/platform/SharedTimebase.h (new)
Source/WebKit/WebProcess/GPU/media/AudioVideoRendererRemote.cpp
In the same commit: AVFoundation's 0→nonzero rate-lie is masked at source with a fine-grained time observer, and the stall cap moves from the deleted TimeProgressEstimator inner class onto AudioVideoRendererRemote itself under m_lock.
Significance
Eliminates steady-state IPC noise for every active media element and introduces a new cross-process shared-memory surface that the WebContent process reads without IPC message validation — a meaningful trust-boundary shift on top of the performance win.
Audit directions
Cross-process shared-memory trust boundary: GPU process writes Snapshot values that WebContent consumes with no IPC validation. JS-observable behaviors gated on video.currentTime — MSE monitorSourceBuffers, EME timing, requestVideoFrameCallback, stall detection — all flow through this reader. A compromised GPU process can write adversarial anchors directly into WebContent's time perception. SequenceLocked<T> correctness across process boundaries requires release barriers on every store and acquire barriers on every load plus a retry loop on sequence-count mismatch; missing or misplaced barriers (especially after compiler optimizations on Arm) can produce torn reads where currentTime from write N pairs with hostTime from write N+1. m_stallCap is set in notifyTimeReachedAndStall, cleared unconditionally in cancelTimeReachedAction, and conditionally cleared in cancelPendingSeek based on seek direction — verify that direction-conditional handles reverse seeks, rate=0 seeks, and seeks arriving after a stall has fired. SharedTimebase::create() returns nullptr on SharedMemory::allocate failure; race between Create reply and async error dispatch leaves m_sharedTimebaseReader null, and any currentTime()/effectiveRate() call dereferencing it crashes. Finally, the maxExtrapolation silent clamp: applications polling video.currentTime to detect hangs would be fooled if the GPU process stalls longer than the cap.