Skip to content

Commit 00248c7

Browse files
eocanhaVolodymyr Ogorodnik
authored andcommitted
[GStreamer] Sometimes progressive playback is not resumed after seek
https://bugs.webkit.org/show_bug.cgi?id=300041 Reviewed by Philippe Normand. Sometimes, in a downstream multimedia player, regular video playback remains paused after seek instead of resuming automatically. It will play normally when play() or another seek operation are manually triggered. Log analys shows that in the failing case the browser missed the state transition to 'HaveCurrentData', and application can't resume playback after seek. It was missed because it happened the gstreamer pipeline remains in state transition for too long and can't process buffering events. Normally it goes: seek -> Paused pipeline -> buffering (HaveCurrentData) -> finish_buffering(HaveEnoughData) -> start_playback. However, in the failing case, seek takes too long (~2sec) to set the PAUSED state on the pipeline and we are missing the buffering(HaveCurrentData) stage. See: WebPlatformForEmbedded#1561 This patch returns the player readyState to HaveCurrentData and the networkState to Loading when a seek is being processed. The states will reach their final values as soon as the async state transition caused by the seek finishes. Original author: Volodymyr Ogorodnik (https://github.com/volodymyr-ogorodnik-red) * Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp: (WebCore::MediaPlayerPrivateGStreamer::updateStates): Reset readyState and networkState to HaveCurrentData and Loading while the player is in an async state transition (in a seek) and buffering. Canonical link: https://commits.webkit.org/300933@main
1 parent 5e3487e commit 00248c7

File tree

1 file changed

+7
-0
lines changed

1 file changed

+7
-0
lines changed

Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2743,6 +2743,13 @@ void MediaPlayerPrivateGStreamer::updateStates()
27432743
GST_DEBUG_OBJECT(pipeline(), "Async: State: %s, pending: %s", gst_element_state_get_name(m_currentState), gst_element_state_get_name(pending));
27442744
// Change in progress.
27452745

2746+
if (m_currentState == GST_STATE_PAUSED && m_isBuffering) {
2747+
// If we are buffering, we could miss HaveCurrentData state if buffering finished before the transition completes.
2748+
GST_DEBUG_OBJECT(pipeline(), "Async: [Buffering] still buffering, so force HaveCurrentData.");
2749+
m_readyState = MediaPlayer::ReadyState::HaveCurrentData;
2750+
m_networkState = MediaPlayer::NetworkState::Loading;
2751+
}
2752+
27462753
// Delay the m_isBuffering change by returning it to its previous value. Without this, the false --> true change
27472754
// would go unnoticed by the code that should trigger a pause.
27482755
if (m_wasBuffering != m_isBuffering && !m_isPaused && m_playbackRate) {

0 commit comments

Comments
 (0)