Title: [281741] trunk/Source/WebCore
Revision
281741
Author
[email protected]
Date
2021-08-29 02:50:28 -0700 (Sun, 29 Aug 2021)

Log Message

[GStreamer] Track handling refactoring
https://bugs.webkit.org/show_bug.cgi?id=229497

Patch by Philippe Normand <[email protected]> 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):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (281740 => 281741)


--- 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)
@@ -1,3 +1,47 @@
+2021-08-29  Philippe Normand  <[email protected]>
+
+        [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):
+
 2021-08-29  Joonghun Park  <[email protected]>
 
         Unreviewed. Remove the build warning below since r280958.

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


--- 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)
@@ -30,31 +30,26 @@
 #include "AudioTrackPrivateGStreamer.h"
 
 #include "MediaPlayerPrivateGStreamer.h"
-#include <glib-object.h>
 
 namespace WebCore {
 
-AudioTrackPrivateGStreamer::AudioTrackPrivateGStreamer(WeakPtr<MediaPlayerPrivateGStreamer> player, gint index, GRefPtr<GstPad> pad)
-    : TrackPrivateBaseGStreamer(this, index, pad)
+AudioTrackPrivateGStreamer::AudioTrackPrivateGStreamer(WeakPtr<MediaPlayerPrivateGStreamer> player, unsigned index, GRefPtr<GstPad>&& pad, bool shouldHandleStreamStartEvent)
+    : TrackPrivateBaseGStreamer(TrackPrivateBaseGStreamer::TrackType::Audio, this, index, WTFMove(pad), shouldHandleStreamStartEvent)
     , m_player(player)
 {
-    // FIXME: Get a real ID from the tkhd atom.
-    m_id = "A" + String::number(index);
 }
 
-AudioTrackPrivateGStreamer::AudioTrackPrivateGStreamer(WeakPtr<MediaPlayerPrivateGStreamer> player, gint index, GRefPtr<GstStream> stream)
-    : TrackPrivateBaseGStreamer(this, index, stream)
+AudioTrackPrivateGStreamer::AudioTrackPrivateGStreamer(WeakPtr<MediaPlayerPrivateGStreamer> player, unsigned index, GRefPtr<GstStream>&& stream)
+    : TrackPrivateBaseGStreamer(TrackPrivateBaseGStreamer::TrackType::Audio, this, index, WTFMove(stream))
     , m_player(player)
 {
-    gint kind;
+    int kind;
     auto tags = adoptGRef(gst_stream_get_tags(m_stream.get()));
 
-    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));
+    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));
     }
-
-    m_id = gst_stream_get_stream_id(stream.get());
 }
 
 AudioTrackPrivate::Kind AudioTrackPrivateGStreamer::kind() const

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


--- 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)
@@ -28,9 +28,8 @@
 #if ENABLE(VIDEO) && USE(GSTREAMER)
 
 #include "AudioTrackPrivate.h"
-#include "GStreamerCommon.h"
 #include "TrackPrivateBaseGStreamer.h"
