Title: [290366] trunk
Revision
290366
Author
[email protected]
Date
2022-02-23 04:27:24 -0800 (Wed, 23 Feb 2022)

Log Message

[GStreamer] Add WebKitDMABufVideoSink
https://bugs.webkit.org/show_bug.cgi?id=236883

Patch by Zan Dobersek <[email protected]> on 2022-02-23
Reviewed by Philippe Normand.

.:

* Source/cmake/FindGStreamer.cmake:
Also search for gstreamer-allocators-1.0, produce the relevant variables
containing include directories and cflags.

Source/WebCore:

Add custom WebKitDMABufVideoSink sink that is able to accept decoded
dmabuf or raw data in a range of RGB-like or YUV formats.

The sink is pretty straightforward, in large part mirroring the
WebKitGLVideoSink implementation. The formats that (at the moment) we
can correctly handle inside the TextureMapper-based graphics pipeline
are combined with both the dmabuf or raw memory type during the caps
construction. Like the GL counterpart, the received samples are passed
on to the associated MediaPlayerPrivateGStreamer object. The common
integration into the MediaPlayerPrivateGStreamer functionality is
encapsulated into the webKitVideoSinkSetMediaPlayerPrivate() function.

The MediaPlayerPrivateGStreamer implementation will be enhanced later to
properly handle samples conforming to either variant of these caps. But
the idea is that when using this sink, a dmabuf-containing sample will
pass the dmabuf to the graphics subsystem and a raw-data-containing
sample will copy the data into a dmabuf object (created or reused) and
then pass it on.

The WEBKIT_GST_DMABUF_SINK_FORCED_FALLBACK_CAPS_FORMAT environment
variable can be set to specify the desired exclusive format that this
sink should support. This is especially helpful to debug the correct
handling of different RGB or YUV formats inside the graphics pipeline.
When set, only raw data of the specified format is accepted, meaning the
pipeline upstream will perform any necessary conversion of the decoded
data into the desired format. Raw data is then packed into dmabufs and
sent into the pipeline for display, enabling the developer to examine
whether the given format is handled appropriately.

The sink element is registered in registerWebKitGStreamerElements().
This functionality will require The GStreamer allocators library, so the
necessary dependency glue is also provided.

* platform/GStreamer.cmake:
* platform/graphics/gstreamer/DMABufVideoSinkGStreamer.cpp: Added.
(forcedFallbackCapsFormat):
(webKitDMABufVideoSinkConstructed):
(webKitDMABufVideoSinkFinalize):
(webKitDMABufVideoSinkGetProperty):
(webkit_dmabuf_video_sink_class_init):
(webKitDMABufVideoSinkSetMediaPlayerPrivate):
(webKitDMABufVideoSinkProbePlatform):
* platform/graphics/gstreamer/DMABufVideoSinkGStreamer.h: Added.
* platform/graphics/gstreamer/GLVideoSinkGStreamer.cpp:
(webKitGLVideoSinkSetMediaPlayerPrivate):
* platform/graphics/gstreamer/GStreamerCommon.cpp:
(WebCore::registerWebKitGStreamerElements):
* platform/graphics/gstreamer/GStreamerVideoSinkCommon.cpp: Added.
(webKitVideoSinkSetMediaPlayerPrivate):
* platform/graphics/gstreamer/GStreamerVideoSinkCommon.h: Added.

Tools:

* Scripts/webkitpy/style/checker.py:
Add two additional files under the GObject-style exceptions.

Modified Paths

Added Paths

Diff

Modified: trunk/ChangeLog (290365 => 290366)


--- trunk/ChangeLog	2022-02-23 12:06:12 UTC (rev 290365)
+++ trunk/ChangeLog	2022-02-23 12:27:24 UTC (rev 290366)
@@ -1,3 +1,14 @@
+2022-02-23  Zan Dobersek  <[email protected]>
+
+        [GStreamer] Add WebKitDMABufVideoSink
+        https://bugs.webkit.org/show_bug.cgi?id=236883
+
+        Reviewed by Philippe Normand.
+
+        * Source/cmake/FindGStreamer.cmake:
+        Also search for gstreamer-allocators-1.0, produce the relevant variables
+        containing include directories and cflags.
+
 2022-02-22  Philippe Normand  <[email protected]>
 
         [GStreamer] Initial MediaRecorder implementation

Modified: trunk/Source/WebCore/ChangeLog (290365 => 290366)


