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 ()