<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[238276] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/238276">238276</a></dd>
<dt>Author</dt> <dd>commit-queue@webkit.org</dd>
<dt>Date</dt> <dd>2018-11-16 06:01:19 -0800 (Fri, 16 Nov 2018)</dd>
</dl>

<h3>Log Message</h3>
<pre>[GStreamer][MediaStream] Handle track addition and removal
https://bugs.webkit.org/show_bug.cgi?id=191599

Patch by Thibault Saunier <tsaunier@igalia.com> on 2018-11-16
Reviewed by Xabier Rodriguez-Calvar.

Source/WebCore:

Test: fast/mediastream/MediaStream-video-element-remove-track.html

* platform/mediastream/gstreamer/GStreamerMediaStreamSource.cpp:
(WebCore::WebKitMediaStreamObserver::~WebKitMediaStreamObserver):
(WebCore::WebKitMediaStreamObserver::WebKitMediaStreamObserver):
(WebCore::webkitMediaStreamSrcFinalize):
(WebCore::webkitMediaStreamSrcChangeState):
(WebCore::webkit_media_stream_src_init):
(WebCore::webkitMediaStreamSrcSetupSrc):
(WebCore::webkitMediaStreamSrcAddTrack):
(WebCore::webkitMediaStreamSrcRemoveTrackByType):
(WebCore::webkitMediaStreamSrcSetStream):

LayoutTests:

* fast/mediastream/MediaStream-video-element-remove-track-expected.txt: Added.
* fast/mediastream/MediaStream-video-element-remove-track.html: Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreplatformmediastreamgstreamerGStreamerMediaStreamSourcecpp">trunk/Source/WebCore/platform/mediastream/gstreamer/GStreamerMediaStreamSource.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformmediastreamgstreamerGStreamerMediaStreamSourceh">trunk/Source/WebCore/platform/mediastream/gstreamer/GStreamerMediaStreamSource.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsfastmediastreamMediaStreamvideoelementremovetrackexpectedtxt">trunk/LayoutTests/fast/mediastream/MediaStream-video-element-remove-track-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastmediastreamMediaStreamvideoelementremovetrackhtml">trunk/LayoutTests/fast/mediastream/MediaStream-video-element-remove-track.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (238275 => 238276)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog      2018-11-16 10:57:17 UTC (rev 238275)
+++ trunk/LayoutTests/ChangeLog 2018-11-16 14:01:19 UTC (rev 238276)
</span><span class="lines">@@ -1,3 +1,13 @@
</span><ins>+2018-11-16  Thibault Saunier  <tsaunier@igalia.com>
+
+        [GStreamer][MediaStream] Handle track addition and removal
+        https://bugs.webkit.org/show_bug.cgi?id=191599
+
+        Reviewed by Xabier Rodriguez-Calvar.
+
+        * fast/mediastream/MediaStream-video-element-remove-track-expected.txt: Added.
+        * fast/mediastream/MediaStream-video-element-remove-track.html: Added.
+
</ins><span class="cx"> 2018-11-16  Antoine Quint  <graouts@apple.com>
</span><span class="cx"> 
</span><span class="cx">         PointerEvents should not require touch event listeners to be registered
</span></span></pre></div>
<a id="trunkLayoutTestsfastmediastreamMediaStreamvideoelementremovetrackexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/mediastream/MediaStream-video-element-remove-track-expected.txt (0 => 238276)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/mediastream/MediaStream-video-element-remove-track-expected.txt                           (rev 0)
+++ trunk/LayoutTests/fast/mediastream/MediaStream-video-element-remove-track-expected.txt      2018-11-16 14:01:19 UTC (rev 238276)
</span><span class="lines">@@ -0,0 +1,47 @@
</span><ins>+Tests checking removing MediaStream track applies to the video element.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+
+
+**** calling mediaDevices.getUserMedia() ****
+PASS mediaDevices.getUserMedia succeeded.
+
+**** setup video element ****
+video.srcObject = mediaStream
+Event 'canplay'
+
+*** start playback ****
+video.play()
+video.pause()
+
+**** check video element ****
+
+**** check video tracks ****
+PASS video.videoTracks.length is 1
+PASS video.videoTracks[0].id is mediaStream.getVideoTracks()[0].id
+
+**** check audio tracks ****
+PASS video.audioTracks.length is 1
+PASS video.audioTracks[0].id is mediaStream.getAudioTracks()[0].id
+
+**** removing audio track ****
+
+**** check video element ****
+PASS video.videoWidth is mediaStream.getVideoTracks()[0].getSettings().width
+PASS video.videoHeight is mediaStream.getVideoTracks()[0].getSettings().height
+
+**** check video tracks ****
+PASS video.videoTracks.length is 1
+PASS video.videoTracks[0].id is mediaStream.getVideoTracks()[0].id
+PASS video.videoTracks[0].language is ""
+PASS video.videoTracks[0].kind is "main"
+
+**** check no audio track ****
+PASS video.audioTracks.length is 0
+PASS mediaStream.getAudioTracks().length is 0
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsfastmediastreamMediaStreamvideoelementremovetrackhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/mediastream/MediaStream-video-element-remove-track.html (0 => 238276)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/mediastream/MediaStream-video-element-remove-track.html                           (rev 0)
+++ trunk/LayoutTests/fast/mediastream/MediaStream-video-element-remove-track.html      2018-11-16 14:01:19 UTC (rev 238276)
</span><span class="lines">@@ -0,0 +1,112 @@
</span><ins>+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+    <head>
+        <script src="../../resources/js-test-pre.js"></script>
+        <script>
+            var video;
+            var mediaStream;
+
+            function logEvent(element, eventName, func)
+            {
+                function _eventCallback(evt)
+                {
+                    if (window.wasFinishJSTestCalled)
+                        return;
+
+                    debug(`Event <em>'${evt.type}'</em>`);
+                    if (func)
+                        func(evt);
+                }
+                element.addEventListener(eventName, _eventCallback, true);
+            }
+
+            function checkVideoElement()
+            {
+                evalAndLog("video.pause()");
+
+                debug("<br>**** check video element ****");
+                debug("<br>**** check video tracks ****");
+                shouldBe('video.videoTracks.length', '1');
+                shouldBe('video.videoTracks[0].id', 'mediaStream.getVideoTracks()[0].id');
+
+                debug("<br>**** check audio tracks ****");
+                shouldBe('video.audioTracks.length', '1');
+                shouldBe('video.audioTracks[0].id', 'mediaStream.getAudioTracks()[0].id');
+
+                setTimeout(removeAudioTrack, 100);
+            }
+
+            function checkVideoElement2()
+            {
+                debug("<br>**** check video element ****");
+                shouldBe('video.videoWidth', 'mediaStream.getVideoTracks()[0].getSettings().width');
+                shouldBe('video.videoHeight', 'mediaStream.getVideoTracks()[0].getSettings().height');
+
+                debug("<br>**** check video tracks ****");
+                shouldBe('video.videoTracks.length', '1');
+                shouldBe('video.videoTracks[0].id', 'mediaStream.getVideoTracks()[0].id');
+                shouldBeEqualToString('video.videoTracks[0].language', '');
+                shouldBeEqualToString('video.videoTracks[0].kind', 'main');
+
+                debug("<br>**** check no audio track ****");
+                shouldBe('video.audioTracks.length', '0');
+                shouldBe('mediaStream.getAudioTracks().length', '0');
+
+                finishJSTest();
+            }
+
+            function canplay()
+            {
+                debug("<br>*** start playback ****");
+                evalAndLog("video.play()");
+                setTimeout(checkVideoElement, 100);
+            }
+
+            function removeAudioTrack() {
+                track = mediaStream.getAudioTracks()[0];
+                debug("<br>**** removing audio track ****");
+                try {
+                    mediaStream.removeTrack(track);
+                } catch (exception) {
+                    testFailed("removeTrack threw an exception.");
+                    finishJSTest();
+                }
+                setTimeout(checkVideoElement2, 100);
+            }
+
+            function setupStream(stream)
+            {
+                mediaStream = stream;
+                testPassed('mediaDevices.getUserMedia succeeded.');
+
+                debug("<br>**** setup video element ****");
+                evalAndLog("video.srcObject = mediaStream");
+            }
+
+            function start()
+            {
+                description("Tests checking removing MediaStream track applies to the video element.");
+                video = document.querySelector('video');
+                logEvent(video, 'canplay', canplay)
+
+                debug("<br>**** calling mediaDevices.getUserMedia() ****");
+                if (window.testRunner)
+                    testRunner.setUserMediaPermission(true);
+                navigator.mediaDevices.getUserMedia( {video: true, audio: true} )
+                    .then(setupStream)
+                    .catch(function(reason) {
+                        debug(`Stream generation failed with error: ${reason}`);
+                    });
+            }
+
+            window.jsTestIsAsync = true;
+            window.successfullyParsed = true;
+        </script>
+    </head>
+    <body onload="start()">
+        <p id="description"></p>
+        <video controls  width="680" height="360"></video>
+        <div id="console"></div>
+        <script src="../../resources/js-test-post.js"></script>
+    </body>
+</html>
</ins></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (238275 => 238276)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog   2018-11-16 10:57:17 UTC (rev 238275)
+++ trunk/Source/WebCore/ChangeLog      2018-11-16 14:01:19 UTC (rev 238276)
</span><span class="lines">@@ -1,3 +1,23 @@
</span><ins>+2018-11-16  Thibault Saunier  <tsaunier@igalia.com>
+
+        [GStreamer][MediaStream] Handle track addition and removal
+        https://bugs.webkit.org/show_bug.cgi?id=191599
+
+        Reviewed by Xabier Rodriguez-Calvar.
+
+        Test: fast/mediastream/MediaStream-video-element-remove-track.html
+
+        * platform/mediastream/gstreamer/GStreamerMediaStreamSource.cpp:
+        (WebCore::WebKitMediaStreamObserver::~WebKitMediaStreamObserver):
+        (WebCore::WebKitMediaStreamObserver::WebKitMediaStreamObserver):
+        (WebCore::webkitMediaStreamSrcFinalize):
+        (WebCore::webkitMediaStreamSrcChangeState):
+        (WebCore::webkit_media_stream_src_init):
+        (WebCore::webkitMediaStreamSrcSetupSrc):
+        (WebCore::webkitMediaStreamSrcAddTrack):
+        (WebCore::webkitMediaStreamSrcRemoveTrackByType):
+        (WebCore::webkitMediaStreamSrcSetStream):
+
</ins><span class="cx"> 2018-11-16  Zan Dobersek  <zdobersek@igalia.com>
</span><span class="cx"> 
</span><span class="cx">         ScalableImageDecoder: don't forcefully decode image data when querying frame completeness, duration
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmediastreamgstreamerGStreamerMediaStreamSourcecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mediastream/gstreamer/GStreamerMediaStreamSource.cpp (238275 => 238276)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mediastream/gstreamer/GStreamerMediaStreamSource.cpp       2018-11-16 10:57:17 UTC (rev 238275)
+++ trunk/Source/WebCore/platform/mediastream/gstreamer/GStreamerMediaStreamSource.cpp  2018-11-16 14:01:19 UTC (rev 238276)
</span><span class="lines">@@ -41,6 +41,8 @@
</span><span class="cx"> static void webkitMediaStreamSrcPushVideoSample(WebKitMediaStreamSrc* self, GstSample* gstsample);
</span><span class="cx"> static void webkitMediaStreamSrcPushAudioSample(WebKitMediaStreamSrc* self, GstSample* gstsample);
</span><span class="cx"> static void webkitMediaStreamSrcTrackEnded(WebKitMediaStreamSrc* self, MediaStreamTrackPrivate&);
</span><ins>+static void webkitMediaStreamSrcAddTrack(WebKitMediaStreamSrc* self, MediaStreamTrackPrivate*);
+static void webkitMediaStreamSrcRemoveTrackByType(WebKitMediaStreamSrc* self, RealtimeMediaSource::Type trackType);
</ins><span class="cx"> 
</span><span class="cx"> static GstStaticPadTemplate videoSrcTemplate = GST_STATIC_PAD_TEMPLATE("video_src",
</span><span class="cx">     GST_PAD_SRC,
</span><span class="lines">@@ -93,7 +95,7 @@
</span><span class="cx">         caps = adoptGRef(gst_static_pad_template_get_caps(&videoSrcTemplate));
</span><span class="cx">         type = GST_STREAM_TYPE_VIDEO;
</span><span class="cx">     } else {
</span><del>-        GST_FIXME("Handle %d type", (gint) track->type());
</del><ins>+        GST_FIXME("Handle %d type", static_cast<int>(track->type()));
</ins><span class="cx"> 
</span><span class="cx">         return nullptr;
</span><span class="cx">     }
</span><span class="lines">@@ -142,6 +144,30 @@
</span><span class="cx">     WebKitMediaStreamSrc* m_mediaStreamSrc;
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+class WebKitMediaStreamObserver
+    : public MediaStreamPrivate::Observer {
+public:
+    virtual ~WebKitMediaStreamObserver() { };
+    WebKitMediaStreamObserver(WebKitMediaStreamSrc* src)
+        : m_mediaStreamSrc(src) { }
+
+    void characteristicsChanged() final { GST_DEBUG_OBJECT(m_mediaStreamSrc.get(), "renegotiation should happen"); }
+    void activeStatusChanged() final { }
+
+    void didAddTrack(MediaStreamTrackPrivate& track) final
+    {
+        webkitMediaStreamSrcAddTrack(m_mediaStreamSrc.get(), &track);
+    }
+
+    void didRemoveTrack(MediaStreamTrackPrivate& track) final
+    {
+        webkitMediaStreamSrcRemoveTrackByType(m_mediaStreamSrc.get(), track.type());
+    }
+
+private:
+    GRefPtr<WebKitMediaStreamSrc> m_mediaStreamSrc;
+};
+
</ins><span class="cx"> typedef struct _WebKitMediaStreamSrcClass WebKitMediaStreamSrcClass;
</span><span class="cx"> struct _WebKitMediaStreamSrc {
</span><span class="cx">     GstBin parent_instance;
</span><span class="lines">@@ -153,7 +179,8 @@
</span><span class="cx">     GstElement* videoSrc;
</span><span class="cx">     GstClockTime firstFramePts;
</span><span class="cx"> 
</span><del>-    std::unique_ptr<WebKitMediaStreamTrackObserver> observer;
</del><ins>+    std::unique_ptr<WebKitMediaStreamTrackObserver> mediaStreamTrackObserver;
+    std::unique_ptr<WebKitMediaStreamObserver> mediaStreamObserver;
</ins><span class="cx">     volatile gint npads;
</span><span class="cx">     gulong probeid;
</span><span class="cx">     RefPtr<MediaStreamPrivate> stream;
</span><span class="lines">@@ -266,8 +293,13 @@
</span><span class="cx">     WebKitMediaStreamSrc* self = WEBKIT_MEDIA_STREAM_SRC(object);
</span><span class="cx"> 
</span><span class="cx">     GST_OBJECT_LOCK(self);
</span><del>-    for (auto& track : self->stream->tracks())
-        track->removeObserver(*self->observer.get());
</del><ins>+    if (self->stream) {
+        for (auto& track : self->stream->tracks())
+            track->removeObserver(*self->mediaStreamTrackObserver.get());
+
+        self->stream->removeObserver(*self->mediaStreamObserver);
+        self->stream = nullptr;
+    }
</ins><span class="cx">     GST_OBJECT_UNLOCK(self);
</span><span class="cx"> 
</span><span class="cx">     g_clear_pointer(&self->uri, g_free);
</span><span class="lines">@@ -283,7 +315,7 @@
</span><span class="cx"> 
</span><span class="cx">         GST_OBJECT_LOCK(self);
</span><span class="cx">         for (auto& track : self->stream->tracks())
</span><del>-            track->removeObserver(*self->observer.get());
</del><ins>+            track->removeObserver(*self->mediaStreamTrackObserver.get());
</ins><span class="cx">         GST_OBJECT_UNLOCK(self);
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -319,7 +351,8 @@
</span><span class="cx"> 
</span><span class="cx"> static void webkit_media_stream_src_init(WebKitMediaStreamSrc* self)
</span><span class="cx"> {
</span><del>-    self->observer = std::make_unique<WebKitMediaStreamTrackObserver>(self);
</del><ins>+    self->mediaStreamTrackObserver = std::make_unique<WebKitMediaStreamTrackObserver>(self);
+    self->mediaStreamObserver = std::make_unique<WebKitMediaStreamObserver>(self);
</ins><span class="cx">     self->flowCombiner = gst_flow_combiner_new();
</span><span class="cx">     self->firstAudioBufferPts = GST_CLOCK_TIME_NONE;
</span><span class="cx">     self->firstFramePts = GST_CLOCK_TIME_NONE;
</span><span class="lines">@@ -420,7 +453,7 @@
</span><span class="cx">         });
</span><span class="cx"> 
</span><span class="cx">     if (observe_track)
</span><del>-        track->addObserver(*self->observer.get());
</del><ins>+        track->addObserver(*self->mediaStreamTrackObserver.get());
</ins><span class="cx"> 
</span><span class="cx">     gst_element_sync_state_with_parent(element);
</span><span class="cx">     return TRUE;
</span><span class="lines">@@ -451,37 +484,47 @@
</span><span class="cx">         gst_message_new_stream_collection(GST_OBJECT(self), self->streamCollection.get()));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-gboolean webkitMediaStreamSrcSetStream(WebKitMediaStreamSrc* self, MediaStreamPrivate* stream)
</del><ins>+static void webkitMediaStreamSrcAddTrack(WebKitMediaStreamSrc* self, MediaStreamTrackPrivate* track)
</ins><span class="cx"> {
</span><del>-    g_return_val_if_fail(WEBKIT_IS_MEDIA_STREAM_SRC(self), FALSE);
</del><ins>+    if (track->type() == RealtimeMediaSource::Type::Audio)
+        webkitMediaStreamSrcSetupAppSrc(self, track, &self->audioSrc, &audioSrcTemplate);
+    else if (track->type() == RealtimeMediaSource::Type::Video)
+        webkitMediaStreamSrcSetupAppSrc(self, track, &self->videoSrc, &videoSrcTemplate);
+    else
+        GST_INFO("Unsupported track type: %d", static_cast<int>(track->type()));
+}
</ins><span class="cx"> 
</span><del>-    if (self->audioSrc) {
-        gst_element_set_state(self->audioSrc, GST_STATE_NULL);
-        gst_bin_remove(GST_BIN(self), self->audioSrc);
-        self->audioSrc = nullptr;
-    }
</del><ins>+static void webkitMediaStreamSrcRemoveTrackByType(WebKitMediaStreamSrc* self, RealtimeMediaSource::Type trackType)
+{
+    if (trackType == RealtimeMediaSource::Type::Audio) {
+        if (self->audioSrc) {
+            gst_element_set_state(self->audioSrc, GST_STATE_NULL);
+            gst_bin_remove(GST_BIN(self), self->audioSrc);
+            self->audioSrc = nullptr;
+        }
+    } else if (trackType == RealtimeMediaSource::Type::Video) {
+        if (self->videoSrc) {
+            gst_element_set_state(self->videoSrc, GST_STATE_NULL);
+            gst_bin_remove(GST_BIN(self), self->videoSrc);
+            self->videoSrc = nullptr;
+        }
+    } else
+        GST_INFO("Unsupported track type: %d", static_cast<int>(trackType));
+}
</ins><span class="cx"> 
</span><del>-    if (self->videoSrc) {
-        gst_element_set_state(self->videoSrc, GST_STATE_NULL);
-        gst_bin_remove(GST_BIN(self), self->videoSrc);
-        self->videoSrc = nullptr;
-    }
</del><ins>+bool webkitMediaStreamSrcSetStream(WebKitMediaStreamSrc* self, MediaStreamPrivate* stream)
+{
+    ASSERT(WEBKIT_IS_MEDIA_STREAM_SRC(self));
</ins><span class="cx"> 
</span><ins>+    webkitMediaStreamSrcRemoveTrackByType(self, RealtimeMediaSource::Type::Audio);
+    webkitMediaStreamSrcRemoveTrackByType(self, RealtimeMediaSource::Type::Video);
+
</ins><span class="cx">     webkitMediaStreamSrcPostStreamCollection(self, stream);
</span><span class="cx"> 
</span><span class="cx">     self->stream = stream;
</span><del>-    for (auto& track : stream->tracks()) {
-        if (track->type() == RealtimeMediaSource::Type::Audio) {
-            webkitMediaStreamSrcSetupAppSrc(self, track.get(), &self->audioSrc,
-                &audioSrcTemplate);
-        } else if (track->type() == RealtimeMediaSource::Type::Video) {
-            webkitMediaStreamSrcSetupAppSrc(self, track.get(), &self->videoSrc,
-                &videoSrcTemplate);
-        } else {
-            GST_INFO("Unsuported track type: %d", (gint) track->type());
-            continue;
-        }
-    }
</del><ins>+    self->stream->addObserver(*self->mediaStreamObserver.get());
+    for (auto& track : stream->tracks())
+        webkitMediaStreamSrcAddTrack(self, track.get());
</ins><span class="cx"> 
</span><span class="cx">     return TRUE;
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmediastreamgstreamerGStreamerMediaStreamSourceh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mediastream/gstreamer/GStreamerMediaStreamSource.h (238275 => 238276)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mediastream/gstreamer/GStreamerMediaStreamSource.h 2018-11-16 10:57:17 UTC (rev 238275)
+++ trunk/Source/WebCore/platform/mediastream/gstreamer/GStreamerMediaStreamSource.h    2018-11-16 14:01:19 UTC (rev 238276)
</span><span class="lines">@@ -40,7 +40,7 @@
</span><span class="cx"> #define WEBKIT_IS_MEDIA_STREAM_SRC(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), WEBKIT_TYPE_MEDIA_STREAM_SRC))
</span><span class="cx"> #define WEBKIT_TYPE_MEDIA_STREAM_SRC (webkit_media_stream_src_get_type())
</span><span class="cx"> GType webkit_media_stream_src_get_type(void) G_GNUC_CONST;
</span><del>-gboolean webkitMediaStreamSrcSetStream(WebKitMediaStreamSrc*, MediaStreamPrivate*);
</del><ins>+bool webkitMediaStreamSrcSetStream(WebKitMediaStreamSrc*, MediaStreamPrivate*);
</ins><span class="cx"> } // WebCore
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(VIDEO) && ENABLE(MEDIA_STREAM) && USE(LIBWEBRTC)
</span></span></pre>
</div>
</div>

</body>
</html>