Title: [280239] trunk
Revision
280239
Author
[email protected]
Date
2021-07-23 03:51:17 -0700 (Fri, 23 Jul 2021)

Log Message

[GLib] Remove libportal dependency
https://bugs.webkit.org/show_bug.cgi?id=228056

Reviewed by Carlos Garcia Campos.

.:

* Source/cmake/FindLIBPORTAL.cmake: Removed.
* Source/cmake/GStreamerChecks.cmake:

Source/WebCore:

The pure-GDBus approach allows us to request the input device (Monitor or Window) depending
on the CaptureDevice type and make the mouse cursor visible in the generated video stream.
Also requesting capture support within computeCaptureDevices() was a bad idea because this
being used by the enumerateMediaDevices API could potentially spam the user with permission
popups.

* platform/GStreamer.cmake:
* platform/mediastream/gstreamer/GStreamerCaptureDeviceManager.cpp:
* platform/mediastream/gstreamer/GStreamerCaptureDeviceManager.h:
* platform/mediastream/gstreamer/GStreamerDisplayCaptureDeviceManager.cpp: Added.
(WebCore::GStreamerDisplayCaptureDeviceManager::singleton):
(WebCore::GStreamerDisplayCaptureDeviceManager::GStreamerDisplayCaptureDeviceManager):
(WebCore::GStreamerDisplayCaptureDeviceManager::~GStreamerDisplayCaptureDeviceManager):
(WebCore::GStreamerDisplayCaptureDeviceManager::computeCaptureDevices):
(WebCore::GStreamerDisplayCaptureDeviceManager::createDisplayCaptureSource):
(WebCore::GStreamerDisplayCaptureDeviceManager::stopSource):
(WebCore::GStreamerDisplayCaptureDeviceManager::waitResponseSignal):
* platform/mediastream/gstreamer/GStreamerVideoCaptureSource.cpp:
(WebCore::GStreamerVideoCaptureSource::createPipewireSource):
(WebCore::GStreamerVideoCaptureSource::factory):
(WebCore::GStreamerVideoCaptureSource::displayFactory):
(WebCore::GStreamerVideoCaptureSource::GStreamerVideoCaptureSource):
(WebCore::GStreamerVideoCaptureSource::stopProducingData):
* platform/mediastream/gstreamer/GStreamerVideoCaptureSource.h:
* platform/mediastream/gstreamer/GStreamerVideoCapturer.cpp:
* platform/mediastream/gstreamer/GStreamerVideoCapturer.h:

Source/WTF:

* Scripts/Preferences/WebPreferencesExperimental.yaml: Enable screen capture on GStreamer
ports. The PIPEWIRE ifdef is redundant.

Modified Paths

Added Paths

Removed Paths

Diff

Modified: trunk/ChangeLog (280238 => 280239)


--- trunk/ChangeLog	2021-07-23 10:11:24 UTC (rev 280238)
+++ trunk/ChangeLog	2021-07-23 10:51:17 UTC (rev 280239)
@@ -1,3 +1,13 @@
+2021-07-23  Philippe Normand  <[email protected]>
+
+        [GLib] Remove libportal dependency
+        https://bugs.webkit.org/show_bug.cgi?id=228056
+
+        Reviewed by Carlos Garcia Campos.
+
+        * Source/cmake/FindLIBPORTAL.cmake: Removed.
+        * Source/cmake/GStreamerChecks.cmake:
+
 2021-07-16  Alexander Mikhaylenko  <[email protected]>
 
         [GTK][WPE] Support color-schemes CSS property

Modified: trunk/Source/WTF/ChangeLog (280238 => 280239)


--- trunk/Source/WTF/ChangeLog	2021-07-23 10:11:24 UTC (rev 280238)
+++ trunk/Source/WTF/ChangeLog	2021-07-23 10:51:17 UTC (rev 280239)
@@ -1,3 +1,13 @@
+2021-07-23  Philippe Normand  <[email protected]>
+
+        [GLib] Remove libportal dependency
+        https://bugs.webkit.org/show_bug.cgi?id=228056
+
+        Reviewed by Carlos Garcia Campos.
+
+        * Scripts/Preferences/WebPreferencesExperimental.yaml: Enable screen capture on GStreamer
+        ports. The PIPEWIRE ifdef is redundant.
+
 2021-07-22  Brent Fulgham  <[email protected]>
 
         REGRESSION (r278877) [Cocoa] WebAuthn stopped working for non-Safari browsers 

Modified: trunk/Source/WTF/Scripts/Preferences/WebPreferencesExperimental.yaml (280238 => 280239)


--- trunk/Source/WTF/Scripts/Preferences/WebPreferencesExperimental.yaml	2021-07-23 10:11:24 UTC (rev 280238)
+++ trunk/Source/WTF/Scripts/Preferences/WebPreferencesExperimental.yaml	2021-07-23 10:51:17 UTC (rev 280239)
@@ -940,7 +940,7 @@
     WebKitLegacy:
       default: false
     WebKit:
-      "PLATFORM(MAC) || USE(PIPEWIRE)": true
+      "PLATFORM(MAC) || USE(GSTREAMER)": true
       default: false
     WebCore:
       default: false

Modified: trunk/Source/WebCore/ChangeLog (280238 => 280239)


