← All issues

AudioVideoRenderer SharedTimebase ownership and drift reduction

d2af128

WebKit splits media playback across processes: the GPU process hosts the AVSampleBufferRenderSynchronizer whose CMTimebase is the authoritative clock, while WebContent reads currentTime during script and requestAnimationFrame. SharedTimebase bridges them via a lock-free SequenceLocked shared-memory region — the GPU process writes snapshots (currentTime + hostTime + rate) and the reader extrapolates forward.

Source/WebCore/platform/SharedTimebase.cpp

- auto elapsed = std::min(m_clock() - snapshot.hostTime, m_maxExtrapolation);
- calculated = snapshot.currentTime + MediaTime::createWithDouble(rate * elapsed.seconds());
+ auto elapsed = m_clock() - snapshot.hostTime;
+ calculated = (snapshot.currentTime + MediaTime::createWithDouble(rate * elapsed.seconds())).toTimeScale(snapshot.currentTime.timeScale());

This commit moves SharedTimebase ownership from RemoteAudioVideoRendererProxyManager into AudioVideoRendererAVFObjC itself and adds three publishing paths — main-thread state changes, a 100ms periodic dispatch timer on a dedicated serial queue, and a synchronous AVF-thread rate→0 callback — all funneled through a publishSnapshot() helper that applies a high-water-mark floor clamp before writing to shared memory. The maxExtrapolation cap is removed; m_publishedTimeFloor (writer-side, reset only on seek) and m_lastReturnedTime (reader-side forward-monotonicity guard) replace it.

This directly changes how media currentTime is computed and shared across the GPU/WebContent process boundary, touching cross-process shared-memory semantics, lock discipline, and forward-monotonicity invariants that are security-relevant for timing-based APIs.

🔒

The instrumentation's custom memory lifecycle and protection-state management introduce several audit-worthy edge cases in the guarded path.

Subscribe to read more