Title: [270906] trunk/Source/WebCore
Revision
270906
Author
[email protected]
Date
2020-12-16 12:57:12 -0800 (Wed, 16 Dec 2020)

Log Message

[Debug][GStreamer] Crash in fast/mediastream/change-tracks-media-stream-being-played.html
https://bugs.webkit.org/show_bug.cgi?id=219437

Patch by Víctor Manuel Jáquez Leal <[email protected]> on 2020-12-16
Reviewed by Philippe Normand.

The crash was a product of a race condition where a new sample, either video or audio,
appeared after the track was already removed from the stream and the GStreamer's source was
already removed. The result was a segmentation fault when the sample observer is called,
since the observer is coupled with the GStreamer's source.

This fix consists of removing the observers as soon as the track is removed from the stream.

No new tests needed since it fix one.

* platform/mediastream/gstreamer/GStreamerMediaStreamSource.cpp:
(webkitMediaStreamSrcRemoveTrackObserver): New function.
(stopObservingTracks): Use new function.
(webkitMediaStreamSrcSetupSrc): Use track's type method rather than source's.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (270905 => 270906)


--- trunk/Source/WebCore/ChangeLog	2020-12-16 20:52:08 UTC (rev 270905)
+++ trunk/Source/WebCore/ChangeLog	2020-12-16 20:57:12 UTC (rev 270906)
@@ -1,3 +1,24 @@
+2020-12-16  Víctor Manuel Jáquez Leal  <[email protected]>
+
+        [Debug][GStreamer] Crash in fast/mediastream/change-tracks-media-stream-being-played.html
+        https://bugs.webkit.org/show_bug.cgi?id=219437
+
+        Reviewed by Philippe Normand.
+
+        The crash was a product of a race condition where a new sample, either video or audio,
+        appeared after the track was already removed from the stream and the GStreamer's source was
+        already removed. The result was a segmentation fault when the sample observer is called,
+        since the observer is coupled with the GStreamer's source.
+
+        This fix consists of removing the observers as soon as the track is removed from the stream.
+
+        No new tests needed since it fix one.
+
+        * platform/mediastream/gstreamer/GStreamerMediaStreamSource.cpp:
+        (webkitMediaStreamSrcRemoveTrackObserver): New function.
+        (stopObservingTracks): Use new function.
+        (webkitMediaStreamSrcSetupSrc): Use track's type method rather than source's.
+
 2020-12-16  Fujii Hironori  <[email protected]>
 
         [WinCairo] Enable USE_ANGLE

Modified: trunk/Source/WebCore/platform/mediastream/gstreamer/GStreamerMediaStreamSource.cpp (270905 => 270906)


--- trunk/Source/WebCore/platform/mediastream/gstreamer/GStreamerMediaStreamSource.cpp	2020-12-16 20:52:08 UTC (rev 270905)
+++ trunk/Source/WebCore/platform/mediastream/gstreamer/GStreamerMediaStreamSource.cpp	2020-12-16 20:57:12 UTC (rev 270906)
@@ -43,6 +43,7 @@
 static void webkitMediaStreamSrcPushAudioSample(WebKitMediaStreamSrc*, const GRefPtr<GstSample>&);
 static void webkitMediaStreamSrcTrackEnded(WebKitMediaStreamSrc*, MediaStreamTrackPrivate&);
 static void webkitMediaStreamSrcRemoveTrackByType(WebKitMediaStreamSrc*, RealtimeMediaSource::Type);
+static void webkitMediaStreamSrcRemoveTrackObserver(WebKitMediaStreamSrc*, MediaStreamTrackPrivate&);
 
 static GstStaticPadTemplate videoSrcTemplate = GST_STATIC_PAD_TEMPLATE("video_src", GST_PAD_SRC, GST_PAD_SOMETIMES,
     GST_STATIC_CAPS("video/x-raw;video/x-h264;video/x-vp8"));
@@ -164,8 +165,11 @@
 
     void didRemoveTrack(MediaStreamTrackPrivate& track) final
     {
-        if (m_src)
-            webkitMediaStreamSrcRemoveTrackByType(WEBKIT_MEDIA_STREAM_SRC(m_src), track.type());
+        if (!m_src)
+            return;
+
+        webkitMediaStreamSrcRemoveTrackObserver(WEBKIT_MEDIA_STREAM_SRC(m_src), track);
+        webkitMediaStreamSrcRemoveTrackByType(WEBKIT_MEDIA_STREAM_SRC(m_src), track.type());
     }
 
 private:
@@ -349,21 +353,31 @@
     ASSERT(g_object_is_floating(self));
 }
 
+static void webkitMediaStreamSrcRemoveTrackObserver(WebKitMediaStreamSrc* self, MediaStreamTrackPrivate& track)
+{
+    auto* priv = self->priv;
+    switch (track.type()) {
+    case RealtimeMediaSource::Type::Video:
+        track.source().removeVideoSampleObserver(*priv->mediaStreamTrackObserver);
+        break;
+    case RealtimeMediaSource::Type::Audio:
+        track.source().removeAudioSampleObserver(*priv->mediaStreamTrackObserver);
+        break;
+    case RealtimeMediaSource::Type::None:
+        ASSERT_NOT_REACHED();
+    }
+    track.removeObserver(*priv->mediaStreamTrackObserver);
+}
+
 static void stopObservingTracks(WebKitMediaStreamSrc* self)
 {
     GST_OBJECT_LOCK(self);
     auto* priv = self->priv;
     if (priv->stream) {
-        for (auto& track : priv->stream->tracks()) {
-            track->source().removeAudioSampleObserver(*priv->mediaStreamTrackObserver);
-            track->source().removeVideoSampleObserver(*priv->mediaStreamTrackObserver);
-            track->removeObserver(*priv->mediaStreamTrackObserver);
-        }
-    } else if (priv->track) {
-        priv->track->source().removeAudioSampleObserver(*priv->mediaStreamTrackObserver);
-        priv->track->source().removeVideoSampleObserver(*priv->mediaStreamTrackObserver);
-        priv->track->removeObserver(*priv->mediaStreamTrackObserver);
-    }
+        for (auto& track : priv->stream->tracks())
+            webkitMediaStreamSrcRemoveTrackObserver(self, *track);
+    } else if (priv->track)
+        webkitMediaStreamSrcRemoveTrackObserver(self, *priv->track);
     GST_OBJECT_UNLOCK(self);
 }
 
@@ -512,14 +526,13 @@
     }
 
     auto* priv = self->priv;
-    track->addObserver(*priv->mediaStreamTrackObserver.get());
-    auto& source = track->source();
-    switch (source.type()) {
+    track->addObserver(*priv->mediaStreamTrackObserver);
+    switch (track->type()) {
     case RealtimeMediaSource::Type::Audio:
-        source.addAudioSampleObserver(*priv->mediaStreamTrackObserver);
+        track->source().addAudioSampleObserver(*priv->mediaStreamTrackObserver);
         break;
     case RealtimeMediaSource::Type::Video:
-        source.addVideoSampleObserver(*priv->mediaStreamTrackObserver);
+        track->source().addVideoSampleObserver(*priv->mediaStreamTrackObserver);
         break;
     case RealtimeMediaSource::Type::None:
         ASSERT_NOT_REACHED();
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to