--- trunk/Source/WebCore/ChangeLog	2021-07-23 10:11:24 UTC (rev 280238)
+++ trunk/Source/WebCore/ChangeLog	2021-07-23 10:51:17 UTC (rev 280239)
@@ -1,3 +1,37 @@
+2021-07-23  Philippe Normand  <[email protected]>
+
+        [GLib] Remove libportal dependency
+        https://bugs.webkit.org/show_bug.cgi?id=228056
+
+        Reviewed by Carlos Garcia Campos.
+
+        The pure-GDBus approach allows us to request the input device (Monitor or Window) depending
+        on the CaptureDevice type and make the mouse cursor visible in the generated video stream.
+        Also requesting capture support within computeCaptureDevices() was a bad idea because this
+        being used by the enumerateMediaDevices API could potentially spam the user with permission
+        popups.
+
+        * platform/GStreamer.cmake:
+        * platform/mediastream/gstreamer/GStreamerCaptureDeviceManager.cpp:
+        * platform/mediastream/gstreamer/GStreamerCaptureDeviceManager.h:
+        * platform/mediastream/gstreamer/GStreamerDisplayCaptureDeviceManager.cpp: Added.
+        (WebCore::GStreamerDisplayCaptureDeviceManager::singleton):
+        (WebCore::GStreamerDisplayCaptureDeviceManager::GStreamerDisplayCaptureDeviceManager):
+        (WebCore::GStreamerDisplayCaptureDeviceManager::~GStreamerDisplayCaptureDeviceManager):
+        (WebCore::GStreamerDisplayCaptureDeviceManager::computeCaptureDevices):
+        (WebCore::GStreamerDisplayCaptureDeviceManager::createDisplayCaptureSource):
+        (WebCore::GStreamerDisplayCaptureDeviceManager::stopSource):
+        (WebCore::GStreamerDisplayCaptureDeviceManager::waitResponseSignal):
+        * platform/mediastream/gstreamer/GStreamerVideoCaptureSource.cpp:
+        (WebCore::GStreamerVideoCaptureSource::createPipewireSource):
+        (WebCore::GStreamerVideoCaptureSource::factory):
+        (WebCore::GStreamerVideoCaptureSource::displayFactory):
+        (WebCore::GStreamerVideoCaptureSource::GStreamerVideoCaptureSource):
+        (WebCore::GStreamerVideoCaptureSource::stopProducingData):
+        * platform/mediastream/gstreamer/GStreamerVideoCaptureSource.h:
+        * platform/mediastream/gstreamer/GStreamerVideoCapturer.cpp:
+        * platform/mediastream/gstreamer/GStreamerVideoCapturer.h:
+
 2021-07-22  Said Abou-Hallawa  <[email protected]>
 
         Unreviewed, reverting 280130.

Modified: trunk/Source/WebCore/platform/GStreamer.cmake (280238 => 280239)


--- trunk/Source/WebCore/platform/GStreamer.cmake	2021-07-23 10:11:24 UTC (rev 280238)
+++ trunk/Source/WebCore/platform/GStreamer.cmake	2021-07-23 10:51:17 UTC (rev 280239)
@@ -58,6 +58,7 @@
         platform/mediastream/gstreamer/GStreamerAudioCapturer.cpp
         platform/mediastream/gstreamer/GStreamerCaptureDeviceManager.cpp
         platform/mediastream/gstreamer/GStreamerCapturer.cpp
+        platform/mediastream/gstreamer/GStreamerDisplayCaptureDeviceManager.cpp
         platform/mediastream/gstreamer/GStreamerMediaStreamSource.cpp
         platform/mediastream/gstreamer/GStreamerVideoCaptureSource.cpp
         platform/mediastream/gstreamer/GStreamerVideoCapturer.cpp
@@ -152,10 +153,6 @@
                 ${GSTREAMER_CODECPARSERS_LIBRARIES}
             )
         endif ()
-
-        if (USE_PIPEWIRE)
-            list(APPEND WebCore_LIBRARIES LIBPORTAL::LIBPORTAL)
-        endif ()
     endif ()
 endif ()
 

Modified: trunk/Source/WebCore/platform/mediastream/gstreamer/GStreamerCaptureDeviceManager.cpp (280238 => 280239)


--- trunk/Source/WebCore/platform/mediastream/gstreamer/GStreamerCaptureDeviceManager.cpp	2021-07-23 10:11:24 UTC (rev 280238)
+++ trunk/Source/WebCore/platform/mediastream/gstreamer/GStreamerCaptureDeviceManager.cpp	2021-07-23 10:51:17 UTC (rev 280239)
@@ -25,7 +25,6 @@
 #include "GStreamerCaptureDeviceManager.h"
 
 #include "GStreamerCommon.h"
-#include <wtf/text/IntegerToStringConversion.h>
 
 namespace WebCore {
 
@@ -64,12 +63,6 @@
     return manager;
 }
 
-GStreamerDisplayCaptureDeviceManager& GStreamerDisplayCaptureDeviceManager::singleton()
-{
-    static NeverDestroyed<GStreamerDisplayCaptureDeviceManager> manager;
-    return manager;
-}
-
 GStreamerCaptureDeviceManager::~GStreamerCaptureDeviceManager()
 {
     if (m_deviceMonitor)
@@ -203,97 +196,6 @@
     }
 }
 
