Title: [228617] trunk
Revision
228617
Author
ph...@webkit.org
Date
2018-02-19 00:58:14 -0800 (Mon, 19 Feb 2018)

Log Message

[GStreamer] Playbin3 support
https://bugs.webkit.org/show_bug.cgi?id=182530

Reviewed by Xabier Rodriguez-Calvar.

.:

* Source/cmake/GStreamerDefinitions.cmake: New
USE(GSTREAMER_PLAYBIN3) feature. This should be enabled only for
very recent versions of GStreamer (1.14 at least) and is optional, for now.

Source/WebCore:

This patch introduces opt-in support for the playbin3 GStreamer
element. This new playback element is still considered
experimental but it can still be very useful for media assets
containing multiple tracks of the same type. In such scenario
audio/video decoders would be created only for the selected tracks
whereas playbin2 creates decoder for each track.

* platform/graphics/gstreamer/AudioTrackPrivateGStreamer.cpp: Take
a weak pointer of the media player instead of playbin and call the
player when enabling tracks. Also use the GstStream API instead of
inspecting the pad when playbin3 is used.
(WebCore::AudioTrackPrivateGStreamer::AudioTrackPrivateGStreamer):
(WebCore::AudioTrackPrivateGStreamer::disconnect):
(WebCore::AudioTrackPrivateGStreamer::markAsActive):
(WebCore::AudioTrackPrivateGStreamer::setEnabled):
* platform/graphics/gstreamer/AudioTrackPrivateGStreamer.h:
* platform/graphics/gstreamer/GRefPtrGStreamer.cpp: GstStream and
GstStreamCollection smart pointer support.
(WTF::adoptGRef):
(WTF::refGPtr<GstStream>):
(WTF::derefGPtr<GstStream>):
(WTF::refGPtr<GstStreamCollection>):
(WTF::derefGPtr<GstStreamCollection>):
* platform/graphics/gstreamer/GRefPtrGStreamer.h:
* platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.cpp:
Use the GstStream API instead of inspecting the pad when playbin3
is used.
(WebCore::InbandTextTrackPrivateGStreamer::InbandTextTrackPrivateGStreamer):
(WebCore::InbandTextTrackPrivateGStreamer::disconnect):
* platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.h:
(WebCore::InbandTextTrackPrivateGStreamer::create):
* platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:
(WebCore::MediaPlayerPrivateGStreamer::~MediaPlayerPrivateGStreamer):
m_{audio,video,text}Tracks are now hashmaps, which is a bit more
convenient to use than Vectors.
(WebCore::MediaPlayerPrivateGStreamer::updateTracks): Update our
tracks implementations depending on the streams stored in the
collection.
(WebCore::MediaPlayerPrivateGStreamer::enableTrack): Activate the
given track. This method is called by the TrackPrivate
implementations.
(WebCore::MediaPlayerPrivateGStreamer::notifyPlayerOfVideo):
Refactored legacy (playbin2) support for track hashmap storage.
(WebCore::MediaPlayerPrivateGStreamer::notifyPlayerOfAudio): Ditto.
(WebCore::MediaPlayerPrivateGStreamer::notifyPlayerOfText): Ditto.
(WebCore::MediaPlayerPrivateGStreamer::newTextSample): Use track hashmap storage.
(WebCore::MediaPlayerPrivateGStreamer::handleMessage): React on
playbin3 GstStream messages, store the collection provided and
activate the given selected streams accordingly.
(WebCore::MediaPlayerPrivateGStreamer::purgeInvalidAudioTracks): Invalidate tracks no longer needed.
(WebCore::MediaPlayerPrivateGStreamer::purgeInvalidVideoTracks): Ditto.
(WebCore::MediaPlayerPrivateGStreamer::purgeInvalidTextTracks): Ditto.
(WebCore::MediaPlayerPrivateGStreamer::sourceSetupCallback):
Refactoring, use source-setup signal instead of the source
property which is not supported in playbin3.
(WebCore::MediaPlayerPrivateGStreamer::uriDecodeBinElementAddedCallback):
Promoted logging messages, GST_TRACE should be used for very
frequent and less interesting messages.
(WebCore::MediaPlayerPrivateGStreamer::downloadBufferFileCreatedCallback): Ditto.
(WebCore::MediaPlayerPrivateGStreamer::sourceSetup): Called by the source-setup signal handler.
(WebCore::MediaPlayerPrivateGStreamer::setDownloadBuffering): Debugging message added.
(WebCore::MediaPlayerPrivateGStreamer::setPreload): Ditto.
(WebCore::MediaPlayerPrivateGStreamer::createGSTPlayBin): Create a
playbin3 element if USE(GSTREAMER_PLAYBIN3) was enabled and
connect to playbin2 signals otherwise.
* platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h:
(WebCore::MediaPlayerPrivateGStreamer::createWeakPtr): Promoted to public.
* platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.h:
New StreamCollectionChanged notification type, used the sub-class.
* platform/graphics/gstreamer/TrackPrivateBaseGStreamer.cpp:
(WebCore::TrackPrivateBaseGStreamer::TrackPrivateBaseGStreamer): Support for GstStream API.
(WebCore::TrackPrivateBaseGStreamer::disconnect): Clear GstStream too.
(WebCore::TrackPrivateBaseGStreamer::tagsChanged): Get tags from GstStream.
(WebCore::TrackPrivateBaseGStreamer::notifyTrackOfActiveChanged): No need to check m_pad twice.
(WebCore::TrackPrivateBaseGStreamer::notifyTrackOfTagsChanged): Ditto.
* platform/graphics/gstreamer/TrackPrivateBaseGStreamer.h:
* platform/graphics/gstreamer/VideoTrackPrivateGStreamer.cpp: Take
a weak pointer of the media player instead of playbin and call the
player when enabling tracks. Also use the GstStream API instead of
inspecting the pad when playbin3 is used.
(WebCore::VideoTrackPrivateGStreamer::VideoTrackPrivateGStreamer):
(WebCore::VideoTrackPrivateGStreamer::disconnect):
(WebCore::VideoTrackPrivateGStreamer::markAsActive):
(WebCore::VideoTrackPrivateGStreamer::setSelected):
* platform/graphics/gstreamer/VideoTrackPrivateGStreamer.h:
* platform/graphics/gstreamer/mse/AppendPipeline.cpp: Pass player pointer to track constructor.
(WebCore::AppendPipeline::connectDemuxerSrcPadToAppsink):
* platform/graphics/gstreamer/mse/MediaPlayerPrivateGStreamerMSE.cpp: Source-setup signal handler.
(WebCore::MediaPlayerPrivateGStreamerMSE::sourceSetup):
* platform/graphics/gstreamer/mse/MediaPlayerPrivateGStreamerMSE.h:

Modified Paths

Diff

Modified: trunk/ChangeLog (228616 => 228617)


--- trunk/ChangeLog	2018-02-19 08:51:26 UTC (rev 228616)
+++ trunk/ChangeLog	2018-02-19 08:58:14 UTC (rev 228617)
@@ -1,3 +1,14 @@
+2018-02-19  Philippe Normand  <pnorm...@igalia.com>
+
+        [GStreamer] Playbin3 support
+        https://bugs.webkit.org/show_bug.cgi?id=182530
+
+        Reviewed by Xabier Rodriguez-Calvar.
+
+        * Source/cmake/GStreamerDefinitions.cmake: New
+        USE(GSTREAMER_PLAYBIN3) feature. This should be enabled only for
+        very recent versions of GStreamer (1.14 at least) and is optional, for now.
+
 2018-02-18  Philippe Normand  <pnorm...@igalia.com>
 
         [GTK][WPE] Fullscreen video is broken

Modified: trunk/Source/WebCore/ChangeLog (228616 => 228617)