-#include <gst/gst.h>
+
 #include <wtf/WeakPtr.h>
 
 namespace WebCore {
@@ -38,34 +37,33 @@
 
 class AudioTrackPrivateGStreamer final : public AudioTrackPrivate, public TrackPrivateBaseGStreamer {
 public:
-    static Ref<AudioTrackPrivateGStreamer> create(WeakPtr<MediaPlayerPrivateGStreamer> player, gint index, GRefPtr<GstPad> pad)
+    static Ref<AudioTrackPrivateGStreamer> create(WeakPtr<MediaPlayerPrivateGStreamer> player, unsigned index, GRefPtr<GstPad>&& pad, bool shouldHandleStreamStartEvent = true)
     {
-        return adoptRef(*new AudioTrackPrivateGStreamer(player, index, pad));
+        return adoptRef(*new AudioTrackPrivateGStreamer(player, index, WTFMove(pad), shouldHandleStreamStartEvent));
     }
 
-    static Ref<AudioTrackPrivateGStreamer> create(WeakPtr<MediaPlayerPrivateGStreamer> player, gint index, GRefPtr<GstStream> stream)
+    static Ref<AudioTrackPrivateGStreamer> create(WeakPtr<MediaPlayerPrivateGStreamer> player, unsigned index, GRefPtr<GstStream>&& stream)
     {
-        return adoptRef(*new AudioTrackPrivateGStreamer(player, index, stream));
+        return adoptRef(*new AudioTrackPrivateGStreamer(player, index, WTFMove(stream)));
     }
 
     Kind kind() const final;
 
-    void disconnect() override;
+    void disconnect() final;
 
-    void setEnabled(bool) override;
-    void setActive(bool enabled) override { setEnabled(enabled); }
+    void setEnabled(bool) final;
+    void setActive(bool enabled) final { setEnabled(enabled); }
 
-    int trackIndex() const override { return m_index; }
+    int trackIndex() const final { return m_index; }
 
-    AtomString id() const override { return m_id; }
-    AtomString label() const override { return m_label; }
-    AtomString language() const override { return m_language; }
+    AtomString id() const final { return m_id; }
+    AtomString label() const final { return m_label; }
+    AtomString language() const final { return m_language; }
 
 private:
-    AudioTrackPrivateGStreamer(WeakPtr<MediaPlayerPrivateGStreamer>, gint index, GRefPtr<GstPad>);
-    AudioTrackPrivateGStreamer(WeakPtr<MediaPlayerPrivateGStreamer>, gint index, GRefPtr<GstStream>);
+    AudioTrackPrivateGStreamer(WeakPtr<MediaPlayerPrivateGStreamer>, unsigned index, GRefPtr<GstPad>&&, bool shouldHandleStreamStartEvent);
+    AudioTrackPrivateGStreamer(WeakPtr<MediaPlayerPrivateGStreamer>, unsigned index, GRefPtr<GstStream>&&);
 
-    AtomString m_id;
     WeakPtr<MediaPlayerPrivateGStreamer> m_player;
 };
 

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


--- 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)
@@ -29,10 +29,7 @@
 
 #include "InbandTextTrackPrivateGStreamer.h"
 
-#include "GStreamerCommon.h"
-#include "Logging.h"
-#include <glib-object.h>
-#include <gst/gst.h>
+#include <wtf/Lock.h>
 
 GST_DEBUG_CATEGORY_EXTERN(webkit_media_player_debug);
 #define GST_CAT_DEFAULT webkit_media_player_debug
@@ -39,48 +36,26 @@
 
 namespace WebCore {
 
-InbandTextTrackPrivateGStreamer::InbandTextTrackPrivateGStreamer(gint index, GRefPtr<GstPad> pad)
+InbandTextTrackPrivateGStreamer::InbandTextTrackPrivateGStreamer(unsigned index, GRefPtr<GstPad>&& pad, bool shouldHandleStreamStartEvent)
     : InbandTextTrackPrivate(CueFormat::WebVTT)
-    , TrackPrivateBaseGStreamer(this, index, pad)
+    , TrackPrivateBaseGStreamer(TrackPrivateBaseGStreamer::TrackType::Text, this, index, WTFMove(pad), shouldHandleStreamStartEvent)
     , m_kind(Kind::Subtitles)
 {
-    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();
 }
 
-InbandTextTrackPrivateGStreamer::InbandTextTrackPrivateGStreamer(gint index, GRefPtr<GstStream> stream)
+InbandTextTrackPrivateGStreamer::InbandTextTrackPrivateGStreamer(unsigned index, GRefPtr<GstStream>&& stream)
     : InbandTextTrackPrivate(CueFormat::WebVTT)
-    , TrackPrivateBaseGStreamer(this, index, stream)
+    , TrackPrivateBaseGStreamer(TrackPrivateBaseGStreamer::TrackType::Text, this, index, WTFMove(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());
+    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());
 
-    GST_DEBUG("Stream %" GST_PTR_FORMAT, stream.get());
-    auto caps = adoptGRef(gst_stream_get_caps(stream.get()));
+    GST_DEBUG("Stream %" GST_PTR_FORMAT, m_stream.get());
+    auto caps = adoptGRef(gst_stream_get_caps(m_stream.get()));
     const char* mediaType = capsMediaType(caps.get());
     m_kind = g_str_has_prefix(mediaType, "closedcaption/") ? Kind::Captions : Kind::Subtitles;
 }
 
