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'),