Title: [271512] trunk
Revision
271512
Author
[email protected]
Date
2021-01-15 01:27:06 -0800 (Fri, 15 Jan 2021)

Log Message

[GStreamer] Clean-up the TextCombiner
https://bugs.webkit.org/show_bug.cgi?id=220463

Reviewed by Xabier Rodriguez-Calvar.

Source/WebCore:

The code style now conforms WebKit's. The GhostPad subclass moved to its own code unit,
because the WEBKIT_DEFINE_TYPE cannot be used multiple times in the same file (it defines a
parent_class symbol). The GhostPad was also decoupled as much as possible from the Combiner.
Most mentions of the funnel GStreamer element were made more generic because we might need
to use a different element in situations where the pipeline is playbin3-based, which requires
the concat element.

No new tests, existing tests cover this patch.

* platform/GStreamer.cmake:
* platform/graphics/gstreamer/GStreamerCommon.cpp:
(WebCore::gstElementFactoryEquals):
* platform/graphics/gstreamer/GStreamerCommon.h:
* platform/graphics/gstreamer/TextCombinerGStreamer.cpp:
(webKitTextCombinerHandleCapsEvent):
(webkitTextCombinerRequestNewPad):
(webkitTextCombinerReleasePad):
(webKitTextCombinerConstructed):
(webkit_text_combiner_class_init):
(webkitTextCombinerNew):
* platform/graphics/gstreamer/TextCombinerGStreamer.h:
* platform/graphics/gstreamer/TextCombinerPadGStreamer.cpp: Added.
(webkitTextCombinerPadEvent):
(webkitTextCombinerPadGetProperty):
(webkitTextCombinerPadSetProperty):
(webkitTextCombinerPadConstructed):
(webkit_text_combiner_pad_class_init):
(webKitTextCombinerPadLeakInternalPadRef):
* platform/graphics/gstreamer/TextCombinerPadGStreamer.h: Copied from Source/WebCore/platform/graphics/gstreamer/TextCombinerGStreamer.h.

Tools:

* Scripts/webkitpy/style/checker.py: Add GStreamer TextCombiner implementation to GObject
classes allow-list.

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (271511 => 271512)


--- trunk/Source/WebCore/ChangeLog	2021-01-15 07:24:48 UTC (rev 271511)
+++ trunk/Source/WebCore/ChangeLog	2021-01-15 09:27:06 UTC (rev 271512)
@@ -1,3 +1,40 @@
+2021-01-15  Philippe Normand  <[email protected]>
+
+        [GStreamer] Clean-up the TextCombiner
+        https://bugs.webkit.org/show_bug.cgi?id=220463
+
+        Reviewed by Xabier Rodriguez-Calvar.
+
+        The code style now conforms WebKit's. The GhostPad subclass moved to its own code unit,
+        because the WEBKIT_DEFINE_TYPE cannot be used multiple times in the same file (it defines a
+        parent_class symbol). The GhostPad was also decoupled as much as possible from the Combiner.
+        Most mentions of the funnel GStreamer element were made more generic because we might need
+        to use a different element in situations where the pipeline is playbin3-based, which requires
+        the concat element.
+
+        No new tests, existing tests cover this patch.
+
+        * platform/GStreamer.cmake:
+        * platform/graphics/gstreamer/GStreamerCommon.cpp:
+        (WebCore::gstElementFactoryEquals):
+        * platform/graphics/gstreamer/GStreamerCommon.h:
+        * platform/graphics/gstreamer/TextCombinerGStreamer.cpp:
+        (webKitTextCombinerHandleCapsEvent):
+        (webkitTextCombinerRequestNewPad):
+        (webkitTextCombinerReleasePad):
+        (webKitTextCombinerConstructed):
+        (webkit_text_combiner_class_init):
+        (webkitTextCombinerNew):
+        * platform/graphics/gstreamer/TextCombinerGStreamer.h:
+        * platform/graphics/gstreamer/TextCombinerPadGStreamer.cpp: Added.
+        (webkitTextCombinerPadEvent):
+        (webkitTextCombinerPadGetProperty):
+        (webkitTextCombinerPadSetProperty):
+        (webkitTextCombinerPadConstructed):
+        (webkit_text_combiner_pad_class_init):
+        (webKitTextCombinerPadLeakInternalPadRef):
+        * platform/graphics/gstreamer/TextCombinerPadGStreamer.h: Copied from Source/WebCore/platform/graphics/gstreamer/TextCombinerGStreamer.h.
+
 2021-01-14  Julian Gonzalez  <[email protected]>
 
         Crash from CompositeEditCommand::moveParagraphs() being passed null end

Modified: trunk/Source/WebCore/platform/GStreamer.cmake (271511 => 271512)


--- trunk/Source/WebCore/platform/GStreamer.cmake	2021-01-15 07:24:48 UTC (rev 271511)
+++ trunk/Source/WebCore/platform/GStreamer.cmake	2021-01-15 09:27:06 UTC (rev 271512)
@@ -21,6 +21,7 @@
         platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp
         platform/graphics/gstreamer/MediaSampleGStreamer.cpp
         platform/graphics/gstreamer/TextCombinerGStreamer.cpp