-void InbandTextTrackPrivateGStreamer::disconnect()
-{
-    if (m_pad)
-        gst_pad_remove_probe(m_pad.get(), m_eventProbe);
-
-    TrackPrivateBaseGStreamer::disconnect();
-}
-
 void InbandTextTrackPrivateGStreamer::handleSample(GRefPtr<GstSample> sample)
 {
     {
@@ -94,14 +69,6 @@
     });
 }
 
-void InbandTextTrackPrivateGStreamer::streamChanged()
-{
-    RefPtr<InbandTextTrackPrivateGStreamer> protectedThis(this);
-    m_notifier->notify(MainThreadNotification::StreamChanged, [protectedThis] {
-        protectedThis->notifyTrackOfStreamChanged();
-    });
-}
-
 void InbandTextTrackPrivateGStreamer::notifyTrackOfSample()
 {
     Vector<GRefPtr<GstSample> > samples;
@@ -130,19 +97,6 @@
     }
 }
 
-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;
-}
-
 } // namespace WebCore
 
 #endif // ENABLE(VIDEO) && USE(GSTREAMER)

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


--- 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)
@@ -27,11 +27,9 @@
 
 #if ENABLE(VIDEO) && USE(GSTREAMER)
 
-#include "GStreamerCommon.h"
 #include "InbandTextTrackPrivate.h"
 #include "TrackPrivateBaseGStreamer.h"
-#include <gst/gst.h>
-#include <wtf/Lock.h>
+#include <wtf/Forward.h>
 
 namespace WebCore {
 
@@ -39,49 +37,38 @@
 
 class InbandTextTrackPrivateGStreamer : public InbandTextTrackPrivate, public TrackPrivateBaseGStreamer {
 public:
-    static Ref<InbandTextTrackPrivateGStreamer> create(gint index, GRefPtr<GstPad> pad)
+    static Ref<InbandTextTrackPrivateGStreamer> create(unsigned index, GRefPtr<GstPad>&& pad, bool shouldHandleStreamStartEvent = true)
     {
-        return adoptRef(*new InbandTextTrackPrivateGStreamer(index, pad));
+        return adoptRef(*new InbandTextTrackPrivateGStreamer(index, WTFMove(pad), shouldHandleStreamStartEvent));
     }
 
-    static Ref<InbandTextTrackPrivateGStreamer> create(WeakPtr<MediaPlayerPrivateGStreamer>, gint index, GRefPtr<GstPad> pad)
+    static Ref<InbandTextTrackPrivateGStreamer> create(WeakPtr<MediaPlayerPrivateGStreamer>, unsigned index, GRefPtr<GstPad> pad)
     {
-        return create(index, pad);
+        return create(index, WTFMove(pad));
     }
 
-    static Ref<InbandTextTrackPrivateGStreamer> create(gint index, GRefPtr<GstStream> stream)
+    static Ref<InbandTextTrackPrivateGStreamer> create(unsigned index, GRefPtr<GstStream>&& stream)
     {
-        return adoptRef(*new InbandTextTrackPrivateGStreamer(index, stream));
+        return adoptRef(*new InbandTextTrackPrivateGStreamer(index, WTFMove(stream)));
     }
 
-    void disconnect() override;
+    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; }
 
-    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; }
-
     void handleSample(GRefPtr<GstSample>);
 
 private:
-    InbandTextTrackPrivateGStreamer(gint index, GRefPtr<GstPad>);
-    InbandTextTrackPrivateGStreamer(gint index, GRefPtr<GstStream>);
+    InbandTextTrackPrivateGStreamer(unsigned index, GRefPtr<GstPad>&&, bool shouldHandleStreamStartEvent);
+    InbandTextTrackPrivateGStreamer(unsigned index, GRefPtr<GstStream>&&);
 
-    void streamChanged();
-
     void notifyTrackOfSample();
-    void notifyTrackOfStreamChanged();
 
-    gulong m_eventProbe;
     Vector<GRefPtr<GstSample>> m_pendingSamples WTF_GUARDED_BY_LOCK(m_sampleMutex);
-    String m_streamId;
     Kind m_kind;
     Lock m_sampleMutex;
-    AtomString m_id;
 };
 
 } // namespace WebCore

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


--- 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)
@@ -990,25 +990,25 @@
     if (UNLIKELY(!m_pipeline || !m_source))
         return;
 
