Skip to content

Commit 2b4f979

Browse files
committed
[GStreamer][MSE] Take playbin's states lock when sending seek event
https://bugs.webkit.org/show_bug.cgi?id=275566 Reviewed by Alicia Boya Garcia. This fixes possible race between application (triggering another seek from 'seeked' event) and 'state chagne' continuation (triggered by playbin). Top level bin element does change the state as result of 'async-done' handling from previous seek request (see gst_bin_continue_func in gstbin.c). Which may race with handling of 'async-start' posted by sinks on flushing seek. And may leave the pipeline in inconsistent state and 'hanging' seek that never finishes. By taking the states lock of top level bin element player will wait for possible state change continuation to complete before sending next seek event. Based on a patch by Eugene Mutavchi <Ievgen_Mutavchi@comcast.com>. * Source/WebCore/platform/graphics/gstreamer/mse/MediaPlayerPrivateGStreamerMSE.cpp: (WebCore::MediaPlayerPrivateGStreamerMSE::doSeek): Canonical link: https://commits.webkit.org/280168@main
1 parent eb6ae0a commit 2b4f979

1 file changed

Lines changed: 13 additions & 2 deletions

File tree

Source/WebCore/platform/graphics/gstreamer/mse/MediaPlayerPrivateGStreamerMSE.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -268,8 +268,19 @@ bool MediaPlayerPrivateGStreamerMSE::doSeek(const MediaTime& position, float rat
268268

269269
// Important: In order to ensure correct propagation whether pre-roll has happened or not, we send the seek directly
270270
// to the source element, rather than letting playbin do the routing.
271-
gst_element_seek(m_source.get(), rate, GST_FORMAT_TIME, seekFlags,
272-
GST_SEEK_TYPE_SET, toGstClockTime(m_seekTime), GST_SEEK_TYPE_NONE, 0);
271+
{
272+
// Take the STATE_LOCK of the __pipeline__.
273+
//
274+
// gst_element_send_event() [which is called by gst_element_seek()] already takes the STATE_LOCK of the element
275+
// in order to delay any state change attempts from other threads while the event is travelling the pipeline.
276+
//
277+
// Normally that would happen to both the pipeline and then recursively to the elements inside as they handle
278+
// the seek event, but since we're sending the event directly to the source element we need to take the
279+
// STATE_LOCK on the pipeline ourselves.
280+
auto locker = GstStateLocker(pipeline());
281+
gst_element_seek(m_source.get(), rate, GST_FORMAT_TIME, seekFlags,
282+
GST_SEEK_TYPE_SET, toGstClockTime(m_seekTime), GST_SEEK_TYPE_NONE, 0);
283+
}
273284
invalidateCachedPosition();
274285

275286
// Notify MediaSource and have new frames enqueued (when they're available).

0 commit comments

Comments
 (0)