+        platform/graphics/gstreamer/TextCombinerPadGStreamer.cpp
         platform/graphics/gstreamer/TextSinkGStreamer.cpp
         platform/graphics/gstreamer/TrackPrivateBaseGStreamer.cpp
         platform/graphics/gstreamer/VideoSinkGStreamer.cpp

Modified: trunk/Source/WebCore/platform/graphics/gstreamer/GStreamerCommon.cpp (271511 => 271512)


--- trunk/Source/WebCore/platform/graphics/gstreamer/GStreamerCommon.cpp	2021-01-15 07:24:48 UTC (rev 271511)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/GStreamerCommon.cpp	2021-01-15 09:27:06 UTC (rev 271512)
@@ -442,6 +442,11 @@
     return plugin;
 }
 
+bool gstElementFactoryEquals(GstElement* element, const char* name)
+{
+    return equal(GST_OBJECT_NAME(gst_element_get_factory(element)), name);
+}
+
 GstElement* createPlatformAudioSink()
 {
     GstElement* audioSink = webkitAudioSinkNew();

Modified: trunk/Source/WebCore/platform/graphics/gstreamer/GStreamerCommon.h (271511 => 271512)


--- trunk/Source/WebCore/platform/graphics/gstreamer/GStreamerCommon.h	2021-01-15 07:24:48 UTC (rev 271511)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/GStreamerCommon.h	2021-01-15 09:27:06 UTC (rev 271512)
@@ -292,6 +292,7 @@
 enum class GstVideoDecoderPlatform { ImxVPU, Video4Linux, OpenMAX };
 
 bool isGStreamerPluginAvailable(const char* name);
+bool gstElementFactoryEquals(GstElement*, const char* name);
 
 GstElement* createPlatformAudioSink();
 

Modified: trunk/Source/WebCore/platform/graphics/gstreamer/TextCombinerGStreamer.cpp (271511 => 271512)


--- trunk/Source/WebCore/platform/graphics/gstreamer/TextCombinerGStreamer.cpp	2021-01-15 07:24:48 UTC (rev 271511)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/TextCombinerGStreamer.cpp	2021-01-15 09:27:06 UTC (rev 271512)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2013 Cable Television Laboratories, Inc.
+ * Copyright (C) 2021 Igalia S.L.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -29,272 +30,160 @@
 #if ENABLE(VIDEO) && USE(GSTREAMER)
 
 #include "GStreamerCommon.h"
+#include "TextCombinerPadGStreamer.h"
+#include <wtf/glib/WTFGType.h>
 
-static GstStaticPadTemplate sinkTemplate =
-    GST_STATIC_PAD_TEMPLATE("sink_%u", GST_PAD_SINK, GST_PAD_REQUEST,
-        GST_STATIC_CAPS_ANY);
+static GstStaticPadTemplate sinkTemplate = GST_STATIC_PAD_TEMPLATE("sink_%u", GST_PAD_SINK, GST_PAD_REQUEST, GST_STATIC_CAPS_ANY);
 
-static GstStaticPadTemplate srcTemplate =
-    GST_STATIC_PAD_TEMPLATE("src", GST_PAD_SRC, GST_PAD_ALWAYS,
-        GST_STATIC_CAPS_ANY);
+static GstStaticPadTemplate srcTemplate = GST_STATIC_PAD_TEMPLATE("src", GST_PAD_SRC, GST_PAD_ALWAYS, GST_STATIC_CAPS_ANY);
 
 GST_DEBUG_CATEGORY_STATIC(webkitTextCombinerDebug);
 #define GST_CAT_DEFAULT webkitTextCombinerDebug
 
-#define webkit_text_combiner_parent_class parent_class
-G_DEFINE_TYPE_WITH_CODE(WebKitTextCombiner, webkit_text_combiner, GST_TYPE_BIN,
-    GST_DEBUG_CATEGORY_INIT(webkitTextCombinerDebug, "webkittextcombiner", 0,
-        "webkit text combiner"));
-
-enum {
-    PROP_PAD_0,
-    PROP_PAD_TAGS
+struct _WebKitTextCombinerPrivate {
+    GRefPtr<GstElement> combinerElement;
 };
 
-#define WEBKIT_TYPE_TEXT_COMBINER_PAD webkit_text_combiner_pad_get_type()
+#define webkit_text_combiner_parent_class parent_class
+WEBKIT_DEFINE_TYPE_WITH_CODE(WebKitTextCombiner, webkit_text_combiner, GST_TYPE_BIN,
+    GST_DEBUG_CATEGORY_INIT(webkitTextCombinerDebug, "webkittextcombiner", 0, "webkit text combiner"))
 
-#define WEBKIT_TEXT_COMBINER_PAD(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WEBKIT_TYPE_TEXT_COMBINER_PAD, WebKitTextCombinerPad))
-#define WEBKIT_TEXT_COMBINER_PAD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WEBKIT_TYPE_TEXT_COMBINER_PAD, WebKitTextCombinerPadClass))
-#define WEBKIT_IS_TEXT_COMBINER_PAD(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), WEBKIT_TYPE_TEXT_COMBINER_PAD))
-#define WEBKIT_IS_TEXT_COMBINER_PAD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WEBKIT_TYPE_TEXT_COMBINER_PAD))
-#define WEBKIT_TEXT_COMBINER_PAD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), WEBKIT_TYPE_TEXT_COMBINER_PAD, WebKitTextCombinerPadClass))
+using namespace WebCore;
 
-typedef struct _WebKitTextCombinerPad WebKitTextCombinerPad;
-typedef struct _WebKitTextCombinerPadClass WebKitTextCombinerPadClass;
-
-struct _WebKitTextCombinerPad {
-    GstGhostPad parent;
-
-    GstTagList* tags;
-    GstPad* funnelPad;
-};
-
-struct _WebKitTextCombinerPadClass {
-    GstGhostPadClass parent;
-};
-
-G_DEFINE_TYPE(WebKitTextCombinerPad, webkit_text_combiner_pad, GST_TYPE_GHOST_PAD);
-
-static GType webVTTEncType;
-
-static gboolean webkitTextCombinerPadEvent(GstPad*, GstObject* parent, GstEvent*);
-
-static void webkit_text_combiner_init(WebKitTextCombiner* combiner)
+void webKitTextCombinerHandleCapsEvent(WebKitTextCombiner* combiner, GstPad* pad, GstEvent* event)
 {
-    combiner->funnel = gst_element_factory_make("funnel", nullptr);
-    ASSERT(combiner->funnel);
+    GstCaps* caps;
+    gst_event_parse_caps(event, &caps);
+    ASSERT(caps);
+    GST_DEBUG_OBJECT(combiner, "Handling caps %" GST_PTR_FORMAT, caps);
 
-    gboolean ret = gst_bin_add(GST_BIN(combiner), combiner->funnel);
-    UNUSED_PARAM(ret);
-    ASSERT(ret);
+    auto target = adoptGRef(gst_ghost_pad_get_target(GST_GHOST_PAD(pad)));
+    auto targetParent = target ? adoptGRef(gst_pad_get_parent_element(target.get())) : nullptr;
+    auto* combinerPad = WEBKIT_TEXT_COMBINER_PAD(pad);
 
-    GRefPtr<GstPad> pad = adoptGRef(gst_element_get_static_pad(combiner->funnel, "src"));
-    ASSERT(pad);
+    GRefPtr<GstPad> internalPad;
+    g_object_get(combinerPad, "inner-combiner-pad", &internalPad.outPtr(), nullptr);
 
-    ret = gst_element_add_pad(GST_ELEMENT(combiner), gst_ghost_pad_new("src", pad.get()));
-    ASSERT(ret);
-}
+    auto textCaps = adoptGRef(gst_caps_new_empty_simple("text/x-raw"));
+    if (gst_caps_can_intersect(textCaps.get(), caps)) {
+        // Caps are plain text, we want a WebVTT encoder between the ghostpad and the combinerElement.
+        if (!target || gstElementFactoryEquals(targetParent.get(), "webvttenc"_s)) {
+            GST_DEBUG_OBJECT(combiner, "Setting up a WebVTT encoder");
+            auto* encoder = gst_element_factory_make("webvttenc", nullptr);
+            ASSERT(encoder);
 
-static void webkit_text_combiner_pad_init(WebKitTextCombinerPad* pad)
-{
-    gst_pad_set_event_function(GST_PAD(pad), webkitTextCombinerPadEvent);
-}
+            gst_bin_add(GST_BIN_CAST(combiner), encoder);
+            gst_element_sync_state_with_parent(encoder);
 
-static void webkitTextCombinerPadDispose(GObject* object)
-{
-    WebKitTextCombinerPad* combinerPad = WEBKIT_TEXT_COMBINER_PAD(object);
-    g_clear_pointer(&combinerPad->tags, gst_tag_list_unref);
-    g_clear_pointer(&combinerPad->funnelPad, gst_object_unref);
-    G_OBJECT_CLASS(webkit_text_combiner_pad_parent_class)->dispose(object);
-}
+            // Switch the ghostpad to target the WebVTT encoder.
+            auto sinkPad = adoptGRef(gst_element_get_static_pad(encoder, "sink"));
+            ASSERT(sinkPad);
 
-static void webkitTextCombinerPadGetProperty(GObject* object, guint propertyId, GValue* value, GParamSpec* pspec)
-{
-    WebKitTextCombinerPad* pad = WEBKIT_TEXT_COMBINER_PAD(object);
-    switch (propertyId) {
-    case PROP_PAD_TAGS:
-        GST_OBJECT_LOCK(object);
-        if (pad->tags)
-            g_value_take_boxed(value, gst_tag_list_copy(pad->tags));
-        GST_OBJECT_UNLOCK(object);
-        break;
-    default:
-        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propertyId, pspec);
-        break;
-    }
-}
+            gst_ghost_pad_set_target(GST_GHOST_PAD(pad), sinkPad.get());
 
-static gboolean webkitTextCombinerPadEvent(GstPad* pad, GstObject* parent, GstEvent* event)
-{
-    gboolean ret;
-    UNUSED_PARAM(ret);
-    WebKitTextCombiner* combiner = WEBKIT_TEXT_COMBINER(parent);
-    WebKitTextCombinerPad* combinerPad = WEBKIT_TEXT_COMBINER_PAD(pad);
-    ASSERT(combiner);
+            // Connect the WebVTT encoder to the combinerElement.
+            auto srcPad = adoptGRef(gst_element_get_static_pad(encoder, "src"));
+            ASSERT(srcPad);
 
-    switch (GST_EVENT_TYPE(event)) {
-    case GST_EVENT_CAPS: {
-        GstCaps* caps;
-        gst_event_parse_caps(event, &caps);
-        ASSERT(caps);
+            gst_pad_link(srcPad.get(), internalPad.get());
+        } // Else: pipeline is already correct.
+    } else {
+        // Caps are not plain text, we assume it's WebVTT.
 
-        GRefPtr<GstPad> target = adoptGRef(gst_ghost_pad_get_target(GST_GHOST_PAD(pad)));
-        GRefPtr<GstElement> targetParent = target ? adoptGRef(gst_pad_get_parent_element(target.get())) : nullptr;
-
-        GRefPtr<GstCaps> textCaps = adoptGRef(gst_caps_new_empty_simple("text/x-raw"));
-        if (gst_caps_can_intersect(textCaps.get(), caps)) {
-            // Caps are plain text, we want a WebVTT encoder between the ghostpad and the funnel.
-            if (!target || G_TYPE_FROM_INSTANCE(targetParent.get()) != webVTTEncType) {
-                // Setup a WebVTT encoder.
-                GstElement* encoder = gst_element_factory_make("webvttenc", nullptr);
-                ASSERT(encoder);
-
-                ret = gst_bin_add(GST_BIN(combiner), encoder);
-                ASSERT(ret);
-
-                ret = gst_element_sync_state_with_parent(encoder);
-                ASSERT(ret);
-
-                // Switch the ghostpad to target the WebVTT encoder.
-                GRefPtr<GstPad> sinkPad = adoptGRef(gst_element_get_static_pad(encoder, "sink"));
-                ASSERT(sinkPad);
-
-                ret = gst_ghost_pad_set_target(GST_GHOST_PAD(pad), sinkPad.get());
-                ASSERT(ret);
-
-                // Connect the WebVTT encoder to the funnel.
-                GRefPtr<GstPad> srcPad = adoptGRef(gst_element_get_static_pad(encoder, "src"));
-                ASSERT(srcPad);
-
-                ret = GST_PAD_LINK_SUCCESSFUL(gst_pad_link(srcPad.get(), combinerPad->funnelPad));
-                ASSERT(ret);
-            } // Else: pipeline is already correct.
-        } else {
-            // Caps are not plain text, we assume it's WebVTT.
-
-            // Remove the WebVTT encoder if present.
-            if (target && G_TYPE_FROM_INSTANCE(targetParent.get()) == webVTTEncType) {
-                ret = gst_bin_remove(GST_BIN(combiner), targetParent.get());
-                ASSERT(ret);
-
-                target = nullptr;
-                targetParent = nullptr;
-            }
-
-            // Link the pad to the funnel.
-            if (!target) {
-                ret = gst_ghost_pad_set_target(GST_GHOST_PAD(pad), combinerPad->funnelPad);
-                ASSERT(ret);
-            } // Else: pipeline is already correct.
+        // Remove the WebVTT encoder if present.
+        if (target && gstElementFactoryEquals(targetParent.get(), "webvttenc"_s)) {
+            GST_DEBUG_OBJECT(combiner, "Removing WebVTT encoder");
+            gst_bin_remove(GST_BIN_CAST(combiner), targetParent.get());
+            target = nullptr;
+            targetParent = nullptr;
         }
-        break;
-    }
-    case GST_EVENT_TAG: {
-        GstTagList* tags;
-        gst_event_parse_tag(event, &tags);
-        ASSERT(tags);
 
-        GST_OBJECT_LOCK(pad);
-        if (!combinerPad->tags)
-            combinerPad->tags = gst_tag_list_copy(tags);
-        else
-            gst_tag_list_insert(combinerPad->tags, tags, GST_TAG_MERGE_REPLACE);
-        GST_OBJECT_UNLOCK(pad);
-
-        g_object_notify(G_OBJECT(pad), "tags");
-        break;
+        // Link the pad to the combinerElement.
+        if (!target) {
+            GST_DEBUG_OBJECT(combiner, "Associating %" GST_PTR_FORMAT " to %" GST_PTR_FORMAT, internalPad.get(), pad);
+            gst_ghost_pad_set_target(GST_GHOST_PAD(pad), internalPad.get());
+        } // Else: pipeline is already correct.
     }
-    default:
-        break;
-    }
-    return gst_pad_event_default(pad, parent, event);
 }
 
-static GstPad* webkitTextCombinerRequestNewPad(GstElement * element,
-    GstPadTemplate * templ, const gchar * name, const GstCaps * caps)
+static GstPad* webkitTextCombinerRequestNewPad(GstElement* element, GstPadTemplate* templ, const char* name, const GstCaps* caps)
 {
-    gboolean ret;
-    UNUSED_PARAM(ret);
-    ASSERT(templ);
-
-    WebKitTextCombiner* combiner = WEBKIT_TEXT_COMBINER(element);
+    auto* combiner = WEBKIT_TEXT_COMBINER(element);
     ASSERT(combiner);
 
-    GstPad* ghostPad = GST_PAD(g_object_new(WEBKIT_TYPE_TEXT_COMBINER_PAD, "direction", GST_PAD_SINK, nullptr));
+    GST_DEBUG_OBJECT(element, "Requesting new sink pad");
+    auto* ghostPad = GST_PAD_CAST(g_object_new(WEBKIT_TYPE_TEXT_COMBINER_PAD, "direction", GST_PAD_SINK, nullptr));
     ASSERT(ghostPad);
 
-    ret = gst_ghost_pad_construct(GST_GHOST_PAD(ghostPad));
-    ASSERT(ret);
+    auto* internalPad = gst_element_request_pad(combiner->priv->combinerElement.get(), templ, name, caps);
+    g_object_set(WEBKIT_TEXT_COMBINER_PAD(ghostPad), "inner-combiner-pad", internalPad, nullptr);
 
-    WebKitTextCombinerPad* combinerPad = WEBKIT_TEXT_COMBINER_PAD(ghostPad);
-    combinerPad->funnelPad = gst_element_request_pad(combiner->funnel, templ, name, caps);
-    ASSERT(combinerPad->funnelPad);
-
-    ret = gst_pad_set_active(ghostPad, true);
-    ASSERT(ret);
-
-    ret = gst_element_add_pad(GST_ELEMENT(combiner), ghostPad);
-    ASSERT(ret);
+    gst_pad_set_active(ghostPad, true);
+    gst_element_add_pad(GST_ELEMENT_CAST(combiner), ghostPad);
     return ghostPad;
 }
 
-static void webkitTextCombinerReleasePad(GstElement *element, GstPad *pad)
+static void webkitTextCombinerReleasePad(GstElement* element, GstPad* pad)
 {
-    WebKitTextCombiner* combiner = WEBKIT_TEXT_COMBINER(element);
-    WebKitTextCombinerPad* combinerPad = WEBKIT_TEXT_COMBINER_PAD(pad);
+    auto* combiner = WEBKIT_TEXT_COMBINER(element);
+    auto* combinerPad = WEBKIT_TEXT_COMBINER_PAD(pad);
 
-    if (GRefPtr<GstPad> target = adoptGRef(gst_ghost_pad_get_target(GST_GHOST_PAD(pad)))) {
-        GRefPtr<GstElement> parent = adoptGRef(gst_pad_get_parent_element(target.get()));
+    if (auto target = adoptGRef(gst_ghost_pad_get_target(GST_GHOST_PAD(pad)))) {
+        auto parent = adoptGRef(gst_pad_get_parent_element(target.get()));
         ASSERT(parent);
-        if (G_TYPE_FROM_INSTANCE(parent.get()) == webVTTEncType) {
+        if (gstElementFactoryEquals(parent.get(), "webvttenc"_s)) {
             gst_element_set_state(parent.get(), GST_STATE_NULL);
-            gst_bin_remove(GST_BIN(combiner), parent.get());
+            gst_bin_remove(GST_BIN_CAST(combiner), parent.get());
         }
     }
 
-    gst_element_release_request_pad(combiner->funnel, combinerPad->funnelPad);
+    auto internalPad = adoptGRef(webKitTextCombinerPadLeakInternalPadRef(combinerPad));
+    gst_element_release_request_pad(combiner->priv->combinerElement.get(), internalPad.get());
+
     gst_element_remove_pad(element, pad);
 }
 
-static void webkit_text_combiner_class_init(WebKitTextCombinerClass* klass)
+static void webKitTextCombinerConstructed(GObject* object)
 {
-    GstElementClass* elementClass = GST_ELEMENT_CLASS(klass);
+    GST_CALL_PARENT(G_OBJECT_CLASS, constructed, (object));
 
-    gst_element_class_add_pad_template(elementClass, gst_static_pad_template_get(&sinkTemplate));
-    gst_element_class_add_pad_template(elementClass, gst_static_pad_template_get(&srcTemplate));
+    auto* combiner = WEBKIT_TEXT_COMBINER(object);
+    auto* priv = combiner->priv;
 
-    gst_element_class_set_metadata(elementClass, "WebKit text combiner", "Generic",
-        "A funnel that accepts any caps, but converts plain text to WebVTT",
-        "Brendan Long <[email protected]>");
+    // For now a funnel is used, but a better combiner, compatible with playbin3 use-cases, would be concat.
+    priv->combinerElement = gst_element_factory_make("funnel", nullptr);
+    ASSERT(priv->combinerElement);
 
-    elementClass->request_new_pad =
-        GST_DEBUG_FUNCPTR(webkitTextCombinerRequestNewPad);
-    elementClass->release_pad =
-        GST_DEBUG_FUNCPTR(webkitTextCombinerReleasePad);
+    gst_bin_add(GST_BIN_CAST(combiner), priv->combinerElement.get());
 
-    GRefPtr<GstElementFactory> webVTTEncFactory = adoptGRef(gst_element_factory_find("webvttenc"));
-    ASSERT(webVTTEncFactory);
-    gst_object_unref(gst_plugin_feature_load(GST_PLUGIN_FEATURE(webVTTEncFactory.get())));
-    webVTTEncType = gst_element_factory_get_element_type(webVTTEncFactory.get());
-    ASSERT(webVTTEncType);
+    auto pad = adoptGRef(gst_element_get_static_pad(priv->combinerElement.get(), "src"));
+    ASSERT(pad);
+
+    gst_element_add_pad(GST_ELEMENT_CAST(combiner), gst_ghost_pad_new("src", pad.get()));
 }
 
-static void webkit_text_combiner_pad_class_init(WebKitTextCombinerPadClass* klass)
+static void webkit_text_combiner_class_init(WebKitTextCombinerClass* klass)
 {
-    GObjectClass* gobjectClass = G_OBJECT_CLASS(klass);
+    auto* elementClass = GST_ELEMENT_CLASS(klass);
+    auto* objectClass = G_OBJECT_CLASS(klass);
 
-    gobjectClass->dispose = GST_DEBUG_FUNCPTR(webkitTextCombinerPadDispose);
-    gobjectClass->get_property = GST_DEBUG_FUNCPTR(webkitTextCombinerPadGetProperty);
+    objectClass->constructed = webKitTextCombinerConstructed;
 
-    g_object_class_install_property(gobjectClass, PROP_PAD_TAGS,
-        g_param_spec_boxed("tags", "Tags", "The currently active tags on the pad", GST_TYPE_TAG_LIST,
-            static_cast<GParamFlags>(G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)));
+    gst_element_class_add_pad_template(elementClass, gst_static_pad_template_get(&sinkTemplate));
+    gst_element_class_add_pad_template(elementClass, gst_static_pad_template_get(&srcTemplate));
+
+    gst_element_class_set_metadata(elementClass, "WebKit text combiner", "Generic",
+        "A combiner that accepts any caps, but converts plain text to WebVTT",
+        "Brendan Long <[email protected]>");
+
+    elementClass->request_new_pad = GST_DEBUG_FUNCPTR(webkitTextCombinerRequestNewPad);
+    elementClass->release_pad = GST_DEBUG_FUNCPTR(webkitTextCombinerReleasePad);
 }
 
 GstElement* webkitTextCombinerNew()
 {
     // The combiner relies on webvttenc, fail early if it's not there.
-    if (!WebCore::isGStreamerPluginAvailable("subenc")) {
+    if (!isGStreamerPluginAvailable("subenc")) {
         WTFLogAlways("WebKit wasn't able to find a WebVTT encoder. Not continuing without platform support for subtitles.");
         return nullptr;
     }

Modified: trunk/Source/WebCore/platform/graphics/gstreamer/TextCombinerGStreamer.h (271511 => 271512)


--- trunk/Source/WebCore/platform/graphics/gstreamer/TextCombinerGStreamer.h	2021-01-15 07:24:48 UTC (rev 271511)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/TextCombinerGStreamer.h	2021-01-15 09:27:06 UTC (rev 271512)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2013 Cable Television Laboratories, Inc.
+ * Copyright (C) 2021 Igalia S.L.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -27,7 +28,6 @@
 
 #if ENABLE(VIDEO) && USE(GSTREAMER)
 
-#include <glib-object.h>
 #include <gst/gst.h>
 
 #define WEBKIT_TYPE_TEXT_COMBINER webkit_text_combiner_get_type()
@@ -38,27 +38,24 @@
 #define WEBKIT_IS_TEXT_COMBINER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WEBKIT_TYPE_TEXT_COMBINER))
 #define WEBKIT_TEXT_COMBINER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), WEBKIT_TYPE_TEXT_COMBINER, WebKitTextCombinerClass))
 
+GType webkit_text_combiner_get_type(void);
+
 typedef struct _WebKitTextCombiner WebKitTextCombiner;
 typedef struct _WebKitTextCombinerClass WebKitTextCombinerClass;
+typedef struct _WebKitTextCombinerPrivate WebKitTextCombinerPrivate;
 
 struct _WebKitTextCombiner {
     GstBin parent;
 
-    GstElement *funnel;
+    WebKitTextCombinerPrivate* priv;
 };
 
 struct _WebKitTextCombinerClass {
     GstBinClass parentClass;
-
-    // Future padding
-    void (* _webkit_reserved1)(void);
-    void (* _webkit_reserved2)(void);
-    void (* _webkit_reserved3)(void);
-    void (* _webkit_reserved4)(void);
-    void (* _webkit_reserved5)(void);
-    void (* _webkit_reserved6)(void);
 };
 
 GstElement* webkitTextCombinerNew();
 
+void webKitTextCombinerHandleCapsEvent(WebKitTextCombiner*, GstPad*, GstEvent*);
+
 #endif // ENABLE(VIDEO) && USE(GSTREAMER)

Added: trunk/Source/WebCore/platform/graphics/gstreamer/TextCombinerPadGStreamer.cpp (0 => 271512)


--- trunk/Source/WebCore/platform/graphics/gstreamer/TextCombinerPadGStreamer.cpp	                        (rev 0)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/TextCombinerPadGStreamer.cpp	2021-01-15 09:27:06 UTC (rev 271512)
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2013 Cable Television Laboratories, Inc.
+ * Copyright (C) 2021 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "TextCombinerPadGStreamer.h"
+
+#if ENABLE(VIDEO) && USE(GSTREAMER)
+
+#include "GStreamerCommon.h"
+#include "TextCombinerGStreamer.h"
+#include <wtf/glib/WTFGType.h>
+
+struct _WebKitTextCombinerPadPrivate {
+    GRefPtr<GstTagList> tags;
+    GRefPtr<GstPad> innerCombinerPad;
+};
+
+enum {
+    PROP_PAD_0,
+    PROP_PAD_TAGS,
+    PROP_INNER_COMBINER_PAD,
+};
+
+#define webkit_text_combiner_pad_parent_class parent_class
+WEBKIT_DEFINE_TYPE(WebKitTextCombinerPad, webkit_text_combiner_pad, GST_TYPE_GHOST_PAD);
+
+static gboolean webkitTextCombinerPadEvent(GstPad* pad, GstObject* parent, GstEvent* event)
+{
+    switch (GST_EVENT_TYPE(event)) {
+    case GST_EVENT_CAPS:
+        webKitTextCombinerHandleCapsEvent(WEBKIT_TEXT_COMBINER(parent), pad, event);
+        break;
+    case GST_EVENT_TAG: {
+        auto* combinerPad = WEBKIT_TEXT_COMBINER_PAD(pad);
+        GstTagList* tags;
+        gst_event_parse_tag(event, &tags);
+        ASSERT(tags);
+
+        GST_OBJECT_LOCK(pad);
+        if (!combinerPad->priv->tags)
+            combinerPad->priv->tags = adoptGRef(gst_tag_list_copy(tags));
+        else
+            gst_tag_list_insert(combinerPad->priv->tags.get(), tags, GST_TAG_MERGE_REPLACE);
+        GST_OBJECT_UNLOCK(pad);
+
+        g_object_notify(G_OBJECT(pad), "tags");
+        break;
+    }
+    default:
+        break;
+    }
+    return gst_pad_event_default(pad, parent, event);
+}
+
+static void webkitTextCombinerPadGetProperty(GObject* object, unsigned propertyId, GValue* value, GParamSpec* pspec)
+{
+    auto* pad = WEBKIT_TEXT_COMBINER_PAD(object);
+    switch (propertyId) {
+    case PROP_PAD_TAGS:
+        GST_OBJECT_LOCK(object);
+        if (pad->priv->tags)
+            g_value_take_boxed(value, gst_tag_list_copy(pad->priv->tags.get()));
+        GST_OBJECT_UNLOCK(object);
+        break;
+    case PROP_INNER_COMBINER_PAD:
+        GST_OBJECT_LOCK(object);
+        g_value_set_object(value, pad->priv->innerCombinerPad.get());
+        GST_OBJECT_UNLOCK(object);
+        break;
+    default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propertyId, pspec);
+        break;
+    }
+}
+
+static void webkitTextCombinerPadSetProperty(GObject* object, guint propertyId, const GValue* value, GParamSpec* pspec)
+{
+    auto* pad = WEBKIT_TEXT_COMBINER_PAD(object);
+    switch (propertyId) {
+    case PROP_INNER_COMBINER_PAD:
+        GST_OBJECT_LOCK(object);
+        pad->priv->innerCombinerPad = adoptGRef(GST_PAD_CAST(g_value_get_object(value)));
+        GST_OBJECT_UNLOCK(object);
+        break;
+    default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propertyId, pspec);
+        break;
+    }
+}
+
+static void webkitTextCombinerPadConstructed(GObject* object)
+{
+    GST_CALL_PARENT(G_OBJECT_CLASS, constructed, (object));
+    gst_ghost_pad_construct(GST_GHOST_PAD(object));
+    gst_pad_set_event_function(GST_PAD_CAST(object), webkitTextCombinerPadEvent);
+}
+
+static void webkit_text_combiner_pad_class_init(WebKitTextCombinerPadClass* klass)
+{
+    auto* gobjectClass = G_OBJECT_CLASS(klass);
+
+    gobjectClass->constructed = webkitTextCombinerPadConstructed;
+    gobjectClass->get_property = GST_DEBUG_FUNCPTR(webkitTextCombinerPadGetProperty);
+    gobjectClass->set_property = GST_DEBUG_FUNCPTR(webkitTextCombinerPadSetProperty);
+
+    g_object_class_install_property(gobjectClass, PROP_PAD_TAGS,
+        g_param_spec_boxed("tags", "Tags", "The currently active tags on the pad", GST_TYPE_TAG_LIST,
+            static_cast<GParamFlags>(G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)));
+
+    g_object_class_install_property(gobjectClass, PROP_INNER_COMBINER_PAD,
+        g_param_spec_object("inner-combiner-pad", "Internal Combiner Pad", "The internal funnel (or concat) pad associated with this pad", GST_TYPE_PAD,
+            static_cast<GParamFlags>(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
+}
+
+GstPad* webKitTextCombinerPadLeakInternalPadRef(WebKitTextCombinerPad* pad)
+{
+    return pad->priv->innerCombinerPad.leakRef();
+}
+
+#endif

Copied: trunk/Source/WebCore/platform/graphics/gstreamer/TextCombinerPadGStreamer.h (from rev 271511, trunk/Source/WebCore/platform/graphics/gstreamer/TextCombinerGStreamer.h) (0 => 271512)


--- trunk/Source/WebCore/platform/graphics/gstreamer/TextCombinerPadGStreamer.h	                        (rev 0)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/TextCombinerPadGStreamer.h	2021-01-15 09:27:06 UTC (rev 271512)
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2013 Cable Television Laboratories, Inc.
+ * Copyright (C) 2021 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(VIDEO) && USE(GSTREAMER)
+
+#include "GRefPtrGStreamer.h"
+
+#define WEBKIT_TYPE_TEXT_COMBINER_PAD webkit_text_combiner_pad_get_type()
+
+#define WEBKIT_TEXT_COMBINER_PAD(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WEBKIT_TYPE_TEXT_COMBINER_PAD, WebKitTextCombinerPad))
+#define WEBKIT_TEXT_COMBINER_PAD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WEBKIT_TYPE_TEXT_COMBINER_PAD, WebKitTextCombinerPadClass))
+#define WEBKIT_IS_TEXT_COMBINER_PAD(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), WEBKIT_TYPE_TEXT_COMBINER_PAD))
+#define WEBKIT_IS_TEXT_COMBINER_PAD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WEBKIT_TYPE_TEXT_COMBINER_PAD))
+#define WEBKIT_TEXT_COMBINER_PAD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), WEBKIT_TYPE_TEXT_COMBINER_PAD, WebKitTextCombinerPadClass))
+
+typedef struct _WebKitTextCombinerPadPrivate WebKitTextCombinerPadPrivate;
+
+struct WebKitTextCombinerPad {
+    GstGhostPad parent;
+    WebKitTextCombinerPadPrivate* priv;
+};
+
+struct WebKitTextCombinerPadClass {
+    GstGhostPadClass parent;
+};
+
+GType webkit_text_combiner_pad_get_type(void);
+
+GstPad* webKitTextCombinerPadLeakInternalPadRef(WebKitTextCombinerPad*);
+
+#endif

Modified: trunk/Tools/ChangeLog (271511 => 271512)


--- trunk/Tools/ChangeLog	2021-01-15 07:24:48 UTC (rev 271511)
+++ trunk/Tools/ChangeLog	2021-01-15 09:27:06 UTC (rev 271512)
@@ -1,3 +1,13 @@
+2021-01-15  Philippe Normand  <[email protected]>
+
+        [GStreamer] Clean-up the TextCombiner
+        https://bugs.webkit.org/show_bug.cgi?id=220463
+
+        Reviewed by Xabier Rodriguez-Calvar.
+
+        * Scripts/webkitpy/style/checker.py: Add GStreamer TextCombiner implementation to GObject
+        classes allow-list.
+
 2021-01-14  Aditya Keerthi  <[email protected]>
 
         [Cocoa] Strip DataDetectors links when copying content to the pasteboard

Modified: trunk/Tools/Scripts/webkitpy/style/checker.py (271511 => 271512)


--- trunk/Tools/Scripts/webkitpy/style/checker.py	2021-01-15 07:24:48 UTC (rev 271511)
+++ trunk/Tools/Scripts/webkitpy/style/checker.py	2021-01-15 09:27:06 UTC (rev 271512)
@@ -219,6 +219,10 @@
       # variables and functions containing underscores.
       os.path.join('Source', 'WebCore', 'platform', 'graphics', 'gstreamer', 'GLVideoSinkGStreamer.cpp'),
       os.path.join('Source', 'WebCore', 'platform', 'graphics', 'gstreamer', 'GLVideoSinkGStreamer.h'),
+      os.path.join('Source', 'WebCore', 'platform', 'graphics', 'gstreamer', 'TextCombinerGStreamer.cpp'),
+      os.path.join('Source', 'WebCore', 'platform', 'graphics', 'gstreamer', 'TextCombinerGStreamer.h'),
+      os.path.join('Source', 'WebCore', 'platform', 'graphics', 'gstreamer', 'TextCombinerPadGStreamer.cpp'),
+      os.path.join('Source', 'WebCore', 'platform', 'graphics', 'gstreamer', 'TextCombinerPadGStreamer.h'),
       os.path.join('Source', 'WebCore', 'platform', 'graphics', 'gstreamer', 'VideoSinkGStreamer.cpp'),
       os.path.join('Source', 'WebCore', 'platform', 'graphics', 'gstreamer', 'WebKitWebSourceGStreamer.cpp'),
       os.path.join('Source', 'WebCore', 'platform', 'graphics', 'gstreamer', 'WebKitAudioSinkGStreamer.cpp'),
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to