-    ASSERT(m_isLegacyPlaybin || isMediaSource());
+    ASSERT(m_isLegacyPlaybin);
 
-    enum TrackType { Audio = 0, Video = 1, Text = 2 };
+    using TrackType = TrackPrivateBaseGStreamer::TrackType;
     Variant<HashMap<AtomString, RefPtr<AudioTrackPrivateGStreamer>>*, HashMap<AtomString, RefPtr<VideoTrackPrivateGStreamer>>*, HashMap<AtomString, RefPtr<InbandTextTrackPrivateGStreamer>>*> variantTracks = static_cast<HashMap<AtomString, RefPtr<TrackPrivateType>>*>(0);
     auto type(static_cast<TrackType>(variantTracks.index()));
     const char* typeName;
     bool* hasType;
     switch (type) {
-    case Audio:
+    case TrackType::Audio:
         typeName = "audio";
         hasType = &m_hasAudio;
         variantTracks = &m_audioTracks;
         break;
-    case Video:
+    case TrackType::Video:
         typeName = "video";
         hasType = &m_hasVideo;
         variantTracks = &m_videoTracks;
         break;
-    case Text:
+    case TrackType::Text:
         typeName = "text";
         hasType = nullptr;
         variantTracks = &m_textTracks;
@@ -1019,18 +1019,14 @@
     HashMap<AtomString, RefPtr<TrackPrivateType>>& tracks = *get<HashMap<AtomString, RefPtr<TrackPrivateType>>*>(variantTracks);
 
     // Ignore notifications after a EOS. We don't want the tracks to disappear when the video is finished.
-    if (m_isEndReached && (type == Audio || type == Video))
+    if (m_isEndReached && (type == TrackType::Audio || type == TrackType::Video))
         return;
 
     unsigned numberOfTracks = 0;
-    bool useMediaSource = isMediaSource();
-
     StringPrintStream numberOfTracksProperty;
     numberOfTracksProperty.printf("n-%s", typeName);
+    g_object_get(m_pipeline.get(), numberOfTracksProperty.toCString().data(), &numberOfTracks, nullptr);
 
-    GstElement* element = useMediaSource ? m_source.get() : m_pipeline.get();
-    g_object_get(element, numberOfTracksProperty.toCString().data(), &numberOfTracks, nullptr);
-
     GST_INFO_OBJECT(pipeline(), "Media has %d %s tracks", numberOfTracks, typeName);
 
     if (hasType) {
@@ -1039,17 +1035,11 @@
         if (oldHasType != *hasType)
             m_player->characteristicChanged();
 
-        if (*hasType && type == Video)
+        if (*hasType && type == TrackType::Video)
             m_player->sizeChanged();
     }
 
-    if (useMediaSource) {
-        GST_DEBUG_OBJECT(pipeline(), "Tracks managed by source element. Bailing out now.");
-        m_player->mediaEngineUpdated();
-        return;
-    }
-
-    Vector<String> validStreams;
+    Vector<AtomString> validStreams;
     StringPrintStream getPadProperty;
     getPadProperty.printf("get-%s-pad", typeName);
 
@@ -1058,7 +1048,9 @@
         g_signal_emit_by_name(m_pipeline.get(), getPadProperty.toCString().data(), i, &pad.outPtr(), nullptr);
         ASSERT(pad);
 
-        String streamId = String(typeName).substring(0, 1).convertToASCIIUppercase() + String::number(i);
+        // 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);
         validStreams.append(streamId);
 
         if (i < tracks.size()) {
@@ -1073,8 +1065,8 @@
             }
         }
 
-        auto track = TrackPrivateType::create(makeWeakPtr(*this), i, pad);
-        if (!track->trackIndex() && (type == Audio || type == Video))
+        auto track = TrackPrivateType::create(makeWeakPtr(*this), i, WTFMove(pad));
+        if (!track->trackIndex() && (type == TrackType::Audio || type == TrackType::Video))
             track->setActive(true);
         ASSERT(streamId == track->id());
         tracks.add(streamId, track.copyRef());
@@ -1081,9 +1073,15 @@
 
         Variant<AudioTrackPrivate&, VideoTrackPrivate&, InbandTextTrackPrivate&> variantTrack(track.get());
         switch (variantTrack.index()) {
-        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;
+        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;
         }
     }
 