-GStreamerDisplayCaptureDeviceManager::GStreamerDisplayCaptureDeviceManager()
-{
-#if USE(PIPEWIRE)
-    m_portal = adoptGRef(xdp_portal_new());
-#endif
-}
-
-GStreamerDisplayCaptureDeviceManager::~GStreamerDisplayCaptureDeviceManager()
-{
-#if USE(PIPEWIRE)
-    if (m_session) {
-        xdp_session_close(m_session.get());
-        m_session = nullptr;
-    }
-#endif
-}
-
-void GStreamerDisplayCaptureDeviceManager::computeCaptureDevices(CompletionHandler<void()>&& callback)
-{
-#if USE(PIPEWIRE)
-    m_callback = WTFMove(callback);
-    xdp_portal_create_screencast_session(m_portal.get(), static_cast<XdpOutputType>(XDP_OUTPUT_MONITOR | XDP_OUTPUT_WINDOW), XDP_SCREENCAST_FLAG_NONE, nullptr, [](GObject* source, GAsyncResult* result, gpointer userData) {
-        GUniqueOutPtr<GError> error;
-        auto* session = xdp_portal_create_screencast_session_finish(XDP_PORTAL(source), result, &error.outPtr());
-        if (!session) {
-            WTFLogAlways("Failed to create screencast session: %s", error->message);
-            return;
-        }
-        auto& manager = *reinterpret_cast<GStreamerDisplayCaptureDeviceManager*>(userData);
-        manager.setSession(session);
-    }, this);
-#else
-    ASSERT_NOT_REACHED();
-    callback();
-#endif
-}
-
-#if USE(PIPEWIRE)
-void GStreamerDisplayCaptureDeviceManager::setSession(XdpSession* session)
-{
-    ASSERT(session);
-    m_session = adoptGRef(session);
-
-    g_signal_connect_swapped(m_session.get(), "closed", G_CALLBACK(+[](GStreamerDisplayCaptureDeviceManager* manager, XdpSession*) {
-        manager->sessionWasClosed();
-    }), this);
-    xdp_session_start(m_session.get(), nullptr, nullptr, [](GObject* source, GAsyncResult* result, gpointer userData) {
-        auto* session = XDP_SESSION(source);
-        GUniqueOutPtr<GError> error;
-        auto& manager = *reinterpret_cast<GStreamerDisplayCaptureDeviceManager*>(userData);
-        if (!xdp_session_start_finish(session, result, &error.outPtr())) {
-            WTFLogAlways("Failed to start screencast session: %s", error->message);
-            manager.notifyClient();
-            return;
-        }
-
-        manager.sessionStarted();
-    }, this);
-}
-#endif
-
-void GStreamerDisplayCaptureDeviceManager::sessionStarted()
-{
-    m_devices.clear();
-#if USE(PIPEWIRE)
-    int fd = xdp_session_open_pipewire_remote(m_session.get());
-
-    // FIXME: The libportal API doesn't seem to expose which XdpOutputType was selected by the
-    // user, so hardcode Screen here. 🤷
-    CaptureDevice captureDevice(WTF::numberToStringUnsigned<String>(fd), CaptureDevice::DeviceType::Screen, makeString("Capture Display"));
-    captureDevice.setEnabled(true);
-    m_devices.append(WTFMove(captureDevice));
-#endif
-    notifyClient();
-}
-
-void GStreamerDisplayCaptureDeviceManager::notifyClient()
-{
-    if (m_callback)
-        m_callback();
-}
-
-void GStreamerDisplayCaptureDeviceManager::sessionWasClosed()
-{
-#if USE(PIPEWIRE)
-    m_session = nullptr;
-#endif
-    m_devices.clear();
-    deviceChanged();
-}
-
 } // namespace WebCore
 
 #endif // ENABLE(MEDIA_STREAM) && USE(GSTREAMER)

Modified: trunk/Source/WebCore/platform/mediastream/gstreamer/GStreamerCaptureDeviceManager.h (280238 => 280239)


--- trunk/Source/WebCore/platform/mediastream/gstreamer/GStreamerCaptureDeviceManager.h	2021-07-23 10:11:24 UTC (rev 280238)
+++ trunk/Source/WebCore/platform/mediastream/gstreamer/GStreamerCaptureDeviceManager.h	2021-07-23 10:51:17 UTC (rev 280239)
@@ -28,10 +28,6 @@
 #include "GStreamerCaptureDevice.h"
 #include "RealtimeMediaSourceFactory.h"
 