--- trunk/Source/WebCore/ChangeLog	2018-02-19 08:51:26 UTC (rev 228616)
+++ trunk/Source/WebCore/ChangeLog	2018-02-19 08:58:14 UTC (rev 228617)
@@ -1,3 +1,101 @@
+2018-02-19  Philippe Normand  <pnorm...@igalia.com>
+
+        [GStreamer] Playbin3 support
+        https://bugs.webkit.org/show_bug.cgi?id=182530
+
+        Reviewed by Xabier Rodriguez-Calvar.
+
+        This patch introduces opt-in support for the playbin3 GStreamer
+        element. This new playback element is still considered
+        experimental but it can still be very useful for media assets
+        containing multiple tracks of the same type. In such scenario
+        audio/video decoders would be created only for the selected tracks
+        whereas playbin2 creates decoder for each track.
+
+        * platform/graphics/gstreamer/AudioTrackPrivateGStreamer.cpp: Take
+        a weak pointer of the media player instead of playbin and call the
+        player when enabling tracks. Also use the GstStream API instead of
+        inspecting the pad when playbin3 is used.
+        (WebCore::AudioTrackPrivateGStreamer::AudioTrackPrivateGStreamer):
+        (WebCore::AudioTrackPrivateGStreamer::disconnect):
+        (WebCore::AudioTrackPrivateGStreamer::markAsActive):
+        (WebCore::AudioTrackPrivateGStreamer::setEnabled):
+        * platform/graphics/gstreamer/AudioTrackPrivateGStreamer.h:
+        * platform/graphics/gstreamer/GRefPtrGStreamer.cpp: GstStream and
+        GstStreamCollection smart pointer support.
+        (WTF::adoptGRef):
+        (WTF::refGPtr<GstStream>):
+        (WTF::derefGPtr<GstStream>):
+        (WTF::refGPtr<GstStreamCollection>):
+        (WTF::derefGPtr<GstStreamCollection>):
+        * platform/graphics/gstreamer/GRefPtrGStreamer.h:
+        * platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.cpp:
+        Use the GstStream API instead of inspecting the pad when playbin3
+        is used.
+        (WebCore::InbandTextTrackPrivateGStreamer::InbandTextTrackPrivateGStreamer):
+        (WebCore::InbandTextTrackPrivateGStreamer::disconnect):
+        * platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.h:
+        (WebCore::InbandTextTrackPrivateGStreamer::create):
+        * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:
+        (WebCore::MediaPlayerPrivateGStreamer::~MediaPlayerPrivateGStreamer):
+        m_{audio,video,text}Tracks are now hashmaps, which is a bit more
+        convenient to use than Vectors.
+        (WebCore::MediaPlayerPrivateGStreamer::updateTracks): Update our
+        tracks implementations depending on the streams stored in the
+        collection.
+        (WebCore::MediaPlayerPrivateGStreamer::enableTrack): Activate the
+        given track. This method is called by the TrackPrivate
+        implementations.
+        (WebCore::MediaPlayerPrivateGStreamer::notifyPlayerOfVideo):
+        Refactored legacy (playbin2) support for track hashmap storage.
+        (WebCore::MediaPlayerPrivateGStreamer::notifyPlayerOfAudio): Ditto.
+        (WebCore::MediaPlayerPrivateGStreamer::notifyPlayerOfText): Ditto.
+        (WebCore::MediaPlayerPrivateGStreamer::newTextSample): Use track hashmap storage.
+        (WebCore::MediaPlayerPrivateGStreamer::handleMessage): React on
+        playbin3 GstStream messages, store the collection provided and
+        activate the given selected streams accordingly.
+        (WebCore::MediaPlayerPrivateGStreamer::purgeInvalidAudioTracks): Invalidate tracks no longer needed.
+        (WebCore::MediaPlayerPrivateGStreamer::purgeInvalidVideoTracks): Ditto.
+        (WebCore::MediaPlayerPrivateGStreamer::purgeInvalidTextTracks): Ditto.
+        (WebCore::MediaPlayerPrivateGStreamer::sourceSetupCallback):
+        Refactoring, use source-setup signal instead of the source
+        property which is not supported in playbin3.
+        (WebCore::MediaPlayerPrivateGStreamer::uriDecodeBinElementAddedCallback):
+        Promoted logging messages, GST_TRACE should be used for very
+        frequent and less interesting messages.
+        (WebCore::MediaPlayerPrivateGStreamer::downloadBufferFileCreatedCallback): Ditto.
+        (WebCore::MediaPlayerPrivateGStreamer::sourceSetup): Called by the source-setup signal handler.
+        (WebCore::MediaPlayerPrivateGStreamer::setDownloadBuffering): Debugging message added.
+        (WebCore::MediaPlayerPrivateGStreamer::setPreload): Ditto.
+        (WebCore::MediaPlayerPrivateGStreamer::createGSTPlayBin): Create a
+        playbin3 element if USE(GSTREAMER_PLAYBIN3) was enabled and
+        connect to playbin2 signals otherwise.
+        * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h:
+        (WebCore::MediaPlayerPrivateGStreamer::createWeakPtr): Promoted to public.
+        * platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.h:
+        New StreamCollectionChanged notification type, used the sub-class.
+        * platform/graphics/gstreamer/TrackPrivateBaseGStreamer.cpp:
+        (WebCore::TrackPrivateBaseGStreamer::TrackPrivateBaseGStreamer): Support for GstStream API.
+        (WebCore::TrackPrivateBaseGStreamer::disconnect): Clear GstStream too.
+        (WebCore::TrackPrivateBaseGStreamer::tagsChanged): Get tags from GstStream.
+        (WebCore::TrackPrivateBaseGStreamer::notifyTrackOfActiveChanged): No need to check m_pad twice.
+        (WebCore::TrackPrivateBaseGStreamer::notifyTrackOfTagsChanged): Ditto.
+        * platform/graphics/gstreamer/TrackPrivateBaseGStreamer.h:
+        * platform/graphics/gstreamer/VideoTrackPrivateGStreamer.cpp: Take
+        a weak pointer of the media player instead of playbin and call the
+        player when enabling tracks. Also use the GstStream API instead of
+        inspecting the pad when playbin3 is used.
+        (WebCore::VideoTrackPrivateGStreamer::VideoTrackPrivateGStreamer):
+        (WebCore::VideoTrackPrivateGStreamer::disconnect):
+        (WebCore::VideoTrackPrivateGStreamer::markAsActive):
+        (WebCore::VideoTrackPrivateGStreamer::setSelected):
+        * platform/graphics/gstreamer/VideoTrackPrivateGStreamer.h:
+        * platform/graphics/gstreamer/mse/AppendPipeline.cpp: Pass player pointer to track constructor.
+        (WebCore::AppendPipeline::connectDemuxerSrcPadToAppsink):
+        * platform/graphics/gstreamer/mse/MediaPlayerPrivateGStreamerMSE.cpp: Source-setup signal handler.
+        (WebCore::MediaPlayerPrivateGStreamerMSE::sourceSetup):
+        * platform/graphics/gstreamer/mse/MediaPlayerPrivateGStreamerMSE.h:
+
 2018-02-19  Fujii Hironori  <hironori.fu...@sony.com>
 
         REGRESSION(r219298): RELEASE_ASSERT(!m_owningPointerForClose) fails in WebCore::IDBServer::UniqueIDBDatabase::scheduleShutdownForClose

Modified: trunk/Source/WebCore/platform/graphics/gstreamer/AudioTrackPrivateGStreamer.cpp (228616 => 228617)


--- trunk/Source/WebCore/platform/graphics/gstreamer/AudioTrackPrivateGStreamer.cpp	2018-02-19 08:51:26 UTC (rev 228616)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/AudioTrackPrivateGStreamer.cpp	2018-02-19 08:58:14 UTC (rev 228617)
@@ -29,13 +29,14 @@
 
 #include "AudioTrackPrivateGStreamer.h"
 
+#include "MediaPlayerPrivateGStreamer.h"
 #include <glib-object.h>
 
 namespace WebCore {
 
-AudioTrackPrivateGStreamer::AudioTrackPrivateGStreamer(GRefPtr<GstElement> playbin, gint index, GRefPtr<GstPad> pad)
+AudioTrackPrivateGStreamer::AudioTrackPrivateGStreamer(WeakPtr<MediaPlayerPrivateGStreamer> player, gint index, GRefPtr<GstPad> pad)
     : TrackPrivateBaseGStreamer(this, index, pad)
-    , m_playbin(playbin)
+    , m_player(player)
 {
     // FIXME: Get a real ID from the tkhd atom.
     m_id = "A" + String::number(index);
@@ -42,12 +43,27 @@
     notifyTrackOfActiveChanged();
 }
 
+#if USE(GSTREAMER_PLAYBIN3)
+AudioTrackPrivateGStreamer::AudioTrackPrivateGStreamer(WeakPtr<MediaPlayerPrivateGStreamer> player, gint index, GRefPtr<GstStream> stream)
+    : TrackPrivateBaseGStreamer(this, index, stream)
+    , m_player(player)
+{
+    m_id = gst_stream_get_stream_id(stream.get());
+    notifyTrackOfActiveChanged();
+}
+#endif
+
 void AudioTrackPrivateGStreamer::disconnect()
 {
-    m_playbin.clear();
+    m_player = nullptr;
     TrackPrivateBaseGStreamer::disconnect();
 }
 
+void AudioTrackPrivateGStreamer::markAsActive()
+{
+    AudioTrackPrivate::setEnabled(true);
+}
+
 void AudioTrackPrivateGStreamer::setEnabled(bool enabled)
 {
     if (enabled == this->enabled())
@@ -54,8 +70,8 @@
         return;
     AudioTrackPrivate::setEnabled(enabled);
 
-    if (enabled && m_playbin)
-        g_object_set(m_playbin.get(), "current-audio", m_index, nullptr);
+    if (enabled && m_player)
+        m_player->enableTrack(TrackPrivateBaseGStreamer::TrackType::Audio, m_index);
 }
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/platform/graphics/gstreamer/AudioTrackPrivateGStreamer.h (228616 => 228617)


--- trunk/Source/WebCore/platform/graphics/gstreamer/AudioTrackPrivateGStreamer.h	2018-02-19 08:51:26 UTC (rev 228616)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/AudioTrackPrivateGStreamer.h	2018-02-19 08:58:14 UTC (rev 228617)
@@ -23,8 +23,7 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef AudioTrackPrivateGStreamer_h
-#define AudioTrackPrivateGStreamer_h
+#pragma once
 
 #if ENABLE(VIDEO) && USE(GSTREAMER) && ENABLE(VIDEO_TRACK)
 
@@ -31,19 +30,30 @@
 #include "AudioTrackPrivate.h"
 #include "GRefPtrGStreamer.h"
 #include "TrackPrivateBaseGStreamer.h"
+#include <gst/gst.h>
+#include <wtf/WeakPtr.h>
 
 namespace WebCore {
+class MediaPlayerPrivateGStreamer;
 
 class AudioTrackPrivateGStreamer final : public AudioTrackPrivate, public TrackPrivateBaseGStreamer {
 public:
-    static RefPtr<AudioTrackPrivateGStreamer> create(GRefPtr<GstElement> playbin, gint index, GRefPtr<GstPad> pad)
+    static RefPtr<AudioTrackPrivateGStreamer> create(WeakPtr<MediaPlayerPrivateGStreamer> player, gint index, GRefPtr<GstPad> pad)
     {
-        return adoptRef(*new AudioTrackPrivateGStreamer(playbin, index, pad));
+        return adoptRef(*new AudioTrackPrivateGStreamer(player, index, pad));
     }
 
+#if USE(GSTREAMER_PLAYBIN3)
+    static RefPtr<AudioTrackPrivateGStreamer> create(WeakPtr<MediaPlayerPrivateGStreamer> player, gint index, GRefPtr<GstStream> stream)
+    {
+        return adoptRef(*new AudioTrackPrivateGStreamer(player, index, stream));
+    }
+#endif
+
     void disconnect() override;
 
     void setEnabled(bool) override;
+    void markAsActive();
     void setActive(bool enabled) override { setEnabled(enabled); }
 
     int trackIndex() const override { return m_index; }
@@ -53,14 +63,15 @@
     AtomicString language() const override { return m_language; }
 
 private:
-    AudioTrackPrivateGStreamer(GRefPtr<GstElement> playbin, gint index, GRefPtr<GstPad>);
+    AudioTrackPrivateGStreamer(WeakPtr<MediaPlayerPrivateGStreamer>, gint index, GRefPtr<GstPad>);
+#if USE(GSTREAMER_PLAYBIN3)
+    AudioTrackPrivateGStreamer(WeakPtr<MediaPlayerPrivateGStreamer>, gint index, GRefPtr<GstStream>);
+#endif
 
     AtomicString m_id;
-    GRefPtr<GstElement> m_playbin;
+    WeakPtr<MediaPlayerPrivateGStreamer> m_player;
 };
 
 } // namespace WebCore
 
 #endif // ENABLE(VIDEO) && USE(GSTREAMER) && ENABLE(VIDEO_TRACK)
-
-#endif // AudioTrackPrivateGStreamer_h

Modified: trunk/Source/WebCore/platform/graphics/gstreamer/GRefPtrGStreamer.cpp (228616 => 228617)


--- trunk/Source/WebCore/platform/graphics/gstreamer/GRefPtrGStreamer.cpp	2018-02-19 08:51:26 UTC (rev 228616)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/GRefPtrGStreamer.cpp	2018-02-19 08:58:14 UTC (rev 228617)
@@ -353,6 +353,48 @@
         gst_query_unref(ptr);
 }
 
