<!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>[281741] trunk/Source/WebCore</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/281741">281741</a></dd>
<dt>Author</dt> <dd>commit-queue@webkit.org</dd>
<dt>Date</dt> <dd>2021-08-29 02:50:28 -0700 (Sun, 29 Aug 2021)</dd>
</dl>

<h3>Log Message</h3>
<pre>[GStreamer] Track handling refactoring
https://bugs.webkit.org/show_bug.cgi?id=229497

Patch by Philippe Normand <pnormand@igalia.com> on 2021-08-29
Reviewed by Xabier Rodriguez-Calvar.

The TrackPrivateBaseGStreamer class now factors most of the common code used by its
sub-classes. The code style was modernised, some MSE-related dead code was removed from the
player. More could be done in the MSE AppendPipeline by making it rely on parsebin, but
that's another quest. The tracks created by the AppendPipeline were triggering track ID
mismatches between the player and those tracks, so a new flag was added in the constructor
of those to prevent stream-start event handling. Ideally that code should rely on GstStream,
that would remove the need of that flag.

No new tests, existing media tests cover this change.

* platform/graphics/gstreamer/AudioTrackPrivateGStreamer.cpp:
(WebCore::AudioTrackPrivateGStreamer::AudioTrackPrivateGStreamer):
* platform/graphics/gstreamer/AudioTrackPrivateGStreamer.h:
* platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.cpp:
(WebCore::InbandTextTrackPrivateGStreamer::InbandTextTrackPrivateGStreamer):
* platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.h:
(WebCore::InbandTextTrackPrivateGStreamer::create):
* platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:
(WebCore::MediaPlayerPrivateGStreamer::notifyPlayerOfTrack):
(WebCore::MediaPlayerPrivateGStreamer::handleTextSample):
(WebCore::MediaPlayerPrivateGStreamer::updateTracks):
* platform/graphics/gstreamer/TrackPrivateBaseGStreamer.cpp:
(WebCore::TrackPrivateBaseGStreamer::generateUniquePlaybin2StreamID):
(WebCore::TrackPrivateBaseGStreamer::TrackPrivateBaseGStreamer):
(WebCore::TrackPrivateBaseGStreamer::setPad):
(WebCore::TrackPrivateBaseGStreamer::tagsChanged):
(WebCore::TrackPrivateBaseGStreamer::notifyTrackOfStreamChanged):
(WebCore::TrackPrivateBaseGStreamer::streamChanged):
* platform/graphics/gstreamer/TrackPrivateBaseGStreamer.h:
(WebCore::TrackPrivateBaseGStreamer::setIndex):
(WebCore::TrackPrivateBaseGStreamer::stream):
* platform/graphics/gstreamer/VideoTrackPrivateGStreamer.cpp:
(WebCore::VideoTrackPrivateGStreamer::VideoTrackPrivateGStreamer):
* platform/graphics/gstreamer/VideoTrackPrivateGStreamer.h:
* platform/graphics/gstreamer/mse/AppendPipeline.cpp:
(WebCore::AppendPipeline::makeWebKitTrack):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsgstreamerAudioTrackPrivateGStreamercpp">trunk/Source/WebCore/platform/graphics/gstreamer/AudioTrackPrivateGStreamer.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsgstreamerAudioTrackPrivateGStreamerh">trunk/Source/WebCore/platform/graphics/gstreamer/AudioTrackPrivateGStreamer.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsgstreamerInbandTextTrackPrivateGStreamercpp">trunk/Source/WebCore/platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsgstreamerInbandTextTrackPrivateGStreamerh">trunk/Source/WebCore/platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsgstreamerMediaPlayerPrivateGStreamercpp">trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsgstreamerTrackPrivateBaseGStreamercpp">trunk/Source/WebCore/platform/graphics/gstreamer/TrackPrivateBaseGStreamer.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsgstreamerTrackPrivateBaseGStreamerh">trunk/Source/WebCore/platform/graphics/gstreamer/TrackPrivateBaseGStreamer.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsgstreamerVideoTrackPrivateGStreamercpp">trunk/Source/WebCore/platform/graphics/gstreamer/VideoTrackPrivateGStreamer.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsgstreamerVideoTrackPrivateGStreamerh">trunk/Source/WebCore/platform/graphics/gstreamer/VideoTrackPrivateGStreamer.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsgstreamermseAppendPipelinecpp">trunk/Source/WebCore/platform/graphics/gstreamer/mse/AppendPipeline.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (281740 => 281741)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog   2021-08-29 09:27:02 UTC (rev 281740)
+++ trunk/Source/WebCore/ChangeLog      2021-08-29 09:50:28 UTC (rev 281741)
</span><span class="lines">@@ -1,3 +1,47 @@
</span><ins>+2021-08-29  Philippe Normand  <pnormand@igalia.com>
+
+        [GStreamer] Track handling refactoring
+        https://bugs.webkit.org/show_bug.cgi?id=229497
+
+        Reviewed by Xabier Rodriguez-Calvar.
+
+        The TrackPrivateBaseGStreamer class now factors most of the common code used by its
+        sub-classes. The code style was modernised, some MSE-related dead code was removed from the
+        player. More could be done in the MSE AppendPipeline by making it rely on parsebin, but
+        that's another quest. The tracks created by the AppendPipeline were triggering track ID
+        mismatches between the player and those tracks, so a new flag was added in the constructor
+        of those to prevent stream-start event handling. Ideally that code should rely on GstStream,
+        that would remove the need of that flag.
+
+        No new tests, existing media tests cover this change.
+
+        * platform/graphics/gstreamer/AudioTrackPrivateGStreamer.cpp:
+        (WebCore::AudioTrackPrivateGStreamer::AudioTrackPrivateGStreamer):
+        * platform/graphics/gstreamer/AudioTrackPrivateGStreamer.h:
+        * platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.cpp:
+        (WebCore::InbandTextTrackPrivateGStreamer::InbandTextTrackPrivateGStreamer):
+        * platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.h:
+        (WebCore::InbandTextTrackPrivateGStreamer::create):
+        * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:
+        (WebCore::MediaPlayerPrivateGStreamer::notifyPlayerOfTrack):
+        (WebCore::MediaPlayerPrivateGStreamer::handleTextSample):
+        (WebCore::MediaPlayerPrivateGStreamer::updateTracks):
+        * platform/graphics/gstreamer/TrackPrivateBaseGStreamer.cpp:
+        (WebCore::TrackPrivateBaseGStreamer::generateUniquePlaybin2StreamID):
+        (WebCore::TrackPrivateBaseGStreamer::TrackPrivateBaseGStreamer):
+        (WebCore::TrackPrivateBaseGStreamer::setPad):
+        (WebCore::TrackPrivateBaseGStreamer::tagsChanged):
+        (WebCore::TrackPrivateBaseGStreamer::notifyTrackOfStreamChanged):
+        (WebCore::TrackPrivateBaseGStreamer::streamChanged):
+        * platform/graphics/gstreamer/TrackPrivateBaseGStreamer.h:
+        (WebCore::TrackPrivateBaseGStreamer::setIndex):
+        (WebCore::TrackPrivateBaseGStreamer::stream):
+        * platform/graphics/gstreamer/VideoTrackPrivateGStreamer.cpp:
+        (WebCore::VideoTrackPrivateGStreamer::VideoTrackPrivateGStreamer):
+        * platform/graphics/gstreamer/VideoTrackPrivateGStreamer.h:
+        * platform/graphics/gstreamer/mse/AppendPipeline.cpp:
+        (WebCore::AppendPipeline::makeWebKitTrack):
+
</ins><span class="cx"> 2021-08-29  Joonghun Park  <jh718.park@samsung.com>
</span><span class="cx"> 
</span><span class="cx">         Unreviewed. Remove the build warning below since r280958.
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsgstreamerAudioTrackPrivateGStreamercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/gstreamer/AudioTrackPrivateGStreamer.cpp (281740 => 281741)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/gstreamer/AudioTrackPrivateGStreamer.cpp  2021-08-29 09:27:02 UTC (rev 281740)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/AudioTrackPrivateGStreamer.cpp     2021-08-29 09:50:28 UTC (rev 281741)
</span><span class="lines">@@ -30,31 +30,26 @@
</span><span class="cx"> #include "AudioTrackPrivateGStreamer.h"
</span><span class="cx"> 
</span><span class="cx"> #include "MediaPlayerPrivateGStreamer.h"
</span><del>-#include <glib-object.h>
</del><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><del>-AudioTrackPrivateGStreamer::AudioTrackPrivateGStreamer(WeakPtr<MediaPlayerPrivateGStreamer> player, gint index, GRefPtr<GstPad> pad)
-    : TrackPrivateBaseGStreamer(this, index, pad)
</del><ins>+AudioTrackPrivateGStreamer::AudioTrackPrivateGStreamer(WeakPtr<MediaPlayerPrivateGStreamer> player, unsigned index, GRefPtr<GstPad>&& pad, bool shouldHandleStreamStartEvent)
+    : TrackPrivateBaseGStreamer(TrackPrivateBaseGStreamer::TrackType::Audio, this, index, WTFMove(pad), shouldHandleStreamStartEvent)
</ins><span class="cx">     , m_player(player)
</span><span class="cx"> {
</span><del>-    // FIXME: Get a real ID from the tkhd atom.
-    m_id = "A" + String::number(index);
</del><span class="cx"> }
</span><span class="cx"> 
</span><del>-AudioTrackPrivateGStreamer::AudioTrackPrivateGStreamer(WeakPtr<MediaPlayerPrivateGStreamer> player, gint index, GRefPtr<GstStream> stream)
-    : TrackPrivateBaseGStreamer(this, index, stream)
</del><ins>+AudioTrackPrivateGStreamer::AudioTrackPrivateGStreamer(WeakPtr<MediaPlayerPrivateGStreamer> player, unsigned index, GRefPtr<GstStream>&& stream)
+    : TrackPrivateBaseGStreamer(TrackPrivateBaseGStreamer::TrackType::Audio, this, index, WTFMove(stream))
</ins><span class="cx">     , m_player(player)
</span><span class="cx"> {
</span><del>-    gint kind;
</del><ins>+    int kind;
</ins><span class="cx">     auto tags = adoptGRef(gst_stream_get_tags(m_stream.get()));
</span><span class="cx"> 
</span><del>-    if (tags && gst_tag_list_get_int(tags.get(), "webkit-media-stream-kind", &kind) && kind == static_cast<int>(VideoTrackPrivate::Kind::Main)) {
-        GstStreamFlags streamFlags = gst_stream_get_stream_flags(stream.get());
-        gst_stream_set_stream_flags(stream.get(), static_cast<GstStreamFlags>(streamFlags | GST_STREAM_FLAG_SELECT));
</del><ins>+    if (tags && gst_tag_list_get_int(tags.get(), "webkit-media-stream-kind", &kind) && kind == static_cast<int>(AudioTrackPrivate::Kind::Main)) {
+        auto streamFlags = gst_stream_get_stream_flags(m_stream.get());
+        gst_stream_set_stream_flags(m_stream.get(), static_cast<GstStreamFlags>(streamFlags | GST_STREAM_FLAG_SELECT));
</ins><span class="cx">     }
</span><del>-
-    m_id = gst_stream_get_stream_id(stream.get());
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> AudioTrackPrivate::Kind AudioTrackPrivateGStreamer::kind() const
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsgstreamerAudioTrackPrivateGStreamerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/gstreamer/AudioTrackPrivateGStreamer.h (281740 => 281741)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/gstreamer/AudioTrackPrivateGStreamer.h    2021-08-29 09:27:02 UTC (rev 281740)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/AudioTrackPrivateGStreamer.h       2021-08-29 09:50:28 UTC (rev 281741)
</span><span class="lines">@@ -28,9 +28,8 @@
</span><span class="cx"> #if ENABLE(VIDEO) && USE(GSTREAMER)
</span><span class="cx"> 
</span><span class="cx"> #include "AudioTrackPrivate.h"
</span><del>-#include "GStreamerCommon.h"
</del><span class="cx"> #include "TrackPrivateBaseGStreamer.h"
</span><del>-#include <gst/gst.h>
</del><ins>+
</ins><span class="cx"> #include <wtf/WeakPtr.h>
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="lines">@@ -38,34 +37,33 @@
</span><span class="cx"> 
</span><span class="cx"> class AudioTrackPrivateGStreamer final : public AudioTrackPrivate, public TrackPrivateBaseGStreamer {
</span><span class="cx"> public:
</span><del>-    static Ref<AudioTrackPrivateGStreamer> create(WeakPtr<MediaPlayerPrivateGStreamer> player, gint index, GRefPtr<GstPad> pad)
</del><ins>+    static Ref<AudioTrackPrivateGStreamer> create(WeakPtr<MediaPlayerPrivateGStreamer> player, unsigned index, GRefPtr<GstPad>&& pad, bool shouldHandleStreamStartEvent = true)
</ins><span class="cx">     {
</span><del>-        return adoptRef(*new AudioTrackPrivateGStreamer(player, index, pad));
</del><ins>+        return adoptRef(*new AudioTrackPrivateGStreamer(player, index, WTFMove(pad), shouldHandleStreamStartEvent));
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    static Ref<AudioTrackPrivateGStreamer> create(WeakPtr<MediaPlayerPrivateGStreamer> player, gint index, GRefPtr<GstStream> stream)
</del><ins>+    static Ref<AudioTrackPrivateGStreamer> create(WeakPtr<MediaPlayerPrivateGStreamer> player, unsigned index, GRefPtr<GstStream>&& stream)
</ins><span class="cx">     {
</span><del>-        return adoptRef(*new AudioTrackPrivateGStreamer(player, index, stream));
</del><ins>+        return adoptRef(*new AudioTrackPrivateGStreamer(player, index, WTFMove(stream)));
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     Kind kind() const final;
</span><span class="cx"> 
</span><del>-    void disconnect() override;
</del><ins>+    void disconnect() final;
</ins><span class="cx"> 
</span><del>-    void setEnabled(bool) override;
-    void setActive(bool enabled) override { setEnabled(enabled); }
</del><ins>+    void setEnabled(bool) final;
+    void setActive(bool enabled) final { setEnabled(enabled); }
</ins><span class="cx"> 
</span><del>-    int trackIndex() const override { return m_index; }
</del><ins>+    int trackIndex() const final { return m_index; }
</ins><span class="cx"> 
</span><del>-    AtomString id() const override { return m_id; }
-    AtomString label() const override { return m_label; }
-    AtomString language() const override { return m_language; }
</del><ins>+    AtomString id() const final { return m_id; }
+    AtomString label() const final { return m_label; }
+    AtomString language() const final { return m_language; }
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    AudioTrackPrivateGStreamer(WeakPtr<MediaPlayerPrivateGStreamer>, gint index, GRefPtr<GstPad>);
-    AudioTrackPrivateGStreamer(WeakPtr<MediaPlayerPrivateGStreamer>, gint index, GRefPtr<GstStream>);
</del><ins>+    AudioTrackPrivateGStreamer(WeakPtr<MediaPlayerPrivateGStreamer>, unsigned index, GRefPtr<GstPad>&&, bool shouldHandleStreamStartEvent);
+    AudioTrackPrivateGStreamer(WeakPtr<MediaPlayerPrivateGStreamer>, unsigned index, GRefPtr<GstStream>&&);
</ins><span class="cx"> 
</span><del>-    AtomString m_id;
</del><span class="cx">     WeakPtr<MediaPlayerPrivateGStreamer> m_player;
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsgstreamerInbandTextTrackPrivateGStreamercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.cpp (281740 => 281741)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.cpp     2021-08-29 09:27:02 UTC (rev 281740)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.cpp        2021-08-29 09:50:28 UTC (rev 281741)
</span><span class="lines">@@ -29,10 +29,7 @@
</span><span class="cx"> 
</span><span class="cx"> #include "InbandTextTrackPrivateGStreamer.h"
</span><span class="cx"> 
</span><del>-#include "GStreamerCommon.h"
-#include "Logging.h"
-#include <glib-object.h>
-#include <gst/gst.h>
</del><ins>+#include <wtf/Lock.h>
</ins><span class="cx"> 
</span><span class="cx"> GST_DEBUG_CATEGORY_EXTERN(webkit_media_player_debug);
</span><span class="cx"> #define GST_CAT_DEFAULT webkit_media_player_debug
</span><span class="lines">@@ -39,48 +36,26 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><del>-InbandTextTrackPrivateGStreamer::InbandTextTrackPrivateGStreamer(gint index, GRefPtr<GstPad> pad)
</del><ins>+InbandTextTrackPrivateGStreamer::InbandTextTrackPrivateGStreamer(unsigned index, GRefPtr<GstPad>&& pad, bool shouldHandleStreamStartEvent)
</ins><span class="cx">     : InbandTextTrackPrivate(CueFormat::WebVTT)
</span><del>-    , TrackPrivateBaseGStreamer(this, index, pad)
</del><ins>+    , TrackPrivateBaseGStreamer(TrackPrivateBaseGStreamer::TrackType::Text, this, index, WTFMove(pad), shouldHandleStreamStartEvent)
</ins><span class="cx">     , m_kind(Kind::Subtitles)
</span><span class="cx"> {
</span><del>-    m_id = "T" + String::number(index);
-    m_eventProbe = gst_pad_add_probe(m_pad.get(), GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM, [] (GstPad*, GstPadProbeInfo* info, gpointer userData) -> GstPadProbeReturn {
-        auto* track = static_cast<InbandTextTrackPrivateGStreamer*>(userData);
-        switch (GST_EVENT_TYPE(gst_pad_probe_info_get_event(info))) {
-        case GST_EVENT_STREAM_START:
-            track->streamChanged();
-            break;
-        default:
-            break;
-        }
-        return GST_PAD_PROBE_OK;
-    }, this, nullptr);
-
-    notifyTrackOfStreamChanged();
</del><span class="cx"> }
</span><span class="cx"> 
</span><del>-InbandTextTrackPrivateGStreamer::InbandTextTrackPrivateGStreamer(gint index, GRefPtr<GstStream> stream)
</del><ins>+InbandTextTrackPrivateGStreamer::InbandTextTrackPrivateGStreamer(unsigned index, GRefPtr<GstStream>&& stream)
</ins><span class="cx">     : InbandTextTrackPrivate(CueFormat::WebVTT)
</span><del>-    , TrackPrivateBaseGStreamer(this, index, stream)
</del><ins>+    , TrackPrivateBaseGStreamer(TrackPrivateBaseGStreamer::TrackType::Text, this, index, WTFMove(stream))
</ins><span class="cx"> {
</span><del>-    m_streamId = gst_stream_get_stream_id(stream.get());
-    GST_INFO("Track %d got stream start for stream %s.", m_index, m_streamId.utf8().data());
</del><ins>+    m_id = gst_stream_get_stream_id(m_stream.get());
+    GST_INFO("Track %d got stream start for stream %s.", m_index, m_id.string().utf8().data());
</ins><span class="cx"> 
</span><del>-    GST_DEBUG("Stream %" GST_PTR_FORMAT, stream.get());
-    auto caps = adoptGRef(gst_stream_get_caps(stream.get()));
</del><ins>+    GST_DEBUG("Stream %" GST_PTR_FORMAT, m_stream.get());
+    auto caps = adoptGRef(gst_stream_get_caps(m_stream.get()));
</ins><span class="cx">     const char* mediaType = capsMediaType(caps.get());
</span><span class="cx">     m_kind = g_str_has_prefix(mediaType, "closedcaption/") ? Kind::Captions : Kind::Subtitles;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void InbandTextTrackPrivateGStreamer::disconnect()
-{
-    if (m_pad)
-        gst_pad_remove_probe(m_pad.get(), m_eventProbe);
-
-    TrackPrivateBaseGStreamer::disconnect();
-}
-
</del><span class="cx"> void InbandTextTrackPrivateGStreamer::handleSample(GRefPtr<GstSample> sample)
</span><span class="cx"> {
</span><span class="cx">     {
</span><span class="lines">@@ -94,14 +69,6 @@
</span><span class="cx">     });
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void InbandTextTrackPrivateGStreamer::streamChanged()
-{
-    RefPtr<InbandTextTrackPrivateGStreamer> protectedThis(this);
-    m_notifier->notify(MainThreadNotification::StreamChanged, [protectedThis] {
-        protectedThis->notifyTrackOfStreamChanged();
-    });
-}
-
</del><span class="cx"> void InbandTextTrackPrivateGStreamer::notifyTrackOfSample()
</span><span class="cx"> {
</span><span class="cx">     Vector<GRefPtr<GstSample> > samples;
</span><span class="lines">@@ -130,19 +97,6 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void InbandTextTrackPrivateGStreamer::notifyTrackOfStreamChanged()
-{
-    GRefPtr<GstEvent> event = adoptGRef(gst_pad_get_sticky_event(m_pad.get(),
-        GST_EVENT_STREAM_START, 0));
-    if (!event)
-        return;
-
-    const gchar* streamId;
-    gst_event_parse_stream_start(event.get(), &streamId);
-    GST_INFO("Track %d got stream start for stream %s.", m_index, streamId);
-    m_streamId = streamId;
-}
-
</del><span class="cx"> } // namespace WebCore
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(VIDEO) && USE(GSTREAMER)
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsgstreamerInbandTextTrackPrivateGStreamerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.h (281740 => 281741)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.h       2021-08-29 09:27:02 UTC (rev 281740)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.h  2021-08-29 09:50:28 UTC (rev 281741)
</span><span class="lines">@@ -27,11 +27,9 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(VIDEO) && USE(GSTREAMER)
</span><span class="cx"> 
</span><del>-#include "GStreamerCommon.h"
</del><span class="cx"> #include "InbandTextTrackPrivate.h"
</span><span class="cx"> #include "TrackPrivateBaseGStreamer.h"
</span><del>-#include <gst/gst.h>
-#include <wtf/Lock.h>
</del><ins>+#include <wtf/Forward.h>
</ins><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="lines">@@ -39,49 +37,38 @@
</span><span class="cx"> 
</span><span class="cx"> class InbandTextTrackPrivateGStreamer : public InbandTextTrackPrivate, public TrackPrivateBaseGStreamer {
</span><span class="cx"> public:
</span><del>-    static Ref<InbandTextTrackPrivateGStreamer> create(gint index, GRefPtr<GstPad> pad)
</del><ins>+    static Ref<InbandTextTrackPrivateGStreamer> create(unsigned index, GRefPtr<GstPad>&& pad, bool shouldHandleStreamStartEvent = true)
</ins><span class="cx">     {
</span><del>-        return adoptRef(*new InbandTextTrackPrivateGStreamer(index, pad));
</del><ins>+        return adoptRef(*new InbandTextTrackPrivateGStreamer(index, WTFMove(pad), shouldHandleStreamStartEvent));
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    static Ref<InbandTextTrackPrivateGStreamer> create(WeakPtr<MediaPlayerPrivateGStreamer>, gint index, GRefPtr<GstPad> pad)
</del><ins>+    static Ref<InbandTextTrackPrivateGStreamer> create(WeakPtr<MediaPlayerPrivateGStreamer>, unsigned index, GRefPtr<GstPad> pad)
</ins><span class="cx">     {
</span><del>-        return create(index, pad);
</del><ins>+        return create(index, WTFMove(pad));
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    static Ref<InbandTextTrackPrivateGStreamer> create(gint index, GRefPtr<GstStream> stream)
</del><ins>+    static Ref<InbandTextTrackPrivateGStreamer> create(unsigned index, GRefPtr<GstStream>&& stream)
</ins><span class="cx">     {
</span><del>-        return adoptRef(*new InbandTextTrackPrivateGStreamer(index, stream));
</del><ins>+        return adoptRef(*new InbandTextTrackPrivateGStreamer(index, WTFMove(stream)));
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    void disconnect() override;
</del><ins>+    Kind kind() const final { return m_kind; }
+    AtomString id() const final { return m_id; }
+    AtomString label() const final { return m_label; }
+    AtomString language() const final { return m_language; }
+    int trackIndex() const final { return m_index; }
</ins><span class="cx"> 
</span><del>-    Kind kind() const override { return m_kind; }
-
-    AtomString id() const override { return m_id; }
-    AtomString label() const override { return m_label; }
-    AtomString language() const override { return m_language; }
-
-    int trackIndex() const override { return m_index; }
-    String streamId() const { return m_streamId; }
-
</del><span class="cx">     void handleSample(GRefPtr<GstSample>);
</span><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    InbandTextTrackPrivateGStreamer(gint index, GRefPtr<GstPad>);
-    InbandTextTrackPrivateGStreamer(gint index, GRefPtr<GstStream>);
</del><ins>+    InbandTextTrackPrivateGStreamer(unsigned index, GRefPtr<GstPad>&&, bool shouldHandleStreamStartEvent);
+    InbandTextTrackPrivateGStreamer(unsigned index, GRefPtr<GstStream>&&);
</ins><span class="cx"> 
</span><del>-    void streamChanged();
-
</del><span class="cx">     void notifyTrackOfSample();
</span><del>-    void notifyTrackOfStreamChanged();
</del><span class="cx"> 
</span><del>-    gulong m_eventProbe;
</del><span class="cx">     Vector<GRefPtr<GstSample>> m_pendingSamples WTF_GUARDED_BY_LOCK(m_sampleMutex);
</span><del>-    String m_streamId;
</del><span class="cx">     Kind m_kind;
</span><span class="cx">     Lock m_sampleMutex;
</span><del>-    AtomString m_id;
</del><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsgstreamerMediaPlayerPrivateGStreamercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp (281740 => 281741)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp 2021-08-29 09:27:02 UTC (rev 281740)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp    2021-08-29 09:50:28 UTC (rev 281741)
</span><span class="lines">@@ -990,25 +990,25 @@
</span><span class="cx">     if (UNLIKELY(!m_pipeline || !m_source))
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    ASSERT(m_isLegacyPlaybin || isMediaSource());
</del><ins>+    ASSERT(m_isLegacyPlaybin);
</ins><span class="cx"> 
</span><del>-    enum TrackType { Audio = 0, Video = 1, Text = 2 };
</del><ins>+    using TrackType = TrackPrivateBaseGStreamer::TrackType;
</ins><span class="cx">     Variant<HashMap<AtomString, RefPtr<AudioTrackPrivateGStreamer>>*, HashMap<AtomString, RefPtr<VideoTrackPrivateGStreamer>>*, HashMap<AtomString, RefPtr<InbandTextTrackPrivateGStreamer>>*> variantTracks = static_cast<HashMap<AtomString, RefPtr<TrackPrivateType>>*>(0);
</span><span class="cx">     auto type(static_cast<TrackType>(variantTracks.index()));
</span><span class="cx">     const char* typeName;
</span><span class="cx">     bool* hasType;
</span><span class="cx">     switch (type) {
</span><del>-    case Audio:
</del><ins>+    case TrackType::Audio:
</ins><span class="cx">         typeName = "audio";
</span><span class="cx">         hasType = &m_hasAudio;
</span><span class="cx">         variantTracks = &m_audioTracks;
</span><span class="cx">         break;
</span><del>-    case Video:
</del><ins>+    case TrackType::Video:
</ins><span class="cx">         typeName = "video";
</span><span class="cx">         hasType = &m_hasVideo;
</span><span class="cx">         variantTracks = &m_videoTracks;
</span><span class="cx">         break;
</span><del>-    case Text:
</del><ins>+    case TrackType::Text:
</ins><span class="cx">         typeName = "text";
</span><span class="cx">         hasType = nullptr;
</span><span class="cx">         variantTracks = &m_textTracks;
</span><span class="lines">@@ -1019,18 +1019,14 @@
</span><span class="cx">     HashMap<AtomString, RefPtr<TrackPrivateType>>& tracks = *get<HashMap<AtomString, RefPtr<TrackPrivateType>>*>(variantTracks);
</span><span class="cx"> 
</span><span class="cx">     // Ignore notifications after a EOS. We don't want the tracks to disappear when the video is finished.
</span><del>-    if (m_isEndReached && (type == Audio || type == Video))
</del><ins>+    if (m_isEndReached && (type == TrackType::Audio || type == TrackType::Video))
</ins><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     unsigned numberOfTracks = 0;
</span><del>-    bool useMediaSource = isMediaSource();
-
</del><span class="cx">     StringPrintStream numberOfTracksProperty;
</span><span class="cx">     numberOfTracksProperty.printf("n-%s", typeName);
</span><ins>+    g_object_get(m_pipeline.get(), numberOfTracksProperty.toCString().data(), &numberOfTracks, nullptr);
</ins><span class="cx"> 
</span><del>-    GstElement* element = useMediaSource ? m_source.get() : m_pipeline.get();
-    g_object_get(element, numberOfTracksProperty.toCString().data(), &numberOfTracks, nullptr);
-
</del><span class="cx">     GST_INFO_OBJECT(pipeline(), "Media has %d %s tracks", numberOfTracks, typeName);
</span><span class="cx"> 
</span><span class="cx">     if (hasType) {
</span><span class="lines">@@ -1039,17 +1035,11 @@
</span><span class="cx">         if (oldHasType != *hasType)
</span><span class="cx">             m_player->characteristicChanged();
</span><span class="cx"> 
</span><del>-        if (*hasType && type == Video)
</del><ins>+        if (*hasType && type == TrackType::Video)
</ins><span class="cx">             m_player->sizeChanged();
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if (useMediaSource) {
-        GST_DEBUG_OBJECT(pipeline(), "Tracks managed by source element. Bailing out now.");
-        m_player->mediaEngineUpdated();
-        return;
-    }
-
-    Vector<String> validStreams;
</del><ins>+    Vector<AtomString> validStreams;
</ins><span class="cx">     StringPrintStream getPadProperty;
</span><span class="cx">     getPadProperty.printf("get-%s-pad", typeName);
</span><span class="cx"> 
</span><span class="lines">@@ -1058,7 +1048,9 @@
</span><span class="cx">         g_signal_emit_by_name(m_pipeline.get(), getPadProperty.toCString().data(), i, &pad.outPtr(), nullptr);
</span><span class="cx">         ASSERT(pad);
</span><span class="cx"> 
</span><del>-        String streamId = String(typeName).substring(0, 1).convertToASCIIUppercase() + String::number(i);
</del><ins>+        // The pad might not have a sticky stream-start event yet, so we can't use
+        // gst_pad_get_stream_id() here.
+        auto streamId = TrackPrivateBaseGStreamer::generateUniquePlaybin2StreamID(type, i);
</ins><span class="cx">         validStreams.append(streamId);
</span><span class="cx"> 
</span><span class="cx">         if (i < tracks.size()) {
</span><span class="lines">@@ -1073,8 +1065,8 @@
</span><span class="cx">             }
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        auto track = TrackPrivateType::create(makeWeakPtr(*this), i, pad);
-        if (!track->trackIndex() && (type == Audio || type == Video))
</del><ins>+        auto track = TrackPrivateType::create(makeWeakPtr(*this), i, WTFMove(pad));
+        if (!track->trackIndex() && (type == TrackType::Audio || type == TrackType::Video))
</ins><span class="cx">             track->setActive(true);
</span><span class="cx">         ASSERT(streamId == track->id());
</span><span class="cx">         tracks.add(streamId, track.copyRef());
</span><span class="lines">@@ -1081,9 +1073,15 @@
</span><span class="cx"> 
</span><span class="cx">         Variant<AudioTrackPrivate&, VideoTrackPrivate&, InbandTextTrackPrivate&> variantTrack(track.get());
</span><span class="cx">         switch (variantTrack.index()) {
</span><del>-        case Audio: m_player->addAudioTrack(get<AudioTrackPrivate&>(variantTrack)); break;
-        case Video: m_player->addVideoTrack(get<VideoTrackPrivate&>(variantTrack)); break;
-        case Text: m_player->addTextTrack(get<InbandTextTrackPrivate&>(variantTrack)); break;
</del><ins>+        case TrackType::Audio:
+            m_player->addAudioTrack(get<AudioTrackPrivate&>(variantTrack));
+            break;
+        case TrackType::Video:
+            m_player->addVideoTrack(get<VideoTrackPrivate&>(variantTrack));
+            break;
+        case TrackType::Text:
+            m_player->addTextTrack(get<InbandTextTrackPrivate&>(variantTrack));
+            break;
</ins><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -1143,7 +1141,7 @@
</span><span class="cx"> void MediaPlayerPrivateGStreamer::handleTextSample(GstSample* sample, const char* streamId)
</span><span class="cx"> {
</span><span class="cx">     for (auto& track : m_textTracks.values()) {
</span><del>-        if (!strcmp(track->streamId().utf8().data(), streamId)) {
</del><ins>+        if (!strcmp(track->id().string().utf8().data(), streamId)) {
</ins><span class="cx">             track->handleSample(sample);
</span><span class="cx">             return;
</span><span class="cx">         }
</span><span class="lines">@@ -1449,8 +1447,8 @@
</span><span class="cx">     unsigned videoTrackIndex = 0;
</span><span class="cx">     unsigned textTrackIndex = 0;
</span><span class="cx"> 
</span><del>-#define CREATE_TRACK(type, Type) G_STMT_START {                         \
-        RefPtr<Type##TrackPrivateGStreamer> track = Type##TrackPrivateGStreamer::create(makeWeakPtr(*this), type##TrackIndex, stream); \
</del><ins>+#define CREATE_TRACK(type, Type) G_STMT_START {                     \
+        RefPtr<Type##TrackPrivateGStreamer> track = Type##TrackPrivateGStreamer::create(makeWeakPtr(*this), type##TrackIndex, WTFMove(stream)); \
</ins><span class="cx">         auto trackId = track->id();                                 \
</span><span class="cx">         if (!type##TrackIndex) {                                    \
</span><span class="cx">             m_wanted##Type##StreamId = trackId;                     \
</span><span class="lines">@@ -1463,11 +1461,11 @@
</span><span class="cx">     } G_STMT_END
</span><span class="cx"> 
</span><span class="cx">     for (unsigned i = 0; i < length; i++) {
</span><del>-        auto* stream = gst_stream_collection_get_stream(streamCollection.get(), i);
-        String streamId(gst_stream_get_stream_id(stream));
-        auto type = gst_stream_get_stream_type(stream);
</del><ins>+        GRefPtr<GstStream> stream = gst_stream_collection_get_stream(streamCollection.get(), i);
+        const char* streamId = gst_stream_get_stream_id(stream.get());
+        auto type = gst_stream_get_stream_type(stream.get());
</ins><span class="cx"> 
</span><del>-        GST_DEBUG_OBJECT(pipeline(), "Inspecting %s track with ID %s", gst_stream_type_get_name(type), streamId.utf8().data());
</del><ins>+        GST_DEBUG_OBJECT(pipeline(), "Inspecting %s track with ID %s", gst_stream_type_get_name(type), streamId);
</ins><span class="cx"> 
</span><span class="cx">         if (type & GST_STREAM_TYPE_AUDIO) {
</span><span class="cx">             CREATE_TRACK(audio, Audio);
</span><span class="lines">@@ -1475,11 +1473,11 @@
</span><span class="cx">         } else if (type & GST_STREAM_TYPE_VIDEO && m_player->isVideoPlayer())
</span><span class="cx">             CREATE_TRACK(video, Video);
</span><span class="cx">         else if (type & GST_STREAM_TYPE_TEXT && !useMediaSource) {
</span><del>-            auto track = InbandTextTrackPrivateGStreamer::create(textTrackIndex++, stream);
</del><ins>+            auto track = InbandTextTrackPrivateGStreamer::create(textTrackIndex++, WTFMove(stream));
</ins><span class="cx">             m_textTracks.add(streamId, track.copyRef());
</span><span class="cx">             m_player->addTextTrack(track.get());
</span><span class="cx">         } else
</span><del>-            GST_WARNING("Unknown track type found for stream %s", streamId.utf8().data());
</del><ins>+            GST_WARNING("Unknown track type found for stream %s", streamId);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     m_hasAudio = !m_audioTracks.isEmpty();
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsgstreamerTrackPrivateBaseGStreamercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/gstreamer/TrackPrivateBaseGStreamer.cpp (281740 => 281741)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/gstreamer/TrackPrivateBaseGStreamer.cpp   2021-08-29 09:27:02 UTC (rev 281740)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/TrackPrivateBaseGStreamer.cpp      2021-08-29 09:50:28 UTC (rev 281741)
</span><span class="lines">@@ -30,12 +30,8 @@
</span><span class="cx"> #include "TrackPrivateBaseGStreamer.h"
</span><span class="cx"> 
</span><span class="cx"> #include "GStreamerCommon.h"
</span><del>-#include "Logging.h"
</del><span class="cx"> #include "TrackPrivateBase.h"
</span><del>-#include <glib-object.h>
-#include <gst/gst.h>
</del><span class="cx"> #include <gst/tag/tag.h>
</span><del>-#include <wtf/glib/GUniquePtr.h>
</del><span class="cx"> #include <wtf/text/CString.h>
</span><span class="cx"> 
</span><span class="cx"> GST_DEBUG_CATEGORY_EXTERN(webkit_media_player_debug);
</span><span class="lines">@@ -43,6 +39,25 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><ins>+AtomString TrackPrivateBaseGStreamer::generateUniquePlaybin2StreamID(TrackType trackType, unsigned index)
+{
+    auto prefix = [trackType]() -> char {
+        switch (trackType) {
+        case TrackPrivateBaseGStreamer::TrackType::Audio:
+            return 'A';
+        case TrackPrivateBaseGStreamer::TrackType::Video:
+            return 'V';
+        case TrackPrivateBaseGStreamer::TrackType::Text:
+            return 'T';
+        default:
+            ASSERT_NOT_REACHED();
+            return 'U';
+        }
+    }();
+
+    return makeString(prefix, index);
+}
+
</ins><span class="cx"> static GRefPtr<GstPad> findBestUpstreamPad(GRefPtr<GstPad> pad)
</span><span class="cx"> {
</span><span class="cx">     GRefPtr<GstPad> sinkPad = pad;
</span><span class="lines">@@ -56,11 +71,12 @@
</span><span class="cx">     return sinkPad;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-TrackPrivateBaseGStreamer::TrackPrivateBaseGStreamer(TrackPrivateBase* owner, gint index, GRefPtr<GstPad> pad)
</del><ins>+TrackPrivateBaseGStreamer::TrackPrivateBaseGStreamer(TrackType type, TrackPrivateBase* owner, unsigned index, GRefPtr<GstPad>&& pad, bool shouldHandleStreamStartEvent)
</ins><span class="cx">     : m_notifier(MainThreadNotifier<MainThreadNotification>::create())
</span><span class="cx">     , m_index(index)
</span><del>-    , m_eventProbe(0)
</del><ins>+    , m_type(type)
</ins><span class="cx">     , m_owner(owner)
</span><ins>+    , m_shouldHandleStreamStartEvent(shouldHandleStreamStartEvent)
</ins><span class="cx"> {
</span><span class="cx">     setPad(WTFMove(pad));
</span><span class="cx">     ASSERT(m_pad);
</span><span class="lines">@@ -69,14 +85,15 @@
</span><span class="cx">     tagsChanged();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-TrackPrivateBaseGStreamer::TrackPrivateBaseGStreamer(TrackPrivateBase* owner, gint index, GRefPtr<GstStream> stream)
</del><ins>+TrackPrivateBaseGStreamer::TrackPrivateBaseGStreamer(TrackType type, TrackPrivateBase* owner, unsigned index, GRefPtr<GstStream>&& stream)
</ins><span class="cx">     : m_notifier(MainThreadNotifier<MainThreadNotification>::create())
</span><span class="cx">     , m_index(index)
</span><del>-    , m_stream(stream)
-    , m_eventProbe(0)
</del><ins>+    , m_stream(WTFMove(stream))
+    , m_type(type)
</ins><span class="cx">     , m_owner(owner)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(m_stream);
</span><ins>+    m_id = gst_stream_get_stream_id(m_stream.get());
</ins><span class="cx"> 
</span><span class="cx">     // We can't call notifyTrackOfTagsChanged() directly, because we need tagsChanged() to setup m_tags.
</span><span class="cx">     tagsChanged();
</span><span class="lines">@@ -89,6 +106,8 @@
</span><span class="cx"> 
</span><span class="cx">     m_pad = WTFMove(pad);
</span><span class="cx">     m_bestUpstreamPad = findBestUpstreamPad(m_pad);
</span><ins>+    m_id = generateUniquePlaybin2StreamID(m_type, m_index);
+
</ins><span class="cx">     m_eventProbe = gst_pad_add_probe(m_bestUpstreamPad.get(), GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM, [] (GstPad*, GstPadProbeInfo* info, gpointer userData) -> GstPadProbeReturn {
</span><span class="cx">         auto* track = static_cast<TrackPrivateBaseGStreamer*>(userData);
</span><span class="cx">         switch (GST_EVENT_TYPE(gst_pad_probe_info_get_event(info))) {
</span><span class="lines">@@ -95,6 +114,10 @@
</span><span class="cx">         case GST_EVENT_TAG:
</span><span class="cx">             tagsChangedCallback(track);
</span><span class="cx">             break;
</span><ins>+        case GST_EVENT_STREAM_START:
+            if (track->m_shouldHandleStreamStartEvent)
+                track->streamChanged();
+            break;
</ins><span class="cx">         default:
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="lines">@@ -163,7 +186,9 @@
</span><span class="cx">         m_tags.swap(tags);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    m_notifier->notify(MainThreadNotification::TagsChanged, [this] { notifyTrackOfTagsChanged(); });
</del><ins>+    m_notifier->notify(MainThreadNotification::TagsChanged, [this] {
+        notifyTrackOfTagsChanged();
+    });
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool TrackPrivateBaseGStreamer::getLanguageCode(GstTagList* tags, AtomString& value)
</span><span class="lines">@@ -220,6 +245,23 @@
</span><span class="cx">         client->languageChanged(m_language);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void TrackPrivateBaseGStreamer::notifyTrackOfStreamChanged()
+{
+    GUniquePtr<char> streamId(gst_pad_get_stream_id(m_pad.get()));
+    if (!streamId)
+        return;
+
+    GST_INFO("Track %d got stream start for stream %s.", m_index, streamId.get());
+    m_id = streamId.get();
+}
+
+void TrackPrivateBaseGStreamer::streamChanged()
+{
+    m_notifier->notify(MainThreadNotification::StreamChanged, [this] {
+        notifyTrackOfStreamChanged();
+    });
+}
+
</ins><span class="cx"> } // namespace WebCore
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(VIDEO) && USE(GSTREAMER)
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsgstreamerTrackPrivateBaseGStreamerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/gstreamer/TrackPrivateBaseGStreamer.h (281740 => 281741)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/gstreamer/TrackPrivateBaseGStreamer.h     2021-08-29 09:27:02 UTC (rev 281740)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/TrackPrivateBaseGStreamer.h        2021-08-29 09:50:28 UTC (rev 281741)
</span><span class="lines">@@ -48,6 +48,8 @@
</span><span class="cx">         Unknown
</span><span class="cx">     };
</span><span class="cx"> 
</span><ins>+    WEBCORE_EXPORT static AtomString generateUniquePlaybin2StreamID(TrackType, unsigned index);
+
</ins><span class="cx">     GstPad* pad() const { return m_pad.get(); }
</span><span class="cx">     void setPad(GRefPtr<GstPad>&&);
</span><span class="cx"> 
</span><span class="lines">@@ -55,12 +57,9 @@
</span><span class="cx"> 
</span><span class="cx">     virtual void setActive(bool) { }
</span><span class="cx"> 
</span><del>-    void setIndex(int index) { m_index =  index; }
</del><ins>+    void setIndex(unsigned index) { m_index =  index; }
</ins><span class="cx"> 
</span><del>-    GstStream* stream()
-    {
-        return m_stream.get();
-    }
</del><ins>+    GstStream* stream() { return m_stream.get(); }
</ins><span class="cx"> 
</span><span class="cx">     // Used for MSE, where the initial caps of the pad are relevant for initializing the matching pad in the
</span><span class="cx">     // playback pipeline.
</span><span class="lines">@@ -68,10 +67,11 @@
</span><span class="cx">     const GRefPtr<GstCaps>& initialCaps() { return m_initialCaps; }
</span><span class="cx"> 
</span><span class="cx"> protected:
</span><del>-    TrackPrivateBaseGStreamer(TrackPrivateBase* owner, gint index, GRefPtr<GstPad>);
-    TrackPrivateBaseGStreamer(TrackPrivateBase* owner, gint index, GRefPtr<GstStream>);
</del><ins>+    TrackPrivateBaseGStreamer(TrackType, TrackPrivateBase*, unsigned index, GRefPtr<GstPad>&&, bool shouldHandleStreamStartEvent);
+    TrackPrivateBaseGStreamer(TrackType, TrackPrivateBase*, unsigned index, GRefPtr<GstStream>&&);
</ins><span class="cx"> 
</span><span class="cx">     void notifyTrackOfTagsChanged();
</span><ins>+    void notifyTrackOfStreamChanged();
</ins><span class="cx"> 
</span><span class="cx">     enum MainThreadNotification {
</span><span class="cx">         TagsChanged = 1 << 1,
</span><span class="lines">@@ -80,13 +80,14 @@
</span><span class="cx">     };
</span><span class="cx"> 
</span><span class="cx">     Ref<MainThreadNotifier<MainThreadNotification>> m_notifier;
</span><del>-    gint m_index;
</del><ins>+    unsigned m_index;
</ins><span class="cx">     AtomString m_label;
</span><span class="cx">     AtomString m_language;
</span><ins>+    AtomString m_id;
</ins><span class="cx">     GRefPtr<GstPad> m_pad;
</span><span class="cx">     GRefPtr<GstPad> m_bestUpstreamPad;
</span><span class="cx">     GRefPtr<GstStream> m_stream;
</span><del>-    gulong m_eventProbe;
</del><ins>+    unsigned long m_eventProbe { 0 };
</ins><span class="cx">     GRefPtr<GstCaps> m_initialCaps;
</span><span class="cx"> 
</span><span class="cx"> private:
</span><span class="lines">@@ -95,14 +96,18 @@
</span><span class="cx">     template<class StringType>
</span><span class="cx">     bool getTag(GstTagList* tags, const gchar* tagName, StringType& value);
</span><span class="cx"> 
</span><ins>+    void streamChanged();
+
</ins><span class="cx">     static void activeChangedCallback(TrackPrivateBaseGStreamer*);
</span><span class="cx">     static void tagsChangedCallback(TrackPrivateBaseGStreamer*);
</span><span class="cx"> 
</span><span class="cx">     void tagsChanged();
</span><span class="cx"> 
</span><ins>+    TrackType m_type;
</ins><span class="cx">     TrackPrivateBase* m_owner;
</span><span class="cx">     Lock m_tagMutex;
</span><span class="cx">     GRefPtr<GstTagList> m_tags;
</span><ins>+    bool m_shouldHandleStreamStartEvent { true };
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsgstreamerVideoTrackPrivateGStreamercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/gstreamer/VideoTrackPrivateGStreamer.cpp (281740 => 281741)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/gstreamer/VideoTrackPrivateGStreamer.cpp  2021-08-29 09:27:02 UTC (rev 281740)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/VideoTrackPrivateGStreamer.cpp     2021-08-29 09:50:28 UTC (rev 281741)
</span><span class="lines">@@ -30,31 +30,26 @@
</span><span class="cx"> #include "VideoTrackPrivateGStreamer.h"
</span><span class="cx"> 
</span><span class="cx"> #include "MediaPlayerPrivateGStreamer.h"
</span><del>-#include <glib-object.h>
</del><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><del>-VideoTrackPrivateGStreamer::VideoTrackPrivateGStreamer(WeakPtr<MediaPlayerPrivateGStreamer> player, gint index, GRefPtr<GstPad> pad)
-    : TrackPrivateBaseGStreamer(this, index, pad)
</del><ins>+VideoTrackPrivateGStreamer::VideoTrackPrivateGStreamer(WeakPtr<MediaPlayerPrivateGStreamer> player, unsigned index, GRefPtr<GstPad>&& pad, bool shouldHandleStreamStartEvent)
+    : TrackPrivateBaseGStreamer(TrackPrivateBaseGStreamer::TrackType::Video, this, index, WTFMove(pad), shouldHandleStreamStartEvent)
</ins><span class="cx">     , m_player(player)
</span><span class="cx"> {
</span><del>-    // FIXME: Get a real ID from the tkhd atom.
-    m_id = "V" + String::number(index);
</del><span class="cx"> }
</span><span class="cx"> 
</span><del>-VideoTrackPrivateGStreamer::VideoTrackPrivateGStreamer(WeakPtr<MediaPlayerPrivateGStreamer> player, gint index, GRefPtr<GstStream> stream)
-    : TrackPrivateBaseGStreamer(this, index, stream)
</del><ins>+VideoTrackPrivateGStreamer::VideoTrackPrivateGStreamer(WeakPtr<MediaPlayerPrivateGStreamer> player, unsigned index, GRefPtr<GstStream>&& stream)
+    : TrackPrivateBaseGStreamer(TrackPrivateBaseGStreamer::TrackType::Video, this, index, WTFMove(stream))
</ins><span class="cx">     , m_player(player)
</span><span class="cx"> {
</span><del>-    gint kind;
</del><ins>+    int kind;
</ins><span class="cx">     auto tags = adoptGRef(gst_stream_get_tags(m_stream.get()));
</span><span class="cx"> 
</span><span class="cx">     if (tags && gst_tag_list_get_int(tags.get(), "webkit-media-stream-kind", &kind) && kind == static_cast<int>(VideoTrackPrivate::Kind::Main)) {
</span><del>-        GstStreamFlags streamFlags = gst_stream_get_stream_flags(stream.get());
-        gst_stream_set_stream_flags(stream.get(), static_cast<GstStreamFlags>(streamFlags | GST_STREAM_FLAG_SELECT));
</del><ins>+        auto streamFlags = gst_stream_get_stream_flags(m_stream.get());
+        gst_stream_set_stream_flags(m_stream.get(), static_cast<GstStreamFlags>(streamFlags | GST_STREAM_FLAG_SELECT));
</ins><span class="cx">     }
</span><del>-
-    m_id = gst_stream_get_stream_id(stream.get());
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> VideoTrackPrivate::Kind VideoTrackPrivateGStreamer::kind() const
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsgstreamerVideoTrackPrivateGStreamerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/gstreamer/VideoTrackPrivateGStreamer.h (281740 => 281741)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/gstreamer/VideoTrackPrivateGStreamer.h    2021-08-29 09:27:02 UTC (rev 281740)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/VideoTrackPrivateGStreamer.h       2021-08-29 09:50:28 UTC (rev 281741)
</span><span class="lines">@@ -31,7 +31,6 @@
</span><span class="cx"> #include "TrackPrivateBaseGStreamer.h"
</span><span class="cx"> #include "VideoTrackPrivate.h"
</span><span class="cx"> 
</span><del>-#include <gst/gst.h>
</del><span class="cx"> #include <wtf/WeakPtr.h>
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="lines">@@ -39,34 +38,33 @@
</span><span class="cx"> 
</span><span class="cx"> class VideoTrackPrivateGStreamer final : public VideoTrackPrivate, public TrackPrivateBaseGStreamer {
</span><span class="cx"> public:
</span><del>-    static Ref<VideoTrackPrivateGStreamer> create(WeakPtr<MediaPlayerPrivateGStreamer> player, gint index, GRefPtr<GstPad> pad)
</del><ins>+    static Ref<VideoTrackPrivateGStreamer> create(WeakPtr<MediaPlayerPrivateGStreamer> player, unsigned index, GRefPtr<GstPad>&& pad, bool shouldHandleStreamStartEvent = true)
</ins><span class="cx">     {
</span><del>-        return adoptRef(*new VideoTrackPrivateGStreamer(player, index, pad));
</del><ins>+        return adoptRef(*new VideoTrackPrivateGStreamer(player, index, WTFMove(pad), shouldHandleStreamStartEvent));
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    static Ref<VideoTrackPrivateGStreamer> create(WeakPtr<MediaPlayerPrivateGStreamer> player, gint index, GRefPtr<GstStream> stream)
</del><ins>+    static Ref<VideoTrackPrivateGStreamer> create(WeakPtr<MediaPlayerPrivateGStreamer> player, unsigned index, GRefPtr<GstStream>&& stream)
</ins><span class="cx">     {
</span><del>-        return adoptRef(*new VideoTrackPrivateGStreamer(player, index, stream));
</del><ins>+        return adoptRef(*new VideoTrackPrivateGStreamer(player, index, WTFMove(stream)));
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     Kind kind() const final;
</span><span class="cx"> 
</span><del>-    void disconnect() override;
</del><ins>+    void disconnect() final;
</ins><span class="cx"> 
</span><del>-    void setSelected(bool) override;
-    void setActive(bool enabled) override { setSelected(enabled); }
</del><ins>+    void setSelected(bool) final;
+    void setActive(bool enabled) final { setSelected(enabled); }
</ins><span class="cx"> 
</span><del>-    int trackIndex() const override { return m_index; }
</del><ins>+    int trackIndex() const final { return m_index; }
</ins><span class="cx"> 
</span><del>-    AtomString id() const override { return m_id; }
-    AtomString label() const override { return m_label; }
-    AtomString language() const override { return m_language; }
</del><ins>+    AtomString id() const final { return m_id; }
+    AtomString label() const final { return m_label; }
+    AtomString language() const final { return m_language; }
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    VideoTrackPrivateGStreamer(WeakPtr<MediaPlayerPrivateGStreamer>, gint index, GRefPtr<GstPad>);
-    VideoTrackPrivateGStreamer(WeakPtr<MediaPlayerPrivateGStreamer>, gint index, GRefPtr<GstStream>);
</del><ins>+    VideoTrackPrivateGStreamer(WeakPtr<MediaPlayerPrivateGStreamer>, unsigned index, GRefPtr<GstPad>&&, bool shouldHandleStreamStartEvent);
+    VideoTrackPrivateGStreamer(WeakPtr<MediaPlayerPrivateGStreamer>, unsigned index, GRefPtr<GstStream>&&);
</ins><span class="cx"> 
</span><del>-    AtomString m_id;
</del><span class="cx">     WeakPtr<MediaPlayerPrivateGStreamer> m_player;
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsgstreamermseAppendPipelinecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/gstreamer/mse/AppendPipeline.cpp (281740 => 281741)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/gstreamer/mse/AppendPipeline.cpp  2021-08-29 09:27:02 UTC (rev 281740)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/mse/AppendPipeline.cpp     2021-08-29 09:50:28 UTC (rev 281741)
</span><span class="lines">@@ -753,21 +753,22 @@
</span><span class="cx">     RefPtr<WebCore::TrackPrivateBase> track;
</span><span class="cx">     TrackPrivateBaseGStreamer* gstreamerTrack = nullptr;
</span><span class="cx">     // FIXME: AudioTrackPrivateGStreamer etc. should probably use pads of the playback pipeline rather than the append pipeline.
</span><ins>+    GRefPtr<GstPad> pad(appendPipelineTrack.appsinkPad);
</ins><span class="cx">     switch (appendPipelineTrack.streamType) {
</span><span class="cx">     case StreamType::Audio: {
</span><del>-        auto specificTrack = AudioTrackPrivateGStreamer::create(makeWeakPtr(m_playerPrivate), trackIndex, appendPipelineTrack.appsinkPad);
</del><ins>+        auto specificTrack = AudioTrackPrivateGStreamer::create(makeWeakPtr(m_playerPrivate), trackIndex, WTFMove(pad), false);
</ins><span class="cx">         gstreamerTrack = specificTrack.ptr();
</span><span class="cx">         track = makeRefPtr(static_cast<TrackPrivateBase*>(specificTrack.ptr()));
</span><span class="cx">         break;
</span><span class="cx">     }
</span><span class="cx">     case StreamType::Video: {
</span><del>-        auto specificTrack = VideoTrackPrivateGStreamer::create(makeWeakPtr(m_playerPrivate), trackIndex, appendPipelineTrack.appsinkPad);
</del><ins>+        auto specificTrack = VideoTrackPrivateGStreamer::create(makeWeakPtr(m_playerPrivate), trackIndex, WTFMove(pad), false);
</ins><span class="cx">         gstreamerTrack = specificTrack.ptr();
</span><span class="cx">         track = makeRefPtr(static_cast<TrackPrivateBase*>(specificTrack.ptr()));
</span><span class="cx">         break;
</span><span class="cx">     }
</span><span class="cx">     case StreamType::Text: {
</span><del>-        auto specificTrack = InbandTextTrackPrivateGStreamer::create(trackIndex, appendPipelineTrack.appsinkPad);
</del><ins>+        auto specificTrack = InbandTextTrackPrivateGStreamer::create(trackIndex, WTFMove(pad), false);
</ins><span class="cx">         gstreamerTrack = specificTrack.ptr();
</span><span class="cx">         track = makeRefPtr(static_cast<TrackPrivateBase*>(specificTrack.ptr()));
</span><span class="cx">         break;
</span></span></pre>
</div>
</div>

</body>
</html>