@@ -1143,7 +1141,7 @@
 void MediaPlayerPrivateGStreamer::handleTextSample(GstSample* sample, const char* streamId)
 {
     for (auto& track : m_textTracks.values()) {
-        if (!strcmp(track->streamId().utf8().data(), streamId)) {
+        if (!strcmp(track->id().string().utf8().data(), streamId)) {
             track->handleSample(sample);
             return;
         }
@@ -1449,8 +1447,8 @@
     unsigned videoTrackIndex = 0;
     unsigned textTrackIndex = 0;
 
-#define CREATE_TRACK(type, Type) G_STMT_START {                         \
-        RefPtr<Type##TrackPrivateGStreamer> track = Type##TrackPrivateGStreamer::create(makeWeakPtr(*this), type##TrackIndex, stream); \
+#define CREATE_TRACK(type, Type) G_STMT_START {                     \
+        RefPtr<Type##TrackPrivateGStreamer> track = Type##TrackPrivateGStreamer::create(makeWeakPtr(*this), type##TrackIndex, WTFMove(stream)); \
         auto trackId = track->id();                                 \
         if (!type##TrackIndex) {                                    \
             m_wanted##Type##StreamId = trackId;                     \
@@ -1463,11 +1461,11 @@
     } G_STMT_END
 
     for (unsigned i = 0; i < length; i++) {
-        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);
+        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());
 
-        GST_DEBUG_OBJECT(pipeline(), "Inspecting %s track with ID %s", gst_stream_type_get_name(type), streamId.utf8().data());
+        GST_DEBUG_OBJECT(pipeline(), "Inspecting %s track with ID %s", gst_stream_type_get_name(type), streamId);
 
         if (type & GST_STREAM_TYPE_AUDIO) {
             CREATE_TRACK(audio, Audio);
@@ -1475,11 +1473,11 @@
         } else if (type & GST_STREAM_TYPE_VIDEO && m_player->isVideoPlayer())
             CREATE_TRACK(video, Video);
         else if (type & GST_STREAM_TYPE_TEXT && !useMediaSource) {
-            auto track = InbandTextTrackPrivateGStreamer::create(textTrackIndex++, stream);
+            auto track = InbandTextTrackPrivateGStreamer::create(textTrackIndex++, WTFMove(stream));
             m_textTracks.add(streamId, track.copyRef());
             m_player->addTextTrack(track.get());
         } else
-            GST_WARNING("Unknown track type found for stream %s", streamId.utf8().data());
+            GST_WARNING("Unknown track type found for stream %s", streamId);
     }
 
     m_hasAudio = !m_audioTracks.isEmpty();

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


--- 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)
@@ -30,12 +30,8 @@
 #include "TrackPrivateBaseGStreamer.h"
 
 #include "GStreamerCommon.h"
-#include "Logging.h"
 #include "TrackPrivateBase.h"
-#include <glib-object.h>
-#include <gst/gst.h>
 #include <gst/tag/tag.h>
-#include <wtf/glib/GUniquePtr.h>
 #include <wtf/text/CString.h>
 
 GST_DEBUG_CATEGORY_EXTERN(webkit_media_player_debug);
@@ -43,6 +39,25 @@
 
 namespace WebCore {
 
+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);
+}
+
 static GRefPtr<GstPad> findBestUpstreamPad(GRefPtr<GstPad> pad)
 {
     GRefPtr<GstPad> sinkPad = pad;
@@ -56,11 +71,12 @@
     return sinkPad;
 }
 
-TrackPrivateBaseGStreamer::TrackPrivateBaseGStreamer(TrackPrivateBase* owner, gint index, GRefPtr<GstPad> pad)
+TrackPrivateBaseGStreamer::TrackPrivateBaseGStreamer(TrackType type, TrackPrivateBase* owner, unsigned index, GRefPtr<GstPad>&& pad, bool shouldHandleStreamStartEvent)
     : m_notifier(MainThreadNotifier<MainThreadNotification>::create())
     , m_index(index)
-    , m_eventProbe(0)
+    , m_type(type)
     , m_owner(owner)