+#if USE(GSTREAMER_PLAYBIN3)
+template <> GRefPtr<GstStream> adoptGRef(GstStream* ptr)
+{
+    ASSERT(!ptr || !g_object_is_floating(ptr));
+    return GRefPtr<GstStream>(ptr, GRefPtrAdopt);
+}
+
+template <> GstStream* refGPtr<GstStream>(GstStream* ptr)
+{
+    if (ptr)
+        gst_object_ref_sink(GST_OBJECT_CAST(ptr));
+
+    return ptr;
+}
+
+template <> void derefGPtr<GstStream>(GstStream* ptr)
+{
+    if (ptr)
+        gst_object_unref(ptr);
+}
+
+template <> GRefPtr<GstStreamCollection> adoptGRef(GstStreamCollection* ptr)
+{
+    ASSERT(!ptr || !g_object_is_floating(ptr));
+    return GRefPtr<GstStreamCollection>(ptr, GRefPtrAdopt);
+}
+
+template <> GstStreamCollection* refGPtr<GstStreamCollection>(GstStreamCollection* ptr)
+{
+    if (ptr)
+        gst_object_ref_sink(GST_OBJECT_CAST(ptr));
+
+    return ptr;
+}
+
+template <> void derefGPtr<GstStreamCollection>(GstStreamCollection* ptr)
+{
+    if (ptr)
+        gst_object_unref(ptr);
+}
+#endif
+
 template <> GRefPtr<WebKitVideoSink> adoptGRef(WebKitVideoSink* ptr)
 {
     ASSERT(!ptr || !g_object_is_floating(ptr));

Modified: trunk/Source/WebCore/platform/graphics/gstreamer/GRefPtrGStreamer.h (228616 => 228617)


--- trunk/Source/WebCore/platform/graphics/gstreamer/GRefPtrGStreamer.h	2018-02-19 08:51:26 UTC (rev 228616)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/GRefPtrGStreamer.h	2018-02-19 08:58:14 UTC (rev 228617)
@@ -17,8 +17,8 @@
  *  Boston, MA 02110-1301, USA.
  */
 
-#ifndef GRefPtrGStreamer_h
-#define GRefPtrGStreamer_h
+#pragma once
+
 #if USE(GSTREAMER)
 
 #include <wtf/glib/GRefPtr.h>
@@ -43,6 +43,11 @@
 typedef struct _WebKitVideoSink WebKitVideoSink;
 typedef struct _WebKitWebSrc WebKitWebSrc;
 
+#if USE(GSTREAMER_PLAYBIN3)
+typedef struct _GstStream GstStream;
+typedef struct _GstStreamCollection GstStreamCollection;
+#endif
+
 #if USE(GSTREAMER_GL)
 typedef struct _GstGLDisplay GstGLDisplay;
 typedef struct _GstGLContext GstGLContext;
@@ -127,6 +132,16 @@
 template<> WebKitWebSrc* refGPtr<WebKitWebSrc>(WebKitWebSrc* ptr);
 template<> void derefGPtr<WebKitWebSrc>(WebKitWebSrc* ptr);
 
+#if USE(GSTREAMER_PLAYBIN3)
+template<> GRefPtr<GstStream> adoptGRef(GstStream*);
+template<> GstStream* refGPtr<GstStream>(GstStream*);
+template<> void derefGPtr<GstStream>(GstStream*);
+
+template<> GRefPtr<GstStreamCollection> adoptGRef(GstStreamCollection*);
+template<> GstStreamCollection* refGPtr<GstStreamCollection>(GstStreamCollection*);
+template<> void derefGPtr<GstStreamCollection>(GstStreamCollection*);
+#endif
+
 #if USE(GSTREAMER_GL)
 template<> GRefPtr<GstGLDisplay> adoptGRef(GstGLDisplay* ptr);
 template<> GstGLDisplay* refGPtr<GstGLDisplay>(GstGLDisplay* ptr);
@@ -140,5 +155,3 @@
 } // namespace WTF
 
 #endif // USE(GSTREAMER)
-
-#endif // GRefPtrGStreamer_h

Modified: trunk/Source/WebCore/platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.cpp (228616 => 228617)


--- trunk/Source/WebCore/platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.cpp	2018-02-19 08:51:26 UTC (rev 228616)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.cpp	2018-02-19 08:58:14 UTC (rev 228617)
@@ -40,7 +40,8 @@
 namespace WebCore {
 
 InbandTextTrackPrivateGStreamer::InbandTextTrackPrivateGStreamer(gint index, GRefPtr<GstPad> pad)
-    : InbandTextTrackPrivate(WebVTT), TrackPrivateBaseGStreamer(this, index, pad)
+    : InbandTextTrackPrivate(WebVTT)
+    , TrackPrivateBaseGStreamer(this, index, pad)
 {
     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);
@@ -57,13 +58,21 @@
     notifyTrackOfStreamChanged();
 }
 
+#if USE(GSTREAMER_PLAYBIN3)
+InbandTextTrackPrivateGStreamer::InbandTextTrackPrivateGStreamer(gint index, GRefPtr<GstStream> stream)
+    : InbandTextTrackPrivate(WebVTT)
+    , TrackPrivateBaseGStreamer(this, index, stream)
+{
+    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());
+}
+#endif
+
 void InbandTextTrackPrivateGStreamer::disconnect()
 {
-    if (!m_pad)
-        return;
+    if (m_pad)
+        gst_pad_remove_probe(m_pad.get(), m_eventProbe);
 
-    gst_pad_remove_probe(m_pad.get(), m_eventProbe);
-
     TrackPrivateBaseGStreamer::disconnect();
 }
 

Modified: trunk/Source/WebCore/platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.h (228616 => 228617)


--- trunk/Source/WebCore/platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.h	2018-02-19 08:51:26 UTC (rev 228616)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.h	2018-02-19 08:58:14 UTC (rev 228617)
@@ -23,8 +23,7 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef InbandTextTrackPrivateGStreamer_h
-#define InbandTextTrackPrivateGStreamer_h
+#pragma once
 
 #if ENABLE(VIDEO) && USE(GSTREAMER) && ENABLE(VIDEO_TRACK)
 
@@ -31,12 +30,12 @@
 #include "GRefPtrGStreamer.h"
 #include "InbandTextTrackPrivate.h"
 #include "TrackPrivateBaseGStreamer.h"
+#include <gst/gst.h>
 #include <wtf/Lock.h>
 
 namespace WebCore {
 
 class MediaPlayerPrivateGStreamer;
-typedef struct _GstSample GstSample;
 
 class InbandTextTrackPrivateGStreamer : public InbandTextTrackPrivate, public TrackPrivateBaseGStreamer {
 public:
@@ -45,6 +44,13 @@
         return adoptRef(*new InbandTextTrackPrivateGStreamer(index, pad));
     }
 
+#if USE(GSTREAMER_PLAYBIN3)
+    static Ref<InbandTextTrackPrivateGStreamer> create(gint index, GRefPtr<GstStream> stream)
+    {
+        return adoptRef(*new InbandTextTrackPrivateGStreamer(index, stream));
+    }
+#endif
+
     void disconnect() override;
 
     AtomicString label() const override { return m_label; }
@@ -57,6 +63,9 @@
 
 private:
     InbandTextTrackPrivateGStreamer(gint index, GRefPtr<GstPad>);
+#if USE(GSTREAMER_PLAYBIN3)
+    InbandTextTrackPrivateGStreamer(gint index, GRefPtr<GstStream>);
+#endif
 
     void streamChanged();
 
@@ -64,7 +73,7 @@
     void notifyTrackOfStreamChanged();
 
     gulong m_eventProbe;
-    Vector<GRefPtr<GstSample> > m_pendingSamples;
+    Vector<GRefPtr<GstSample>> m_pendingSamples;
     String m_streamId;
     Lock m_sampleMutex;
 };
@@ -72,5 +81,3 @@
 } // namespace WebCore
 
 #endif // ENABLE(VIDEO) && USE(GSTREAMER) && ENABLE(VIDEO_TRACK)
-
-#endif // InbandTextTrackPrivateGStreamer_h

Modified: trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp (228616 => 228617)


--- trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp	2018-02-19 08:51:26 UTC (rev 228616)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp	2018-02-19 08:58:14 UTC (rev 228617)
@@ -166,14 +166,14 @@
 MediaPlayerPrivateGStreamer::~MediaPlayerPrivateGStreamer()
 {
 #if ENABLE(VIDEO_TRACK)
-    for (size_t i = 0; i < m_audioTracks.size(); ++i)
-        m_audioTracks[i]->disconnect();
+    for (auto& track : m_audioTracks.values())
+        track->disconnect();
 
-    for (size_t i = 0; i < m_textTracks.size(); ++i)
-        m_textTracks[i]->disconnect();
+    for (auto& track : m_textTracks.values())
+        track->disconnect();
 
-    for (size_t i = 0; i < m_videoTracks.size(); ++i)
-        m_videoTracks[i]->disconnect();
+    for (auto& track : m_videoTracks.values())
+        track->disconnect();
 #endif
     if (m_fillTimer.isActive())
         m_fillTimer.stop();
@@ -612,6 +612,158 @@
     return m_seeking;
 }
 
+#if USE(GSTREAMER_PLAYBIN3)
+void MediaPlayerPrivateGStreamer::updateTracks()
+{
+    ASSERT(!m_isLegacyPlaybin);
+
+    bool useMediaSource = isMediaSource();
+    unsigned length = gst_stream_collection_get_size(m_streamCollection.get());
+    Vector<String> validAudioStreams;
+    Vector<String> validVideoStreams;
+    Vector<String> validTextStreams;
+    for (unsigned i = 0; i < length; i++) {
+        GRefPtr<GstStream> stream = gst_stream_collection_get_stream(m_streamCollection.get(), i);
+        String streamId(gst_stream_get_stream_id(stream.get()));
+        GstStreamType type = gst_stream_get_stream_type(stream.get());
+        GST_DEBUG("Inspecting %s track with ID %s", gst_stream_type_get_name(type), streamId.utf8().data());
+        if (type & GST_STREAM_TYPE_AUDIO) {
+            validAudioStreams.append(streamId);
+#if ENABLE(VIDEO_TRACK)
+            if (!useMediaSource) {
+                unsigned localIndex = i - validVideoStreams.size() - validTextStreams.size();
+                if (localIndex < m_audioTracks.size()) {
+                    if (m_audioTracks.contains(streamId))
+                        continue;
+                }
+
+                RefPtr<AudioTrackPrivateGStreamer> track = AudioTrackPrivateGStreamer::create(createWeakPtr(), i, stream);
+                m_audioTracks.add(track->id(), track);
+                m_player->addAudioTrack(*track);
+            }
+#endif
+        } else if (type & GST_STREAM_TYPE_VIDEO) {
+            validVideoStreams.append(streamId);
+#if ENABLE(VIDEO_TRACK)
+            if (!useMediaSource) {
+                unsigned localIndex = i - validAudioStreams.size() - validTextStreams.size();
+                if (localIndex < m_videoTracks.size()) {
+                    if (m_videoTracks.contains(streamId))
+                        continue;
+                }
+
+                RefPtr<VideoTrackPrivateGStreamer> track = VideoTrackPrivateGStreamer::create(createWeakPtr(), i, stream);
+                m_videoTracks.add(track->id(), track);
+                m_player->addVideoTrack(*track);
+            }
+#endif
+        } else if (type & GST_STREAM_TYPE_TEXT) {
+            validTextStreams.append(streamId);
+#if ENABLE(VIDEO_TRACK)
+            if (!useMediaSource) {
+                unsigned localIndex = i - validVideoStreams.size() - validAudioStreams.size();
+                if (localIndex < m_textTracks.size()) {
+                    if (m_textTracks.contains(streamId))
+                        continue;
+                }
+
+                RefPtr<InbandTextTrackPrivateGStreamer> track = InbandTextTrackPrivateGStreamer::create(localIndex, stream);
+                m_textTracks.add(streamId, track);
+                m_player->addTextTrack(*track);
+            }
+#endif
+        } else
+            GST_WARNING("Unknown track type found for stream %s", streamId.utf8().data());
+    }
+
+    GST_INFO("Media has %u video tracks, %u audio tracks and %u text tracks", validVideoStreams.size(), validAudioStreams.size(), validTextStreams.size());
+
+    bool oldHasAudio = m_hasAudio;
+    bool oldHasVideo = m_hasVideo;
+    m_hasAudio = !validAudioStreams.isEmpty();
+    m_hasVideo = !validVideoStreams.isEmpty();
+    if ((oldHasVideo != m_hasVideo) || (oldHasAudio != m_hasAudio))
+        m_player->characteristicChanged();
+
+    if (m_hasVideo)
+        m_player->sizeChanged();
+
+    if (useMediaSource) {
+        GST_DEBUG("Tracks managed by source element. Bailing out now.");
+        m_player->client().mediaPlayerEngineUpdated(m_player);
+        return;
+    }
+
+#if ENABLE(VIDEO_TRACK)
+    purgeInvalidAudioTracks(validAudioStreams);
+    purgeInvalidVideoTracks(validVideoStreams);
+    purgeInvalidTextTracks(validTextStreams);
+#endif
+
+    m_player->client().mediaPlayerEngineUpdated(m_player);
+}
+#endif
+
+void MediaPlayerPrivateGStreamer::enableTrack(TrackPrivateBaseGStreamer::TrackType trackType, unsigned index)
+{
+    const char* propertyName;
+    const char* trackTypeAsString;
+    GList* selectedStreams = nullptr;
+
+    switch (trackType) {
+    case TrackPrivateBaseGStreamer::TrackType::Audio:
+        propertyName = "current-audio";
+        trackTypeAsString = "audio";
+        if (!m_currentTextStreamId.isEmpty())
+            selectedStreams = g_list_append(selectedStreams, g_strdup(m_currentTextStreamId.utf8().data()));
+        if (!m_currentVideoStreamId.isEmpty())
+            selectedStreams = g_list_append(selectedStreams, g_strdup(m_currentVideoStreamId.utf8().data()));
+        break;
+    case TrackPrivateBaseGStreamer::TrackType::Video:
+        propertyName = "current-video";
+        trackTypeAsString = "video";
+        if (!m_currentAudioStreamId.isEmpty())
+            selectedStreams = g_list_append(selectedStreams, g_strdup(m_currentAudioStreamId.utf8().data()));
+        if (!m_currentTextStreamId.isEmpty())
+            selectedStreams = g_list_append(selectedStreams, g_strdup(m_currentTextStreamId.utf8().data()));
+        break;
+    case TrackPrivateBaseGStreamer::TrackType::Text:
+        propertyName = "current-text";
+        trackTypeAsString = "text";
+        if (!m_currentAudioStreamId.isEmpty())
+            selectedStreams = g_list_append(selectedStreams, g_strdup(m_currentAudioStreamId.utf8().data()));
+        if (!m_currentVideoStreamId.isEmpty())
+            selectedStreams = g_list_append(selectedStreams, g_strdup(m_currentVideoStreamId.utf8().data()));
+        break;
+    case TrackPrivateBaseGStreamer::TrackType::Unknown:
+    default:
+        ASSERT_NOT_REACHED();
+    }
+
+    GST_INFO("Enabling %s track with index: %lu", trackTypeAsString, index);
+    // FIXME: Remove isMediaSource() test below when fixing https://bugs.webkit.org/show_bug.cgi?id=182531
+    if (m_isLegacyPlaybin || isMediaSource()) {
+        GstElement* element = isMediaSource() ? m_source.get() : m_pipeline.get();
+        g_object_set(element, propertyName, index, nullptr);
+    }
+#if USE(GSTREAMER_PLAYBIN3)
+    else {
+        GstStream* stream = gst_stream_collection_get_stream(m_streamCollection.get(), index);
+        if (stream) {
+            String streamId = gst_stream_get_stream_id(stream);
+            selectedStreams = g_list_append(selectedStreams, g_strdup(streamId.utf8().data()));
+        } else
+            GST_WARNING("%s stream %lu not found", trackTypeAsString, index);
+
+        // TODO: MSE GstStream API support: https://bugs.webkit.org/show_bug.cgi?id=182531
+        gst_element_send_event(m_pipeline.get(), gst_event_new_select_streams(selectedStreams));
+    }
+#endif
+
+    if (selectedStreams)
+        g_list_free_full(selectedStreams, reinterpret_cast<GDestroyNotify>(g_free));
+}
+
 void MediaPlayerPrivateGStreamer::videoChangedCallback(MediaPlayerPrivateGStreamer* player)
 {
     player->m_notifier->notify(MainThreadNotification::VideoChanged, [player] { player->notifyPlayerOfVideo(); });
@@ -622,6 +774,8 @@
     if (UNLIKELY(!m_pipeline || !m_source))
         return;
 
+    ASSERT(m_isLegacyPlaybin || isMediaSource());
+
     gint numTracks = 0;
     bool useMediaSource = isMediaSource();
     GstElement* element = useMediaSource ? m_source.get() : m_pipeline.get();
@@ -644,29 +798,30 @@
     }
 
 #if ENABLE(VIDEO_TRACK)
+    Vector<String> validVideoStreams;
     for (gint i = 0; i < numTracks; ++i) {
         GRefPtr<GstPad> pad;
         g_signal_emit_by_name(m_pipeline.get(), "get-video-pad", i, &pad.outPtr(), nullptr);
         ASSERT(pad);
 
+        String streamId = "V" + String::number(i);
+        validVideoStreams.append(streamId);
         if (i < static_cast<gint>(m_videoTracks.size())) {
-            RefPtr<VideoTrackPrivateGStreamer> existingTrack = m_videoTracks[i];
-            existingTrack->setIndex(i);
-            if (existingTrack->pad() == pad)
-                continue;
+            RefPtr<VideoTrackPrivateGStreamer> existingTrack = m_videoTracks.get(streamId);
+            if (existingTrack) {
+                existingTrack->setIndex(i);
+                if (existingTrack->pad() == pad)
+                    continue;
+            }
         }
 
-        RefPtr<VideoTrackPrivateGStreamer> track = VideoTrackPrivateGStreamer::create(m_pipeline, i, pad);
-        m_videoTracks.append(track);
+        RefPtr<VideoTrackPrivateGStreamer> track = VideoTrackPrivateGStreamer::create(createWeakPtr(), i, pad);
+        ASSERT(streamId == track->id());
+        m_videoTracks.add(streamId, track);
         m_player->addVideoTrack(*track);
     }
 