-#if USE(PIPEWIRE)
-#include <libportal/portal.h>
-#endif
-
 namespace WebCore {
 
 class GStreamerCaptureDeviceManager : public CaptureDeviceManager {
@@ -76,26 +72,46 @@
     static GStreamerDisplayCaptureDeviceManager& singleton();
     const Vector<CaptureDevice>& captureDevices() final { return m_devices; };
     void computeCaptureDevices(CompletionHandler<void()>&&) final;
+    CaptureSourceOrError createDisplayCaptureSource(const CaptureDevice&, const MediaConstraints*);
 
+    enum PipeWireOutputType {
+        Monitor = 1 << 0,
+        Window = 1 << 1
+    };
+
+    void stopSource(const String& persistentID);
+
 protected:
-#if USE(PIPEWIRE)
-    void setSession(XdpSession*);
-#endif
-    void sessionStarted();
-    void notifyClient();
-    void sessionWasClosed();
+    void notifyResponse() { m_currentResponseCallback(); }
 
 private:
     GStreamerDisplayCaptureDeviceManager();
     ~GStreamerDisplayCaptureDeviceManager();
 
-    CompletionHandler<void()> m_callback;
+    void waitResponseSignal(const char* objectPath);
+
     Vector<CaptureDevice> m_devices;
-#if USE(PIPEWIRE)
-    GRefPtr<XdpPortal> m_portal;
-    GRefPtr<XdpSession> m_session;
-#endif
+
+    struct Session {
+        WTF_MAKE_STRUCT_FAST_ALLOCATED;
+        WTF_MAKE_NONCOPYABLE(Session);
+        Session(int fd, String&& path)
+            : fd(fd)
+            , path(WTFMove(path)) { }
+
+        ~Session()
+        {
+            close(fd);
+        }
+
+        int fd;
+        String path;
+    };
+    HashMap<String, std::unique_ptr<Session>> m_sessions;
+
+    GRefPtr<GDBusProxy> m_proxy;
+    CompletionHandler<void()> m_currentResponseCallback;
 };
 }
 
-#endif // ENABLE(MEDIA_STREAM)  && USE(GSTREAMER)
+#endif // ENABLE(MEDIA_STREAM) && USE(GSTREAMER)

Added: trunk/Source/WebCore/platform/mediastream/gstreamer/GStreamerDisplayCaptureDeviceManager.cpp (0 => 280239)