+    , m_shouldHandleStreamStartEvent(shouldHandleStreamStartEvent)
 {
     setPad(WTFMove(pad));
     ASSERT(m_pad);
@@ -69,14 +85,15 @@
     tagsChanged();
 }
 
-TrackPrivateBaseGStreamer::TrackPrivateBaseGStreamer(TrackPrivateBase* owner, gint index, GRefPtr<GstStream> stream)
+TrackPrivateBaseGStreamer::TrackPrivateBaseGStreamer(TrackType type, TrackPrivateBase* owner, unsigned index, GRefPtr<GstStream>&& stream)
     : m_notifier(MainThreadNotifier<MainThreadNotification>::create())
     , m_index(index)
-    , m_stream(stream)
-    , m_eventProbe(0)
+    , m_stream(WTFMove(stream))
+    , m_type(type)
     , m_owner(owner)
 {
     ASSERT(m_stream);
+    m_id = gst_stream_get_stream_id(m_stream.get());
 
     // We can't call notifyTrackOfTagsChanged() directly, because we need tagsChanged() to setup m_tags.
     tagsChanged();
@@ -89,6 +106,8 @@
 
     m_pad = WTFMove(pad);
     m_bestUpstreamPad = findBestUpstreamPad(m_pad);
+    m_id = generateUniquePlaybin2StreamID(m_type, m_index);
+
     m_eventProbe = gst_pad_add_probe(m_bestUpstreamPad.get(), GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM, [] (GstPad*, GstPadProbeInfo* info, gpointer userData) -> GstPadProbeReturn {
         auto* track = static_cast<TrackPrivateBaseGStreamer*>(userData);
         switch (GST_EVENT_TYPE(gst_pad_probe_info_get_event(info))) {
@@ -95,6 +114,10 @@
         case GST_EVENT_TAG:
             tagsChangedCallback(track);
             break;
+        case GST_EVENT_STREAM_START:
+            if (track->m_shouldHandleStreamStartEvent)
+                track->streamChanged();
+            break;
         default:
             break;
         }
@@ -163,7 +186,9 @@
         m_tags.swap(tags);
     }
 
-    m_notifier->notify(MainThreadNotification::TagsChanged, [this] { notifyTrackOfTagsChanged(); });
+    m_notifier->notify(MainThreadNotification::TagsChanged, [this] {
+        notifyTrackOfTagsChanged();
+    });
 }
 
 bool TrackPrivateBaseGStreamer::getLanguageCode(GstTagList* tags, AtomString& value)
@@ -220,6 +245,23 @@
         client->languageChanged(m_language);
 }
 
+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();
+    });
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(VIDEO) && USE(GSTREAMER)

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


--- 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)
@@ -48,6 +48,8 @@
         Unknown
     };
 
+    WEBCORE_EXPORT static AtomString generateUniquePlaybin2StreamID(TrackType, unsigned index);
+
     GstPad* pad() const { return m_pad.get(); }
     void setPad(GRefPtr<GstPad>&&);
 
@@ -55,12 +57,9 @@
 
     virtual void setActive(bool) { }
 
-    void setIndex(int index) { m_index =  index; }
+    void setIndex(unsigned index) { m_index =  index; }
 
-    GstStream* stream()
-    {
-        return m_stream.get();
-    }
+    GstStream* stream() { return m_stream.get(); }
 
     // Used for MSE, where the initial caps of the pad are relevant for initializing the matching pad in the
     // playback pipeline.
@@ -68,10 +67,11 @@
     const GRefPtr<GstCaps>& initialCaps() { return m_initialCaps; }
 
 protected:
-    TrackPrivateBaseGStreamer(TrackPrivateBase* owner, gint index, GRefPtr<GstPad>);
-    TrackPrivateBaseGStreamer(TrackPrivateBase* owner, gint index, GRefPtr<GstStream>);
+    TrackPrivateBaseGStreamer(TrackType, TrackPrivateBase*, unsigned index, GRefPtr<GstPad>&&, bool shouldHandleStreamStartEvent);
+    TrackPrivateBaseGStreamer(TrackType, TrackPrivateBase*, unsigned index, GRefPtr<GstStream>&&);
 
     void notifyTrackOfTagsChanged();