-    while (static_cast<gint>(m_videoTracks.size()) > numTracks) {
-        RefPtr<VideoTrackPrivateGStreamer> track = m_videoTracks.last();
-        track->disconnect();
-        m_videoTracks.removeLast();
-        m_player->removeVideoTrack(*track);
-    }
+    purgeInvalidVideoTracks(validVideoStreams);
 #endif
 
     m_player->client().mediaPlayerEngineUpdated(m_player);
@@ -693,6 +848,8 @@
     if (UNLIKELY(!m_pipeline || !m_source))
         return;
 
+    ASSERT(m_isLegacyPlaybin || isMediaSource());
+
     gint numTracks = 0;
     bool useMediaSource = isMediaSource();
     GstElement* element = useMediaSource ? m_source.get() : m_pipeline.get();
@@ -711,29 +868,30 @@
     }
 
 #if ENABLE(VIDEO_TRACK)
+    Vector<String> validAudioStreams;
     for (gint i = 0; i < numTracks; ++i) {
         GRefPtr<GstPad> pad;
         g_signal_emit_by_name(m_pipeline.get(), "get-audio-pad", i, &pad.outPtr(), nullptr);
         ASSERT(pad);
 
+        String streamId = "A" + String::number(i);
+        validAudioStreams.append(streamId);
         if (i < static_cast<gint>(m_audioTracks.size())) {
-            RefPtr<AudioTrackPrivateGStreamer> existingTrack = m_audioTracks[i];
-            existingTrack->setIndex(i);
-            if (existingTrack->pad() == pad)
-                continue;
+            RefPtr<AudioTrackPrivateGStreamer> existingTrack = m_audioTracks.get(streamId);
+            if (existingTrack) {
+                existingTrack->setIndex(i);
+                if (existingTrack->pad() == pad)
+                    continue;
+            }
         }
 
-        RefPtr<AudioTrackPrivateGStreamer> track = AudioTrackPrivateGStreamer::create(m_pipeline, i, pad);
-        m_audioTracks.insert(i, track);
+        RefPtr<AudioTrackPrivateGStreamer> track = AudioTrackPrivateGStreamer::create(createWeakPtr(), i, pad);
+        ASSERT(streamId == track->id());
+        m_audioTracks.add(streamId, track);
         m_player->addAudioTrack(*track);
     }
 
-    while (static_cast<gint>(m_audioTracks.size()) > numTracks) {
-        RefPtr<AudioTrackPrivateGStreamer> track = m_audioTracks.last();
-        track->disconnect();
-        m_audioTracks.removeLast();
-        m_player->removeAudioTrack(*track);
-    }
+    purgeInvalidAudioTracks(validAudioStreams);
 #endif
 
     m_player->client().mediaPlayerEngineUpdated(m_player);
@@ -750,6 +908,8 @@
     if (UNLIKELY(!m_pipeline || !m_source))
         return;
 
+    ASSERT(m_isLegacyPlaybin || isMediaSource());
+
     gint numTracks = 0;
     bool useMediaSource = isMediaSource();
     GstElement* element = useMediaSource ? m_source.get() : m_pipeline.get();
@@ -760,29 +920,35 @@
         return;
     }
 
+    Vector<String> validTextStreams;
     for (gint i = 0; i < numTracks; ++i) {
         GRefPtr<GstPad> pad;
         g_signal_emit_by_name(m_pipeline.get(), "get-text-pad", i, &pad.outPtr(), nullptr);
         ASSERT(pad);
 
+        GRefPtr<GstEvent> event = adoptGRef(gst_pad_get_sticky_event(pad.get(), GST_EVENT_STREAM_START, 0));
+        if (!event)
+            continue;
+
+        const char* streamId;
+        gst_event_parse_stream_start(event.get(), &streamId);
+
+        validTextStreams.append(streamId);
         if (i < static_cast<gint>(m_textTracks.size())) {
-            RefPtr<InbandTextTrackPrivateGStreamer> existingTrack = m_textTracks[i];
-            existingTrack->setIndex(i);
-            if (existingTrack->pad() == pad)
-                continue;
+            RefPtr<InbandTextTrackPrivateGStreamer> existingTrack = m_textTracks.get(streamId);
+            if (existingTrack) {
+                existingTrack->setIndex(i);
+                if (existingTrack->pad() == pad)
+                    continue;
+            }
         }
 
         RefPtr<InbandTextTrackPrivateGStreamer> track = InbandTextTrackPrivateGStreamer::create(i, pad);
-        m_textTracks.insert(i, track);
+        m_textTracks.add(streamId, track);
         m_player->addTextTrack(*track);
     }
 
-    while (static_cast<gint>(m_textTracks.size()) > numTracks) {
-        RefPtr<InbandTextTrackPrivateGStreamer> track = m_textTracks.last();
-        track->disconnect();
-        m_textTracks.removeLast();
-        m_player->removeTextTrack(*track);
-    }
+    purgeInvalidTextTracks(validTextStreams);
 }
 
 GstFlowReturn MediaPlayerPrivateGStreamer::newTextSampleCallback(MediaPlayerPrivateGStreamer* player)
@@ -808,8 +974,8 @@
         const gchar* id;
         gst_event_parse_stream_start(streamStartEvent.get(), &id);
         for (size_t i = 0; i < m_textTracks.size(); ++i) {
-            RefPtr<InbandTextTrackPrivateGStreamer> track = m_textTracks[i];
-            if (track->streamId() == id) {
+            RefPtr<InbandTextTrackPrivateGStreamer> track = m_textTracks.get(id);
+            if (track) {
                 track->handleSample(sample);
                 found = true;
                 break;
@@ -1097,6 +1263,61 @@
         gst_tag_list_unref(tags);
         break;
     }
+#if USE(GSTREAMER_PLAYBIN3)
+    case GST_MESSAGE_STREAM_COLLECTION: {
+        GRefPtr<GstStreamCollection> collection;
+        gst_message_parse_stream_collection(message, &collection.outPtr());
+
+        if (collection) {
+            m_streamCollection.swap(collection);
+            m_notifier->notify(MainThreadNotification::StreamCollectionChanged, [this] {
+                this->updateTracks();
+            });
+        }
+        break;
+    }
+    case GST_MESSAGE_STREAMS_SELECTED: {
+        GRefPtr<GstStreamCollection> collection;
+        gst_message_parse_streams_selected(message, &collection.outPtr());
+
+        if (!collection)
+            break;
+
+        m_streamCollection.swap(collection);
+        m_currentAudioStreamId = "";
+        m_currentVideoStreamId = "";
+        m_currentTextStreamId = "";
+
+        unsigned length = gst_message_streams_selected_get_size(message);
+        for (unsigned i = 0; i < length; i++) {
+            GRefPtr<GstStream> stream = adoptGRef(gst_message_streams_selected_get_stream(message, i));
+            if (!stream)
+                continue;
+            GstStreamType type = gst_stream_get_stream_type(stream.get());
+            String streamId(gst_stream_get_stream_id(stream.get()));
+
+            GST_DEBUG("Selecting %s track with ID: %s", gst_stream_type_get_name(type), streamId.utf8().data());
+            // Playbin3 can send more than one selected stream of the same type
+            // but there's no priority or ordering system in place, so we assume
+            // the selected stream is the last one as reported by playbin3.
+            if (type & GST_STREAM_TYPE_AUDIO) {
+                m_currentAudioStreamId = streamId;
+                auto track = m_audioTracks.get(m_currentAudioStreamId);
+                ASSERT(track);
+                track->markAsActive();
+            } else if (type & GST_STREAM_TYPE_VIDEO) {
+                m_currentVideoStreamId = streamId;
+                auto track = m_videoTracks.get(m_currentVideoStreamId);
+                ASSERT(track);
+                track->markAsActive();
+            } else if (type & GST_STREAM_TYPE_TEXT)
+                m_currentTextStreamId = streamId;
+            else
+                GST_WARNING("Unknown stream type with stream-id %s", streamId);
+        }
+        break;
+    }
+#endif
     default:
         GST_DEBUG("Unhandled GStreamer message type: %s", GST_MESSAGE_TYPE_NAME(message));
         break;
@@ -1213,6 +1434,42 @@
     for (GList* i = gst_toc_entry_get_sub_entries(entry); i; i = i->next)
         processTableOfContentsEntry(static_cast<GstTocEntry*>(i->data));
 }
+
+void MediaPlayerPrivateGStreamer::purgeInvalidAudioTracks(Vector<String> validTrackIds)
+{
+    for (auto audioTrackId : m_audioTracks.keys()) {
+        if (validTrackIds.contains(audioTrackId))
+            continue;
+        auto track = m_audioTracks.get(audioTrackId);
+        track->disconnect();
+        m_player->removeAudioTrack(*track);
+        m_audioTracks.remove(audioTrackId);
+    }
+}
+
+void MediaPlayerPrivateGStreamer::purgeInvalidVideoTracks(Vector<String> validTrackIds)
+{
+    for (auto videoTrackId : m_videoTracks.keys()) {
+        if (validTrackIds.contains(videoTrackId))
+            continue;
+        auto track = m_videoTracks.get(videoTrackId);
+        track->disconnect();
+        m_player->removeVideoTrack(*track);
+        m_videoTracks.remove(videoTrackId);
+    }
+}
+
+void MediaPlayerPrivateGStreamer::purgeInvalidTextTracks(Vector<String> validTrackIds)
+{
+    for (auto textTrackId : m_textTracks.keys()) {
+        if (validTrackIds.contains(textTrackId))
+            continue;
+        auto track = m_textTracks.get(textTrackId);
+        track->disconnect();
+        m_player->removeTextTrack(*track);
+        m_textTracks.remove(textTrackId);
+    }
+}
 #endif
 
 static int findHLSQueue(const GValue* item)
@@ -1400,9 +1657,9 @@
     return m_totalBytes;
 }
 
