Diff
Modified: releases/WebKitGTK/webkit-2.32/LayoutTests/ChangeLog (275026 => 275027)
--- releases/WebKitGTK/webkit-2.32/LayoutTests/ChangeLog 2021-03-25 14:07:06 UTC (rev 275026)
+++ releases/WebKitGTK/webkit-2.32/LayoutTests/ChangeLog 2021-03-25 14:07:14 UTC (rev 275027)
@@ -1,3 +1,12 @@
+2021-03-23 Philippe Normand <[email protected]>
+
+ [MSE][GStreamer] SIGSEV in webKitMediaSrcFreeStream
+ https://bugs.webkit.org/show_bug.cgi?id=220091
+
+ Reviewed by Xabier Rodriguez-Calvar.
+
+ * platform/gtk/TestExpectations: Unflag now-passing tests.
+
2021-03-04 Youenn Fablet <[email protected]>
In case of POST navigation redirected by a 302, the 'Origin' header is kept in the redirected request
Modified: releases/WebKitGTK/webkit-2.32/LayoutTests/platform/gtk/TestExpectations (275026 => 275027)
--- releases/WebKitGTK/webkit-2.32/LayoutTests/platform/gtk/TestExpectations 2021-03-25 14:07:06 UTC (rev 275026)
+++ releases/WebKitGTK/webkit-2.32/LayoutTests/platform/gtk/TestExpectations 2021-03-25 14:07:14 UTC (rev 275027)
@@ -411,15 +411,11 @@
webkit.org/b/167108 imported/w3c/web-platform-tests/media-source/mediasource-errors.html [ Failure ]
webkit.org/b/210486 imported/w3c/web-platform-tests/media-source/mediasource-correct-frames-after-reappend.html [ Failure Crash Pass ]
-# Known issues that were fixed by the WebKitMediaSrc rework that is now reverted.
-webkit.org/b/203078 imported/w3c/web-platform-tests/media-source/mediasource-replay.html [ Failure Crash ]
-
webkit.org/b/176020 imported/w3c/web-platform-tests/media-source/mediasource-removesourcebuffer.html [ Crash Pass ]
webkit.org/b/180803 imported/w3c/web-platform-tests/media-source/mediasource-duration-boundaryconditions.html [ Failure ]
webkit.org/b/197711 imported/w3c/web-platform-tests/media-source/mediasource-correct-frames.html [ Pass Failure ]
webkit.org/b/205110 imported/w3c/web-platform-tests/media-source/mediasource-changetype-play.html [ Failure Crash Pass ]
-webkit.org/b/167108 imported/w3c/web-platform-tests/media-source/mediasource-preload.html [ Failure ]
webkit.org/b/167108 imported/w3c/web-platform-tests/media-source/mediasource-trackdefaultlist.html [ Failure ]
webkit.org/b/210341 imported/w3c/web-platform-tests/media-source/mediasource-sourcebuffer-mode-timestamps.html [ Failure ]
webkit.org/b/210342 imported/w3c/web-platform-tests/media-source/mediasource-sourcebuffer-trackdefaults.html [ Failure ]
Modified: releases/WebKitGTK/webkit-2.32/Source/WebCore/ChangeLog (275026 => 275027)
--- releases/WebKitGTK/webkit-2.32/Source/WebCore/ChangeLog 2021-03-25 14:07:06 UTC (rev 275026)
+++ releases/WebKitGTK/webkit-2.32/Source/WebCore/ChangeLog 2021-03-25 14:07:14 UTC (rev 275027)
@@ -1,5 +1,43 @@
2021-03-23 Philippe Normand <[email protected]>
+ [MSE][GStreamer] SIGSEV in webKitMediaSrcFreeStream
+ https://bugs.webkit.org/show_bug.cgi?id=220091
+
+ Reviewed by Xabier Rodriguez-Calvar.
+
+ The pipeline used by the MSE player is now able reload the MediaSource from the beginning if
+ a seek to 0 was requested. The problem was that uridecodebin was creating a new source
+ element and notifying the player which was then trying to dispose underlying platform track
+ informations, and also related appsrc elements. The latter was specially problematic because
+ the appsrc elements ownership was badly handled (elements added to a bin should not be
+ reused, unless an extra ref is added), leading to racy crashes.
+
+ So now when uridecodebin creates a new source element, the player detects this is a new
+ source and transfers track-related informations to the new element. Additionally, new appsrc
+ elements are created for the new element and track signals emitted so that the player is
+ still fully aware of the MSE tracks topology.
+
+ No new tests but two existing tests are now passing.
+
+ * platform/graphics/gstreamer/mse/MediaPlayerPrivateGStreamerMSE.cpp:
+ (WebCore::MediaPlayerPrivateGStreamerMSE::load):
+ (WebCore::MediaPlayerPrivateGStreamerMSE::sourceSetup):
+ * platform/graphics/gstreamer/mse/MediaPlayerPrivateGStreamerMSE.h:
+ * platform/graphics/gstreamer/mse/MediaSourcePrivateGStreamer.cpp:
+ (WebCore::MediaSourcePrivateGStreamer::open):
+ * platform/graphics/gstreamer/mse/MediaSourcePrivateGStreamer.h:
+ * platform/graphics/gstreamer/mse/PlaybackPipeline.cpp:
+ (WebCore::PlaybackPipeline::addSourceBuffer):
+ * platform/graphics/gstreamer/mse/WebKitMediaSourceGStreamer.cpp:
+ (webKitMediaSrcFinalize):
+ (webKitMediaSrcChangeState):
+ (webKitMediaSrcFreeStream):
+ (webKitMediaSrcRestoreTracks):
+ (webKitMediaSrcSignalTracks):
+ * platform/graphics/gstreamer/mse/WebKitMediaSourceGStreamer.h:
+
+2021-03-23 Philippe Normand <[email protected]>
+
[GTK] X11 build fixes
https://bugs.webkit.org/show_bug.cgi?id=223577
Modified: releases/WebKitGTK/webkit-2.32/Source/WebCore/platform/graphics/gstreamer/mse/MediaPlayerPrivateGStreamerMSE.cpp (275026 => 275027)
--- releases/WebKitGTK/webkit-2.32/Source/WebCore/platform/graphics/gstreamer/mse/MediaPlayerPrivateGStreamerMSE.cpp 2021-03-25 14:07:06 UTC (rev 275026)
+++ releases/WebKitGTK/webkit-2.32/Source/WebCore/platform/graphics/gstreamer/mse/MediaPlayerPrivateGStreamerMSE.cpp 2021-03-25 14:07:14 UTC (rev 275027)
@@ -121,25 +121,24 @@
m_playbackPipeline->setWebKitMediaSrc(nullptr);
}
-void MediaPlayerPrivateGStreamerMSE::load(const String& urlString)
+void MediaPlayerPrivateGStreamerMSE::load(const String&)
{
- if (!urlString.startsWith("mediasource")) {
- // Properly fail so the global MediaPlayer tries to fallback to the next MediaPlayerPrivate.
- m_networkState = MediaPlayer::NetworkState::FormatError;
- m_player->networkStateChanged();
- return;
- }
+ // This media engine only supports MediaSource URLs.
+ m_networkState = MediaPlayer::NetworkState::FormatError;
+ m_player->networkStateChanged();
+}
+void MediaPlayerPrivateGStreamerMSE::load(const URL& url, const ContentType&, MediaSourcePrivateClient* mediaSource)
+{
+ GST_DEBUG("Loading %s", url.string().ascii().data());
+ m_mediaSource = mediaSource;
+
if (!m_playbackPipeline)
m_playbackPipeline = PlaybackPipeline::create();
- MediaPlayerPrivateGStreamer::load(urlString);
-}
+ m_mediaSourcePrivate = MediaSourcePrivateGStreamer::open(*m_mediaSource.get(), *this);
-void MediaPlayerPrivateGStreamerMSE::load(const URL& url, const ContentType&, MediaSourcePrivateClient* mediaSource)
-{
- m_mediaSource = mediaSource;
- load(makeString("mediasource", url.string()));
+ MediaPlayerPrivateGStreamer::load(makeString("mediasource", url.string()));
}
void MediaPlayerPrivateGStreamerMSE::pause()
@@ -475,17 +474,33 @@
void MediaPlayerPrivateGStreamerMSE::sourceSetup(GstElement* sourceElement)
{
+ ASSERT(WEBKIT_IS_MEDIA_SRC(sourceElement));
+ GST_DEBUG_OBJECT(pipeline(), "Source %p setup (old was: %p)", sourceElement, m_source.get());
+
+ bool shouldRestoreTracks = m_source;
+ if (shouldRestoreTracks)
+ webKitMediaSrcRestoreTracks(WEBKIT_MEDIA_SRC(m_source.get()), WEBKIT_MEDIA_SRC(sourceElement));
m_source = sourceElement;
+ m_eosMarked = false;
- ASSERT(WEBKIT_IS_MEDIA_SRC(m_source.get()));
-
m_playbackPipeline->setWebKitMediaSrc(WEBKIT_MEDIA_SRC(m_source.get()));
-
- MediaSourcePrivateGStreamer::open(*m_mediaSource.get(), *this);
g_signal_connect_swapped(m_source.get(), "video-changed", G_CALLBACK(videoChangedCallback), this);
g_signal_connect_swapped(m_source.get(), "audio-changed", G_CALLBACK(audioChangedCallback), this);
g_signal_connect_swapped(m_source.get(), "text-changed", G_CALLBACK(textChangedCallback), this);
webKitMediaSrcSetMediaPlayerPrivate(WEBKIT_MEDIA_SRC(m_source.get()), this);
+
+ if (shouldRestoreTracks) {
+ callOnMainThread([player = makeWeakPtr(*this)] {
+ if (!player)
+ return;
+ webKitMediaSrcSignalTracks(WEBKIT_MEDIA_SRC(player->m_source.get()));
+ player->m_mediaSource->monitorSourceBuffers();
+
+ auto seekTime = MediaTime::zeroTime();
+ webKitMediaSrcPrepareInitialSeek(WEBKIT_MEDIA_SRC(player->m_source.get()), player->m_playbackRate, seekTime, MediaTime::invalidTime());
+ player->notifySeekNeedsDataForTime(seekTime);
+ });
+ }
}
void MediaPlayerPrivateGStreamerMSE::updateStates()
Modified: releases/WebKitGTK/webkit-2.32/Source/WebCore/platform/graphics/gstreamer/mse/MediaPlayerPrivateGStreamerMSE.h (275026 => 275027)
--- releases/WebKitGTK/webkit-2.32/Source/WebCore/platform/graphics/gstreamer/mse/MediaPlayerPrivateGStreamerMSE.h 2021-03-25 14:07:06 UTC (rev 275026)
+++ releases/WebKitGTK/webkit-2.32/Source/WebCore/platform/graphics/gstreamer/mse/MediaPlayerPrivateGStreamerMSE.h 2021-03-25 14:07:14 UTC (rev 275027)
@@ -108,6 +108,7 @@
mutable bool m_eosPending = false;
bool m_gstSeekCompleted = true;
RefPtr<MediaSourcePrivateClient> m_mediaSource;
+ RefPtr<MediaSourcePrivateGStreamer> m_mediaSourcePrivate;
MediaTime m_mediaTimeDuration;
bool m_mseSeekCompleted = true;
bool m_areDurationChangesBlocked = false;
Modified: releases/WebKitGTK/webkit-2.32/Source/WebCore/platform/graphics/gstreamer/mse/MediaSourcePrivateGStreamer.cpp (275026 => 275027)
--- releases/WebKitGTK/webkit-2.32/Source/WebCore/platform/graphics/gstreamer/mse/MediaSourcePrivateGStreamer.cpp 2021-03-25 14:07:06 UTC (rev 275026)
+++ releases/WebKitGTK/webkit-2.32/Source/WebCore/platform/graphics/gstreamer/mse/MediaSourcePrivateGStreamer.cpp 2021-03-25 14:07:14 UTC (rev 275027)
@@ -51,9 +51,11 @@
namespace WebCore {
-void MediaSourcePrivateGStreamer::open(MediaSourcePrivateClient& mediaSource, MediaPlayerPrivateGStreamerMSE& playerPrivate)
+Ref<MediaSourcePrivateGStreamer> MediaSourcePrivateGStreamer::open(MediaSourcePrivateClient& mediaSource, MediaPlayerPrivateGStreamerMSE& playerPrivate)
{
- mediaSource.setPrivateAndOpen(adoptRef(*new MediaSourcePrivateGStreamer(mediaSource, playerPrivate)));
+ auto mediaSourcePrivate = adoptRef(*new MediaSourcePrivateGStreamer(mediaSource, playerPrivate));
+ mediaSource.setPrivateAndOpen(mediaSourcePrivate.copyRef());
+ return mediaSourcePrivate;
}
MediaSourcePrivateGStreamer::MediaSourcePrivateGStreamer(MediaSourcePrivateClient& mediaSource, MediaPlayerPrivateGStreamerMSE& playerPrivate)
Modified: releases/WebKitGTK/webkit-2.32/Source/WebCore/platform/graphics/gstreamer/mse/MediaSourcePrivateGStreamer.h (275026 => 275027)
--- releases/WebKitGTK/webkit-2.32/Source/WebCore/platform/graphics/gstreamer/mse/MediaSourcePrivateGStreamer.h 2021-03-25 14:07:06 UTC (rev 275026)
+++ releases/WebKitGTK/webkit-2.32/Source/WebCore/platform/graphics/gstreamer/mse/MediaSourcePrivateGStreamer.h 2021-03-25 14:07:14 UTC (rev 275027)
@@ -55,7 +55,7 @@
#endif
{
public:
- static void open(MediaSourcePrivateClient&, MediaPlayerPrivateGStreamerMSE&);
+ static Ref<MediaSourcePrivateGStreamer> open(MediaSourcePrivateClient&, MediaPlayerPrivateGStreamerMSE&);
virtual ~MediaSourcePrivateGStreamer();
AddStatus addSourceBuffer(const ContentType&, bool, RefPtr<SourceBufferPrivate>&) override;
Modified: releases/WebKitGTK/webkit-2.32/Source/WebCore/platform/graphics/gstreamer/mse/PlaybackPipeline.cpp (275026 => 275027)
--- releases/WebKitGTK/webkit-2.32/Source/WebCore/platform/graphics/gstreamer/mse/PlaybackPipeline.cpp 2021-03-25 14:07:06 UTC (rev 275026)
+++ releases/WebKitGTK/webkit-2.32/Source/WebCore/platform/graphics/gstreamer/mse/PlaybackPipeline.cpp 2021-03-25 14:07:14 UTC (rev 275027)
@@ -114,7 +114,10 @@
Stream* stream = new Stream{ };
stream->parent = m_webKitMediaSrc.get();
- stream->appsrc = gst_element_factory_make("appsrc", nullptr);
+
+ // Ensure ownership is not transfered to the bin. The appsrc element is managed by its parent Stream.
+ stream->appsrc = GST_ELEMENT_CAST(gst_object_ref_sink(gst_element_factory_make("appsrc", nullptr)));
+
stream->appsrcNeedDataFlag = false;
stream->sourceBuffer = sourceBufferPrivate.get();
@@ -137,7 +140,7 @@
priv->streams.append(stream);
GST_OBJECT_UNLOCK(m_webKitMediaSrc.get());
- gst_bin_add(GST_BIN(m_webKitMediaSrc.get()), stream->appsrc);
+ gst_bin_add(GST_BIN_CAST(m_webKitMediaSrc.get()), stream->appsrc);
gst_element_sync_state_with_parent(stream->appsrc);
return MediaSourcePrivate::AddStatus::Ok;
Modified: releases/WebKitGTK/webkit-2.32/Source/WebCore/platform/graphics/gstreamer/mse/WebKitMediaSourceGStreamer.cpp (275026 => 275027)
--- releases/WebKitGTK/webkit-2.32/Source/WebCore/platform/graphics/gstreamer/mse/WebKitMediaSourceGStreamer.cpp 2021-03-25 14:07:06 UTC (rev 275026)
+++ releases/WebKitGTK/webkit-2.32/Source/WebCore/platform/graphics/gstreamer/mse/WebKitMediaSourceGStreamer.cpp 2021-03-25 14:07:14 UTC (rev 275027)
@@ -271,6 +271,7 @@
WebKitMediaSrc* source = WEBKIT_MEDIA_SRC(object);
WebKitMediaSrcPrivate* priv = source->priv;
+ GST_DEBUG_OBJECT(source, "Finalizing %p", source);
Vector<Stream*> oldStreams;
source->priv->streams.swap(oldStreams);
@@ -352,6 +353,7 @@
WebKitMediaSrc* source = WEBKIT_MEDIA_SRC(element);
WebKitMediaSrcPrivate* priv = source->priv;
+ GST_DEBUG_OBJECT(element, "%s", gst_state_change_get_name(transition));
switch (transition) {
case GST_STATE_CHANGE_READY_TO_PAUSED:
priv->allTracksConfigured = false;
@@ -509,10 +511,13 @@
void webKitMediaSrcFreeStream(WebKitMediaSrc* source, Stream* stream)
{
+ GST_DEBUG_OBJECT(source, "Releasing stream: %p", stream);
+
if (GST_IS_APP_SRC(stream->appsrc)) {
// Don't trigger callbacks from this appsrc to avoid using the stream anymore.
gst_app_src_set_callbacks(GST_APP_SRC(stream->appsrc), &disabledAppsrcCallbacks, nullptr, nullptr);
gst_app_src_end_of_stream(GST_APP_SRC(stream->appsrc));
+ gst_object_unref(stream->appsrc);
}
GST_OBJECT_LOCK(source);
@@ -566,7 +571,6 @@
source->priv->streamCondition.notifyOne();
}
- GST_DEBUG("Releasing stream: %p", stream);
delete stream;
}
@@ -692,6 +696,73 @@
GST_OBJECT_UNLOCK(source);
}
+void webKitMediaSrcRestoreTracks(WebKitMediaSrc* oldSource, WebKitMediaSrc* newSource)
+{
+ newSource->priv->streams = WTFMove(oldSource->priv->streams);
+ for (auto* stream : newSource->priv->streams) {
+ stream->parent = newSource;
+
+ auto oldSourcePad = adoptGRef(gst_element_get_static_pad(stream->appsrc, "src"));
+ unsigned padId = static_cast<unsigned>(GPOINTER_TO_INT(g_object_get_data(G_OBJECT(oldSourcePad.get()), "padId")));
+
+ gst_object_unref(stream->appsrc);
+
+ // Ensure ownership is not transfered to the bin. The appsrc element is managed by its parent Stream.
+ stream->appsrc = GST_ELEMENT_CAST(gst_object_ref_sink(gst_element_factory_make("appsrc", nullptr)));
+ stream->appsrcNeedDataFlag = true;
+
+ gst_app_src_set_callbacks(GST_APP_SRC(stream->appsrc), &enabledAppsrcCallbacks, stream->parent, nullptr);
+ gst_app_src_set_emit_signals(GST_APP_SRC(stream->appsrc), FALSE);
+ gst_app_src_set_stream_type(GST_APP_SRC(stream->appsrc), GST_APP_STREAM_TYPE_SEEKABLE);
+
+ gst_app_src_set_max_bytes(GST_APP_SRC(stream->appsrc), 2 * WTF::MB);
+ g_object_set(G_OBJECT(stream->appsrc), "block", FALSE, "min-percent", 20, "format", GST_FORMAT_TIME, nullptr);
+
+ gst_bin_add(GST_BIN_CAST(newSource), stream->appsrc);
+
+ auto sourcePad = adoptGRef(gst_element_get_static_pad(stream->appsrc, "src"));
+ g_object_set_data(G_OBJECT(sourcePad.get()), "padId", GINT_TO_POINTER(padId));
+ }
+
+ newSource->priv->numberOfAudioStreams = oldSource->priv->numberOfAudioStreams;
+ newSource->priv->numberOfTextStreams = oldSource->priv->numberOfTextStreams;
+ newSource->priv->numberOfVideoStreams = oldSource->priv->numberOfVideoStreams;
+ newSource->priv->numberOfPads = oldSource->priv->numberOfPads;
+ newSource->priv->allTracksConfigured = oldSource->priv->allTracksConfigured;
+}
+
+void webKitMediaSrcSignalTracks(WebKitMediaSrc* source)
+{
+ for (auto* stream : source->priv->streams) {
+ auto sourcePad = adoptGRef(gst_element_get_static_pad(stream->appsrc, "src"));
+ webKitMediaSrcLinkStreamToSrcPad(sourcePad.get(), stream);
+
+ gst_element_sync_state_with_parent(stream->appsrc);
+
+ int signal = -1;
+ switch (stream->type) {
+ case WebCore::MediaSourceStreamTypeGStreamer::Video:
+ signal = SIGNAL_VIDEO_CHANGED;
+ break;
+ case WebCore::MediaSourceStreamTypeGStreamer::Audio:
+ signal = SIGNAL_AUDIO_CHANGED;
+ break;
+ case WebCore::MediaSourceStreamTypeGStreamer::Text:
+ signal = SIGNAL_TEXT_CHANGED;
+ break;
+ default:
+ break;
+ }
+ if (signal != -1)
+ g_signal_emit(G_OBJECT(stream->parent), webKitMediaSrcSignals[signal], 0, nullptr);
+ }
+
+ if (source->priv->streams.size()) {
+ gst_element_no_more_pads(GST_ELEMENT_CAST(source));
+ webKitMediaSrcDoAsyncDone(source);
+ }
+}
+
void webKitMediaSrcSetMediaPlayerPrivate(WebKitMediaSrc* source, WebCore::MediaPlayerPrivateGStreamerMSE* mediaPlayerPrivate)
{
GST_OBJECT_LOCK(source);
Modified: releases/WebKitGTK/webkit-2.32/Source/WebCore/platform/graphics/gstreamer/mse/WebKitMediaSourceGStreamer.h (275026 => 275027)
--- releases/WebKitGTK/webkit-2.32/Source/WebCore/platform/graphics/gstreamer/mse/WebKitMediaSourceGStreamer.h 2021-03-25 14:07:06 UTC (rev 275026)
+++ releases/WebKitGTK/webkit-2.32/Source/WebCore/platform/graphics/gstreamer/mse/WebKitMediaSourceGStreamer.h 2021-03-25 14:07:14 UTC (rev 275027)
@@ -70,6 +70,8 @@
GType webkit_media_src_get_type(void);
+void webKitMediaSrcRestoreTracks(WebKitMediaSrc*, WebKitMediaSrc*);
+void webKitMediaSrcSignalTracks(WebKitMediaSrc*);
void webKitMediaSrcSetMediaPlayerPrivate(WebKitMediaSrc*, WebCore::MediaPlayerPrivateGStreamerMSE*);
void webKitMediaSrcPrepareSeek(WebKitMediaSrc*, const MediaTime&);