+    void notifyTrackOfStreamChanged();
 
     enum MainThreadNotification {
         TagsChanged = 1 << 1,
@@ -80,13 +80,14 @@
     };
 
     Ref<MainThreadNotifier<MainThreadNotification>> m_notifier;
-    gint m_index;
+    unsigned m_index;
     AtomString m_label;
     AtomString m_language;
+    AtomString m_id;
     GRefPtr<GstPad> m_pad;
     GRefPtr<GstPad> m_bestUpstreamPad;
     GRefPtr<GstStream> m_stream;
-    gulong m_eventProbe;
+    unsigned long m_eventProbe { 0 };
     GRefPtr<GstCaps> m_initialCaps;
 
 private:
@@ -95,14 +96,18 @@
     template<class StringType>
     bool getTag(GstTagList* tags, const gchar* tagName, StringType& value);
 
+    void streamChanged();
+
     static void activeChangedCallback(TrackPrivateBaseGStreamer*);
     static void tagsChangedCallback(TrackPrivateBaseGStreamer*);
 
     void tagsChanged();
 
+    TrackType m_type;
     TrackPrivateBase* m_owner;
     Lock m_tagMutex;
     GRefPtr<GstTagList> m_tags;
+    bool m_shouldHandleStreamStartEvent { true };
 };
 
 } // namespace WebCore

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


--- 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)
@@ -30,31 +30,26 @@
 #include "VideoTrackPrivateGStreamer.h"
 
 #include "MediaPlayerPrivateGStreamer.h"
-#include <glib-object.h>
 
 namespace WebCore {
 
-VideoTrackPrivateGStreamer::VideoTrackPrivateGStreamer(WeakPtr<MediaPlayerPrivateGStreamer> player, gint index, GRefPtr<GstPad> pad)
-    : TrackPrivateBaseGStreamer(this, index, pad)
+VideoTrackPrivateGStreamer::VideoTrackPrivateGStreamer(WeakPtr<MediaPlayerPrivateGStreamer> player, unsigned index, GRefPtr<GstPad>&& pad, bool shouldHandleStreamStartEvent)
+    : TrackPrivateBaseGStreamer(TrackPrivateBaseGStreamer::TrackType::Video, this, index, WTFMove(pad), shouldHandleStreamStartEvent)
     , m_player(player)
 {
-    // FIXME: Get a real ID from the tkhd atom.
-    m_id = "V" + String::number(index);
 }
 
-VideoTrackPrivateGStreamer::VideoTrackPrivateGStreamer(WeakPtr<MediaPlayerPrivateGStreamer> player, gint index, GRefPtr<GstStream> stream)
-    : TrackPrivateBaseGStreamer(this, index, stream)
+VideoTrackPrivateGStreamer::VideoTrackPrivateGStreamer(WeakPtr<MediaPlayerPrivateGStreamer> player, unsigned index, GRefPtr<GstStream>&& stream)
+    : TrackPrivateBaseGStreamer(TrackPrivateBaseGStreamer::TrackType::Video, this, index, WTFMove(stream))
     , m_player(player)
 {
-    gint kind;
+    int kind;
     auto tags = adoptGRef(gst_stream_get_tags(m_stream.get()));
 
     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));
+        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));
     }
-
-    m_id = gst_stream_get_stream_id(stream.get());
 }
 
 VideoTrackPrivate::Kind VideoTrackPrivateGStreamer::kind() const

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


--- 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)
@@ -31,7 +31,6 @@
 #include "TrackPrivateBaseGStreamer.h"
 #include "VideoTrackPrivate.h"
 