--- trunk/Source/WebCore/ChangeLog	2022-02-23 12:06:12 UTC (rev 290365)
+++ trunk/Source/WebCore/ChangeLog	2022-02-23 12:27:24 UTC (rev 290366)
@@ -1,3 +1,61 @@
+2022-02-23  Zan Dobersek  <[email protected]>
+
+        [GStreamer] Add WebKitDMABufVideoSink
+        https://bugs.webkit.org/show_bug.cgi?id=236883
+
+        Reviewed by Philippe Normand.
+
+        Add custom WebKitDMABufVideoSink sink that is able to accept decoded
+        dmabuf or raw data in a range of RGB-like or YUV formats.
+
+        The sink is pretty straightforward, in large part mirroring the
+        WebKitGLVideoSink implementation. The formats that (at the moment) we
+        can correctly handle inside the TextureMapper-based graphics pipeline
+        are combined with both the dmabuf or raw memory type during the caps
+        construction. Like the GL counterpart, the received samples are passed
+        on to the associated MediaPlayerPrivateGStreamer object. The common
+        integration into the MediaPlayerPrivateGStreamer functionality is
+        encapsulated into the webKitVideoSinkSetMediaPlayerPrivate() function.
+
+        The MediaPlayerPrivateGStreamer implementation will be enhanced later to
+        properly handle samples conforming to either variant of these caps. But
+        the idea is that when using this sink, a dmabuf-containing sample will
+        pass the dmabuf to the graphics subsystem and a raw-data-containing
+        sample will copy the data into a dmabuf object (created or reused) and
+        then pass it on.
+
+        The WEBKIT_GST_DMABUF_SINK_FORCED_FALLBACK_CAPS_FORMAT environment
+        variable can be set to specify the desired exclusive format that this
+        sink should support. This is especially helpful to debug the correct
+        handling of different RGB or YUV formats inside the graphics pipeline.
+        When set, only raw data of the specified format is accepted, meaning the
+        pipeline upstream will perform any necessary conversion of the decoded
+        data into the desired format. Raw data is then packed into dmabufs and
+        sent into the pipeline for display, enabling the developer to examine
+        whether the given format is handled appropriately.
+
+        The sink element is registered in registerWebKitGStreamerElements().
+        This functionality will require The GStreamer allocators library, so the
+        necessary dependency glue is also provided.
+
+        * platform/GStreamer.cmake:
+        * platform/graphics/gstreamer/DMABufVideoSinkGStreamer.cpp: Added.
+        (forcedFallbackCapsFormat):
+        (webKitDMABufVideoSinkConstructed):
+        (webKitDMABufVideoSinkFinalize):
+        (webKitDMABufVideoSinkGetProperty):
+        (webkit_dmabuf_video_sink_class_init):
+        (webKitDMABufVideoSinkSetMediaPlayerPrivate):
+        (webKitDMABufVideoSinkProbePlatform):
+        * platform/graphics/gstreamer/DMABufVideoSinkGStreamer.h: Added.
+        * platform/graphics/gstreamer/GLVideoSinkGStreamer.cpp:
+        (webKitGLVideoSinkSetMediaPlayerPrivate):
+        * platform/graphics/gstreamer/GStreamerCommon.cpp:
+        (WebCore::registerWebKitGStreamerElements):
+        * platform/graphics/gstreamer/GStreamerVideoSinkCommon.cpp: Added.
+        (webKitVideoSinkSetMediaPlayerPrivate):
+        * platform/graphics/gstreamer/GStreamerVideoSinkCommon.h: Added.
+
 2022-02-23  Sihui Liu  <[email protected]>
 
         REGRESSION(r289474): [iOS] ASSERTION FAILED: isMainThread() under WebCore::IDBServer::UniqueIDBDatabase::abortActiveTransactions()

Modified: trunk/Source/WebCore/platform/GStreamer.cmake (290365 => 290366)