-void MediaPlayerPrivateGStreamer::sourceChangedCallback(MediaPlayerPrivateGStreamer* player)
+void MediaPlayerPrivateGStreamer::sourceSetupCallback(MediaPlayerPrivateGStreamer* player, GstElement* sourceElement)
 {
-    player->sourceChanged();
+    player->sourceSetup(sourceElement);
 }
 
 void MediaPlayerPrivateGStreamer::uriDecodeBinElementAddedCallback(GstBin* bin, GstElement* element, MediaPlayerPrivateGStreamer* player)
@@ -1419,7 +1676,7 @@
 
     GUniquePtr<char> newDownloadTemplate(g_build_filename(G_DIR_SEPARATOR_S, "var", "tmp", "WebKit-Media-XXXXXX", nullptr));
     g_object_set(element, "temp-template", newDownloadTemplate.get(), nullptr);
-    GST_TRACE("Reconfigured file download template from '%s' to '%s'", oldDownloadTemplate.get(), newDownloadTemplate.get());
+    GST_DEBUG("Reconfigured file download template from '%s' to '%s'", oldDownloadTemplate.get(), newDownloadTemplate.get());
 
     player->purgeOldDownloadFiles(oldDownloadTemplate.get());
 }
@@ -1439,7 +1696,7 @@
         return;
     }
 
-    GST_TRACE("Unlinked media temporary file %s after creation", downloadFile.get());
+    GST_DEBUG("Unlinked media temporary file %s after creation", downloadFile.get());
 }
 
 void MediaPlayerPrivateGStreamer::purgeOldDownloadFiles(const char* downloadFileTemplate)
@@ -1461,13 +1718,14 @@
     }
 }
 