--- trunk/Source/WebCore/platform/mediastream/gstreamer/GStreamerDisplayCaptureDeviceManager.cpp	                        (rev 0)
+++ trunk/Source/WebCore/platform/mediastream/gstreamer/GStreamerDisplayCaptureDeviceManager.cpp	2021-07-23 10:51:17 UTC (rev 280239)
@@ -0,0 +1,198 @@
+/*
+ * Copyright (C) 2018 Metrological Group B.V.
+ * Author: Thibault Saunier <[email protected]>
+ * Author: Alejandro G. Castro <[email protected]>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * aint with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+
+#if ENABLE(MEDIA_STREAM) && USE(GSTREAMER)
+#include "GStreamerCaptureDeviceManager.h"
+
+#include "GStreamerCommon.h"
+#include "GStreamerVideoCaptureSource.h"
+#include <gio/gunixfdlist.h>
+#include <wtf/UUID.h>
+
+namespace WebCore {
+
+static const Seconds s_dbusCallTimeout = 10_ms;
+
+GStreamerDisplayCaptureDeviceManager& GStreamerDisplayCaptureDeviceManager::singleton()
+{
+    static NeverDestroyed<GStreamerDisplayCaptureDeviceManager> manager;
+    return manager;
+}
+
+GStreamerDisplayCaptureDeviceManager::GStreamerDisplayCaptureDeviceManager()
+{
+}
+
+GStreamerDisplayCaptureDeviceManager::~GStreamerDisplayCaptureDeviceManager()
+{
+    for (auto& sourceId : m_sessions.keys())
+        stopSource(sourceId);
+}
+
+void GStreamerDisplayCaptureDeviceManager::computeCaptureDevices(CompletionHandler<void()>&& callback)
+{
+    m_devices.clear();
+
+    CaptureDevice screenCaptureDevice(WTF::createCanonicalUUIDString(), CaptureDevice::DeviceType::Screen, makeString("Capture Screen"));
+    screenCaptureDevice.setEnabled(true);
+    m_devices.append(WTFMove(screenCaptureDevice));
+    callback();
+}
+
+CaptureSourceOrError GStreamerDisplayCaptureDeviceManager::createDisplayCaptureSource(const CaptureDevice& device, const MediaConstraints* constraints)
+{
+    const auto it = m_sessions.find(device.persistentId());
+    if (it != m_sessions.end()) {
+        return GStreamerVideoCaptureSource::createPipewireSource(device.persistentId().isolatedCopy(),
+            it->value->fd, { }, constraints, device.type());
+    }
+
+    GUniqueOutPtr<GError> error;
+    m_proxy = adoptGRef(g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SESSION,
+        static_cast<GDBusProxyFlags>(G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS | G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES), nullptr,
+        "org.freedesktop.portal.Desktop", "/org/freedesktop/portal/desktop", "org.freedesktop.portal.ScreenCast", nullptr, &error.outPtr()));
+    if (error) {
+        WTFLogAlways("Unable to connect to the Deskop portal: %s\n", error->message);
+        return { };
+    }
+
+    auto token = makeString("WebKit", WTF::weakRandomUint32());
+    auto sessionToken = makeString("WebKit", WTF::weakRandomUint32());
+    GVariantBuilder options;
+    g_variant_builder_init(&options, G_VARIANT_TYPE_VARDICT);
+    g_variant_builder_add(&options, "{sv}", "handle_token", g_variant_new_string(token.ascii().data()));
+    g_variant_builder_add(&options, "{sv}", "session_handle_token", g_variant_new_string(sessionToken.ascii().data()));
+
+    auto result = adoptGRef(g_dbus_proxy_call_sync(m_proxy.get(), "CreateSession", g_variant_new("(a{sv})", &options),
+        G_DBUS_CALL_FLAGS_NONE, s_dbusCallTimeout.millisecondsAs<int>(), nullptr, &error.outPtr()));
+    if (error) {
+        WTFLogAlways("Unable to create a Deskop portal session: %s\n", error->message);
+        return { };
+    }
+
+    GUniqueOutPtr<char> objectPath;
+    g_variant_get(result.get(), "(o)", &objectPath.outPtr());
+    waitResponseSignal(objectPath.get());
+
+    String requestPath(objectPath.get());
+    auto sessionPath = requestPath.replace("/request/", "/session/").replace(token, sessionToken);
+
+    // FIXME: Maybe check this depending on device.type().
+    auto outputType = GStreamerDisplayCaptureDeviceManager::PipeWireOutputType::Monitor | GStreamerDisplayCaptureDeviceManager::PipeWireOutputType::Window;
+
+    token = makeString("WebKit", WTF::weakRandomUint32());
+    g_variant_builder_init(&options, G_VARIANT_TYPE_VARDICT);
+    g_variant_builder_add(&options, "{sv}", "handle_token", g_variant_new_string(token.ascii().data()));
+    g_variant_builder_add(&options, "{sv}", "types", g_variant_new_uint32(static_cast<uint32_t>(outputType)));
+    g_variant_builder_add(&options, "{sv}", "multiple", g_variant_new_boolean(false));
+
+    auto propertiesResult = adoptGRef(g_dbus_proxy_call_sync(m_proxy.get(), "org.freedesktop.DBus.Properties.Get",
+        g_variant_new("(ss)", "org.freedesktop.portal.ScreenCast", "version"), G_DBUS_CALL_FLAGS_NONE,
+        s_dbusCallTimeout.millisecondsAs<int>(), nullptr, nullptr));
+    if (propertiesResult) {
+        GRefPtr<GVariant> property;
+        g_variant_get(propertiesResult.get(), "(v)", &property.outPtr());
+        if (g_variant_get_uint32(property.get()) >= 2) {
+            // Enable embedded cursor. FIXME: Should be checked in the constraints.
+            g_variant_builder_add(&options, "{sv}", "cursor_mode", g_variant_new_uint32(2));
+        }
+    }
+
+    result = adoptGRef(g_dbus_proxy_call_sync(m_proxy.get(), "SelectSources",
+        g_variant_new("(oa{sv})", sessionPath.ascii().data(), &options), G_DBUS_CALL_FLAGS_NONE, s_dbusCallTimeout.millisecondsAs<int>(), nullptr, &error.outPtr()));
+    if (error) {
+        WTFLogAlways("SelectSources error: %s\n", error->message);
+        return { };
+    }
+    g_variant_get(result.get(), "(o)", &objectPath.outPtr());
+    waitResponseSignal(objectPath.get());
+
+    token = makeString("WebKit", WTF::weakRandomUint32());
+    g_variant_builder_init(&options, G_VARIANT_TYPE_VARDICT);
+    g_variant_builder_add(&options, "{sv}", "handle_token", g_variant_new_string(token.ascii().data()));
+    result = adoptGRef(g_dbus_proxy_call_sync(m_proxy.get(), "Start",
+        g_variant_new("(osa{sv})", sessionPath.ascii().data(), "", &options), G_DBUS_CALL_FLAGS_NONE, s_dbusCallTimeout.millisecondsAs<int>(), nullptr, &error.outPtr()));
+    if (error) {
+        WTFLogAlways("Start error: %s\n", error->message);
+        return { };
+    }
+
+    g_variant_get(result.get(), "(o)", &objectPath.outPtr());
+    waitResponseSignal(objectPath.get());
+
+    GRefPtr<GUnixFDList> fdList;
+    int fd = -1;
+    g_variant_builder_init(&options, G_VARIANT_TYPE_VARDICT);
+    result = adoptGRef(g_dbus_proxy_call_with_unix_fd_list_sync(m_proxy.get(), "OpenPipeWireRemote",
+        g_variant_new("(oa{sv})", sessionPath.ascii().data(), &options), G_DBUS_CALL_FLAGS_NONE, s_dbusCallTimeout.millisecondsAs<int>(), nullptr, &fdList.outPtr(), nullptr, &error.outPtr()));
+    if (error) {
+        WTFLogAlways("Unable to request display capture. Error: %s", error->message);
+        return { };
+    }
+
+    int fdOut;
+    g_variant_get(result.get(), "(h)", &fdOut);
+    fd = g_unix_fd_list_get(fdList.get(), fdOut, nullptr);
+
+    auto session = WTF::makeUnique<GStreamerDisplayCaptureDeviceManager::Session>(fd, WTFMove(sessionPath));
+    m_sessions.add(device.persistentId(), WTFMove(session));
+    return GStreamerVideoCaptureSource::createPipewireSource(device.persistentId().isolatedCopy(), fd, { }, constraints, device.type());
+}
+
+void GStreamerDisplayCaptureDeviceManager::stopSource(const String& persistentID)
+{
+    auto session = m_sessions.take(persistentID);
+    GUniqueOutPtr<GError> error;
+    auto proxy = adoptGRef(g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SESSION,
+        static_cast<GDBusProxyFlags>(G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS | G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES), nullptr,
+        "org.freedesktop.portal.Desktop", session->path.ascii().data(), "org.freedesktop.portal.Session", nullptr, &error.outPtr()));
+    if (error) {
+        WTFLogAlways("Unable to connect to the Deskop portal: %s\n", error->message);
+        return;
+    }
+    auto result = adoptGRef(g_dbus_proxy_call_sync(proxy.get(), "Close", nullptr, G_DBUS_CALL_FLAGS_NONE,
+        s_dbusCallTimeout.millisecondsAs<int>(), nullptr, &error.outPtr()));
+    if (error)
+        WTFLogAlways("Portal session could not be closed: %s\n", error->message);
+}
+
+void GStreamerDisplayCaptureDeviceManager::waitResponseSignal(const char* objectPath)
+{
+    RELEASE_ASSERT(!m_currentResponseCallback);
+    m_currentResponseCallback = [] { };
+    auto* connection = g_dbus_proxy_get_connection(m_proxy.get());
+    auto signalId = g_dbus_connection_signal_subscribe(connection, "org.freedesktop.portal.Desktop", "org.freedesktop.portal.Request",
+        "Response", objectPath, nullptr, G_DBUS_SIGNAL_FLAGS_NO_MATCH_RULE, reinterpret_cast<GDBusSignalCallback>(+[](GDBusConnection*, const char* /* senderName */, const char* /* objectPath */, const char* /* interfaceName */, const char* /* signalName */, GVariant* /* parameters */, gpointer userData) {
+            auto& manager = *reinterpret_cast<GStreamerDisplayCaptureDeviceManager*>(userData);
+            manager.notifyResponse();
+        }), this, nullptr);
+
+    while (m_currentResponseCallback)
+        g_main_context_iteration(nullptr, false);
+
+    g_dbus_connection_signal_unsubscribe(connection, signalId);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(MEDIA_STREAM) && USE(GSTREAMER)