--- trunk/Source/WebCore/platform/GStreamer.cmake	2022-02-23 12:06:12 UTC (rev 290365)
+++ trunk/Source/WebCore/platform/GStreamer.cmake	2022-02-23 12:27:24 UTC (rev 290366)
@@ -9,6 +9,7 @@
     list(APPEND WebCore_SOURCES
         Modules/webaudio/MediaStreamAudioSourceGStreamer.cpp
         platform/graphics/gstreamer/AudioTrackPrivateGStreamer.cpp
+        platform/graphics/gstreamer/DMABufVideoSinkGStreamer.cpp
         platform/graphics/gstreamer/GLVideoSinkGStreamer.cpp
         platform/graphics/gstreamer/GRefPtrGStreamer.cpp
         platform/graphics/gstreamer/GStreamerAudioMixer.cpp
@@ -16,6 +17,7 @@
         platform/graphics/gstreamer/GstAllocatorFastMalloc.cpp
         platform/graphics/gstreamer/GStreamerRegistryScanner.cpp
         platform/graphics/gstreamer/GStreamerVideoFrameHolder.cpp
+        platform/graphics/gstreamer/GStreamerVideoSinkCommon.cpp
         platform/graphics/gstreamer/ImageDecoderGStreamer.cpp
         platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.cpp
         platform/graphics/gstreamer/MediaEngineConfigurationFactoryGStreamer.cpp
@@ -94,11 +96,13 @@
         list(APPEND WebCore_SYSTEM_INCLUDE_DIRECTORIES
             ${GSTREAMER_INCLUDE_DIRS}
             ${GSTREAMER_BASE_INCLUDE_DIRS}
+            ${GSTREAMER_ALLOCATORS_INCLUDE_DIRS}
             ${GSTREAMER_APP_INCLUDE_DIRS}
             ${GSTREAMER_PBUTILS_INCLUDE_DIRS}
         )
 
         list(APPEND WebCore_LIBRARIES
+            ${GSTREAMER_ALLOCATORS_LIBRARIES}
             ${GSTREAMER_APP_LIBRARIES}
             ${GSTREAMER_BASE_LIBRARIES}
             ${GSTREAMER_LIBRARIES}

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


--- trunk/Source/WebCore/platform/graphics/gstreamer/DMABufVideoSinkGStreamer.cpp	                        (rev 0)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/DMABufVideoSinkGStreamer.cpp	2022-02-23 12:27:24 UTC (rev 290366)
@@ -0,0 +1,176 @@
+/*
+ *  Copyright (C) 2022 Igalia, S.L
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "config.h"
+#include "DMABufVideoSinkGStreamer.h"
+
+#if ENABLE(VIDEO)
+
+#include "GStreamerCommon.h"
+#include "GStreamerVideoSinkCommon.h"
+#include <gst/allocators/gstdmabuf.h>
+#include <mutex>
+#include <wtf/glib/WTFGType.h>
+
+using namespace WebCore;
+
+enum {
+    PROP_0,
+    PROP_STATS,
+    PROP_LAST
+};
+
+struct _WebKitDMABufVideoSinkPrivate {
+    GRefPtr<GstElement> appSink;
+    MediaPlayerPrivateGStreamer* mediaPlayerPrivate;
+};
+
+GST_DEBUG_CATEGORY_STATIC(webkit_dmabuf_video_sink_debug);
+#define GST_CAT_DEFAULT webkit_dmabuf_video_sink_debug
+
+#define GST_WEBKIT_DMABUF_SINK_CAPS_FORMAT_LIST "{ RGBA, RGBx, BGRA, BGRx, I420, YV12, A420, NV12, NV12, Y444, Y42B, VUYA }"
+static GstStaticPadTemplate sinkTemplate = GST_STATIC_PAD_TEMPLATE("sink", GST_PAD_SINK, GST_PAD_ALWAYS, GST_STATIC_CAPS_ANY);
+
+// TODO: this is a list of remaining YUV formats we want to support, but don't currently work (due to improper handling in TextureMapper):
+//     YUY2, YVYU, UYVY, VYUY, AYUV, Y41B
+
+#define webkit_dmabuf_video_sink_parent_class parent_class
+WEBKIT_DEFINE_TYPE_WITH_CODE(WebKitDMABufVideoSink, webkit_dmabuf_video_sink, GST_TYPE_BIN,
+    GST_DEBUG_CATEGORY_INIT(webkit_dmabuf_video_sink_debug, "webkitdmabufvideosink", 0, "DMABuf video sink element"))
+
+// WEBKIT_GST_DMABUF_SINK_FORCED_FALLBACK_CAPS_FORMAT env can be used to force a specific format to be used as the only supported format
+// by this sink. This is most useful for testing and debugging the rendering pipeline behavior for a given format.
+static const char* forcedFallbackCapsFormat()
+{
+    static char s_format[64] { };
+    static std::once_flag s_flag;
+    std::call_once(s_flag,
+        [&] {
+            const char* format = g_getenv("WEBKIT_GST_DMABUF_SINK_FORCED_FALLBACK_CAPS_FORMAT");
+            if (format)
+                g_strlcpy(const_cast<char*>(s_format), format, 64);
+            else
+                s_format[0] = 0;
+        });
+
+    if (!s_format[0])
+        return nullptr;
+    return s_format;
+}
+
+static void webKitDMABufVideoSinkConstructed(GObject* object)
+{
+    GST_CALL_PARENT(G_OBJECT_CLASS, constructed, (object));
+
+    WebKitDMABufVideoSink* sink = WEBKIT_DMABUF_VIDEO_SINK(object);
+
+    sink->priv->appSink = makeGStreamerElement("appsink", "webkit-dmabuf-video-appsink");
+    ASSERT(sink->priv->appSink);
+    g_object_set(sink->priv->appSink.get(), "enable-last-sample", FALSE, "emit-signals", TRUE, "max-buffers", 1, nullptr);
+
+    gst_bin_add(GST_BIN_CAST(sink), sink->priv->appSink.get());
+
+    // This sink handles dmabuf data or raw data of any format in the supported format list.
+    // The dmabuf and raw data types are the two types of data we can handle via this sink (in combination with functionality in
+    // MediaPlayerPrivateGStreamer). The format list corresponds to the formats we are able to then handle in the graphics pipeline.
+    // In case of dmabuf data, that dmabuf is handled most optimally and just relayed to the graphics pipeline.
+    // In case of raw data, dmabuf objects are produced on the spot and filled with that data, and then pushed to the graphics pipeline.
+    static GstStaticCaps s_dmabufCaps = GST_STATIC_CAPS(
+        GST_VIDEO_CAPS_MAKE_WITH_FEATURES(GST_CAPS_FEATURE_MEMORY_DMABUF, GST_WEBKIT_DMABUF_SINK_CAPS_FORMAT_LIST));
+    static GstStaticCaps s_fallbackCaps = GST_STATIC_CAPS(GST_VIDEO_CAPS_MAKE(GST_WEBKIT_DMABUF_SINK_CAPS_FORMAT_LIST));
+
+    GRefPtr<GstCaps> caps = adoptGRef(gst_caps_new_empty());
+    {
+        if (forcedFallbackCapsFormat()) {
+            caps = gst_caps_new_simple("video/x-raw",
+                "format", G_TYPE_STRING, forcedFallbackCapsFormat(), nullptr);
+        } else {
+            gst_caps_append(caps.get(), gst_static_caps_get(&s_dmabufCaps));
+            gst_caps_append(caps.get(), gst_static_caps_get(&s_fallbackCaps));
+        }
+    }
+    g_object_set(sink->priv->appSink.get(), "caps", caps.get(), nullptr);
+
+    GRefPtr<GstPad> pad = adoptGRef(gst_element_get_static_pad(sink->priv->appSink.get(), "sink"));
+    gst_element_add_pad(GST_ELEMENT_CAST(sink), gst_ghost_pad_new("sink", pad.get()));
+}
+
+void webKitDMABufVideoSinkFinalize(GObject* object)
+{
+    ASSERT(isMainThread());
+
+    WebKitDMABufVideoSink* sink = WEBKIT_DMABUF_VIDEO_SINK(object);
+    WebKitDMABufVideoSinkPrivate* priv = sink->priv;
+
+    if (priv->mediaPlayerPrivate)
+        g_signal_handlers_disconnect_by_data(priv->appSink.get(), priv->mediaPlayerPrivate);
+
+    GST_DEBUG_OBJECT(object, "WebKitDMABufVideoSink finalized.");
+
+    GST_CALL_PARENT(G_OBJECT_CLASS, finalize, (object));
+}
+
+static void webKitDMABufVideoSinkGetProperty(GObject* object, guint propertyId, GValue* value, GParamSpec* paramSpec)
+{
+    WebKitDMABufVideoSink* sink = WEBKIT_DMABUF_VIDEO_SINK(object);
+
+    switch (propertyId) {
+    case PROP_STATS:
+        if (webkitGstCheckVersion(1, 18, 0)) {
+            GUniqueOutPtr<GstStructure> stats;
+            g_object_get(sink->priv->appSink.get(), "stats", &stats.outPtr(), nullptr);
+            gst_value_set_structure(value, stats.get());
+        }
+        break;
+    default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propertyId, paramSpec);
+        RELEASE_ASSERT_NOT_REACHED();
+        break;
+    }
+}
+
+static void webkit_dmabuf_video_sink_class_init(WebKitDMABufVideoSinkClass* klass)
+{
+    GObjectClass* objectClass = G_OBJECT_CLASS(klass);
+    GstElementClass* elementClass = GST_ELEMENT_CLASS(klass);
+
+    objectClass->constructed = webKitDMABufVideoSinkConstructed;
+    objectClass->finalize = webKitDMABufVideoSinkFinalize;
+    objectClass->get_property = webKitDMABufVideoSinkGetProperty;
+
+    gst_element_class_add_pad_template(elementClass, gst_static_pad_template_get(&sinkTemplate));
+    gst_element_class_set_static_metadata(elementClass, "WebKit DMABuf video sink", "Sink/Video", "Renders video", "Zan Dobersek <[email protected]>");
+
+    g_object_class_install_property(objectClass, PROP_STATS, g_param_spec_boxed("stats", "Statistics",
+        "Sink Statistics", GST_TYPE_STRUCTURE, static_cast<GParamFlags>(G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)));
+}
+
+void webKitDMABufVideoSinkSetMediaPlayerPrivate(WebKitDMABufVideoSink* sink, MediaPlayerPrivateGStreamer* player)
+{
+    WebKitDMABufVideoSinkPrivate* priv = sink->priv;
+
+    priv->mediaPlayerPrivate = player;
+    webKitVideoSinkSetMediaPlayerPrivate(priv->appSink.get(), priv->mediaPlayerPrivate);
+}
+
+bool webKitDMABufVideoSinkProbePlatform()
+{
+    return isGStreamerPluginAvailable("app");
+}
+
+#endif // ENABLE(VIDEO)

Added: trunk/Source/WebCore/platform/graphics/gstreamer/DMABufVideoSinkGStreamer.h (0 => 290366)


--- trunk/Source/WebCore/platform/graphics/gstreamer/DMABufVideoSinkGStreamer.h	                        (rev 0)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/DMABufVideoSinkGStreamer.h	2022-02-23 12:27:24 UTC (rev 290366)
@@ -0,0 +1,58 @@
+/*
+ *  Copyright (C) 2022 Igalia, S.L
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#pragma once
+
+#if ENABLE(VIDEO)
+
+#include <gst/gst.h>
+
+namespace WebCore {
+class MediaPlayerPrivateGStreamer;
+}
+
+G_BEGIN_DECLS
+
+#define WEBKIT_TYPE_DMABUF_VIDEO_SINK            (webkit_dmabuf_video_sink_get_type ())
+#define WEBKIT_DMABUF_VIDEO_SINK(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), WEBKIT_TYPE_DMABUF_VIDEO_SINK, WebKitDMABufVideoSink))
+#define WEBKIT_DMABUF_VIDEO_SINK_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), WEBKIT_TYPE_DMABUF_VIDEO_SINK, WebKitDMABufVideoSinkClass))
+#define WEBKIT_IS_DMABUF_VIDEO_SINK(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), WEBKIT_TYPE_DMABUF_VIDEO_SINK))
+#define WEBKIT_IS_DMABUF_VIDEO_SINK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), WEBKIT_TYPE_DMABUF_VIDEO_SINK))
+
+typedef struct _WebKitDMABufVideoSink        WebKitDMABufVideoSink;
+typedef struct _WebKitDMABufVideoSinkClass   WebKitDMABufVideoSinkClass;
+typedef struct _WebKitDMABufVideoSinkPrivate WebKitDMABufVideoSinkPrivate;
+
+struct _WebKitDMABufVideoSink {
+    GstBin parent;
+
+    WebKitDMABufVideoSinkPrivate *priv;
+};
+
+struct _WebKitDMABufVideoSinkClass {
+    GstBinClass parentClass;
+};
+
+GType webkit_dmabuf_video_sink_get_type(void);
+
+bool webKitDMABufVideoSinkProbePlatform();
+void webKitDMABufVideoSinkSetMediaPlayerPrivate(WebKitDMABufVideoSink*, WebCore::MediaPlayerPrivateGStreamer*);
+
+G_END_DECLS
+
+#endif // ENABLE(VIDEO)

Modified: trunk/Source/WebCore/platform/graphics/gstreamer/GLVideoSinkGStreamer.cpp (290365 => 290366)


--- trunk/Source/WebCore/platform/graphics/gstreamer/GLVideoSinkGStreamer.cpp	2022-02-23 12:06:12 UTC (rev 290365)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/GLVideoSinkGStreamer.cpp	2022-02-23 12:27:24 UTC (rev 290366)
@@ -23,10 +23,9 @@
 #if ENABLE(VIDEO) && USE(GSTREAMER_GL)
 
 #include "GStreamerCommon.h"
-#include "MediaPlayerPrivateGStreamer.h"
+#include "GStreamerVideoSinkCommon.h"
 #include "PlatformDisplay.h"
-
-#include <gst/app/gstappsink.h>
+#include <gst/gl/gl.h>
 #include <wtf/glib/WTFGType.h>
 
 // gstglapi.h may include eglplatform.h and it includes X.h, which
@@ -242,53 +241,7 @@
     WebKitGLVideoSinkPrivate* priv = sink->priv;
 
     priv->mediaPlayerPrivate = player;
-    g_signal_connect(priv->appSink.get(), "new-sample", G_CALLBACK(+[](GstElement* sink, MediaPlayerPrivateGStreamer* player) -> GstFlowReturn {
-        GRefPtr<GstSample> sample = adoptGRef(gst_app_sink_pull_sample(GST_APP_SINK(sink)));
-        GstBuffer* buffer = gst_sample_get_buffer(sample.get());
-        GST_TRACE_OBJECT(sink, "new-sample with PTS=%" GST_TIME_FORMAT, GST_TIME_ARGS(GST_BUFFER_PTS(buffer)));
-        player->triggerRepaint(sample.get());
-        return GST_FLOW_OK;
-    }), player);
-    g_signal_connect(priv->appSink.get(), "new-preroll", G_CALLBACK(+[](GstElement* sink, MediaPlayerPrivateGStreamer* player) -> GstFlowReturn {
-        GRefPtr<GstSample> sample = adoptGRef(gst_app_sink_pull_preroll(GST_APP_SINK(sink)));
-        GstBuffer* buffer = gst_sample_get_buffer(sample.get());
-        GST_DEBUG_OBJECT(sink, "new-preroll with PTS=%" GST_TIME_FORMAT, GST_TIME_ARGS(GST_BUFFER_PTS(buffer)));
-        player->triggerRepaint(sample.get());
-        return GST_FLOW_OK;
-    }), player);
-
-    GRefPtr<GstPad> pad = adoptGRef(gst_element_get_static_pad(priv->appSink.get(), "sink"));
-    gst_pad_add_probe(pad.get(), static_cast<GstPadProbeType>(GST_PAD_PROBE_TYPE_PUSH | GST_PAD_PROBE_TYPE_QUERY_DOWNSTREAM | GST_PAD_PROBE_TYPE_EVENT_FLUSH | GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM), [](GstPad*, GstPadProbeInfo* info, gpointer userData) -> GstPadProbeReturn {
-        auto* player = static_cast<MediaPlayerPrivateGStreamer*>(userData);
-
-        if (info->type & GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM) {
-            if (GST_EVENT_TYPE(GST_PAD_PROBE_INFO_EVENT(info)) != GST_EVENT_TAG)
-                return GST_PAD_PROBE_OK;
-            GstTagList* tagList;
-            gst_event_parse_tag(GST_PAD_PROBE_INFO_EVENT(info), &tagList);
-            player->updateVideoOrientation(tagList);
-            return GST_PAD_PROBE_OK;
-        }
-
-        // In some platforms (e.g. OpenMAX on the Raspberry Pi) when a resolution change occurs the
-        // pipeline has to be drained before a frame with the new resolution can be decoded.
-        // In this context, it's important that we don't hold references to any previous frame
-        // (e.g. m_sample) so that decoding can continue.
-        // We are also not supposed to keep the original frame after a flush.
-        if (info->type & GST_PAD_PROBE_TYPE_QUERY_DOWNSTREAM) {
-            if (GST_QUERY_TYPE(GST_PAD_PROBE_INFO_QUERY(info)) != GST_QUERY_DRAIN)
-                return GST_PAD_PROBE_OK;
-            GST_DEBUG("Acting upon DRAIN query");
-        }
-        if (info->type & GST_PAD_PROBE_TYPE_EVENT_FLUSH) {
-            if (GST_EVENT_TYPE(GST_PAD_PROBE_INFO_EVENT(info)) != GST_EVENT_FLUSH_START)
-                return GST_PAD_PROBE_OK;
-            GST_DEBUG("Acting upon flush-start event");
-        }
-
-        player->flushCurrentBuffer();
-        return GST_PAD_PROBE_OK;
-    }, player, nullptr);
+    webKitVideoSinkSetMediaPlayerPrivate(priv->appSink.get(), priv->mediaPlayerPrivate);
 }
 
 bool webKitGLVideoSinkProbePlatform()

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


--- trunk/Source/WebCore/platform/graphics/gstreamer/GStreamerCommon.cpp	2022-02-23 12:06:12 UTC (rev 290365)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/GStreamerCommon.cpp	2022-02-23 12:27:24 UTC (rev 290366)
@@ -24,6 +24,7 @@
 #if USE(GSTREAMER)
 
 #include "ApplicationGLib.h"
+#include "DMABufVideoSinkGStreamer.h"
 #include "GLVideoSinkGStreamer.h"
 #include "GStreamerAudioMixer.h"
 #include "GUniquePtrGStreamer.h"
@@ -335,6 +336,7 @@
 
 #if ENABLE(VIDEO)
         gst_element_register(0, "webkitwebsrc", GST_RANK_PRIMARY + 100, WEBKIT_TYPE_WEB_SRC);
+        gst_element_register(0, "webkitdmabufvideosink", GST_RANK_NONE, WEBKIT_TYPE_DMABUF_VIDEO_SINK);
 #if USE(GSTREAMER_GL)
         gst_element_register(0, "webkitglvideosink", GST_RANK_NONE, WEBKIT_TYPE_GL_VIDEO_SINK);
 #endif

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


--- trunk/Source/WebCore/platform/graphics/gstreamer/GStreamerVideoSinkCommon.cpp	                        (rev 0)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/GStreamerVideoSinkCommon.cpp	2022-02-23 12:27:24 UTC (rev 290366)
@@ -0,0 +1,80 @@
+/*
+ *  Copyright (C) 2022 Igalia, S.L
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "config.h"
+#include "GStreamerVideoSinkCommon.h"
+
+#if ENABLE(VIDEO)
+
+#include "MediaPlayerPrivateGStreamer.h"
+#include <gst/app/gstappsink.h>
+
+using namespace WebCore;
+
+void webKitVideoSinkSetMediaPlayerPrivate(GstElement* appSink, MediaPlayerPrivateGStreamer* player)
+{
+    g_signal_connect(appSink, "new-sample", G_CALLBACK(+[](GstElement* sink, MediaPlayerPrivateGStreamer* player) -> GstFlowReturn {
+        GRefPtr<GstSample> sample = adoptGRef(gst_app_sink_pull_sample(GST_APP_SINK(sink)));
+        GstBuffer* buffer = gst_sample_get_buffer(sample.get());
+        GST_TRACE_OBJECT(sink, "new-sample with PTS=%" GST_TIME_FORMAT, GST_TIME_ARGS(GST_BUFFER_PTS(buffer)));
+        player->triggerRepaint(sample.get());
+        return GST_FLOW_OK;
+    }), player);
+    g_signal_connect(appSink, "new-preroll", G_CALLBACK(+[](GstElement* sink, MediaPlayerPrivateGStreamer* player) -> GstFlowReturn {
+        GRefPtr<GstSample> sample = adoptGRef(gst_app_sink_pull_preroll(GST_APP_SINK(sink)));
+        GstBuffer* buffer = gst_sample_get_buffer(sample.get());
+        GST_DEBUG_OBJECT(sink, "new-preroll with PTS=%" GST_TIME_FORMAT, GST_TIME_ARGS(GST_BUFFER_PTS(buffer)));
+        player->triggerRepaint(sample.get());
+        return GST_FLOW_OK;
+    }), player);
+
+    GRefPtr<GstPad> pad = adoptGRef(gst_element_get_static_pad(appSink, "sink"));
+    gst_pad_add_probe(pad.get(), static_cast<GstPadProbeType>(GST_PAD_PROBE_TYPE_PUSH | GST_PAD_PROBE_TYPE_QUERY_DOWNSTREAM | GST_PAD_PROBE_TYPE_EVENT_FLUSH | GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM), [](GstPad*, GstPadProbeInfo* info, gpointer userData) -> GstPadProbeReturn {
+        auto* player = static_cast<MediaPlayerPrivateGStreamer*>(userData);
+
+        if (info->type & GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM) {
+            if (GST_EVENT_TYPE(GST_PAD_PROBE_INFO_EVENT(info)) != GST_EVENT_TAG)
+                return GST_PAD_PROBE_OK;
+            GstTagList* tagList;
+            gst_event_parse_tag(GST_PAD_PROBE_INFO_EVENT(info), &tagList);
+            player->updateVideoOrientation(tagList);
+            return GST_PAD_PROBE_OK;
+        }
+
+        // In some platforms (e.g. OpenMAX on the Raspberry Pi) when a resolution change occurs the
+        // pipeline has to be drained before a frame with the new resolution can be decoded.
+        // In this context, it's important that we don't hold references to any previous frame
+        // (e.g. m_sample) so that decoding can continue.
+        // We are also not supposed to keep the original frame after a flush.
+        if (info->type & GST_PAD_PROBE_TYPE_QUERY_DOWNSTREAM) {
+            if (GST_QUERY_TYPE(GST_PAD_PROBE_INFO_QUERY(info)) != GST_QUERY_DRAIN)
+                return GST_PAD_PROBE_OK;
+            GST_DEBUG("Acting upon DRAIN query");
+        }
+        if (info->type & GST_PAD_PROBE_TYPE_EVENT_FLUSH) {
+            if (GST_EVENT_TYPE(GST_PAD_PROBE_INFO_EVENT(info)) != GST_EVENT_FLUSH_START)
+                return GST_PAD_PROBE_OK;
+            GST_DEBUG("Acting upon flush-start event");
+        }
+
+        player->flushCurrentBuffer();
+        return GST_PAD_PROBE_OK;
+    }, player, nullptr);
+}
+
+#endif // ENABLE(VIDEO)

Added: trunk/Source/WebCore/platform/graphics/gstreamer/GStreamerVideoSinkCommon.h (0 => 290366)


--- trunk/Source/WebCore/platform/graphics/gstreamer/GStreamerVideoSinkCommon.h	                        (rev 0)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/GStreamerVideoSinkCommon.h	2022-02-23 12:27:24 UTC (rev 290366)
@@ -0,0 +1,31 @@
+/*
+ *  Copyright (C) 2022 Igalia, S.L
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#pragma once
+
+#if ENABLE(VIDEO)
+
+#include <gst/gst.h>
+
+namespace WebCore {
+class MediaPlayerPrivateGStreamer;
+}
+
+void webKitVideoSinkSetMediaPlayerPrivate(GstElement*, WebCore::MediaPlayerPrivateGStreamer*);
+
+#endif // ENABLE(VIDEO)

Modified: trunk/Source/cmake/FindGStreamer.cmake (290365 => 290366)


--- trunk/Source/cmake/FindGStreamer.cmake	2022-02-23 12:06:12 UTC (rev 290365)
+++ trunk/Source/cmake/FindGStreamer.cmake	2022-02-23 12:27:24 UTC (rev 290366)
@@ -16,6 +16,7 @@
 # plugins can be searched, and they define the following variables if
 # found:
 #
+#  gstreamer-allocators: GSTREAMER_ALLOCATORS_INCLUDE_DIRS and GSTREAMER_ALLOCATORS_LIBRARIES
 #  gstreamer-app:        GSTREAMER_APP_INCLUDE_DIRS and GSTREAMER_APP_LIBRARIES
 #  gstreamer-audio:      GSTREAMER_AUDIO_INCLUDE_DIRS and GSTREAMER_AUDIO_LIBRARIES
 #  gstreamer-fft:        GSTREAMER_FFT_INCLUDE_DIRS and GSTREAMER_FFT_LIBRARIES
@@ -98,6 +99,7 @@
 # 2. Find GStreamer plugins
 # -------------------------
 
+FIND_GSTREAMER_COMPONENT(GSTREAMER_ALLOCATORS gstreamer-allocators-1.0 gstallocators-1.0)
 FIND_GSTREAMER_COMPONENT(GSTREAMER_APP gstreamer-app-1.0 gstapp-1.0)
 FIND_GSTREAMER_COMPONENT(GSTREAMER_AUDIO gstreamer-audio-1.0 gstaudio-1.0)
 FIND_GSTREAMER_COMPONENT(GSTREAMER_FFT gstreamer-fft-1.0 gstfft-1.0)
@@ -126,6 +128,8 @@
                                             VERSION_VAR   GSTREAMER_VERSION)
 
 mark_as_advanced(
+    GSTREAMER_ALLOCATORS_INCLUDE_DIRS
+    GSTREAMER_ALLOCATORS_LIBRARIES
     GSTREAMER_APP_INCLUDE_DIRS
     GSTREAMER_APP_LIBRARIES
     GSTREAMER_AUDIO_INCLUDE_DIRS

Modified: trunk/Tools/ChangeLog (290365 => 290366)


--- trunk/Tools/ChangeLog	2022-02-23 12:06:12 UTC (rev 290365)
+++ trunk/Tools/ChangeLog	2022-02-23 12:27:24 UTC (rev 290366)
@@ -1,3 +1,13 @@
+2022-02-23  Zan Dobersek  <[email protected]>
+
+        [GStreamer] Add WebKitDMABufVideoSink
+        https://bugs.webkit.org/show_bug.cgi?id=236883
+
+        Reviewed by Philippe Normand.
+
+        * Scripts/webkitpy/style/checker.py:
+        Add two additional files under the GObject-style exceptions.
+
 2022-02-23  Kimmo Kinnunen  <[email protected]>
 
         Thread safety analysis macros are confusing for non-Lock use-cases

Modified: trunk/Tools/Scripts/webkitpy/style/checker.py (290365 => 290366)


--- trunk/Tools/Scripts/webkitpy/style/checker.py	2022-02-23 12:06:12 UTC (rev 290365)
+++ trunk/Tools/Scripts/webkitpy/style/checker.py	2022-02-23 12:27:24 UTC (rev 290366)
@@ -230,6 +230,8 @@
       # 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', 'DMABufVideoSinkGStreamer.cpp'),
+      os.path.join('Source', 'WebCore', 'platform', 'graphics', 'gstreamer', 'DMABufVideoSinkGStreamer.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'),
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to