-void MediaPlayerPrivateGStreamer::sourceChanged()
+void MediaPlayerPrivateGStreamer::sourceSetup(GstElement* sourceElement)
 {
+    GST_DEBUG("Source element set-up for %s", GST_ELEMENT_NAME(sourceElement));
+
     if (WEBKIT_IS_WEB_SRC(m_source.get()) && GST_OBJECT_PARENT(m_source.get()))
         g_signal_handlers_disconnect_by_func(GST_ELEMENT_PARENT(m_source.get()), reinterpret_cast<gpointer>(uriDecodeBinElementAddedCallback), this);
 
-    m_source.clear();
-    g_object_get(m_pipeline.get(), "source", &m_source.outPtr(), nullptr);
+    m_source = sourceElement;
 
     if (WEBKIT_IS_WEB_SRC(m_source.get())) {
         webKitWebSrcSetMediaPlayer(WEBKIT_WEB_SRC(m_source.get()), m_player);
@@ -2019,8 +2277,10 @@
     unsigned flagDownload = getGstPlayFlag("download");
 
     // We don't want to stop downloading if we already started it.
-    if (flags & flagDownload && m_readyState > MediaPlayer::HaveNothing && !m_resetPipeline)
+    if (flags & flagDownload && m_readyState > MediaPlayer::HaveNothing && !m_resetPipeline) {
+        GST_DEBUG("Download already started, not starting again");
         return;
+    }
 
     bool shouldDownload = !isLiveStream() && m_preload == MediaPlayer::Auto;
     if (shouldDownload) {
@@ -2036,6 +2296,7 @@
 
 void MediaPlayerPrivateGStreamer::setPreload(MediaPlayer::Preload preload)
 {
+    GST_DEBUG("Setting preload to %s", convertEnumerationToString(preload).utf8().data());
     if (preload == MediaPlayer::Auto && isLiveStream())
         return;
 
@@ -2140,9 +2401,17 @@
 
     // gst_element_factory_make() returns a floating reference so
     // we should not adopt.
+#if USE(GSTREAMER_PLAYBIN3)
+    m_isLegacyPlaybin = false;
+    setPipeline(gst_element_factory_make("playbin3", "play"));
+#else
+    m_isLegacyPlaybin = true;
     setPipeline(gst_element_factory_make("playbin", "play"));
+#endif
     setStreamVolumeElement(GST_STREAM_VOLUME(m_pipeline.get()));
 
+    GST_INFO("Using legacy playbin element: %s", boolForPrinting(m_isLegacyPlaybin));
+
     // Let also other listeners subscribe to (application) messages in this bus.
     GRefPtr<GstBus> bus = adoptGRef(gst_pipeline_get_bus(GST_PIPELINE(m_pipeline.get())));
     gst_bus_add_signal_watch_full(bus.get(), RunLoopSourcePriority::RunLoopDispatcher);
@@ -2150,11 +2419,15 @@
 
     g_object_set(m_pipeline.get(), "mute", m_player->muted(), nullptr);
 
-    g_signal_connect_swapped(m_pipeline.get(), "notify::source", G_CALLBACK(sourceChangedCallback), this);
-    g_signal_connect_swapped(m_pipeline.get(), "video-changed", G_CALLBACK(videoChangedCallback), this);
-    g_signal_connect_swapped(m_pipeline.get(), "audio-changed", G_CALLBACK(audioChangedCallback), this);
+    g_signal_connect_swapped(m_pipeline.get(), "source-setup", G_CALLBACK(sourceSetupCallback), this);
+    if (m_isLegacyPlaybin) {
+        g_signal_connect_swapped(m_pipeline.get(), "video-changed", G_CALLBACK(videoChangedCallback), this);
+        g_signal_connect_swapped(m_pipeline.get(), "audio-changed", G_CALLBACK(audioChangedCallback), this);
+    }
+
 #if ENABLE(VIDEO_TRACK)
-    g_signal_connect_swapped(m_pipeline.get(), "text-changed", G_CALLBACK(textChangedCallback), this);
+    if (m_isLegacyPlaybin)
+        g_signal_connect_swapped(m_pipeline.get(), "text-changed", G_CALLBACK(textChangedCallback), this);
 
     GstElement* textCombiner = webkitTextCombinerNew();
     ASSERT(textCombiner);

Modified: trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h (228616 => 228617)


--- trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h	2018-02-19 08:51:26 UTC (rev 228616)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h	2018-02-19 08:58:14 UTC (rev 228617)
@@ -22,8 +22,8 @@
  * Boston, MA 02110-1301, USA.
  */
 
-#ifndef MediaPlayerPrivateGStreamer_h
-#define MediaPlayerPrivateGStreamer_h
+#pragma once
+
 #if ENABLE(VIDEO) && USE(GSTREAMER)
 
 #include "GRefPtrGStreamer.h"
@@ -36,13 +36,11 @@
 #include <wtf/RunLoop.h>
 #include <wtf/WeakPtr.h>
 
-#if ENABLE(VIDEO_TRACK) && USE(GSTREAMER_MPEGTS)
+#if ENABLE(VIDEO_TRACK)
+#include "TrackPrivateBaseGStreamer.h"
 #include <wtf/text/AtomicStringHash.h>
 #endif
 
-typedef struct _GstBuffer GstBuffer;
-typedef struct _GstMessage GstMessage;
-typedef struct _GstElement GstElement;
 typedef struct _GstMpegtsSection GstMpegtsSection;
 
 namespace WebCore {
@@ -67,6 +65,8 @@
     explicit MediaPlayerPrivateGStreamer(MediaPlayer*);
     virtual ~MediaPlayerPrivateGStreamer();
 
+    WeakPtr<MediaPlayerPrivateGStreamer> createWeakPtr() { return m_weakPtrFactory.createWeakPtr(*this); }
+
     static void registerMediaEngine(MediaEngineRegistrar);
     void handleMessage(GstMessage*);
     void handlePluginInstallerResult(GstInstallPluginsReturn);
@@ -116,7 +116,7 @@
     virtual void durationChanged();
     void loadingFailed(MediaPlayer::NetworkState);
 
-    virtual void sourceChanged();
+    virtual void sourceSetup(GstElement*);
 
     GstElement* audioSink() const override;
     virtual void configurePlaySink() { }
@@ -131,6 +131,8 @@
 
     bool isLiveStream() const override { return m_isStreaming; }
 
+    void enableTrack(TrackPrivateBaseGStreamer::TrackType, unsigned index);
+
 private:
     static void getSupportedTypes(HashSet<String, ASCIICaseInsensitiveHash>&);
     static MediaPlayer::SupportsType supportsType(const MediaEngineSupportParameters&);
@@ -137,8 +139,6 @@
 
     static bool isAvailable();
 
-    WeakPtr<MediaPlayerPrivateGStreamer> createWeakPtr() { return m_weakPtrFactory.createWeakPtr(*this); }
-
     GstElement* createAudioSink() override;
 
     MediaTime playbackPosition() const;
@@ -153,12 +153,17 @@
 
     virtual void setDownloadBuffering();
     void processBufferingStats(GstMessage*);
-#if ENABLE(VIDEO_TRACK) && USE(GSTREAMER_MPEGTS)
+#if ENABLE(VIDEO_TRACK)
+#if USE(GSTREAMER_MPEGTS)
     void processMpegTsSection(GstMpegtsSection*);
 #endif
-#if ENABLE(VIDEO_TRACK)
+
     void processTableOfContents(GstMessage*);
     void processTableOfContentsEntry(GstTocEntry*);
+
+    void purgeInvalidAudioTracks(Vector<String> validTrackIds);
+    void purgeInvalidVideoTracks(Vector<String> validTrackIds);
+    void purgeInvalidTextTracks(Vector<String> validTrackIds);
 #endif
     virtual bool doSeek(const MediaTime& position, float rate, GstSeekFlags seekType);
     virtual void updatePlaybackRate();
@@ -173,6 +178,10 @@
 
     void setPlaybinURL(const URL& urlString);
 
+#if USE(GSTREAMER_PLAYBIN3)
+    void updateTracks();
+#endif
+
 protected:
     void cacheDuration();
 
@@ -214,7 +223,7 @@
 
     static void setAudioStreamPropertiesCallback(MediaPlayerPrivateGStreamer*, GObject*);
 
-    static void sourceChangedCallback(MediaPlayerPrivateGStreamer*);
+    static void sourceSetupCallback(MediaPlayerPrivateGStreamer*, GstElement*);
     static void videoChangedCallback(MediaPlayerPrivateGStreamer*);
     static void videoSinkCapsChangedCallback(MediaPlayerPrivateGStreamer*);
     static void audioChangedCallback(MediaPlayerPrivateGStreamer*);
@@ -247,6 +256,13 @@
     mutable unsigned long long m_totalBytes;
     URL m_url;
     bool m_preservesPitch;
+    bool m_isLegacyPlaybin;
+#if USE(GSTREAMER_PLAYBIN3)
+    GRefPtr<GstStreamCollection> m_streamCollection;
+#endif
+    String m_currentAudioStreamId;
+    String m_currentVideoStreamId;
+    String m_currentTextStreamId;
 #if ENABLE(WEB_AUDIO)
     std::unique_ptr<AudioSourceProviderGStreamer> m_audioSourceProvider;
 #endif
@@ -254,17 +270,16 @@
     GRefPtr<GstElement> m_downloadBuffer;
     RefPtr<MediaPlayerRequestInstallMissingPluginsCallback> m_missingPluginsCallback;
 #if ENABLE(VIDEO_TRACK)
-    Vector<RefPtr<AudioTrackPrivateGStreamer>> m_audioTracks;
-    Vector<RefPtr<InbandTextTrackPrivateGStreamer>> m_textTracks;
-    Vector<RefPtr<VideoTrackPrivateGStreamer>> m_videoTracks;
+    HashMap<AtomicString, RefPtr<AudioTrackPrivateGStreamer>> m_audioTracks;
+    HashMap<AtomicString, RefPtr<InbandTextTrackPrivateGStreamer>> m_textTracks;
+    HashMap<AtomicString, RefPtr<VideoTrackPrivateGStreamer>> m_videoTracks;
     RefPtr<InbandMetadataTextTrackPrivateGStreamer> m_chaptersTrack;
-#endif
-#if ENABLE(VIDEO_TRACK) && USE(GSTREAMER_MPEGTS)
+#if USE(GSTREAMER_MPEGTS)
     HashMap<AtomicString, RefPtr<InbandMetadataTextTrackPrivateGStreamer>> m_metadataTracks;
 #endif
+#endif
     virtual bool isMediaSource() const { return false; }
 };
 }
 
 #endif // USE(GSTREAMER)
-#endif

Modified: trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.h (228616 => 228617)


--- trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.h	2018-02-19 08:51:26 UTC (rev 228616)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.h	2018-02-19 08:58:14 UTC (rev 228617)
@@ -209,7 +209,10 @@
 #if ENABLE(VIDEO_TRACK)
         TextChanged = 1 << 5,
 #endif
-        SizeChanged = 1 << 6
+        SizeChanged = 1 << 6,
+#if ENABLE(GSTREAMER_PLAYBIN3)
+        StreamCollectionChanged = 1 << 7
+#endif
     };
 
     WeakPtrFactory<MediaPlayerPrivateGStreamerBase> m_weakPtrFactory;

Modified: trunk/Source/WebCore/platform/graphics/gstreamer/TrackPrivateBaseGStreamer.cpp (228616 => 228617)


--- trunk/Source/WebCore/platform/graphics/gstreamer/TrackPrivateBaseGStreamer.cpp	2018-02-19 08:51:26 UTC (rev 228616)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/TrackPrivateBaseGStreamer.cpp	2018-02-19 08:58:14 UTC (rev 228617)
@@ -54,11 +54,24 @@
     g_signal_connect_swapped(m_pad.get(), "notify::active", G_CALLBACK(activeChangedCallback), this);
     g_signal_connect_swapped(m_pad.get(), "notify::tags", G_CALLBACK(tagsChangedCallback), this);
 
-    // We can't call notifyTrackOfTagsChanged() directly, because we need tagsChanged()
-    // to setup m_tags.
+    // We can't call notifyTrackOfTagsChanged() directly, because we need tagsChanged() to setup m_tags.
     tagsChanged();
 }
 
+#if USE(GSTREAMER_PLAYBIN3)
+TrackPrivateBaseGStreamer::TrackPrivateBaseGStreamer(TrackPrivateBase* owner, gint index, GRefPtr<GstStream> stream)
+    : m_notifier(MainThreadNotifier<MainThreadNotification>::create())
+    , m_index(index)
+    , m_stream(stream)
+    , m_owner(owner)
+{
+    ASSERT(m_stream);
+
+    // We can't call notifyTrackOfTagsChanged() directly, because we need tagsChanged() to setup m_tags.
+    tagsChanged();
+}
+#endif
+
 TrackPrivateBaseGStreamer::~TrackPrivateBaseGStreamer()
 {
     disconnect();
@@ -67,14 +80,20 @@
 
 void TrackPrivateBaseGStreamer::disconnect()
 {
+    m_tags.clear();
+
+#if USE(GSTREAMER_PLAYBIN3)
+    if (m_stream)
+        m_stream.clear();
+#endif
+
+    m_notifier->cancelPendingNotifications();
+
     if (!m_pad)
         return;
 
-    m_notifier->cancelPendingNotifications();
     g_signal_handlers_disconnect_matched(m_pad.get(), G_SIGNAL_MATCH_DATA, 0, 0, nullptr, nullptr, this);
-
     m_pad.clear();
-    m_tags.clear();
 }
 
 void TrackPrivateBaseGStreamer::activeChangedCallback(TrackPrivateBaseGStreamer* track)
@@ -90,11 +109,20 @@
 void TrackPrivateBaseGStreamer::tagsChanged()
 {
     GRefPtr<GstTagList> tags;
-    if (g_object_class_find_property(G_OBJECT_GET_CLASS(m_pad.get()), "tags"))
-        g_object_get(m_pad.get(), "tags", &tags.outPtr(), nullptr);
+    if (m_pad) {
+        if (g_object_class_find_property(G_OBJECT_GET_CLASS(m_pad.get()), "tags"))
+            g_object_get(m_pad.get(), "tags", &tags.outPtr(), nullptr);
+        else
+            tags = adoptGRef(gst_tag_list_new_empty());
+    }
+#if USE(GSTREAMER_PLAYBIN3)
+    else if (m_stream)
+        tags = adoptGRef(gst_stream_get_tags(m_stream.get()));
+#endif
     else
         tags = adoptGRef(gst_tag_list_new_empty());
 
+    GST_DEBUG("Inspecting track at index %d with tags: %" GST_PTR_FORMAT, m_index, tags.get());
     {
         LockHolder lock(m_tagMutex);
         m_tags.swap(tags);
@@ -109,7 +137,7 @@
         return;
 
     gboolean active = false;
-    if (m_pad && g_object_class_find_property(G_OBJECT_GET_CLASS(m_pad.get()), "active"))
+    if (g_object_class_find_property(G_OBJECT_GET_CLASS(m_pad.get()), "active"))
         g_object_get(m_pad.get(), "active", &active, nullptr);
 
     setActive(active);
@@ -143,9 +171,6 @@
 
 void TrackPrivateBaseGStreamer::notifyTrackOfTagsChanged()
 {
-    if (!m_pad)
-        return;
-
     TrackPrivateBaseClient* client = m_owner->client();
     if (!client)
         return;

Modified: trunk/Source/WebCore/platform/graphics/gstreamer/TrackPrivateBaseGStreamer.h (228616 => 228617)


--- trunk/Source/WebCore/platform/graphics/gstreamer/TrackPrivateBaseGStreamer.h	2018-02-19 08:51:26 UTC (rev 228616)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/TrackPrivateBaseGStreamer.h	2018-02-19 08:58:14 UTC (rev 228617)
@@ -23,13 +23,13 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef TrackPrivateBaseGStreamer_h
-#define TrackPrivateBaseGStreamer_h
+#pragma once
 
 #if ENABLE(VIDEO) && USE(GSTREAMER) && ENABLE(VIDEO_TRACK)
 
 #include "GRefPtrGStreamer.h"
 #include "MainThreadNotifier.h"
+#include <gst/gst.h>
 #include <wtf/Lock.h>
 #include <wtf/text/WTFString.h>
 
@@ -41,6 +41,13 @@
 public:
     virtual ~TrackPrivateBaseGStreamer();
 
+    enum TrackType {
+        Audio,
+        Video,
+        Text,
+        Unknown
+    };
+
     GstPad* pad() const { return m_pad.get(); }
 
     virtual void disconnect();
@@ -51,7 +58,9 @@
 
 protected:
     TrackPrivateBaseGStreamer(TrackPrivateBase* owner, gint index, GRefPtr<GstPad>);
-
+#if USE(GSTREAMER_PLAYBIN3)
+    TrackPrivateBaseGStreamer(TrackPrivateBase* owner, gint index, GRefPtr<GstStream>);
+#endif
     void notifyTrackOfActiveChanged();
     void notifyTrackOfTagsChanged();
 
@@ -67,6 +76,9 @@
     AtomicString m_label;
     AtomicString m_language;
     GRefPtr<GstPad> m_pad;
+#if USE(GSTREAMER_PLAYBIN3)
+    GRefPtr<GstStream> m_stream;
+#endif
 
 private:
     bool getLanguageCode(GstTagList* tags, AtomicString& value);
@@ -87,5 +99,3 @@
 } // namespace WebCore
 
 #endif // ENABLE(VIDEO) && USE(GSTREAMER) && ENABLE(VIDEO_TRACK)
-
-#endif // TrackPrivateBaseGStreamer_h

Modified: trunk/Source/WebCore/platform/graphics/gstreamer/VideoTrackPrivateGStreamer.cpp (228616 => 228617)


--- trunk/Source/WebCore/platform/graphics/gstreamer/VideoTrackPrivateGStreamer.cpp	2018-02-19 08:51:26 UTC (rev 228616)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/VideoTrackPrivateGStreamer.cpp	2018-02-19 08:58:14 UTC (rev 228617)
@@ -29,13 +29,14 @@
 
 #include "VideoTrackPrivateGStreamer.h"
 
+#include "MediaPlayerPrivateGStreamer.h"
 #include <glib-object.h>
 
 namespace WebCore {
 
-VideoTrackPrivateGStreamer::VideoTrackPrivateGStreamer(GRefPtr<GstElement> playbin, gint index, GRefPtr<GstPad> pad)
+VideoTrackPrivateGStreamer::VideoTrackPrivateGStreamer(WeakPtr<MediaPlayerPrivateGStreamer> player, gint index, GRefPtr<GstPad> pad)
     : TrackPrivateBaseGStreamer(this, index, pad)
-    , m_playbin(playbin)
+    , m_player(player)
 {
     // FIXME: Get a real ID from the tkhd atom.
     m_id = "V" + String::number(index);
@@ -42,12 +43,27 @@
     notifyTrackOfActiveChanged();
 }
 
+#if USE(GSTREAMER_PLAYBIN3)
+VideoTrackPrivateGStreamer::VideoTrackPrivateGStreamer(WeakPtr<MediaPlayerPrivateGStreamer> player, gint index, GRefPtr<GstStream> stream)
+    : TrackPrivateBaseGStreamer(this, index, stream)
+    , m_player(player)
+{
+    m_id = gst_stream_get_stream_id(stream.get());
+    notifyTrackOfActiveChanged();
+}
+#endif
+
 void VideoTrackPrivateGStreamer::disconnect()
 {
-    m_playbin.clear();
+    m_player = nullptr;
     TrackPrivateBaseGStreamer::disconnect();
 }
 
+void VideoTrackPrivateGStreamer::markAsActive()
+{
+    VideoTrackPrivate::setSelected(true);
+}
+
 void VideoTrackPrivateGStreamer::setSelected(bool selected)
 {
     if (selected == this->selected())
@@ -54,8 +70,8 @@
         return;
     VideoTrackPrivate::setSelected(selected);
 
-    if (selected && m_playbin)
-        g_object_set(m_playbin.get(), "current-video", m_index, nullptr);
+    if (selected && m_player)
+        m_player->enableTrack(TrackPrivateBaseGStreamer::TrackType::Video, m_index);
 }
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/platform/graphics/gstreamer/VideoTrackPrivateGStreamer.h (228616 => 228617)


--- trunk/Source/WebCore/platform/graphics/gstreamer/VideoTrackPrivateGStreamer.h	2018-02-19 08:51:26 UTC (rev 228616)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/VideoTrackPrivateGStreamer.h	2018-02-19 08:58:14 UTC (rev 228617)
@@ -23,8 +23,7 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef VideoTrackPrivateGStreamer_h
-#define VideoTrackPrivateGStreamer_h
+#pragma once
 
 #if ENABLE(VIDEO) && USE(GSTREAMER) && ENABLE(VIDEO_TRACK)
 
@@ -32,17 +31,28 @@
 #include "TrackPrivateBaseGStreamer.h"
 #include "VideoTrackPrivate.h"
 
+#include <gst/gst.h>
+#include <wtf/WeakPtr.h>
+
 namespace WebCore {
+class MediaPlayerPrivateGStreamer;
 
 class VideoTrackPrivateGStreamer final : public VideoTrackPrivate, public TrackPrivateBaseGStreamer {
 public:
-    static Ref<VideoTrackPrivateGStreamer> create(GRefPtr<GstElement> playbin, gint index, GRefPtr<GstPad> pad)
+    static Ref<VideoTrackPrivateGStreamer> create(WeakPtr<MediaPlayerPrivateGStreamer> player, gint index, GRefPtr<GstPad> pad)
     {
-        return adoptRef(*new VideoTrackPrivateGStreamer(playbin, index, pad));
+        return adoptRef(*new VideoTrackPrivateGStreamer(player, index, pad));
     }
+#if USE(GSTREAMER_PLAYBIN3)
+    static Ref<VideoTrackPrivateGStreamer> create(WeakPtr<MediaPlayerPrivateGStreamer> player, gint index, GRefPtr<GstStream> stream)
+    {
+        return adoptRef(*new VideoTrackPrivateGStreamer(player, index, stream));
+    }
+#endif
 
     void disconnect() override;
 
+    void markAsActive();
     void setSelected(bool) override;
     void setActive(bool enabled) override { setSelected(enabled); }
 
@@ -53,14 +63,14 @@
     AtomicString language() const override { return m_language; }
 
 private:
-    VideoTrackPrivateGStreamer(GRefPtr<GstElement> playbin, gint index, GRefPtr<GstPad>);
-
+    VideoTrackPrivateGStreamer(WeakPtr<MediaPlayerPrivateGStreamer>, gint index, GRefPtr<GstPad>);
+#if USE(GSTREAMER_PLAYBIN3)
+    VideoTrackPrivateGStreamer(WeakPtr<MediaPlayerPrivateGStreamer>, gint index, GRefPtr<GstStream>);
+#endif
     AtomicString m_id;
-    GRefPtr<GstElement> m_playbin;
+    WeakPtr<MediaPlayerPrivateGStreamer> m_player;
 };
 
 } // namespace WebCore
 
 #endif // ENABLE(VIDEO) && USE(GSTREAMER) && ENABLE(VIDEO_TRACK)
-
-#endif // VideoTrackPrivateGStreamer_h

Modified: trunk/Source/WebCore/platform/graphics/gstreamer/mse/AppendPipeline.cpp (228616 => 228617)


--- trunk/Source/WebCore/platform/graphics/gstreamer/mse/AppendPipeline.cpp	2018-02-19 08:51:26 UTC (rev 228616)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/mse/AppendPipeline.cpp	2018-02-19 08:58:14 UTC (rev 228617)
@@ -1073,11 +1073,11 @@
     switch (m_streamType) {
     case WebCore::MediaSourceStreamTypeGStreamer::Audio:
         if (m_playerPrivate)
-            m_track = WebCore::AudioTrackPrivateGStreamer::create(m_playerPrivate->pipeline(), id(), sinkSinkPad.get());
+            m_track = WebCore::AudioTrackPrivateGStreamer::create(m_playerPrivate->createWeakPtr(), id(), sinkSinkPad.get());
         break;
     case WebCore::MediaSourceStreamTypeGStreamer::Video:
         if (m_playerPrivate)
-            m_track = WebCore::VideoTrackPrivateGStreamer::create(m_playerPrivate->pipeline(), id(), sinkSinkPad.get());
+            m_track = WebCore::VideoTrackPrivateGStreamer::create(m_playerPrivate->createWeakPtr(), id(), sinkSinkPad.get());
         break;
     case WebCore::MediaSourceStreamTypeGStreamer::Text:
         m_track = WebCore::InbandTextTrackPrivateGStreamer::create(id(), sinkSinkPad.get());

Modified: trunk/Source/WebCore/platform/graphics/gstreamer/mse/MediaPlayerPrivateGStreamerMSE.cpp (228616 => 228617)


--- trunk/Source/WebCore/platform/graphics/gstreamer/mse/MediaPlayerPrivateGStreamerMSE.cpp	2018-02-19 08:51:26 UTC (rev 228616)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/mse/MediaPlayerPrivateGStreamerMSE.cpp	2018-02-19 08:58:14 UTC (rev 228617)
@@ -486,10 +486,9 @@
     return m_mediaSource ? m_mediaSource->buffered() : std::make_unique<PlatformTimeRanges>();
 }
 
-void MediaPlayerPrivateGStreamerMSE::sourceChanged()
+void MediaPlayerPrivateGStreamerMSE::sourceSetup(GstElement* sourceElement)
 {
-    m_source = nullptr;
-    g_object_get(m_pipeline.get(), "source", &m_source.outPtr(), nullptr);
+    m_source = sourceElement;
 
     ASSERT(WEBKIT_IS_MEDIA_SRC(m_source.get()));
 

Modified: trunk/Source/WebCore/platform/graphics/gstreamer/mse/MediaPlayerPrivateGStreamerMSE.h (228616 => 228617)


--- trunk/Source/WebCore/platform/graphics/gstreamer/mse/MediaPlayerPrivateGStreamerMSE.h	2018-02-19 08:51:26 UTC (rev 228616)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/mse/MediaPlayerPrivateGStreamerMSE.h	2018-02-19 08:58:14 UTC (rev 228617)
@@ -71,7 +71,7 @@
     std::unique_ptr<PlatformTimeRanges> buffered() const override;
     MediaTime maxMediaTimeSeekable() const override;
 
-    void sourceChanged() override;
+    void sourceSetup(GstElement*) override;
 
     void setReadyState(MediaPlayer::ReadyState);
     void waitForSeekCompleted();

Modified: trunk/Source/cmake/GStreamerDefinitions.cmake (228616 => 228617)


--- trunk/Source/cmake/GStreamerDefinitions.cmake	2018-02-19 08:51:26 UTC (rev 228616)
+++ trunk/Source/cmake/GStreamerDefinitions.cmake	2018-02-19 08:58:14 UTC (rev 228617)
@@ -5,3 +5,4 @@
 
 WEBKIT_OPTION_DEFINE(USE_GSTREAMER_GL "Whether to enable support for GStreamer GL" PRIVATE ON)
 WEBKIT_OPTION_DEFINE(USE_GSTREAMER_MPEGTS "Whether to enable support for MPEG-TS" PRIVATE OFF)
+WEBKIT_OPTION_DEFINE(USE_GSTREAMER_PLAYBIN3 "Whether to enable support for GStreamer's playbin3 element" PRIVATE OFF)
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to