Modified: trunk/Source/WebCore/platform/mediastream/gstreamer/GStreamerVideoCaptureSource.cpp (280238 => 280239)


--- trunk/Source/WebCore/platform/mediastream/gstreamer/GStreamerVideoCaptureSource.cpp	2021-07-23 10:11:24 UTC (rev 280238)
+++ trunk/Source/WebCore/platform/mediastream/gstreamer/GStreamerVideoCaptureSource.cpp	2021-07-23 10:51:17 UTC (rev 280239)
@@ -29,7 +29,6 @@
 #include "MediaSampleGStreamer.h"
 
 #include <gst/app/gstappsink.h>
-#include <wtf/text/StringToIntegerConversion.h>
 
 namespace WebCore {
 
@@ -70,34 +69,17 @@
     CaptureDeviceManager& videoCaptureDeviceManager() final { return GStreamerVideoCaptureDeviceManager::singleton(); }
 };
 
-VideoCaptureFactory& libWebRTCVideoCaptureSourceFactory()
-{
-    static NeverDestroyed<GStreamerVideoCaptureSourceFactory> factory;
-    return factory.get();
-}
-
 class GStreamerDisplayCaptureSourceFactory final : public DisplayCaptureFactory {
 public:
     CaptureSourceOrError createDisplayCaptureSource(const CaptureDevice& device, const MediaConstraints* constraints) final
     {
-#if USE(PIPEWIRE)
-        return GStreamerVideoCaptureSource::createPipewireSource(device.persistentId().isolatedCopy(), { }, constraints, device.type());
-#else
-        UNUSED_PARAM(device);
-        UNUSED_PARAM(constraints);
-        return { };
-#endif
+        auto& manager = GStreamerDisplayCaptureDeviceManager::singleton();
+        return manager.createDisplayCaptureSource(device, constraints);
     }
 private:
     CaptureDeviceManager& displayCaptureDeviceManager() final { return GStreamerDisplayCaptureDeviceManager::singleton(); }
 };
 
-DisplayCaptureFactory& libWebRTCDisplayCaptureSourceFactory()
-{
-    static NeverDestroyed<GStreamerDisplayCaptureSourceFactory> factory;
-    return factory.get();
-}
-
 CaptureSourceOrError GStreamerVideoCaptureSource::create(String&& deviceID, String&& hashSalt, const MediaConstraints* constraints)
 {
     auto device = GStreamerVideoCaptureDeviceManager::singleton().gstreamerDeviceWithUID(deviceID);
@@ -114,9 +96,9 @@
     return CaptureSourceOrError(WTFMove(source));
 }
 
