AudioVideoRenderer TimeProgressEstimator incorrectly set m_effectiveRate#64909
Merged
Conversation
Collaborator
|
EWS run on previous version of this PR (hash 73514ac) Details
|
73514ac to
f9ad1aa
Compare
Collaborator
|
EWS run on current version of this PR (hash f9ad1aa) Details
|
eric-carlson
approved these changes
May 14, 2026
jernoble
approved these changes
May 14, 2026
https://bugs.webkit.org/show_bug.cgi?id=314795 rdar://177046564 Reviewed by Jer Noble and Eric Carlson. 311867@main ("Use a TimeProgressEstimator to interpolate AudioVideoRendererRemote::currentTime() between GPU updates") introduced two issues. 1. Every Play / Pause / SetRate IPC from WebContent caused the GPU-side RemoteAudioVideoRendererProxyManager handler to synchronously build a RemoteAudioVideoRendererState via stateFor() and push a StateUpdate IPC back to the WebContent. stateFor() reads videoPlaybackQualityMetrics, which on the protected-content AVSampleBufferDisplayLayer path (for example Netflix) fans into four separate [renderer videoPerformanceMetrics] synchronous XPCs into mediaserverd. The only consumer of that reply in the WebContent is the client-side TimeProgressEstimator, which only needs the MediaTimeUpdateData fields (currentTime, effectiveRate, wallTime) to unfreeze and re-anchor after the local setRate / pause already froze it. The full state payload and its metrics fetch were wasted work on every transition. 2. AudioVideoRendererRemote::TimeProgressEstimator::setRate() gated the assignment m_effectiveRate = rate on the same "if (currentRate)" guard that controls the rebase of m_cachedTime. The guard is only meaningful for the rebase (nothing to fold in when the old rate was already zero); the new-rate assignment shouldn't ride on it. As a result, when setRate() was called on an estimator whose current rate was 0 (for example immediately after a stall()), m_effectiveRate stayed at 0 locally until the next setTime() arrived. timeIsProgressing() and effectiveRate() would keep reporting 0 in that round-trip window. Fix 1: change Play / Pause / SetRate to asynchronous replies carrying only WebCore::MediaTimeUpdateData. The GPU handlers now call renderer->play / pause / setRate and invoke the completion with a fresh MediaTimeUpdateData built by a new static helper timeUpdateDataFor(renderer). stateFor() is refactored to reuse the same helper for the fields it shares. The new payload contains no videoPlaybackQualityMetrics, so these transitions no longer touch mediaserverd. The WebContent callers use sendWithAsyncReplyOnDispatcher on queueSingleton(); the reply handler applies m_timeEstimator.setTime(timeUpdateData) which is exactly the unfreeze that the old StateUpdate reply performed via updateCacheState. Fix 2: hoist m_effectiveRate = rate out of the rebase guard in TimeProgressEstimator::setRate, and drop the now-redundant m_effectiveRate = 0 inside the if (!rate) branch. All four (currentRate, rate) cases now leave m_effectiveRate == rate on exit. In a follow-up change we will extract the AudioVideoRendererRemote's TimeProgressEstimator to its own class and combine with the one used in MediaPlayerPrivateRemote this will allow for API tests and simplify the change. It will also allows for using a SharedMemory timeBase removing the need for sending IPC messages. * Source/WebKit/GPUProcess/media/RemoteAudioVideoRendererProxyManager.messages.in: Declare MediaTimeUpdateData async replies on Play, Pause, SetRate. * Source/WebKit/GPUProcess/media/RemoteAudioVideoRendererProxyManager.h: (WebKit::RemoteAudioVideoRendererProxyManager::play): (WebKit::RemoteAudioVideoRendererProxyManager::pause): (WebKit::RemoteAudioVideoRendererProxyManager::setRate): Take a CompletionHandler<void(WebCore::MediaTimeUpdateData&&)>&&. * Source/WebKit/GPUProcess/media/RemoteAudioVideoRendererProxyManager.cpp: (WebKit::timeUpdateDataFor): New file-local helper that returns a MediaTimeUpdateData without fetching videoPlaybackQualityMetrics. Stamps effectiveRate = timeIsProgressing() ? effectiveRate() : 0 and wallTime = MonotonicTime::now(), matching what stateFor() used to do inline. (WebKit::RemoteAudioVideoRendererProxyManager::play): (WebKit::RemoteAudioVideoRendererProxyManager::pause): (WebKit::RemoteAudioVideoRendererProxyManager::setRate): Invoke the completion with timeUpdateDataFor(*renderer) instead of sending a StateUpdate(stateFor(...)). Null-renderer path still invokes the completion with a default MediaTimeUpdateData so the IPC reply never hangs. (WebKit::RemoteAudioVideoRendererProxyManager::stateFor): Reuse timeUpdateDataFor for the timeUpdateData sub-struct. * Source/WebKit/WebProcess/GPU/media/AudioVideoRendererRemote.cpp: (WebKit::AudioVideoRendererRemote::TimeProgressEstimator::setRate): Always apply m_effectiveRate = rate; only the m_cachedTime / m_wallTime rebase remains conditional on the prior rate being non-zero. Drop the redundant m_effectiveRate = 0 inside the if (!rate) branch. (WebKit::AudioVideoRendererRemote::play): (WebKit::AudioVideoRendererRemote::pause): (WebKit::AudioVideoRendererRemote::setRate): Use sendWithAsyncReplyOnDispatcher on queueSingleton(); the reply handler calls m_timeEstimator.setTime(timeUpdateData) so the estimator still gets the same anchor it used to receive from the full StateUpdate reply. Canonical link: https://commits.webkit.org/313249@main
f9ad1aa to
5a1e303
Compare
Collaborator
|
Committed 313249@main (5a1e303): https://commits.webkit.org/313249@main Reviewed commits have been landed. Closing PR #64909 and removing active labels. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
5a1e303
f9ad1aa
🛠 win🧪 win-tests🧪 api-mac-debug