Skip to content
Permalink
Browse files
REGRESSION(r290375) [GStreamer] Deadlock in WebProcess termination if…
… AppendPipeline is started

https://bugs.webkit.org/show_bug.cgi?id=240716

Patch by Olivier Blin <olivier.blin@softathome.com> on 2022-05-23
Reviewed by Alicia Boya Garcia.

Since r290375, GStreamer ports are calling gst_deinit() at WebProcess
termination.

This is causing a deadlock if a MSE SourceBuffer has been instantiated.
That is because the GstTask from the appsrc element in the
AppendPipeline is still running.

To avoid the deadlock, stop the appsrc element in the AppendPipeline
when the SourceBuffer is removed from the MediaSource, since it will
not be useful anymore after being removed from its associated MediaSource.

The W3C spec of MediaSource.removeSourceBuffer mentions as a last step
that it should destroy all resources for sourceBuffer.

The MediaSource will be stopped at WebProcess termination, since
active DOM objects are stopped when detaching the frame.
This ensures that MediaSource is detached from its media element, and
that it removes its source buffers.

Drive-by fix: remove resetPipeline declaration, deleted in r238892

* Source/WebCore/platform/graphics/gstreamer/mse/AppendPipeline.cpp:
(WebCore::AppendPipeline::stopParser):
* Source/WebCore/platform/graphics/gstreamer/mse/AppendPipeline.h:
* Source/WebCore/platform/graphics/gstreamer/mse/SourceBufferPrivateGStreamer.cpp:
(WebCore::SourceBufferPrivateGStreamer::removedFromMediaSource):

Canonical link: https://commits.webkit.org/250860@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@294634 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
blino authored and webkit-commit-queue committed May 23, 2022
1 parent 848c6dd commit aa4848abf7f8468e632a47c7bbe9fd7506cfbddc
Showing 3 changed files with 17 additions and 2 deletions.
@@ -569,6 +569,20 @@ void AppendPipeline::resetParserState()
#endif
}

void AppendPipeline::stopParser()
{
ASSERT(isMainThread());
GST_DEBUG_OBJECT(m_pipeline.get(), "Stopping parser");

// Forget all pending tasks and unblock the streaming thread if it was blocked.
m_taskQueue.startAborting();

// Reset the state of all elements in the pipeline.
assertedElementSetState(m_pipeline.get(), GST_STATE_READY);

m_taskQueue.finishAborting();
}

void AppendPipeline::pushNewBuffer(GRefPtr<GstBuffer>&& buffer)
{
GST_TRACE_OBJECT(m_pipeline.get(), "pushing data buffer %" GST_PTR_FORMAT, buffer.get());
@@ -51,6 +51,7 @@ class AppendPipeline {

void pushNewBuffer(GRefPtr<GstBuffer>&&);
void resetParserState();
void stopParser();
SourceBufferPrivateGStreamer& sourceBufferPrivate() { return m_sourceBufferPrivate; }
MediaPlayerPrivateGStreamerMSE* playerPrivate() { return m_playerPrivate; }

@@ -126,8 +127,6 @@ class AppendPipeline {
AppendPipeline::Track* tryMatchPadToExistingTrack(GstPad* demuxerSrcPad);
void linkPadWithTrack(GstPad* demuxerSrcPad, Track&);

void resetPipeline();

void consumeAppsinksAvailableSamples();

GstPadProbeReturn appsrcEndOfAppendCheckerProbe(GstPadProbeInfo*);
@@ -120,6 +120,8 @@ void SourceBufferPrivateGStreamer::removedFromMediaSource()
for (auto& track : m_tracks.values())
track->remove();
m_hasBeenRemovedFromMediaSource = true;

m_appendPipeline->stopParser();
}

MediaPlayer::ReadyState SourceBufferPrivateGStreamer::readyState() const

0 comments on commit aa4848a

Please sign in to comment.