-CaptureSourceOrError GStreamerVideoCaptureSource::createPipewireSource(String&& deviceID, String&& hashSalt, const MediaConstraints* constraints, CaptureDevice::DeviceType deviceType)
+CaptureSourceOrError GStreamerVideoCaptureSource::createPipewireSource(String&& deviceID, int fd, String&& hashSalt, const MediaConstraints* constraints, CaptureDevice::DeviceType deviceType)
 {
-    auto source = adoptRef(*new GStreamerVideoCaptureSource(WTFMove(deviceID), { }, WTFMove(hashSalt), "pipewiresrc", deviceType));
+    auto source = adoptRef(*new GStreamerVideoCaptureSource(WTFMove(deviceID), { }, WTFMove(hashSalt), "pipewiresrc", deviceType, fd));
     if (constraints) {
         if (auto result = source->applyConstraints(*constraints))
             return WTFMove(result->badConstraint);
@@ -126,25 +108,23 @@
 
 VideoCaptureFactory& GStreamerVideoCaptureSource::factory()
 {
-    return libWebRTCVideoCaptureSourceFactory();
+    static NeverDestroyed<GStreamerVideoCaptureSourceFactory> factory;
+    return factory.get();
 }
 
 DisplayCaptureFactory& GStreamerVideoCaptureSource::displayFactory()
 {
-    return libWebRTCDisplayCaptureSourceFactory();
+    static NeverDestroyed<GStreamerDisplayCaptureSourceFactory> factory;
+    return factory.get();
 }
 
-GStreamerVideoCaptureSource::GStreamerVideoCaptureSource(String&& deviceID, String&& name, String&& hashSalt, const gchar* sourceFactory, CaptureDevice::DeviceType deviceType)
+GStreamerVideoCaptureSource::GStreamerVideoCaptureSource(String&& deviceID, String&& name, String&& hashSalt, const gchar* sourceFactory, CaptureDevice::DeviceType deviceType, int fd)
     : RealtimeVideoCaptureSource(WTFMove(name), WTFMove(deviceID), WTFMove(hashSalt))
     , m_capturer(makeUnique<GStreamerVideoCapturer>(sourceFactory, deviceType))
     , m_deviceType(deviceType)
 {
     initializeDebugCategory();
-
-    if (g_str_equal(sourceFactory, "pipewiresrc")) {
-        if (auto fd = parseInteger<int>(persistentID()))
-            m_capturer->setPipewireFD(*fd);
-    }
+    m_capturer->setPipewireFD(fd);
     m_capturer->addObserver(*this);
 }
 
@@ -224,6 +204,11 @@
 {
     GST_INFO("Reset height and width after stopping source");
     setSize({ 0, 0 });
+
+    if (auto fd = m_capturer->pipewireFD()) {
+        auto& manager = GStreamerDisplayCaptureDeviceManager::singleton();
+        manager.stopSource(persistentID());
+    }
 }
 
 const RealtimeMediaSourceCapabilities& GStreamerVideoCaptureSource::capabilities()

Modified: trunk/Source/WebCore/platform/mediastream/gstreamer/GStreamerVideoCaptureSource.h (280238 => 280239)


--- trunk/Source/WebCore/platform/mediastream/gstreamer/GStreamerVideoCaptureSource.h	2021-07-23 10:11:24 UTC (rev 280238)
+++ trunk/Source/WebCore/platform/mediastream/gstreamer/GStreamerVideoCaptureSource.h	2021-07-23 10:51:17 UTC (rev 280239)
@@ -32,7 +32,7 @@
 class GStreamerVideoCaptureSource : public RealtimeVideoCaptureSource, GStreamerCapturer::Observer {
 public:
     static CaptureSourceOrError create(String&& deviceID, String&& hashSalt, const MediaConstraints*);
-    static CaptureSourceOrError createPipewireSource(String&& deviceID, String&& hashSalt, const MediaConstraints*, CaptureDevice::DeviceType);
+    static CaptureSourceOrError createPipewireSource(String&& deviceID, int fd, String&& hashSalt, const MediaConstraints*, CaptureDevice::DeviceType);
 
     WEBCORE_EXPORT static VideoCaptureFactory& factory();
 
@@ -48,7 +48,7 @@
     void sourceCapsChanged(const GstCaps*) final;
 
 protected:
-    GStreamerVideoCaptureSource(String&& deviceID, String&& name, String&& hashSalt, const gchar* source_factory, CaptureDevice::DeviceType);
+    GStreamerVideoCaptureSource(String&& deviceID, String&& name, String&& hashSalt, const gchar* source_factory, CaptureDevice::DeviceType, int fd);
     GStreamerVideoCaptureSource(GStreamerCaptureDevice, String&& hashSalt);
     virtual ~GStreamerVideoCaptureSource();
     void startProducingData() override;

Modified: trunk/Source/WebCore/platform/mediastream/gstreamer/GStreamerVideoCapturer.cpp (280238 => 280239)


--- trunk/Source/WebCore/platform/mediastream/gstreamer/GStreamerVideoCapturer.cpp	2021-07-23 10:11:24 UTC (rev 280238)
+++ trunk/Source/WebCore/platform/mediastream/gstreamer/GStreamerVideoCapturer.cpp	2021-07-23 10:51:17 UTC (rev 280239)
@@ -75,11 +75,6 @@
     return info;
 }
 
-void GStreamerVideoCapturer::setPipewireFD(int fd)
-{
-    m_fd = fd;
-}
-
 bool GStreamerVideoCapturer::setSize(int width, int height)
 {
     if (m_fd.has_value()) {

Modified: trunk/Source/WebCore/platform/mediastream/gstreamer/GStreamerVideoCapturer.h (280238 => 280239)


--- trunk/Source/WebCore/platform/mediastream/gstreamer/GStreamerVideoCapturer.h	2021-07-23 10:11:24 UTC (rev 280238)
+++ trunk/Source/WebCore/platform/mediastream/gstreamer/GStreamerVideoCapturer.h	2021-07-23 10:51:17 UTC (rev 280239)
@@ -43,7 +43,9 @@
     bool setFrameRate(double);
     GstVideoInfo getBestFormat();
 
-    void setPipewireFD(int);
+    void setPipewireFD(int fd) { m_fd = fd; }
+    std::optional<int> pipewireFD() const { return m_fd; }
+
 private:
     std::optional<int> m_fd;
 };

Deleted: trunk/Source/cmake/FindLIBPORTAL.cmake (280238 => 280239)


--- trunk/Source/cmake/FindLIBPORTAL.cmake	2021-07-23 10:11:24 UTC (rev 280238)
+++ trunk/Source/cmake/FindLIBPORTAL.cmake	2021-07-23 10:51:17 UTC (rev 280239)
@@ -1,101 +0,0 @@
-# - Try to find libportal
-# Once done, this will define
-#
-#  LIBPORTAL_FOUND - system has libportal
-#  LIBPORTAL_INCLUDE_DIRS - the libportal include directories
-#  LIBPORTAL_LIBRARIES - link these to use libportal
-#
-# 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 HOLDER AND ITS 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 THE COPYRIGHT HOLDER 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.
-
-#[=======================================================================[.rst:
-FindLIBPORTAL
--------------
-
-Find libportal headers and libraries.
-
-Imported Targets
-^^^^^^^^^^^^^^^^
-
-``LIBPORTAL::LIBPORTAL``
-  The LIBPORTAL library, if found.
-
-Result Variables
-^^^^^^^^^^^^^^^^
-
-This will define the following variables in your project:
-
-``LIBPORTAL_FOUND``
-  true if (the requested version of) LIBPORTAL is available.
-``LIBPORTAL_VERSION``
-  the version of LIBPORTAL.
-``LIBPORTAL_LIBRARIES``
-  the libraries to link against to use LIBPORTAL.
-``LIBPORTAL_INCLUDE_DIRS``
-  where to find the LIBPORTAL headers.
-``LIBPORTAL_COMPILE_OPTIONS``
-  this should be passed to target_compile_options(), if the
-  target is not used for linking
-
-#]=======================================================================]
-
-find_package(PkgConfig)
-pkg_check_modules(PC_LIBPORTAL QUIET libportal)
-set(LIBPORTAL_COMPILE_OPTIONS ${PC_LIBPORTAL_CFLAGS_OTHER})
-set(LIBPORTAL_VERSION ${PC_LIBPORTAL_VERSION})
-
-find_path(LIBPORTAL_INCLUDE_DIR
-    NAMES portal.h
-    HINTS ${PC_LIBPORTAL_INCLUDEDIR}
-          ${PC_LIBPORTAL_INCLUDE_DIRS}
-    PATH_SUFFIXES libportal
-)
-
-find_library(LIBPORTAL_LIBRARY
-    NAMES ${LIBPORTAL_NAMES} portal
-    HINTS ${PC_LIBPORTAL_LIBDIR}
-          ${PC_LIBPORTAL_LIBRARY_DIRS}
-)
-
-include(FindPackageHandleStandardArgs)
-find_package_handle_standard_args(LIBPORTAL
-    FOUND_VAR LIBPORTAL_FOUND
-    REQUIRED_VARS LIBPORTAL_INCLUDE_DIR LIBPORTAL_LIBRARY
-    VERSION_VAR LIBPORTAL_VERSION
-)
-
-if (LIBPORTAL_LIBRARY AND NOT TARGET LIBPORTAL::LIBPORTAL)
-    add_library(LIBPORTAL::LIBPORTAL UNKNOWN IMPORTED GLOBAL)
-    set_target_properties(LIBPORTAL::LIBPORTAL PROPERTIES
-        IMPORTED_LOCATION "${LIBPORTAL_LIBRARY}"
-        INTERFACE_COMPILE_OPTIONS "${LIBPORTAL_COMPILE_OPTIONS}"
-        INTERFACE_INCLUDE_DIRECTORIES "${LIBPORTAL_INCLUDE_DIR}"
-    )
-endif ()
-
-mark_as_advanced(LIBPORTAL_INCLUDE_DIR LIBPORTAL_LIBRARY)
-
-if (LIBPORTAL_FOUND)
-    set(LIBPORTAL_LIBRARIES ${LIBPORTAL_LIBRARY})
-    set(LIBPORTAL_INCLUDE_DIRS ${LIBPORTAL_INCLUDE_DIR})
-endif ()

Modified: trunk/Source/cmake/GStreamerChecks.cmake (280238 => 280239)


--- trunk/Source/cmake/GStreamerChecks.cmake	2021-07-23 10:11:24 UTC (rev 280238)
+++ trunk/Source/cmake/GStreamerChecks.cmake	2021-07-23 10:51:17 UTC (rev 280239)
@@ -57,12 +57,3 @@
 else ()
     SET_AND_EXPOSE_TO_BUILD(USE_LIBWEBRTC FALSE)
 endif ()
-
-if (ENABLE_MEDIA_STREAM)
-    find_package(LIBPORTAL)
-    if (LIBPORTAL_FOUND)
-        SET_AND_EXPOSE_TO_BUILD(USE_PIPEWIRE TRUE)
-    else ()
-        SET_AND_EXPOSE_TO_BUILD(USE_PIPEWIRE FALSE)
-    endif ()
-endif ()
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to