-#include <gst/gst.h>
 #include <wtf/WeakPtr.h>
 
 namespace WebCore {
@@ -39,34 +38,33 @@
 
 class VideoTrackPrivateGStreamer final : public VideoTrackPrivate, public TrackPrivateBaseGStreamer {
 public:
-    static Ref<VideoTrackPrivateGStreamer> create(WeakPtr<MediaPlayerPrivateGStreamer> player, gint index, GRefPtr<GstPad> pad)
+    static Ref<VideoTrackPrivateGStreamer> create(WeakPtr<MediaPlayerPrivateGStreamer> player, unsigned index, GRefPtr<GstPad>&& pad, bool shouldHandleStreamStartEvent = true)
     {
-        return adoptRef(*new VideoTrackPrivateGStreamer(player, index, pad));
+        return adoptRef(*new VideoTrackPrivateGStreamer(player, index, WTFMove(pad), shouldHandleStreamStartEvent));
     }
 
-    static Ref<VideoTrackPrivateGStreamer> create(WeakPtr<MediaPlayerPrivateGStreamer> player, gint index, GRefPtr<GstStream> stream)
+    static Ref<VideoTrackPrivateGStreamer> create(WeakPtr<MediaPlayerPrivateGStreamer> player, unsigned index, GRefPtr<GstStream>&& stream)
     {
-        return adoptRef(*new VideoTrackPrivateGStreamer(player, index, stream));
+        return adoptRef(*new VideoTrackPrivateGStreamer(player, index, WTFMove(stream)));
     }
 
     Kind kind() const final;
 
-    void disconnect() override;
+    void disconnect() final;
 
-    void setSelected(bool) override;
-    void setActive(bool enabled) override { setSelected(enabled); }
+    void setSelected(bool) final;
+    void setActive(bool enabled) final { setSelected(enabled); }
 
-    int trackIndex() const override { return m_index; }
+    int trackIndex() const final { return m_index; }
 
-    AtomString id() const override { return m_id; }
-    AtomString label() const override { return m_label; }
-    AtomString language() const override { return m_language; }
+    AtomString id() const final { return m_id; }
+    AtomString label() const final { return m_label; }
+    AtomString language() const final { return m_language; }
 
 private:
-    VideoTrackPrivateGStreamer(WeakPtr<MediaPlayerPrivateGStreamer>, gint index, GRefPtr<GstPad>);
-    VideoTrackPrivateGStreamer(WeakPtr<MediaPlayerPrivateGStreamer>, gint index, GRefPtr<GstStream>);
+    VideoTrackPrivateGStreamer(WeakPtr<MediaPlayerPrivateGStreamer>, unsigned index, GRefPtr<GstPad>&&, bool shouldHandleStreamStartEvent);
+    VideoTrackPrivateGStreamer(WeakPtr<MediaPlayerPrivateGStreamer>, unsigned index, GRefPtr<GstStream>&&);
 
-    AtomString m_id;
     WeakPtr<MediaPlayerPrivateGStreamer> m_player;
 };
 

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


--- 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)
@@ -753,21 +753,22 @@
     RefPtr<WebCore::TrackPrivateBase> track;
     TrackPrivateBaseGStreamer* gstreamerTrack = nullptr;
     // FIXME: AudioTrackPrivateGStreamer etc. should probably use pads of the playback pipeline rather than the append pipeline.
+    GRefPtr<GstPad> pad(appendPipelineTrack.appsinkPad);
     switch (appendPipelineTrack.streamType) {
     case StreamType::Audio: {
-        auto specificTrack = AudioTrackPrivateGStreamer::create(makeWeakPtr(m_playerPrivate), trackIndex, appendPipelineTrack.appsinkPad);
+        auto specificTrack = AudioTrackPrivateGStreamer::create(makeWeakPtr(m_playerPrivate), trackIndex, WTFMove(pad), false);
         gstreamerTrack = specificTrack.ptr();
         track = makeRefPtr(static_cast<TrackPrivateBase*>(specificTrack.ptr()));
         break;
     }
     case StreamType::Video: {
-        auto specificTrack = VideoTrackPrivateGStreamer::create(makeWeakPtr(m_playerPrivate), trackIndex, appendPipelineTrack.appsinkPad);
+        auto specificTrack = VideoTrackPrivateGStreamer::create(makeWeakPtr(m_playerPrivate), trackIndex, WTFMove(pad), false);
         gstreamerTrack = specificTrack.ptr();
         track = makeRefPtr(static_cast<TrackPrivateBase*>(specificTrack.ptr()));
         break;
     }
     case StreamType::Text: {
-        auto specificTrack = InbandTextTrackPrivateGStreamer::create(trackIndex, appendPipelineTrack.appsinkPad);
+        auto specificTrack = InbandTextTrackPrivateGStreamer::create(trackIndex, WTFMove(pad), false);
         gstreamerTrack = specificTrack.ptr();
         track = makeRefPtr(static_cast<TrackPrivateBase*>(specificTrack.ptr()));
         break;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to