summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firefox-pipewire.patch1506
1 files changed, 839 insertions, 667 deletions
diff --git a/firefox-pipewire.patch b/firefox-pipewire.patch
index 6ed5801..f4d6c55 100644
--- a/firefox-pipewire.patch
+++ b/firefox-pipewire.patch
@@ -1,8 +1,11 @@
-PipeWire WebRTC patch from https://github.com/xhorak/firefox-devedition-flatpak
-https://bugzilla.mozilla.org/show_bug.cgi?id=1496359
+>From 4709953855a4243ce2d2ec45f63059baf604a499 Mon Sep 17 00:00:00 2001
+From: Jan Grulich <jgrulich@redhat.com>
+Date: Thu, 18 Oct 2018 10:25:56 +0200
+Subject: PW support
+
diff --git a/config/system-headers.mozbuild b/config/system-headers.mozbuild
-index 7f17843a37bd..1f4d711e5d39 100644
+index 60967bd51..11eb07a65 100644
--- a/config/system-headers.mozbuild
+++ b/config/system-headers.mozbuild
@@ -314,6 +314,7 @@ system_headers = [
@@ -22,7 +25,7 @@ index 7f17843a37bd..1f4d711e5d39 100644
'pk11func.h',
'pk11pqg.h',
diff --git a/media/webrtc/trunk/webrtc/modules/desktop_capture/BUILD.gn b/media/webrtc/trunk/webrtc/modules/desktop_capture/BUILD.gn
-index ed12a1521eb0..a9e700ccd3e0 100644
+index ed12a1521..a9e700ccd 100644
--- a/media/webrtc/trunk/webrtc/modules/desktop_capture/BUILD.gn
+++ b/media/webrtc/trunk/webrtc/modules/desktop_capture/BUILD.gn
@@ -213,7 +213,6 @@ rtc_static_library("desktop_capture") {
@@ -35,7 +38,7 @@ index ed12a1521eb0..a9e700ccd3e0 100644
"x11/shared_x_util.cc",
diff --git a/media/webrtc/trunk/webrtc/modules/desktop_capture/app_capturer_linux.cc b/media/webrtc/trunk/webrtc/modules/desktop_capture/app_capturer_linux.cc
new file mode 100644
-index 000000000000..4ac35aa8496b
+index 000000000..4ac35aa84
--- /dev/null
+++ b/media/webrtc/trunk/webrtc/modules/desktop_capture/app_capturer_linux.cc
@@ -0,0 +1,55 @@
@@ -95,7 +98,7 @@ index 000000000000..4ac35aa8496b
+
+} // namespace webrtc
diff --git a/media/webrtc/trunk/webrtc/modules/desktop_capture/app_capturer_null.cc b/media/webrtc/trunk/webrtc/modules/desktop_capture/app_capturer_null.cc
-index 5a0b1a28f058..84a7e5951032 100644
+index 5a0b1a28f..84a7e5951 100644
--- a/media/webrtc/trunk/webrtc/modules/desktop_capture/app_capturer_null.cc
+++ b/media/webrtc/trunk/webrtc/modules/desktop_capture/app_capturer_null.cc
@@ -7,8 +7,8 @@
@@ -105,12 +108,12 @@ index 5a0b1a28f058..84a7e5951032 100644
-#include "webrtc/modules/desktop_capture/window_capturer.h"
#include "webrtc/modules/desktop_capture/app_capturer.h"
+#include "webrtc/modules/desktop_capture/desktop_capturer.h"
-
+
#include <assert.h>
-
+
@@ -29,9 +29,11 @@ public:
virtual bool BringAppToFront() override;
-
+
// DesktopCapturer interface.
- virtual void Start(Callback* callback) override;
- virtual void Stop() override;
@@ -120,13 +123,13 @@ index 5a0b1a28f058..84a7e5951032 100644
+ void CaptureFrame() override;
+ bool GetSourceList(SourceList* sources) override;
+ bool SelectSource(SourceId id) override;
-
+
private:
Callback* callback_;
@@ -61,7 +63,16 @@ bool AppCapturerNull::BringAppToFront() {
return false;
}
-
+
-// DesktopCapturer interface.
+bool AppCapturerNull::GetSourceList(SourceList* sources) {
+ // Not implemented yet.
@@ -144,7 +147,7 @@ index 5a0b1a28f058..84a7e5951032 100644
@@ -73,16 +84,19 @@ void AppCapturerNull::Stop() {
callback_ = NULL;
}
-
+
-void AppCapturerNull::Capture(const DesktopRegion& region) {
- // Not implemented yet: See Bug 1036653
- callback_->OnCaptureCompleted(NULL);
@@ -152,9 +155,9 @@ index 5a0b1a28f058..84a7e5951032 100644
+ // Not implemented yet.
+ callback_->OnCaptureResult(Result::ERROR_TEMPORARY, nullptr);
}
-
+
} // namespace
-
+
+#if not defined(USE_PIPEWIRE)
// static
-AppCapturer* AppCapturer::Create(const DesktopCaptureOptions& options) {
@@ -164,16 +167,16 @@ index 5a0b1a28f058..84a7e5951032 100644
+ return std::unique_ptr<DesktopCapturer>(new AppCapturerNull());
}
+#endif // not defined(USE_PIPEWIRE)
-
+
} // namespace webrtc
diff --git a/media/webrtc/trunk/webrtc/modules/desktop_capture/app_capturer_x11.cc b/media/webrtc/trunk/webrtc/modules/desktop_capture/app_capturer_x11.cc
-index 8215823672b6..5c20ed0a517b 100755
+index 821582367..5c20ed0a5 100755
--- a/media/webrtc/trunk/webrtc/modules/desktop_capture/app_capturer_x11.cc
+++ b/media/webrtc/trunk/webrtc/modules/desktop_capture/app_capturer_x11.cc
@@ -53,10 +53,13 @@ protected:
std::unique_ptr<DesktopFrame> frame_;
};
-
+
-class AppCapturerLinux : public AppCapturer {
+class AppCapturerX11 : public AppCapturer {
public:
@@ -184,12 +187,12 @@ index 8215823672b6..5c20ed0a517b 100755
+
+ static AppCapturer* Create(const DesktopCaptureOptions& options);
+ static std::unique_ptr<DesktopCapturer> CreateRawAppCapturer(const DesktopCaptureOptions& options);
-
+
// AppCapturer interface.
virtual bool GetAppList(AppList* apps) override;
@@ -91,10 +94,9 @@ private:
Region rgn_background_;
-
+
rtc::scoped_refptr<SharedXDisplay> x_display_;
- RTC_DISALLOW_COPY_AND_ASSIGN(AppCapturerLinux);
+ RTC_DISALLOW_COPY_AND_ASSIGN(AppCapturerX11);
@@ -203,7 +206,7 @@ index 8215823672b6..5c20ed0a517b 100755
@@ -103,7 +105,7 @@ AppCapturerLinux::AppCapturerLinux(const DesktopCaptureOptions& options)
rgn_background_ = XCreateRegion();
}
-
+
-AppCapturerLinux::~AppCapturerLinux() {
+AppCapturerX11::~AppCapturerX11() {
if (rgn_mask_) {
@@ -211,7 +214,7 @@ index 8215823672b6..5c20ed0a517b 100755
}
@@ -116,32 +118,32 @@ AppCapturerLinux::~AppCapturerLinux() {
}
-
+
// AppCapturer interface.
-bool AppCapturerLinux::GetAppList(AppList* apps) {
+bool AppCapturerX11::GetAppList(AppList* apps) {
@@ -228,163 +231,75 @@ index 8215823672b6..5c20ed0a517b 100755
// Not implemented yet: See Bug 1036653
return true;
}
-
+
// DesktopCapturer interface.
-void AppCapturerLinux::Start(Callback* callback) {
+void AppCapturerX11::Start(Callback* callback) {
assert(!callback_);
assert(callback);
-
+
callback_ = callback;
}
-
+
-void AppCapturerLinux::Stop() {
+void AppCapturerX11::Stop() {
callback_ = NULL;
}
-
+
-void AppCapturerLinux::CaptureFrame() {
+void AppCapturerX11::CaptureFrame() {
XErrorTrap error_trap(GetDisplay());
-
+
//Capture screen >> set root window as capture window
@@ -169,7 +171,7 @@ void AppCapturerLinux::CaptureFrame() {
}
}
-
+
-void AppCapturerLinux::FillDesktopFrameRegionWithColor(DesktopFrame* pDesktopFrame, Region rgn, uint32_t color) {
+void AppCapturerX11::FillDesktopFrameRegionWithColor(DesktopFrame* pDesktopFrame, Region rgn, uint32_t color) {
XErrorTrap error_trap(GetDisplay());
-
+
if (!pDesktopFrame) {
@@ -192,7 +194,7 @@ void AppCapturerLinux::FillDesktopFrameRegionWithColor(DesktopFrame* pDesktopFra
}
}
-
+
-bool AppCapturerLinux::UpdateRegions() {
+bool AppCapturerX11::UpdateRegions() {
XErrorTrap error_trap(GetDisplay());
-
+
XSubtractRegion(rgn_visual_, rgn_visual_, rgn_visual_);
@@ -272,18 +274,18 @@ bool AppCapturerLinux::UpdateRegions() {
} // namespace
-
+
// static
-AppCapturer* AppCapturer::Create(const DesktopCaptureOptions& options) {
- return new AppCapturerLinux(options);
+AppCapturer* AppCapturerX11::Create(const DesktopCaptureOptions& options) {
+ return new AppCapturerX11(options);
}
-
+
// static
-std::unique_ptr<DesktopCapturer> DesktopCapturer::CreateRawAppCapturer(
+std::unique_ptr<DesktopCapturer> AppCapturerX11::CreateRawAppCapturer(
const DesktopCaptureOptions& options) {
-
+
if (!options.x_display())
return nullptr;
-
+
- std::unique_ptr<AppCapturerLinux> capturer(new AppCapturerLinux(options));
+ std::unique_ptr<AppCapturerX11> capturer(new AppCapturerX11(options));
-
+
return std::unique_ptr<DesktopCapturer>(std::move(capturer));
}
-diff --git a/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capture_gn/moz.build b/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capture_gn/moz.build
-index d7909d983053..b50b005c300e 100644
---- a/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capture_gn/moz.build
-+++ b/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capture_gn/moz.build
-@@ -166,10 +166,6 @@ if CONFIG["OS_TARGET"] == "Linux":
- ]
-
- UNIFIED_SOURCES += [
-- "/media/webrtc/trunk/webrtc/modules/desktop_capture/app_capturer_x11.cc",
-- "/media/webrtc/trunk/webrtc/modules/desktop_capture/mouse_cursor_monitor_x11.cc",
-- "/media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer_x11.cc",
-- "/media/webrtc/trunk/webrtc/modules/desktop_capture/window_capturer_x11.cc",
- "/media/webrtc/trunk/webrtc/modules/desktop_capture/x11/desktop_device_info_x11.cc",
- "/media/webrtc/trunk/webrtc/modules/desktop_capture/x11/shared_x_display.cc",
- "/media/webrtc/trunk/webrtc/modules/desktop_capture/x11/shared_x_util.cc",
-@@ -177,6 +173,35 @@ if CONFIG["OS_TARGET"] == "Linux":
- "/media/webrtc/trunk/webrtc/modules/desktop_capture/x11/x_server_pixel_buffer.cc"
- ]
-
-+# Common stuff between Pipewire and X11
-+if CONFIG["OS_TARGET"] == "Linux":
-+
-+ UNIFIED_SOURCES += [
-+ "/media/webrtc/trunk/webrtc/modules/desktop_capture/app_capturer_linux.cc",
-+ "/media/webrtc/trunk/webrtc/modules/desktop_capture/mouse_cursor_monitor_linux.cc",
-+ "/media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer_linux.cc",
-+ "/media/webrtc/trunk/webrtc/modules/desktop_capture/window_capturer_linux.cc"
-+ ]
-+
-+# Pipewire
-+if CONFIG["OS_TARGET"] == "Linux":
-+
-+ DEFINES["USE_PIPEWIRE"] = "1"
-+
-+ OS_LIBS += [
-+ "rt",
-+ "pipewire-0.2",
-+ "glib-2.0",
-+ "gio-2.0",
-+ "gobject-2.0"
-+ ]
-+
-+ CXXFLAGS += CONFIG['TK_CFLAGS']
-+
-+ UNIFIED_SOURCES += [
-+ "/media/webrtc/trunk/webrtc/modules/desktop_capture/mouse_cursor_monitor_null.cc"
-+ ]
-+
- if CONFIG["OS_TARGET"] == "NetBSD":
-
- DEFINES["USE_X11"] = "1"
-diff --git a/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capturer.cc b/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capturer.cc
-index 7510bde47fbb..9dab1eb503f6 100644
---- a/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capturer.cc
-+++ b/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capturer.cc
-@@ -66,4 +66,17 @@ std::unique_ptr<DesktopCapturer> DesktopCapturer::CreateAppCapturer(
- return capturer;
- }
-
-+#if defined(USE_PIPEWIRE) || defined(USE_X11)
-+bool DesktopCapturer::IsRunningUnderWayland() {
-+ const char* xdg_session_type = getenv("XDG_SESSION_TYPE");
-+ if (!xdg_session_type || strncmp(xdg_session_type, "wayland", 7) != 0)
-+ return false;
-+
-+ if (!(getenv("WAYLAND_DISPLAY")))
-+ return false;
-+
-+ return true;
-+}
-+#endif
-+
- } // namespace webrtc
-diff --git a/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capturer.h b/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capturer.h
-index eb84d3c3bf50..17cacc5dcac6 100644
---- a/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capturer.h
-+++ b/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capturer.h
-@@ -129,6 +129,10 @@ class DesktopCapturer {
- static std::unique_ptr<DesktopCapturer> CreateAppCapturer(
- const DesktopCaptureOptions& options);
-
-+#if defined(USE_PIPEWIRE) || defined(USE_X11)
-+ static bool IsRunningUnderWayland();
-+#endif
-+
- protected:
- // CroppingWindowCapturer needs to create raw capturers without wrappers, so
- // the following two functions are protected.
-diff --git a/media/webrtc/trunk/webrtc/modules/desktop_capture/mouse_cursor_monitor_linux.cc b/media/webrtc/trunk/webrtc/modules/desktop_capture/mouse_cursor_monitor_linux.cc
+diff --git a/media/webrtc/trunk/webrtc/modules/desktop_capture/base_capturer_pipewire.cc b/media/webrtc/trunk/webrtc/modules/desktop_capture/base_capturer_pipewire.cc
new file mode 100644
-index 000000000000..f7aaf3dcd6d9
+index 000000000..39c19164d
--- /dev/null
-+++ b/media/webrtc/trunk/webrtc/modules/desktop_capture/mouse_cursor_monitor_linux.cc
-@@ -0,0 +1,44 @@
++++ b/media/webrtc/trunk/webrtc/modules/desktop_capture/base_capturer_pipewire.cc
+@@ -0,0 +1,849 @@
+/*
-+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
++ * Copyright 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
@@ -393,176 +308,23 @@ index 000000000000..f7aaf3dcd6d9
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
-+#include "webrtc/modules/desktop_capture/mouse_cursor_monitor.h"
-+
-+#if defined(USE_PIPEWIRE)
-+#include "webrtc/modules/desktop_capture/mouse_cursor_monitor_null.cc"
-+#endif // defined(USE_PIPEWIRE)
-+
-+#if defined(USE_X11)
-+#include "webrtc/modules/desktop_capture/mouse_cursor_monitor_x11.cc"
-+#endif // defined(USE_X11)
-+
-+namespace webrtc {
-+
-+// static
-+MouseCursorMonitor* MouseCursorMonitor::CreateForWindow(
-+ const DesktopCaptureOptions& options, WindowId window) {
-+#if defined(USE_X11)
-+ return MouseCursorMonitorX11::CreateForWindow(options, window);
-+#else
-+ return nullptr;
-+#endif // defined(USE_X11)
-+}
-+
-+// static
-+MouseCursorMonitor* MouseCursorMonitor::CreateForScreen(
-+ const DesktopCaptureOptions& options,
-+ ScreenId screen) {
-+#if defined(USE_X11)
-+ return MouseCursorMonitorX11::CreateForScreen(options, screen);
-+#else
-+ return nullptr;
-+#endif // defined(USE_X11)
-+}
-+
-+} // namespace webrtc
-diff --git a/media/webrtc/trunk/webrtc/modules/desktop_capture/mouse_cursor_monitor_null.cc b/media/webrtc/trunk/webrtc/modules/desktop_capture/mouse_cursor_monitor_null.cc
-index 3a632cc0d9cd..b70b4e2568dc 100644
---- a/media/webrtc/trunk/webrtc/modules/desktop_capture/mouse_cursor_monitor_null.cc
-+++ b/media/webrtc/trunk/webrtc/modules/desktop_capture/mouse_cursor_monitor_null.cc
-@@ -14,6 +14,7 @@
-
- namespace webrtc {
-
-+#if not defined(USE_PIPEWIRE)
- MouseCursorMonitor* MouseCursorMonitor::CreateForWindow(
- const DesktopCaptureOptions& options,
- WindowId window) {
-@@ -25,5 +26,6 @@ MouseCursorMonitor* MouseCursorMonitor::CreateForScreen(
- ScreenId screen) {
- return NULL;
- }
-+#endif // not defined(USE_PIPEWIRE)
-
- } // namespace webrtc
-diff --git a/media/webrtc/trunk/webrtc/modules/desktop_capture/mouse_cursor_monitor_x11.cc b/media/webrtc/trunk/webrtc/modules/desktop_capture/mouse_cursor_monitor_x11.cc
-index 2dcad5b3887f..a8397f1ec15c 100644
---- a/media/webrtc/trunk/webrtc/modules/desktop_capture/mouse_cursor_monitor_x11.cc
-+++ b/media/webrtc/trunk/webrtc/modules/desktop_capture/mouse_cursor_monitor_x11.cc
-@@ -69,6 +69,9 @@ class MouseCursorMonitorX11 : public MouseCursorMonitor,
- void Stop() override;
- void Capture() override;
-
-+ static MouseCursorMonitor* CreateForWindow(const DesktopCaptureOptions& options, WindowId window);
-+ static MouseCursorMonitor* CreateForScreen(const DesktopCaptureOptions& options, ScreenId screen);
-+
- private:
- // SharedXDisplay::XEventHandler interface.
- bool HandleXEvent(const XEvent& event) override;
-@@ -244,7 +247,7 @@ void MouseCursorMonitorX11::CaptureCursor() {
- }
-
- // static
--MouseCursorMonitor* MouseCursorMonitor::CreateForWindow(
-+MouseCursorMonitor* MouseCursorMonitorX11::CreateForWindow(
- const DesktopCaptureOptions& options, WindowId window) {
- if (!options.x_display())
- return NULL;
-@@ -254,7 +257,7 @@ MouseCursorMonitor* MouseCursorMonitor::CreateForWindow(
- return new MouseCursorMonitorX11(options, outer_window, window);
- }
-
--MouseCursorMonitor* MouseCursorMonitor::CreateForScreen(
-+MouseCursorMonitor* MouseCursorMonitorX11::CreateForScreen(
- const DesktopCaptureOptions& options,
- ScreenId screen) {
- if (!options.x_display())
-diff --git a/media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer_linux.cc b/media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer_linux.cc
-new file mode 100644
-index 000000000000..8c155102ed74
---- /dev/null
-+++ b/media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer_linux.cc
-@@ -0,0 +1,42 @@
-+/*
-+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
-+ *
-+ * Use of this source code is governed by a BSD-style license
-+ * that can be found in the LICENSE file in the root of the source
-+ * tree. An additional intellectual property rights grant can be found
-+ * in the file PATENTS. All contributing project authors may
-+ * be found in the AUTHORS file in the root of the source tree.
-+ */
-+
-+#include "webrtc/modules/desktop_capture/desktop_capture_options.h"
-+#include "webrtc/modules/desktop_capture/desktop_capturer.h"
-+
-+#include <cstdio>
-+
-+#if defined(USE_PIPEWIRE)
-+#include "webrtc/modules/desktop_capture/screen_capturer_pipewire.cc"
-+#endif // defined(USE_PIPEWIRE)
-+
-+#if defined(USE_X11)
-+#include "webrtc/modules/desktop_capture/screen_capturer_x11.cc"
-+#endif // defined(USE_X11)
-+
-+namespace webrtc {
-+
-+// static
-+std::unique_ptr<DesktopCapturer> DesktopCapturer::CreateRawScreenCapturer(
-+ const DesktopCaptureOptions& options) {
-+#if defined(USE_PIPEWIRE)
-+ if (DesktopCapturer::IsRunningUnderWayland()) {
-+ return ScreenCapturerPipeWire::CreateRawScreenCapturer(options);
-+ }
-+#endif // defined(USE_PIPEWIRE)
-+
-+#if defined(USE_X11)
-+ return ScreenCapturerX11::CreateRawScreenCapturer(options);
-+#endif // defined(USE_X11)
-+
-+ return nullptr;
-+}
-+
-+} // namespace webrtc
-diff --git a/media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer_pipewire.cc b/media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer_pipewire.cc
-new file mode 100644
-index 000000000000..ce47ae29eac9
---- /dev/null
-+++ b/media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer_pipewire.cc
-@@ -0,0 +1,1003 @@
-+/*
-+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
-+ *
-+ * Use of this source code is governed by a BSD-style license
-+ * that can be found in the LICENSE file in the root of the source
-+ * tree. An additional intellectual property rights grant can be found
-+ * in the file PATENTS. All contributing project authors may
-+ * be found in the AUTHORS file in the root of the source tree.
-+ */
-+
-+#include <sys/mman.h>
-+
-+#include <gio/gio.h>
++#include <cstring>
+#include <gio/gunixfdlist.h>
+#include <glib-object.h>
-+#define typeof __typeof__
-+#include <pipewire/pipewire.h>
+
+#include <spa/param/format-utils.h>
+#include <spa/param/props.h>
-+#include <spa/param/video/format-utils.h>
+#include <spa/param/video/raw-utils.h>
+#include <spa/support/type-map.h>
+
-+#include "webrtc/base/checks.h"
-+#include "webrtc/base/logging.h"
++#include "webrtc/modules/desktop_capture/base_capturer_pipewire.h"
++
+#include "webrtc/modules/desktop_capture/desktop_capture_options.h"
+#include "webrtc/modules/desktop_capture/desktop_capturer.h"
++#include "webrtc/base/checks.h"
++#include "webrtc/base/logging.h"
+
+namespace webrtc {
-+namespace {
+
+const char kDesktopBusName[] = "org.freedesktop.portal.Desktop";
+const char kDesktopObjectPath[] = "/org/freedesktop/portal/desktop";
@@ -572,150 +334,14 @@ index 000000000000..ce47ae29eac9
+const char kRequestInterfaceName[] = "org.freedesktop.portal.Request";
+const char kScreenCastInterfaceName[] = "org.freedesktop.portal.ScreenCast";
+
-+const int kBytesPerPixel = 4;
-+
-+class PipeWireType {
-+ public:
-+ spa_type_media_type media_type;
-+ spa_type_media_subtype media_subtype;
-+ spa_type_format_video format_video;
-+ spa_type_video_format video_format;
-+};
-+
-+class ScreenCapturerPipeWire : public DesktopCapturer {
-+ public:
-+ ScreenCapturerPipeWire();
-+ ~ScreenCapturerPipeWire() override;
-+
-+ static std::unique_ptr<DesktopCapturer> CreateRawScreenCapturer(
-+ const DesktopCaptureOptions& options);
-+
-+ // DesktopCapturer interface.
-+ void Start(Callback* delegate) override;
-+ void Stop() override;
-+ void CaptureFrame() override;
-+ bool GetSourceList(SourceList* sources) override;
-+ bool SelectSource(SourceId id) override;
-+
-+ private:
-+ // PipeWire types -->
-+ pw_core* pw_core_ = nullptr;
-+ pw_type* pw_core_type_ = nullptr;
-+ pw_stream* pw_stream_ = nullptr;
-+ pw_remote* pw_remote_ = nullptr;
-+ pw_loop* pw_loop_ = nullptr;
-+ pw_thread_loop* pw_main_loop_ = nullptr;
-+ PipeWireType* pw_type_ = nullptr;
-+
-+ spa_hook spa_stream_listener_ = {};
-+ spa_hook spa_remote_listener_ = {};
-+
-+ pw_stream_events pw_stream_events_ = {};
-+ pw_remote_events pw_remote_events_ = {};
-+
-+ spa_video_info_raw* spa_video_format_ = nullptr;
-+
-+ gint32 pw_fd_ = -1;
-+
-+ // <-- end of PipeWire types
-+
-+ GDBusConnection* connection_ = nullptr;
-+ GDBusProxy* proxy_ = nullptr;
-+ gchar* portal_handle_ = nullptr;
-+ gchar* session_handle_ = nullptr;
-+ gchar* sources_handle_ = nullptr;
-+ gchar* start_handle_ = nullptr;
-+ guint session_request_signal_id_ = 0;
-+ guint sources_request_signal_id_ = 0;
-+ guint start_request_signal_id_ = 0;
-+
-+ DesktopSize desktop_size_ = {};
-+ DesktopCaptureOptions options_ = {};
-+
-+ uint8_t* current_frame_ = nullptr;
-+ Callback* callback_ = nullptr;
-+
-+ void InitPipeWire();
-+ void InitPipeWireTypes();
-+
-+ void CreateReceivingStream();
-+ void HandleBuffer(pw_buffer* buffer);
-+
-+ void ConvertRGBxToBGRxIfNeeded(uint8_t* frame, uint32_t size);
-+
-+ static void OnStateChanged(void* data,
-+ pw_remote_state old_state,
-+ pw_remote_state state,
-+ const char* error);
-+ static void OnStreamStateChanged(void* data,
-+ pw_stream_state old_state,
-+ pw_stream_state state,
-+ const char* error_message);
-+
-+ static void OnStreamFormatChanged(void* data, const struct spa_pod* format);
-+ static void OnStreamProcess(void* data);
-+ static void OnNewBuffer(void* data, uint32_t id);
-+
-+ guint SetupRequestResponseSignal(const gchar* object_path,
-+ GDBusSignalCallback callback);
-+
-+ static void OnProxyRequested(GObject* object,
-+ GAsyncResult* result,
-+ gpointer user_data);
-+
-+ static gchar* PrepareSignalHandle(GDBusConnection* connection,
-+ const gchar* token);
-+
-+ void SessionRequest();
-+ static void OnSessionRequested(GDBusConnection* connection,
-+ GAsyncResult* result,
-+ gpointer user_data);
-+ static void OnSessionRequestResponseSignal(GDBusConnection* connection,
-+ const gchar* sender_name,
-+ const gchar* object_path,
-+ const gchar* interface_name,
-+ const gchar* signal_name,
-+ GVariant* parameters,
-+ gpointer user_data);
-+
-+ void SourcesRequest();
-+ static void OnSourcesRequested(GDBusConnection* connection,
-+ GAsyncResult* result,
-+ gpointer user_data);
-+ static void OnSourcesRequestResponseSignal(GDBusConnection* connection,
-+ const gchar* sender_name,
-+ const gchar* object_path,
-+ const gchar* interface_name,
-+ const gchar* signal_name,
-+ GVariant* parameters,
-+ gpointer user_data);
-+
-+ void StartRequest();
-+ static void OnStartRequested(GDBusConnection* connection,
-+ GAsyncResult* result,
-+ gpointer user_data);
-+ static void OnStartRequestResponseSignal(GDBusConnection* connection,
-+ const gchar* sender_name,
-+ const gchar* object_path,
-+ const gchar* interface_name,
-+ const gchar* signal_name,
-+ GVariant* parameters,
-+ gpointer user_data);
-+
-+ void OpenPipeWireRemote();
-+ static void OnOpenPipeWireRemoteRequested(GDBusConnection* connection,
-+ GAsyncResult* result,
-+ gpointer user_data);
-+
-+ RTC_DISALLOW_COPY_AND_ASSIGN(ScreenCapturerPipeWire);
-+};
++const int kBytesPerPixelPw = 4;
+
+// static
-+void ScreenCapturerPipeWire::OnStateChanged(void* data,
++void BaseCapturerPipeWire::OnStateChanged(void* data,
+ pw_remote_state old_state,
+ pw_remote_state state,
+ const char* error_message) {
-+ ScreenCapturerPipeWire* that = static_cast<ScreenCapturerPipeWire*>(data);
++ BaseCapturerPipeWire* that = static_cast<BaseCapturerPipeWire*>(data);
+ RTC_DCHECK(that);
+
+ switch (state) {
@@ -736,11 +362,11 @@ index 000000000000..ce47ae29eac9
+}
+
+// static
-+void ScreenCapturerPipeWire::OnStreamStateChanged(void* data,
++void BaseCapturerPipeWire::OnStreamStateChanged(void* data,
+ pw_stream_state old_state,
+ pw_stream_state state,
+ const char* error_message) {
-+ ScreenCapturerPipeWire* that = static_cast<ScreenCapturerPipeWire*>(data);
++ BaseCapturerPipeWire* that = static_cast<BaseCapturerPipeWire*>(data);
+ RTC_DCHECK(that);
+
+ switch (state) {
@@ -760,10 +386,10 @@ index 000000000000..ce47ae29eac9
+}
+
+// static
-+void ScreenCapturerPipeWire::OnStreamFormatChanged(
++void BaseCapturerPipeWire::OnStreamFormatChanged(
+ void* data,
+ const struct spa_pod* format) {
-+ ScreenCapturerPipeWire* that = static_cast<ScreenCapturerPipeWire*>(data);
++ BaseCapturerPipeWire* that = static_cast<BaseCapturerPipeWire*>(data);
+ RTC_DCHECK(that);
+
+ LOG(LS_INFO) << "PipeWire stream format changed.";
@@ -780,7 +406,7 @@ index 000000000000..ce47ae29eac9
+
+ auto width = that->spa_video_format_->size.width;
+ auto height = that->spa_video_format_->size.height;
-+ auto stride = SPA_ROUND_UP_N(width * kBytesPerPixel, 4);
++ auto stride = SPA_ROUND_UP_N(width * kBytesPerPixelPw, 4);
+ auto size = height * stride;
+
+ uint8_t buffer[1024] = {};
@@ -788,34 +414,41 @@ index 000000000000..ce47ae29eac9
+
+ // Setup buffers and meta header for new format.
+ const struct spa_pod* params[2];
-+ params[0] = reinterpret_cast<spa_pod*>(spa_pod_builder_object(&builder,
++ params[0] = reinterpret_cast<spa_pod*>(spa_pod_builder_object(
++ &builder,
+ // id to enumerate buffer requirements
-+ that->pw_core_type_->param.idBuffers, that->pw_core_type_->param_buffers.Buffers,
++ that->pw_core_type_->param.idBuffers,
++ that->pw_core_type_->param_buffers.Buffers,
+ // Size: specified as integer (i) and set to specified size
+ ":", that->pw_core_type_->param_buffers.size, "i", size,
+ // Stride: specified as integer (i) and set to specified stride
+ ":", that->pw_core_type_->param_buffers.stride, "i", stride,
-+ // Buffers: specifies how many buffers we want to deal with, set as integer (i)
-+ // where preferred number is 8, then allowed number is defined as range (r) from
-+ // min and max values and it is undecided (u) to allow negotiation
-+ ":", that->pw_core_type_->param_buffers.buffers, "iru",
-+ 8, SPA_POD_PROP_MIN_MAX(1, 32),
-+ // Align: memory alignment of the buffer, set as integer (i) to specified value
++ // Buffers: specifies how many buffers we want to deal with, set as
++ // integer (i) where preferred number is 8, then allowed number is defined
++ // as range (r) from min and max values and it is undecided (u) to allow
++ // negotiation
++ ":", that->pw_core_type_->param_buffers.buffers, "iru", 8,
++ SPA_POD_PROP_MIN_MAX(1, 32),
++ // Align: memory alignment of the buffer, set as integer (i) to specified
++ // value
+ ":", that->pw_core_type_->param_buffers.align, "i", 16));
-+ params[1] = reinterpret_cast<spa_pod*>(spa_pod_builder_object(&builder,
++ params[1] = reinterpret_cast<spa_pod*>(spa_pod_builder_object(
++ &builder,
+ // id to enumerate supported metadata
+ that->pw_core_type_->param.idMeta, that->pw_core_type_->param_meta.Meta,
+ // Type: specified as id or enum (I)
-+ ":", that->pw_core_type_->param_meta.type, "I", that->pw_core_type_->meta.Header,
++ ":", that->pw_core_type_->param_meta.type, "I",
++ that->pw_core_type_->meta.Header,
+ // Size: size of the metadata, specified as integer (i)
-+ ":", that->pw_core_type_->param_meta.size, "i", sizeof(struct spa_meta_header)));
++ ":", that->pw_core_type_->param_meta.size, "i",
++ sizeof(struct spa_meta_header)));
+
+ pw_stream_finish_format(that->pw_stream_, /*res=*/0, params, /*n_params=*/2);
+}
+
+// static
-+void ScreenCapturerPipeWire::OnStreamProcess(void* data) {
-+ ScreenCapturerPipeWire* that = static_cast<ScreenCapturerPipeWire*>(data);
++void BaseCapturerPipeWire::OnStreamProcess(void* data) {
++ BaseCapturerPipeWire* that = static_cast<BaseCapturerPipeWire*>(data);
+ RTC_DCHECK(that);
+
+ pw_buffer* buf = nullptr;
@@ -829,15 +462,14 @@ index 000000000000..ce47ae29eac9
+ pw_stream_queue_buffer(that->pw_stream_, buf);
+}
+
-+ScreenCapturerPipeWire::ScreenCapturerPipeWire() {
-+ g_dbus_proxy_new_for_bus(
-+ G_BUS_TYPE_SESSION, G_DBUS_PROXY_FLAGS_NONE, /*info=*/nullptr,
-+ kDesktopBusName, kDesktopObjectPath, kScreenCastInterfaceName,
-+ /*cancellable=*/nullptr,
-+ reinterpret_cast<GAsyncReadyCallback>(OnProxyRequested), this);
-+}
++BaseCapturerPipeWire::BaseCapturerPipeWire(CaptureSourceType source_type)
++ : capture_source_type_(source_type) {}
++
++BaseCapturerPipeWire::~BaseCapturerPipeWire() {
++ if (pw_main_loop_) {
++ pw_thread_loop_stop(pw_main_loop_);
++ }
+
-+ScreenCapturerPipeWire::~ScreenCapturerPipeWire() {
+ if (pw_type_) {
+ delete pw_type_;
+ }
@@ -906,13 +538,17 @@ index 000000000000..ce47ae29eac9
+ if (proxy_) {
+ g_clear_object(&proxy_);
+ }
++}
+
-+ if (connection_) {
-+ g_clear_object(&connection_);
-+ }
++void BaseCapturerPipeWire::InitPortals() {
++ g_dbus_proxy_new_for_bus(
++ G_BUS_TYPE_SESSION, G_DBUS_PROXY_FLAGS_NONE, /*info=*/nullptr,
++ kDesktopBusName, kDesktopObjectPath, kScreenCastInterfaceName,
++ /*cancellable=*/nullptr,
++ reinterpret_cast<GAsyncReadyCallback>(OnProxyRequested), this);
+}
+
-+void ScreenCapturerPipeWire::InitPipeWire() {
++void BaseCapturerPipeWire::InitPipeWire() {
+ pw_init(/*argc=*/nullptr, /*argc=*/nullptr);
+
+ pw_loop_ = pw_loop_new(/*properties=*/nullptr);
@@ -920,7 +556,7 @@ index 000000000000..ce47ae29eac9
+
+ pw_core_ = pw_core_new(pw_loop_, /*properties=*/nullptr);
+ pw_core_type_ = pw_core_get_type(pw_core_);
-+ pw_remote_ = pw_remote_new(pw_core_, nullptr, 0);
++ pw_remote_ = pw_remote_new(pw_core_, nullptr, /*user_data_size=*/0);
+
+ InitPipeWireTypes();
+
@@ -939,10 +575,11 @@ index 000000000000..ce47ae29eac9
+
+ if (pw_thread_loop_start(pw_main_loop_) < 0) {
+ LOG(LS_ERROR) << "Failed to start main PipeWire loop";
++ portal_init_failed_ = true;
+ }
+}
+
-+void ScreenCapturerPipeWire::InitPipeWireTypes() {
++void BaseCapturerPipeWire::InitPipeWireTypes() {
+ spa_type_map* map = pw_core_type_->map;
+ pw_type_ = new PipeWireType();
+
@@ -952,7 +589,7 @@ index 000000000000..ce47ae29eac9
+ spa_type_video_format_map(map, &pw_type_->video_format);
+}
+
-+void ScreenCapturerPipeWire::CreateReceivingStream() {
++void BaseCapturerPipeWire::CreateReceivingStream() {
+ spa_rectangle pwMinScreenBounds = spa_rectangle{1, 1};
+ spa_rectangle pwScreenBounds =
+ spa_rectangle{static_cast<uint32_t>(desktop_size_.width()),
@@ -968,40 +605,46 @@ index 000000000000..ce47ae29eac9
+ uint8_t buffer[1024] = {};
+ const spa_pod* params[1];
+ spa_pod_builder builder = spa_pod_builder{buffer, sizeof(buffer)};
-+ params[0] = reinterpret_cast<spa_pod*>(spa_pod_builder_object(&builder,
++ params[0] = reinterpret_cast<spa_pod*>(spa_pod_builder_object(
++ &builder,
+ // id to enumerate formats
-+ pw_core_type_->param.idEnumFormat, pw_core_type_->spa_format,
-+ "I", pw_type_->media_type.video,
-+ "I", pw_type_->media_subtype.raw,
-+ // Video format: specified as id or enum (I), preferred format is BGRx, then allowed
-+ // formats are enumerated (e) and the format is undecided (u) to allow negotiation
-+ ":", pw_type_->format_video.format, "Ieu",
-+ pw_type_->video_format.BGRx, SPA_POD_PROP_ENUM(2, pw_type_->video_format.RGBx,
-+ pw_type_->video_format.BGRx),
-+ // Video size: specified as rectangle (R), preferred size is specified as first
-+ // parameter, then allowed size is defined as range (r) from min and max values
-+ // and the format is undecided (u) to allow negotiation
-+ ":", pw_type_->format_video.size, "Rru",
-+ &pwScreenBounds, 2, &pwMinScreenBounds, &pwScreenBounds,
-+ // Frame rate: specified as fraction (F) and set to minimum frame rate value
++ pw_core_type_->param.idEnumFormat, pw_core_type_->spa_format, "I",
++ pw_type_->media_type.video, "I", pw_type_->media_subtype.raw,
++ // Video format: specified as id or enum (I), preferred format is BGRx,
++ // then allowed formats are enumerated (e) and the format is undecided (u)
++ // to allow negotiation
++ ":", pw_type_->format_video.format, "Ieu", pw_type_->video_format.BGRx,
++ SPA_POD_PROP_ENUM(2, pw_type_->video_format.RGBx,
++ pw_type_->video_format.BGRx),
++ // Video size: specified as rectangle (R), preferred size is specified as
++ // first parameter, then allowed size is defined as range (r) from min and
++ // max values and the format is undecided (u) to allow negotiation
++ ":", pw_type_->format_video.size, "Rru", &pwScreenBounds, 2,
++ &pwMinScreenBounds, &pwScreenBounds,
++ // Frame rate: specified as fraction (F) and set to minimum frame rate
++ // value
+ ":", pw_type_->format_video.framerate, "F", &pwFrameRateMin,
-+ // Max frame rate: specified as fraction (F), preferred frame rate is set to maximum
-+ // value, then allowed frame rate is defined as range (r) from min and max values
-+ // and it is undecided (u) to allow negotiation
-+ ":", pw_type_->format_video.max_framerate, "Fru",
-+ &pwFrameRateMax, 2, &pwFrameRateMin, &pwFrameRateMax));
++ // Max frame rate: specified as fraction (F), preferred frame rate is set
++ // to maximum value, then allowed frame rate is defined as range (r) from
++ // min and max values and it is undecided (u) to allow negotiation
++ ":", pw_type_->format_video.max_framerate, "Fru", &pwFrameRateMax, 2,
++ &pwFrameRateMin, &pwFrameRateMax));
+
+ pw_stream_add_listener(pw_stream_, &spa_stream_listener_, &pw_stream_events_,
+ this);
+ pw_stream_flags flags = static_cast<pw_stream_flags>(
-+ PW_STREAM_FLAG_AUTOCONNECT | PW_STREAM_FLAG_INACTIVE | PW_STREAM_FLAG_MAP_BUFFERS);
-+ if (pw_stream_connect(pw_stream_, PW_DIRECTION_INPUT, nullptr, flags, params,
-+ 1) != 0) {
++ PW_STREAM_FLAG_AUTOCONNECT | PW_STREAM_FLAG_INACTIVE |
++ PW_STREAM_FLAG_MAP_BUFFERS);
++ if (pw_stream_connect(pw_stream_, PW_DIRECTION_INPUT, /*port_path=*/nullptr,
++ flags, params,
++ /*n_params=*/1) != 0) {
+ LOG(LS_ERROR) << "Could not connect receiving stream.";
++ portal_init_failed_ = true;
++ return;
+ }
+}
+
-+void ScreenCapturerPipeWire::HandleBuffer(pw_buffer* buffer) {
++void BaseCapturerPipeWire::HandleBuffer(pw_buffer* buffer) {
+ spa_buffer* spaBuffer = buffer->buffer;
+ void* src = nullptr;
+
@@ -1011,44 +654,43 @@ index 000000000000..ce47ae29eac9
+
+ uint32_t maxSize = spaBuffer->datas[0].maxsize;
+ int32_t srcStride = spaBuffer->datas[0].chunk->stride;
-+ if (srcStride != (desktop_size_.width() * kBytesPerPixel)) {
++ if (srcStride != (desktop_size_.width() * kBytesPerPixelPw)) {
+ LOG(LS_ERROR) << "Got buffer with stride different from screen stride: "
-+ << srcStride
-+ << " != " << (desktop_size_.width() * kBytesPerPixel);
++ << srcStride
++ << " != " << (desktop_size_.width() * kBytesPerPixelPw);
++ portal_init_failed_ = true;
+ return;
+ }
+
-+ uint8_t* tempFrame = static_cast<uint8_t*>(malloc(maxSize));
-+ std::memcpy(tempFrame, src, maxSize);
-+
-+ ConvertRGBxToBGRxIfNeeded(tempFrame, maxSize);
-+
+ if (!current_frame_) {
+ current_frame_ = static_cast<uint8_t*>(malloc(maxSize));
+ }
-+
+ RTC_DCHECK(current_frame_ != nullptr);
-+ std::memcpy(current_frame_, tempFrame, maxSize);
+
-+ free(tempFrame);
-+}
-+
-+void ScreenCapturerPipeWire::ConvertRGBxToBGRxIfNeeded(uint8_t* frame, uint32_t size)
-+{
+ // If both sides decided to go with the RGBx format we need to convert it to
+ // BGRx to match color format expected by WebRTC.
+ if (spa_video_format_->format == pw_type_->video_format.RGBx) {
-+ // Change color format for KDE KWin which uses RGBx and not BGRx.
-+ for (uint32_t i = 0; i < size; i += 4) {
-+ uint8_t tempR = frame[i];
-+ uint8_t tempB = frame[i + 2];
-+ frame[i] = tempB;
-+ frame[i + 2] = tempR;
-+ }
++ uint8_t* tempFrame = static_cast<uint8_t*>(malloc(maxSize));
++ std::memcpy(tempFrame, src, maxSize);
++ ConvertRGBxToBGRx(tempFrame, maxSize);
++ std::memcpy(current_frame_, tempFrame, maxSize);
++ free(tempFrame);
++ } else {
++ std::memcpy(current_frame_, src, maxSize);
+ }
+}
+
-+guint ScreenCapturerPipeWire::SetupRequestResponseSignal(
++void BaseCapturerPipeWire::ConvertRGBxToBGRx(uint8_t* frame, uint32_t size) {
++ // Change color format for KDE KWin which uses RGBx and not BGRx
++ for (uint32_t i = 0; i < size; i += 4) {
++ uint8_t tempR = frame[i];
++ uint8_t tempB = frame[i + 2];
++ frame[i] = tempB;
++ frame[i + 2] = tempR;
++ }
++}
++
++guint BaseCapturerPipeWire::SetupRequestResponseSignal(
+ const gchar* object_path,
+ GDBusSignalCallback callback) {
+ return g_dbus_connection_signal_subscribe(
@@ -1058,19 +700,20 @@ index 000000000000..ce47ae29eac9
+}
+
+// static
-+void ScreenCapturerPipeWire::OnProxyRequested(GObject* /*object*/,
++void BaseCapturerPipeWire::OnProxyRequested(GObject* /*object*/,
+ GAsyncResult* result,
+ gpointer user_data) {
-+ ScreenCapturerPipeWire* that =
-+ static_cast<ScreenCapturerPipeWire*>(user_data);
++ BaseCapturerPipeWire* that =
++ static_cast<BaseCapturerPipeWire*>(user_data);
+ RTC_DCHECK(that);
+
+ GError* error = nullptr;
+ that->proxy_ = g_dbus_proxy_new_finish(result, &error);
+ if (!that->proxy_) {
+ LOG(LS_ERROR) << "Failed to create a proxy for the screen cast portal: "
-+ << error->message;
++ << error->message;
+ g_error_free(error);
++ that->portal_init_failed_ = true;
+ return;
+ }
+ that->connection_ = g_dbus_proxy_get_connection(that->proxy_);
@@ -1080,7 +723,7 @@ index 000000000000..ce47ae29eac9
+}
+
+// static
-+gchar* ScreenCapturerPipeWire::PrepareSignalHandle(GDBusConnection* connection,
++gchar* BaseCapturerPipeWire::PrepareSignalHandle(GDBusConnection* connection,
+ const gchar* token) {
+ gchar* sender = g_strdup(g_dbus_connection_get_unique_name(connection) + 1);
+ for (int i = 0; sender[i]; i++) {
@@ -1096,7 +739,7 @@ index 000000000000..ce47ae29eac9
+ return handle;
+}
+
-+void ScreenCapturerPipeWire::SessionRequest() {
++void BaseCapturerPipeWire::SessionRequest() {
+ GVariantBuilder builder;
+ gchar* variant_string;
+
@@ -1123,19 +766,20 @@ index 000000000000..ce47ae29eac9
+}
+
+// static
-+void ScreenCapturerPipeWire::OnSessionRequested(GDBusConnection* connection,
++void BaseCapturerPipeWire::OnSessionRequested(GDBusConnection* connection,
+ GAsyncResult* result,
+ gpointer user_data) {
-+ ScreenCapturerPipeWire* that =
-+ static_cast<ScreenCapturerPipeWire*>(user_data);
++ BaseCapturerPipeWire* that =
++ static_cast<BaseCapturerPipeWire*>(user_data);
+ RTC_DCHECK(that);
+
+ GError* error = nullptr;
+ GVariant* variant = g_dbus_proxy_call_finish(that->proxy_, result, &error);
+ if (!variant) {
+ LOG(LS_ERROR) << "Failed to create a screen cast session: "
-+ << error->message;
++ << error->message;
+ g_error_free(error);
++ that->portal_init_failed_ = true;
+ return;
+ }
+ LOG(LS_INFO) << "Initializing the screen cast session.";
@@ -1150,31 +794,17 @@ index 000000000000..ce47ae29eac9
+ that->session_request_signal_id_);
+ that->session_request_signal_id_ = 0;
+ }
++ that->portal_init_failed_ = true;
+ return;
+ }
+
-+ // Support for older xdg-desktop-portal version.
-+ if (g_strcmp0(that->portal_handle_, handle) != 0) {
-+ if (that->session_request_signal_id_) {
-+ g_dbus_connection_signal_unsubscribe(connection,
-+ that->session_request_signal_id_);
-+ that->session_request_signal_id_ = 0;
-+ }
-+
-+ g_clear_pointer(&that->portal_handle_, g_free);
-+ that->portal_handle_ = handle;
-+
-+ that->session_request_signal_id_ = that->SetupRequestResponseSignal(
-+ that->portal_handle_, OnSessionRequestResponseSignal);
-+ }
-+
+ g_free(handle);
+
+ LOG(LS_INFO) << "Subscribing to the screen cast session.";
+}
+
+// static
-+void ScreenCapturerPipeWire::OnSessionRequestResponseSignal(
++void BaseCapturerPipeWire::OnSessionRequestResponseSignal(
+ GDBusConnection* connection,
+ const gchar* sender_name,
+ const gchar* object_path,
@@ -1182,11 +812,13 @@ index 000000000000..ce47ae29eac9
+ const gchar* signal_name,
+ GVariant* parameters,
+ gpointer user_data) {
-+ ScreenCapturerPipeWire* that =
-+ static_cast<ScreenCapturerPipeWire*>(user_data);
++ BaseCapturerPipeWire* that =
++ static_cast<BaseCapturerPipeWire*>(user_data);
+ RTC_DCHECK(that);
+
-+ LOG(LS_INFO) << "Received response for the screen cast session subscription.";
++
++ LOG(LS_INFO)
++ << "Received response for the screen cast session subscription.";
+
+ guint32 portal_response;
+ GVariant* response_data;
@@ -1196,20 +828,23 @@ index 000000000000..ce47ae29eac9
+ g_variant_unref(response_data);
+
+ if (!that->session_handle_ || portal_response) {
-+ LOG(LS_ERROR) << "Failed to request the screen cast session subscription.";
++ LOG(LS_ERROR)
++ << "Failed to request the screen cast session subscription.";
++ that->portal_init_failed_ = true;
+ return;
+ }
+
+ that->SourcesRequest();
+}
+
-+void ScreenCapturerPipeWire::SourcesRequest() {
++void BaseCapturerPipeWire::SourcesRequest() {
+ GVariantBuilder builder;
+ gchar* variant_string;
+
+ g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT);
+ // We want to record monitor content.
-+ g_variant_builder_add(&builder, "{sv}", "types", g_variant_new_uint32(1));
++ g_variant_builder_add(&builder, "{sv}", "types",
++ g_variant_new_uint32(capture_source_type_));
+ // We don't want to allow selection of multiple sources.
+ g_variant_builder_add(&builder, "{sv}", "multiple",
+ g_variant_new_boolean(false));
@@ -1231,11 +866,11 @@ index 000000000000..ce47ae29eac9
+}
+
+// static
-+void ScreenCapturerPipeWire::OnSourcesRequested(GDBusConnection* connection,
++void BaseCapturerPipeWire::OnSourcesRequested(GDBusConnection* connection,
+ GAsyncResult* result,
+ gpointer user_data) {
-+ ScreenCapturerPipeWire* that =
-+ static_cast<ScreenCapturerPipeWire*>(user_data);
++ BaseCapturerPipeWire* that =
++ static_cast<BaseCapturerPipeWire*>(user_data);
+ RTC_DCHECK(that);
+
+ GError* error = nullptr;
@@ -1243,6 +878,7 @@ index 000000000000..ce47ae29eac9
+ if (!variant) {
+ LOG(LS_ERROR) << "Failed to request the sources: " << error->message;
+ g_error_free(error);
++ that->portal_init_failed_ = true;
+ return;
+ }
+
@@ -1258,31 +894,17 @@ index 000000000000..ce47ae29eac9
+ that->sources_request_signal_id_);
+ that->sources_request_signal_id_ = 0;
+ }
++ that->portal_init_failed_ = true;
+ return;
+ }
+
-+ // Support for older xdg-desktop-portal version.
-+ if (g_strcmp0(that->sources_handle_, handle) != 0) {
-+ if (that->sources_request_signal_id_) {
-+ g_dbus_connection_signal_unsubscribe(connection,
-+ that->sources_request_signal_id_);
-+ that->sources_request_signal_id_ = 0;
-+ }
-+
-+ g_clear_pointer(&that->sources_handle_, g_free);
-+ that->sources_handle_ = handle;
-+
-+ that->sources_request_signal_id_ = that->SetupRequestResponseSignal(
-+ that->sources_handle_, OnSourcesRequestResponseSignal);
-+ }
-+
+ g_free(handle);
+
+ LOG(LS_INFO) << "Subscribed to sources signal.";
+}
+
+// static
-+void ScreenCapturerPipeWire::OnSourcesRequestResponseSignal(
++void BaseCapturerPipeWire::OnSourcesRequestResponseSignal(
+ GDBusConnection* connection,
+ const gchar* sender_name,
+ const gchar* object_path,
@@ -1290,15 +912,24 @@ index 000000000000..ce47ae29eac9
+ const gchar* signal_name,
+ GVariant* parameters,
+ gpointer user_data) {
-+ ScreenCapturerPipeWire* that =
-+ static_cast<ScreenCapturerPipeWire*>(user_data);
++ BaseCapturerPipeWire* that =
++ static_cast<BaseCapturerPipeWire*>(user_data);
+ RTC_DCHECK(that);
+
++ guint32 portal_response;
++ g_variant_get(parameters, "(u@a{sv})", &portal_response, nullptr);
++ if (portal_response) {
++ LOG(LS_ERROR)
++ << "Failed to select sources for the screen cast session.";
++ that->portal_init_failed_ = true;
++ return;
++ }
++
+ LOG(LS_INFO) << "Received sources signal from session.";
+ that->StartRequest();
+}
+
-+void ScreenCapturerPipeWire::StartRequest() {
++void BaseCapturerPipeWire::StartRequest() {
+ GVariantBuilder builder;
+ gchar* variant_string;
+
@@ -1324,19 +955,20 @@ index 000000000000..ce47ae29eac9
+}
+
+// static
-+void ScreenCapturerPipeWire::OnStartRequested(GDBusConnection* connection,
++void BaseCapturerPipeWire::OnStartRequested(GDBusConnection* connection,
+ GAsyncResult* result,
+ gpointer user_data) {
-+ ScreenCapturerPipeWire* that =
-+ static_cast<ScreenCapturerPipeWire*>(user_data);
++ BaseCapturerPipeWire* that =
++ static_cast<BaseCapturerPipeWire*>(user_data);
+ RTC_DCHECK(that);
+
+ GError* error = nullptr;
+ GVariant* variant = g_dbus_proxy_call_finish(that->proxy_, result, &error);
+ if (!variant) {
+ LOG(LS_ERROR) << "Failed to start the screen cast session: "
-+ << error->message;
++ << error->message;
+ g_error_free(error);
++ that->portal_init_failed_ = true;
+ return;
+ }
+
@@ -1353,31 +985,17 @@ index 000000000000..ce47ae29eac9
+ that->start_request_signal_id_);
+ that->start_request_signal_id_ = 0;
+ }
++ that->portal_init_failed_ = true;
+ return;
+ }
+
-+ // Support for older xdg-desktop-portal version.
-+ if (g_strcmp0(that->start_handle_, handle) != 0) {
-+ if (that->start_request_signal_id_) {
-+ g_dbus_connection_signal_unsubscribe(connection,
-+ that->start_request_signal_id_);
-+ that->start_request_signal_id_ = 0;
-+ }
-+
-+ g_clear_pointer(&that->start_handle_, g_free);
-+ that->start_handle_ = handle;
-+
-+ that->start_request_signal_id_ = that->SetupRequestResponseSignal(
-+ that->start_handle_, OnStartRequestResponseSignal);
-+ }
-+
+ g_free(handle);
+
+ LOG(LS_INFO) << "Subscribed to the start signal.";
+}
+
+// static
-+void ScreenCapturerPipeWire::OnStartRequestResponseSignal(
++void BaseCapturerPipeWire::OnStartRequestResponseSignal(
+ GDBusConnection* connection,
+ const gchar* sender_name,
+ const gchar* object_path,
@@ -1385,8 +1003,8 @@ index 000000000000..ce47ae29eac9
+ const gchar* signal_name,
+ GVariant* parameters,
+ gpointer user_data) {
-+ ScreenCapturerPipeWire* that =
-+ static_cast<ScreenCapturerPipeWire*>(user_data);
++ BaseCapturerPipeWire* that =
++ static_cast<BaseCapturerPipeWire*>(user_data);
+ RTC_DCHECK(that);
+
+ LOG(LS_INFO) << "Start signal received.";
@@ -1396,6 +1014,7 @@ index 000000000000..ce47ae29eac9
+ g_variant_get(parameters, "(u@a{sv})", &portal_response, &response_data);
+ if (portal_response || !response_data) {
+ LOG(LS_ERROR) << "Failed to start the screen cast session.";
++ that->portal_init_failed_ = true;
+ return;
+ }
+
@@ -1428,7 +1047,7 @@ index 000000000000..ce47ae29eac9
+ that->OpenPipeWireRemote();
+}
+
-+void ScreenCapturerPipeWire::OpenPipeWireRemote() {
++void BaseCapturerPipeWire::OpenPipeWireRemote() {
+ GVariantBuilder builder;
+ g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT);
+
@@ -1444,12 +1063,12 @@ index 000000000000..ce47ae29eac9
+}
+
+// static
-+void ScreenCapturerPipeWire::OnOpenPipeWireRemoteRequested(
++void BaseCapturerPipeWire::OnOpenPipeWireRemoteRequested(
+ GDBusConnection* connection,
+ GAsyncResult* result,
+ gpointer user_data) {
-+ ScreenCapturerPipeWire* that =
-+ static_cast<ScreenCapturerPipeWire*>(user_data);
++ BaseCapturerPipeWire* that =
++ static_cast<BaseCapturerPipeWire*>(user_data);
+ RTC_DCHECK(that);
+
+ GError* error = nullptr;
@@ -1457,8 +1076,10 @@ index 000000000000..ce47ae29eac9
+ GVariant* variant = g_dbus_proxy_call_with_unix_fd_list_finish(
+ that->proxy_, &outlist, result, &error);
+ if (!variant) {
-+ LOG(LS_ERROR) << "Failed to open the PipeWire remote: " << error->message;
++ LOG(LS_ERROR) << "Failed to open the PipeWire remote: "
++ << error->message;
+ g_error_free(error);
++ that->portal_init_failed_ = true;
+ return;
+ }
+
@@ -1467,9 +1088,10 @@ index 000000000000..ce47ae29eac9
+
+ if ((that->pw_fd_ = g_unix_fd_list_get(outlist, index, &error)) == -1) {
+ LOG(LS_ERROR) << "Failed to get file descriptor from the list: "
-+ << error->message;
++ << error->message;
+ g_error_free(error);
+ g_variant_unref(variant);
++ that->portal_init_failed_ = true;
+ return;
+ }
+
@@ -1480,21 +1102,21 @@ index 000000000000..ce47ae29eac9
+ LOG(LS_INFO) << "PipeWire remote opened.";
+}
+
-+void ScreenCapturerPipeWire::Start(Callback* callback) {
++void BaseCapturerPipeWire::Start(Callback* callback) {
+ RTC_DCHECK(!callback_);
+ RTC_DCHECK(callback);
+
++ InitPortals();
++
+ callback_ = callback;
+}
+
-+void ScreenCapturerPipeWire::Stop() {
-+ callback_ = nullptr;
-+ if (pw_main_loop_) {
-+ pw_thread_loop_stop(pw_main_loop_);
++void BaseCapturerPipeWire::CaptureFrame() {
++ if (portal_init_failed_) {
++ callback_->OnCaptureResult(Result::ERROR_PERMANENT, nullptr);
++ return;
+ }
-+}
+
-+void ScreenCapturerPipeWire::CaptureFrame() {
+ if (!current_frame_) {
+ callback_->OnCaptureResult(Result::ERROR_TEMPORARY, nullptr);
+ return;
@@ -1502,7 +1124,7 @@ index 000000000000..ce47ae29eac9
+
+ std::unique_ptr<DesktopFrame> result(new BasicDesktopFrame(desktop_size_));
+ result->CopyPixelsFrom(
-+ current_frame_, (desktop_size_.width() * kBytesPerPixel),
++ current_frame_, (desktop_size_.width() * kBytesPerPixelPw),
+ DesktopRect::MakeWH(desktop_size_.width(), desktop_size_.height()));
+ if (!result) {
+ callback_->OnCaptureResult(Result::ERROR_TEMPORARY, nullptr);
@@ -1511,18 +1133,456 @@ index 000000000000..ce47ae29eac9
+ callback_->OnCaptureResult(Result::SUCCESS, std::move(result));
+}
+
-+bool ScreenCapturerPipeWire::GetSourceList(SourceList* sources) {
++bool BaseCapturerPipeWire::GetSourceList(SourceList* sources) {
+ RTC_DCHECK(sources->size() == 0);
++ // List of available screens is already presented by the xdg-desktop-portal.
++ // But we have to add an empty source as the code expects it.
+ sources->push_back({0});
+ return true;
+}
+
-+bool ScreenCapturerPipeWire::SelectSource(SourceId id) {
-+ // TODO
++bool BaseCapturerPipeWire::SelectSource(SourceId id) {
++ // Screen selection is handled by the xdg-desktop-portal.
++ return true;
++}
++
++} // namespace webrtc
+diff --git a/media/webrtc/trunk/webrtc/modules/desktop_capture/base_capturer_pipewire.h b/media/webrtc/trunk/webrtc/modules/desktop_capture/base_capturer_pipewire.h
+new file mode 100644
+index 000000000..4577ddf6b
+--- /dev/null
++++ b/media/webrtc/trunk/webrtc/modules/desktop_capture/base_capturer_pipewire.h
+@@ -0,0 +1,167 @@
++/*
++ * Copyright 2018 The WebRTC project authors. All Rights Reserved.
++ *
++ * Use of this source code is governed by a BSD-style license
++ * that can be found in the LICENSE file in the root of the source
++ * tree. An additional intellectual property rights grant can be found
++ * in the file PATENTS. All contributing project authors may
++ * be found in the AUTHORS file in the root of the source tree.
++ */
++
++#ifndef MODULES_DESKTOP_CAPTURE_LINUX_BASE_CAPTURER_PIPEWIRE_H_
++#define MODULES_DESKTOP_CAPTURE_LINUX_BASE_CAPTURER_PIPEWIRE_H_
++
++#include <gio/gio.h>
++#define typeof __typeof__
++#include <pipewire/pipewire.h>
++#include <spa/param/video/format-utils.h>
++
++#include "webrtc/modules/desktop_capture/desktop_capture_options.h"
++#include "webrtc/modules/desktop_capture/desktop_capturer.h"
++
++namespace webrtc {
++
++class PipeWireType {
++ public:
++ spa_type_media_type media_type;
++ spa_type_media_subtype media_subtype;
++ spa_type_format_video format_video;
++ spa_type_video_format video_format;
++};
++
++class BaseCapturerPipeWire : public DesktopCapturer {
++ public:
++ enum CaptureSourceType { Screen = 1, Window };
++
++ explicit BaseCapturerPipeWire(CaptureSourceType source_type);
++ ~BaseCapturerPipeWire() override;
++
++ // DesktopCapturer interface.
++ void Start(Callback* delegate) override;
++ void Stop() override { callback_ = nullptr; }
++ void CaptureFrame() override;
++ bool GetSourceList(SourceList* sources) override;
++ bool SelectSource(SourceId id) override;
++
++ private:
++ // PipeWire types -->
++ pw_core* pw_core_ = nullptr;
++ pw_type* pw_core_type_ = nullptr;
++ pw_stream* pw_stream_ = nullptr;
++ pw_remote* pw_remote_ = nullptr;
++ pw_loop* pw_loop_ = nullptr;
++ pw_thread_loop* pw_main_loop_ = nullptr;
++ PipeWireType* pw_type_ = nullptr;
++
++ spa_hook spa_stream_listener_ = {};
++ spa_hook spa_remote_listener_ = {};
++
++ pw_stream_events pw_stream_events_ = {};
++ pw_remote_events pw_remote_events_ = {};
++
++ spa_video_info_raw* spa_video_format_ = nullptr;
++
++ gint32 pw_fd_ = -1;
++
++ CaptureSourceType capture_source_type_ =
++ BaseCapturerPipeWire::CaptureSourceType::Screen;
++
++ // <-- end of PipeWire types
++
++ GDBusConnection* connection_ = nullptr;
++ GDBusProxy* proxy_ = nullptr;
++ gchar* portal_handle_ = nullptr;
++ gchar* session_handle_ = nullptr;
++ gchar* sources_handle_ = nullptr;
++ gchar* start_handle_ = nullptr;
++ guint session_request_signal_id_ = 0;
++ guint sources_request_signal_id_ = 0;
++ guint start_request_signal_id_ = 0;
++
++ DesktopSize desktop_size_ = {};
++ DesktopCaptureOptions options_ = {};
++
++ uint8_t* current_frame_ = nullptr;
++ Callback* callback_ = nullptr;
++
++ bool portal_init_failed_ = false;
++
++ void InitPortals();
++ void InitPipeWire();
++ void InitPipeWireTypes();
++
++ void CreateReceivingStream();
++ void HandleBuffer(pw_buffer* buffer);
++
++ void ConvertRGBxToBGRx(uint8_t* frame, uint32_t size);
++
++ static void OnStateChanged(void* data,
++ pw_remote_state old_state,
++ pw_remote_state state,
++ const char* error);
++ static void OnStreamStateChanged(void* data,
++ pw_stream_state old_state,
++ pw_stream_state state,
++ const char* error_message);
++
++ static void OnStreamFormatChanged(void* data, const struct spa_pod* format);
++ static void OnStreamProcess(void* data);
++ static void OnNewBuffer(void* data, uint32_t id);
++
++ guint SetupRequestResponseSignal(const gchar* object_path,
++ GDBusSignalCallback callback);
++
++ static void OnProxyRequested(GObject* object,
++ GAsyncResult* result,
++ gpointer user_data);
++
++ static gchar* PrepareSignalHandle(GDBusConnection* connection,
++ const gchar* token);
++
++ void SessionRequest();
++ static void OnSessionRequested(GDBusConnection* connection,
++ GAsyncResult* result,
++ gpointer user_data);
++ static void OnSessionRequestResponseSignal(GDBusConnection* connection,
++ const gchar* sender_name,
++ const gchar* object_path,
++ const gchar* interface_name,
++ const gchar* signal_name,
++ GVariant* parameters,
++ gpointer user_data);
++
++ void SourcesRequest();
++ static void OnSourcesRequested(GDBusConnection* connection,
++ GAsyncResult* result,
++ gpointer user_data);
++ static void OnSourcesRequestResponseSignal(GDBusConnection* connection,
++ const gchar* sender_name,
++ const gchar* object_path,
++ const gchar* interface_name,
++ const gchar* signal_name,
++ GVariant* parameters,
++ gpointer user_data);
++
++ void StartRequest();
++ static void OnStartRequested(GDBusConnection* connection,
++ GAsyncResult* result,
++ gpointer user_data);
++ static void OnStartRequestResponseSignal(GDBusConnection* connection,
++ const gchar* sender_name,
++ const gchar* object_path,
++ const gchar* interface_name,
++ const gchar* signal_name,
++ GVariant* parameters,
++ gpointer user_data);
++
++ void OpenPipeWireRemote();
++ static void OnOpenPipeWireRemoteRequested(GDBusConnection* connection,
++ GAsyncResult* result,
++ gpointer user_data);
++
++ RTC_DISALLOW_COPY_AND_ASSIGN(BaseCapturerPipeWire);
++};
++
++} // namespace webrtc
++
++#endif // MODULES_DESKTOP_CAPTURE_LINUX_BASE_CAPTURER_PIPEWIRE_H_
+diff --git a/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capture_gn/moz.build b/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capture_gn/moz.build
+index ea1726a51..d72fe8161 100644
+--- a/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capture_gn/moz.build
++++ b/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capture_gn/moz.build
+@@ -166,10 +166,6 @@ if CONFIG["OS_TARGET"] == "Linux":
+ ]
+
+ UNIFIED_SOURCES += [
+- "/media/webrtc/trunk/webrtc/modules/desktop_capture/app_capturer_x11.cc",
+- "/media/webrtc/trunk/webrtc/modules/desktop_capture/mouse_cursor_monitor_x11.cc",
+- "/media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer_x11.cc",
+- "/media/webrtc/trunk/webrtc/modules/desktop_capture/window_capturer_x11.cc",
+ "/media/webrtc/trunk/webrtc/modules/desktop_capture/x11/desktop_device_info_x11.cc",
+ "/media/webrtc/trunk/webrtc/modules/desktop_capture/x11/shared_x_display.cc",
+ "/media/webrtc/trunk/webrtc/modules/desktop_capture/x11/shared_x_util.cc",
+@@ -177,6 +173,38 @@ if CONFIG["OS_TARGET"] == "Linux":
+ "/media/webrtc/trunk/webrtc/modules/desktop_capture/x11/x_server_pixel_buffer.cc"
+ ]
+
++# Common stuff between Pipewire and X11
++if CONFIG["OS_TARGET"] == "Linux":
++
++ UNIFIED_SOURCES += [
++ "/media/webrtc/trunk/webrtc/modules/desktop_capture/app_capturer_linux.cc",
++ "/media/webrtc/trunk/webrtc/modules/desktop_capture/base_capturer_pipewire.cc",
++ "/media/webrtc/trunk/webrtc/modules/desktop_capture/mouse_cursor_monitor_linux.cc",
++ "/media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer_linux.cc",
++ "/media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer_pipewire.cc",
++ "/media/webrtc/trunk/webrtc/modules/desktop_capture/window_capturer_linux.cc",
++ "/media/webrtc/trunk/webrtc/modules/desktop_capture/window_capturer_pipewire.cc",
++ ]
++
++# Pipewire
++if CONFIG["OS_TARGET"] == "Linux":
++
++ DEFINES["USE_PIPEWIRE"] = "1"
++
++ OS_LIBS += [
++ "rt",
++ "pipewire-0.2",
++ "glib-2.0",
++ "gio-2.0",
++ "gobject-2.0"
++ ]
++
++ CXXFLAGS += CONFIG['TK_CFLAGS']
++
++ UNIFIED_SOURCES += [
++ "/media/webrtc/trunk/webrtc/modules/desktop_capture/mouse_cursor_monitor_null.cc"
++ ]
++
+ if CONFIG["OS_TARGET"] == "NetBSD":
+
+ DEFINES["USE_X11"] = "1"
+diff --git a/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capturer.cc b/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capturer.cc
+index 7510bde47..9dab1eb50 100644
+--- a/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capturer.cc
++++ b/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capturer.cc
+@@ -66,4 +66,17 @@ std::unique_ptr<DesktopCapturer> DesktopCapturer::CreateAppCapturer(
+ return capturer;
+ }
+
++#if defined(USE_PIPEWIRE) || defined(USE_X11)
++bool DesktopCapturer::IsRunningUnderWayland() {
++ const char* xdg_session_type = getenv("XDG_SESSION_TYPE");
++ if (!xdg_session_type || strncmp(xdg_session_type, "wayland", 7) != 0)
++ return false;
++
++ if (!(getenv("WAYLAND_DISPLAY")))
++ return false;
++
+ return true;
+}
++#endif
+
-+} // namespace
+ } // namespace webrtc
+diff --git a/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capturer.h b/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capturer.h
+index eb84d3c3b..17cacc5dc 100644
+--- a/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capturer.h
++++ b/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capturer.h
+@@ -129,6 +129,10 @@ class DesktopCapturer {
+ static std::unique_ptr<DesktopCapturer> CreateAppCapturer(
+ const DesktopCaptureOptions& options);
+
++#if defined(USE_PIPEWIRE) || defined(USE_X11)
++ static bool IsRunningUnderWayland();
++#endif
++
+ protected:
+ // CroppingWindowCapturer needs to create raw capturers without wrappers, so
+ // the following two functions are protected.
+diff --git a/media/webrtc/trunk/webrtc/modules/desktop_capture/mouse_cursor_monitor_linux.cc b/media/webrtc/trunk/webrtc/modules/desktop_capture/mouse_cursor_monitor_linux.cc
+new file mode 100644
+index 000000000..f7aaf3dcd
+--- /dev/null
++++ b/media/webrtc/trunk/webrtc/modules/desktop_capture/mouse_cursor_monitor_linux.cc
+@@ -0,0 +1,44 @@
++/*
++ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
++ *
++ * Use of this source code is governed by a BSD-style license
++ * that can be found in the LICENSE file in the root of the source
++ * tree. An additional intellectual property rights grant can be found
++ * in the file PATENTS. All contributing project authors may
++ * be found in the AUTHORS file in the root of the source tree.
++ */
++
++#include "webrtc/modules/desktop_capture/mouse_cursor_monitor.h"
++
++#if defined(USE_PIPEWIRE)
++#include "webrtc/modules/desktop_capture/mouse_cursor_monitor_null.cc"
++#endif // defined(USE_PIPEWIRE)
++
++#if defined(USE_X11)
++#include "webrtc/modules/desktop_capture/mouse_cursor_monitor_x11.cc"
++#endif // defined(USE_X11)
++
++namespace webrtc {
++
++// static
++MouseCursorMonitor* MouseCursorMonitor::CreateForWindow(
++ const DesktopCaptureOptions& options, WindowId window) {
++#if defined(USE_X11)
++ return MouseCursorMonitorX11::CreateForWindow(options, window);
++#else
++ return nullptr;
++#endif // defined(USE_X11)
++}
++
++// static
++MouseCursorMonitor* MouseCursorMonitor::CreateForScreen(
++ const DesktopCaptureOptions& options,
++ ScreenId screen) {
++#if defined(USE_X11)
++ return MouseCursorMonitorX11::CreateForScreen(options, screen);
++#else
++ return nullptr;
++#endif // defined(USE_X11)
++}
++
++} // namespace webrtc
+diff --git a/media/webrtc/trunk/webrtc/modules/desktop_capture/mouse_cursor_monitor_null.cc b/media/webrtc/trunk/webrtc/modules/desktop_capture/mouse_cursor_monitor_null.cc
+index 3a632cc0d..b70b4e256 100644
+--- a/media/webrtc/trunk/webrtc/modules/desktop_capture/mouse_cursor_monitor_null.cc
++++ b/media/webrtc/trunk/webrtc/modules/desktop_capture/mouse_cursor_monitor_null.cc
+@@ -14,6 +14,7 @@
+
+ namespace webrtc {
+
++#if not defined(USE_PIPEWIRE)
+ MouseCursorMonitor* MouseCursorMonitor::CreateForWindow(
+ const DesktopCaptureOptions& options,
+ WindowId window) {
+@@ -25,5 +26,6 @@ MouseCursorMonitor* MouseCursorMonitor::CreateForScreen(
+ ScreenId screen) {
+ return NULL;
+ }
++#endif // not defined(USE_PIPEWIRE)
+
+ } // namespace webrtc
+diff --git a/media/webrtc/trunk/webrtc/modules/desktop_capture/mouse_cursor_monitor_x11.cc b/media/webrtc/trunk/webrtc/modules/desktop_capture/mouse_cursor_monitor_x11.cc
+index 2dcad5b38..a8397f1ec 100644
+--- a/media/webrtc/trunk/webrtc/modules/desktop_capture/mouse_cursor_monitor_x11.cc
++++ b/media/webrtc/trunk/webrtc/modules/desktop_capture/mouse_cursor_monitor_x11.cc
+@@ -69,6 +69,9 @@ class MouseCursorMonitorX11 : public MouseCursorMonitor,
+ void Stop() override;
+ void Capture() override;
+
++ static MouseCursorMonitor* CreateForWindow(const DesktopCaptureOptions& options, WindowId window);
++ static MouseCursorMonitor* CreateForScreen(const DesktopCaptureOptions& options, ScreenId screen);
++
+ private:
+ // SharedXDisplay::XEventHandler interface.
+ bool HandleXEvent(const XEvent& event) override;
+@@ -244,7 +247,7 @@ void MouseCursorMonitorX11::CaptureCursor() {
+ }
+
+ // static
+-MouseCursorMonitor* MouseCursorMonitor::CreateForWindow(
++MouseCursorMonitor* MouseCursorMonitorX11::CreateForWindow(
+ const DesktopCaptureOptions& options, WindowId window) {
+ if (!options.x_display())
+ return NULL;
+@@ -254,7 +257,7 @@ MouseCursorMonitor* MouseCursorMonitor::CreateForWindow(
+ return new MouseCursorMonitorX11(options, outer_window, window);
+ }
+
+-MouseCursorMonitor* MouseCursorMonitor::CreateForScreen(
++MouseCursorMonitor* MouseCursorMonitorX11::CreateForScreen(
+ const DesktopCaptureOptions& options,
+ ScreenId screen) {
+ if (!options.x_display())
+diff --git a/media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer_linux.cc b/media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer_linux.cc
+new file mode 100644
+index 000000000..43c4098e2
+--- /dev/null
++++ b/media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer_linux.cc
+@@ -0,0 +1,40 @@
++/*
++ * Copyright 2018 The WebRTC project authors. All Rights Reserved.
++ *
++ * Use of this source code is governed by a BSD-style license
++ * that can be found in the LICENSE file in the root of the source
++ * tree. An additional intellectual property rights grant can be found
++ * in the file PATENTS. All contributing project authors may
++ * be found in the AUTHORS file in the root of the source tree.
++ */
++
++#include "webrtc/modules/desktop_capture/desktop_capture_options.h"
++#include "webrtc/modules/desktop_capture/desktop_capturer.h"
++
++#if defined(USE_PIPEWIRE)
++#include "webrtc/modules/desktop_capture/screen_capturer_pipewire.h"
++#endif // defined(USE_PIPEWIRE)
++
++#if defined(USE_X11)
++#include "webrtc/modules/desktop_capture/screen_capturer_x11.cc"
++#endif // defined(USE_X11)
++
++namespace webrtc {
++
++// static
++std::unique_ptr<DesktopCapturer> DesktopCapturer::CreateRawScreenCapturer(
++ const DesktopCaptureOptions& options) {
++#if defined(USE_PIPEWIRE)
++ if (DesktopCapturer::IsRunningUnderWayland()) {
++ return ScreenCapturerPipeWire::CreateRawScreenCapturer(options);
++ }
++#endif // defined(USE_PIPEWIRE)
++
++#if defined(USE_X11)
++ return ScreenCapturerX11::CreateRawScreenCapturer(options);
++#endif // defined(USE_X11)
++
++ return nullptr;
++}
++
++} // namespace webrtc
+diff --git a/media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer_pipewire.cc b/media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer_pipewire.cc
+new file mode 100644
+index 000000000..b506c562f
+--- /dev/null
++++ b/media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer_pipewire.cc
+@@ -0,0 +1,31 @@
++/*
++ * Copyright 2018 The WebRTC project authors. All Rights Reserved.
++ *
++ * Use of this source code is governed by a BSD-style license
++ * that can be found in the LICENSE file in the root of the source
++ * tree. An additional intellectual property rights grant can be found
++ * in the file PATENTS. All contributing project authors may
++ * be found in the AUTHORS file in the root of the source tree.
++ */
++
++#include "webrtc/modules/desktop_capture/screen_capturer_pipewire.h"
++
++#include <memory>
++
++namespace webrtc {
++
++ScreenCapturerPipeWire::ScreenCapturerPipeWire()
++ : BaseCapturerPipeWire(BaseCapturerPipeWire::CaptureSourceType::Screen) {}
++ScreenCapturerPipeWire::~ScreenCapturerPipeWire() {}
+
+// static
+std::unique_ptr<DesktopCapturer>
@@ -1535,14 +1595,53 @@ index 000000000000..ce47ae29eac9
+}
+
+} // namespace webrtc
+diff --git a/media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer_pipewire.h b/media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer_pipewire.h
+new file mode 100644
+index 000000000..23cc3a53d
+--- /dev/null
++++ b/media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer_pipewire.h
+@@ -0,0 +1,33 @@
++/*
++ * Copyright 2018 The WebRTC project authors. All Rights Reserved.
++ *
++ * Use of this source code is governed by a BSD-style license
++ * that can be found in the LICENSE file in the root of the source
++ * tree. An additional intellectual property rights grant can be found
++ * in the file PATENTS. All contributing project authors may
++ * be found in the AUTHORS file in the root of the source tree.
++ */
++
++#ifndef MODULES_DESKTOP_CAPTURE_LINUX_SCREEN_CAPTURER_PIPEWIRE_H_
++#define MODULES_DESKTOP_CAPTURE_LINUX_SCREEN_CAPTURER_PIPEWIRE_H_
++
++#include <memory>
++
++#include "webrtc/modules/desktop_capture/base_capturer_pipewire.h"
++
++namespace webrtc {
++
++class ScreenCapturerPipeWire : public BaseCapturerPipeWire {
++ public:
++ ScreenCapturerPipeWire();
++ ~ScreenCapturerPipeWire() override;
++
++ static std::unique_ptr<DesktopCapturer> CreateRawScreenCapturer(
++ const DesktopCaptureOptions& options);
++
++ RTC_DISALLOW_COPY_AND_ASSIGN(ScreenCapturerPipeWire);
++};
++
++} // namespace webrtc
++
++#endif // MODULES_DESKTOP_CAPTURE_LINUX_SCREEN_CAPTURER_PIPEWIRE_H_
diff --git a/media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer_x11.cc b/media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer_x11.cc
-index 7692f8b70181..ba137853456c 100644
+index 7692f8b70..ba1378534 100644
--- a/media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer_x11.cc
+++ b/media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer_x11.cc
@@ -34,18 +34,20 @@
namespace webrtc {
namespace {
-
+
-// A class to perform video frame capturing for Linux.
+// A class to perform video frame capturing for Linux on X11.
//
@@ -1561,13 +1660,13 @@ index 7692f8b70181..ba137853456c 100644
+ ~ScreenCapturerX11() override;
+
+ static std::unique_ptr<DesktopCapturer> CreateRawScreenCapturer(const DesktopCaptureOptions& options);
-
+
// TODO(ajwong): Do we really want this to be synchronous?
bool Init(const DesktopCaptureOptions& options);
@@ -118,14 +120,13 @@ class ScreenCapturerLinux : public DesktopCapturer,
// current with the last buffer used.
DesktopRegion last_invalid_region_;
-
+
- RTC_DISALLOW_COPY_AND_ASSIGN(ScreenCapturerLinux);
+ RTC_DISALLOW_COPY_AND_ASSIGN(ScreenCapturerX11);
};
@@ -1576,7 +1675,7 @@ index 7692f8b70181..ba137853456c 100644
+ScreenCapturerX11::ScreenCapturerX11() {
helper_.SetLogGridSize(4);
}
-
+
-ScreenCapturerLinux::~ScreenCapturerLinux() {
+ScreenCapturerX11::~ScreenCapturerX11() {
options_.x_display()->RemoveEventHandler(ConfigureNotify, this);
@@ -1585,16 +1684,16 @@ index 7692f8b70181..ba137853456c 100644
@@ -134,7 +135,7 @@ ScreenCapturerLinux::~ScreenCapturerLinux() {
DeinitXlib();
}
-
+
-bool ScreenCapturerLinux::Init(const DesktopCaptureOptions& options) {
+bool ScreenCapturerX11::Init(const DesktopCaptureOptions& options) {
options_ = options;
-
+
root_window_ = RootWindow(display(), DefaultScreen(display()));
@@ -177,7 +178,7 @@ bool ScreenCapturerLinux::Init(const DesktopCaptureOptions& options) {
return true;
}
-
+
-void ScreenCapturerLinux::InitXDamage() {
+void ScreenCapturerX11::InitXDamage() {
// Our use of XDamage requires XFixes.
@@ -1603,24 +1702,24 @@ index 7692f8b70181..ba137853456c 100644
@@ -218,18 +219,18 @@ void ScreenCapturerLinux::InitXDamage() {
LOG(LS_INFO) << "Using XDamage extension.";
}
-
+
-void ScreenCapturerLinux::Start(Callback* callback) {
+void ScreenCapturerX11::Start(Callback* callback) {
RTC_DCHECK(!callback_);
RTC_DCHECK(callback);
-
+
callback_ = callback;
}
-
+
-void ScreenCapturerLinux::Stop() {
+void ScreenCapturerX11::Stop() {
callback_ = NULL;
}
-
+
-void ScreenCapturerLinux::CaptureFrame() {
+void ScreenCapturerX11::CaptureFrame() {
int64_t capture_start_time_nanos = rtc::TimeNanos();
-
+
queue_.MoveToNextFrame();
@@ -243,6 +244,7 @@ void ScreenCapturerLinux::CaptureFrame() {
// in a good shape.
@@ -1631,7 +1730,7 @@ index 7692f8b70181..ba137853456c 100644
return;
}
@@ -258,6 +260,7 @@ void ScreenCapturerLinux::CaptureFrame() {
-
+
std::unique_ptr<DesktopFrame> result = CaptureScreen();
if (!result) {
+ LOG(LS_WARNING) << "Temporarily failed to capture screen.";
@@ -1641,7 +1740,7 @@ index 7692f8b70181..ba137853456c 100644
@@ -268,19 +271,19 @@ void ScreenCapturerLinux::CaptureFrame() {
callback_->OnCaptureResult(Result::SUCCESS, std::move(result));
}
-
+
-bool ScreenCapturerLinux::GetSourceList(SourceList* sources) {
+bool ScreenCapturerX11::GetSourceList(SourceList* sources) {
RTC_DCHECK(sources->size() == 0);
@@ -1649,13 +1748,13 @@ index 7692f8b70181..ba137853456c 100644
sources->push_back({0});
return true;
}
-
+
-bool ScreenCapturerLinux::SelectSource(SourceId id) {
+bool ScreenCapturerX11::SelectSource(SourceId id) {
// TODO(jiayl): implement screen selection.
return true;
}
-
+
-bool ScreenCapturerLinux::HandleXEvent(const XEvent& event) {
+bool ScreenCapturerX11::HandleXEvent(const XEvent& event) {
if (use_damage_ && (event.type == damage_event_base_ + XDamageNotify)) {
@@ -1664,12 +1763,12 @@ index 7692f8b70181..ba137853456c 100644
@@ -295,7 +298,7 @@ bool ScreenCapturerLinux::HandleXEvent(const XEvent& event) {
return false;
}
-
+
-std::unique_ptr<DesktopFrame> ScreenCapturerLinux::CaptureScreen() {
+std::unique_ptr<DesktopFrame> ScreenCapturerX11::CaptureScreen() {
std::unique_ptr<SharedDesktopFrame> frame = queue_.current_frame()->Share();
RTC_DCHECK(x_server_pixel_buffer_.window_size().equals(frame->size()));
-
+
@@ -345,25 +348,26 @@ std::unique_ptr<DesktopFrame> ScreenCapturerLinux::CaptureScreen() {
// Doing full-screen polling, or this is the first capture after a
// screen-resolution change. In either case, need a full-screen capture.
@@ -1679,15 +1778,15 @@ index 7692f8b70181..ba137853456c 100644
+ return nullptr;
updated_region->SetRect(screen_rect);
}
-
+
return std::move(frame);
}
-
+
-void ScreenCapturerLinux::ScreenConfigurationChanged() {
+void ScreenCapturerX11::ScreenConfigurationChanged() {
// Make sure the frame buffers will be reallocated.
queue_.Reset();
-
+
helper_.ClearInvalidRegion();
if (!x_server_pixel_buffer_.Init(display(), DefaultRootWindow(display()))) {
LOG(LS_ERROR) << "Failed to initialize pixel buffer after screen "
@@ -1695,7 +1794,7 @@ index 7692f8b70181..ba137853456c 100644
+ "configuration change.";
}
}
-
+
-void ScreenCapturerLinux::SynchronizeFrame() {
+void ScreenCapturerX11::SynchronizeFrame() {
// Synchronize the current buffer with the previous one since we do not
@@ -1704,7 +1803,7 @@ index 7692f8b70181..ba137853456c 100644
@@ -383,7 +387,7 @@ void ScreenCapturerLinux::SynchronizeFrame() {
}
}
-
+
-void ScreenCapturerLinux::DeinitXlib() {
+void ScreenCapturerX11::DeinitXlib() {
if (gc_) {
@@ -1712,33 +1811,33 @@ index 7692f8b70181..ba137853456c 100644
gc_ = nullptr;
@@ -407,17 +411,17 @@ void ScreenCapturerLinux::DeinitXlib() {
} // namespace
-
+
// static
-std::unique_ptr<DesktopCapturer> DesktopCapturer::CreateRawScreenCapturer(
+std::unique_ptr<DesktopCapturer> ScreenCapturerX11::CreateRawScreenCapturer(
const DesktopCaptureOptions& options) {
if (!options.x_display())
return nullptr;
-
+
- std::unique_ptr<ScreenCapturerLinux> capturer(new ScreenCapturerLinux());
+ std::unique_ptr<ScreenCapturerX11> capturer(new ScreenCapturerX11());
if (!capturer.get()->Init(options)) {
return nullptr;
}
-
+
- return std::unique_ptr<DesktopCapturer>(capturer.release());
+ return std::move(capturer);
}
-
+
} // namespace webrtc
diff --git a/media/webrtc/trunk/webrtc/modules/desktop_capture/window_capturer_linux.cc b/media/webrtc/trunk/webrtc/modules/desktop_capture/window_capturer_linux.cc
new file mode 100644
-index 000000000000..fde7750c878b
+index 000000000..284ccdb7b
--- /dev/null
+++ b/media/webrtc/trunk/webrtc/modules/desktop_capture/window_capturer_linux.cc
@@ -0,0 +1,40 @@
+/*
-+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
++ * Copyright 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
@@ -1751,12 +1850,12 @@ index 000000000000..fde7750c878b
+#include "webrtc/modules/desktop_capture/desktop_capturer.h"
+
+#if defined(USE_PIPEWIRE)
-+#include "webrtc/modules/desktop_capture/window_capturer_null.cc"
-+#endif // defined(USE_PIPEWIRE)
++#include "webrtc/modules/desktop_capture/window_capturer_pipewire.h"
++#endif // defined(USE_PIPEWIRE)
+
+#if defined(USE_X11)
+#include "webrtc/modules/desktop_capture/window_capturer_x11.cc"
-+#endif // defined(USE_X11)
++#endif // defined(USE_X11)
+
+namespace webrtc {
+
@@ -1765,26 +1864,26 @@ index 000000000000..fde7750c878b
+ const DesktopCaptureOptions& options) {
+#if defined(USE_PIPEWIRE)
+ if (DesktopCapturer::IsRunningUnderWayland()) {
-+ return std::unique_ptr<DesktopCapturer>(new WindowCapturerNull());
++ return WindowCapturerPipeWire::CreateRawWindowCapturer(options);
+ }
-+#endif // defined(USE_PIPEWIRE)
++#endif // defined(USE_PIPEWIRE)
+
+#if defined(USE_X11)
+ return WindowCapturerX11::CreateRawWindowCapturer(options);
-+#endif // defined(USE_X11)
++#endif // defined(USE_X11)
+
+ return nullptr;
+}
+
+} // namespace webrtc
diff --git a/media/webrtc/trunk/webrtc/modules/desktop_capture/window_capturer_null.cc b/media/webrtc/trunk/webrtc/modules/desktop_capture/window_capturer_null.cc
-index 0f0159bb5f16..f6ef0639a586 100755
+index 0f0159bb5..f6ef0639a 100755
--- a/media/webrtc/trunk/webrtc/modules/desktop_capture/window_capturer_null.cc
+++ b/media/webrtc/trunk/webrtc/modules/desktop_capture/window_capturer_null.cc
@@ -67,10 +67,12 @@ void WindowCapturerNull::CaptureFrame() {
-
+
} // namespace
-
+
+#if not defined(USE_PIPEWIRE)
// static
std::unique_ptr<DesktopCapturer> DesktopCapturer::CreateRawWindowCapturer(
@@ -1792,16 +1891,89 @@ index 0f0159bb5f16..f6ef0639a586 100755
return std::unique_ptr<DesktopCapturer>(new WindowCapturerNull());
}
+#endif // not defined(USE_PIPEWIRE)
-
+
} // namespace webrtc
+diff --git a/media/webrtc/trunk/webrtc/modules/desktop_capture/window_capturer_pipewire.cc b/media/webrtc/trunk/webrtc/modules/desktop_capture/window_capturer_pipewire.cc
+new file mode 100644
+index 000000000..4f97e6ac2
+--- /dev/null
++++ b/media/webrtc/trunk/webrtc/modules/desktop_capture/window_capturer_pipewire.cc
+@@ -0,0 +1,28 @@
++/*
++ * Copyright 2018 The WebRTC project authors. All Rights Reserved.
++ *
++ * Use of this source code is governed by a BSD-style license
++ * that can be found in the LICENSE file in the root of the source
++ * tree. An additional intellectual property rights grant can be found
++ * in the file PATENTS. All contributing project authors may
++ * be found in the AUTHORS file in the root of the source tree.
++ */
++
++#include "webrtc/modules/desktop_capture/window_capturer_pipewire.h"
++
++namespace webrtc {
++
++WindowCapturerPipeWire::WindowCapturerPipeWire()
++ : BaseCapturerPipeWire(BaseCapturerPipeWire::CaptureSourceType::Window) {}
++WindowCapturerPipeWire::~WindowCapturerPipeWire() {}
++
++// static
++std::unique_ptr<DesktopCapturer>
++WindowCapturerPipeWire::CreateRawWindowCapturer(
++ const DesktopCaptureOptions& options) {
++ std::unique_ptr<WindowCapturerPipeWire> capturer(
++ new WindowCapturerPipeWire());
++
++ return std::move(capturer);
++}
++} // namespace webrtc
+diff --git a/media/webrtc/trunk/webrtc/modules/desktop_capture/window_capturer_pipewire.h b/media/webrtc/trunk/webrtc/modules/desktop_capture/window_capturer_pipewire.h
+new file mode 100644
+index 000000000..e04bc7151
+--- /dev/null
++++ b/media/webrtc/trunk/webrtc/modules/desktop_capture/window_capturer_pipewire.h
+@@ -0,0 +1,33 @@
++/*
++ * Copyright 2018 The WebRTC project authors. All Rights Reserved.
++ *
++ * Use of this source code is governed by a BSD-style license
++ * that can be found in the LICENSE file in the root of the source
++ * tree. An additional intellectual property rights grant can be found
++ * in the file PATENTS. All contributing project authors may
++ * be found in the AUTHORS file in the root of the source tree.
++ */
++
++#ifndef MODULES_DESKTOP_CAPTURE_LINUX_WINDOW_CAPTURER_PIPEWIRE_H_
++#define MODULES_DESKTOP_CAPTURE_LINUX_WINDOW_CAPTURER_PIPEWIRE_H_
++
++#include <memory>
++
++#include "webrtc/modules/desktop_capture/base_capturer_pipewire.h"
++
++namespace webrtc {
++
++class WindowCapturerPipeWire : public BaseCapturerPipeWire {
++ public:
++ WindowCapturerPipeWire();
++ ~WindowCapturerPipeWire() override;
++
++ static std::unique_ptr<DesktopCapturer> CreateRawWindowCapturer(
++ const DesktopCaptureOptions& options);
++
++ RTC_DISALLOW_COPY_AND_ASSIGN(WindowCapturerPipeWire);
++};
++
++} // namespace webrtc
++
++#endif // MODULES_DESKTOP_CAPTURE_LINUX_WINDOW_CAPTURER_PIPEWIRE_H_
diff --git a/media/webrtc/trunk/webrtc/modules/desktop_capture/window_capturer_x11.cc b/media/webrtc/trunk/webrtc/modules/desktop_capture/window_capturer_x11.cc
-index fecb329db546..d478604aa3de 100644
+index fecb329db..d478604aa 100644
--- a/media/webrtc/trunk/webrtc/modules/desktop_capture/window_capturer_x11.cc
+++ b/media/webrtc/trunk/webrtc/modules/desktop_capture/window_capturer_x11.cc
@@ -32,11 +32,13 @@ namespace webrtc {
-
+
namespace {
-
+
-class WindowCapturerLinux : public DesktopCapturer,
+class WindowCapturerX11 : public DesktopCapturer,
public SharedXDisplay::XEventHandler {
@@ -1812,17 +1984,17 @@ index fecb329db546..d478604aa3de 100644
+ ~WindowCapturerX11() override;
+
+ static std::unique_ptr<DesktopCapturer> CreateRawWindowCapturer(const DesktopCaptureOptions& options);
-
+
// DesktopCapturer interface.
void Start(Callback* callback) override;
@@ -78,10 +80,10 @@ class WindowCapturerLinux : public DesktopCapturer,
::Window selected_window_ = 0;
XServerPixelBuffer x_server_pixel_buffer_;
-
+
- RTC_DISALLOW_COPY_AND_ASSIGN(WindowCapturerLinux);
+ RTC_DISALLOW_COPY_AND_ASSIGN(WindowCapturerX11);
};
-
+
-WindowCapturerLinux::WindowCapturerLinux(const DesktopCaptureOptions& options)
+WindowCapturerX11::WindowCapturerX11(const DesktopCaptureOptions& options)
: x_display_(options.x_display()) {
@@ -1831,61 +2003,61 @@ index fecb329db546..d478604aa3de 100644
@@ -102,11 +104,11 @@ WindowCapturerLinux::WindowCapturerLinux(const DesktopCaptureOptions& options)
x_display_->AddEventHandler(ConfigureNotify, this);
}
-
+
-WindowCapturerLinux::~WindowCapturerLinux() {
+WindowCapturerX11::~WindowCapturerX11() {
x_display_->RemoveEventHandler(ConfigureNotify, this);
}
-
+
-bool WindowCapturerLinux::GetSourceList(SourceList* sources) {
+bool WindowCapturerX11::GetSourceList(SourceList* sources) {
SourceList result;
-
+
XErrorTrap error_trap(display());
@@ -159,7 +161,7 @@ bool WindowCapturerLinux::GetSourceList(SourceList* sources) {
return true;
}
-
+
-bool WindowCapturerLinux::SelectSource(SourceId id) {
+bool WindowCapturerX11::SelectSource(SourceId id) {
if (!x_server_pixel_buffer_.Init(display(), id))
return false;
-
+
@@ -180,7 +182,7 @@ bool WindowCapturerLinux::SelectSource(SourceId id) {
return true;
}
-
+
-bool WindowCapturerLinux::FocusOnSelectedSource() {
+bool WindowCapturerX11::FocusOnSelectedSource() {
if (!selected_window_)
return false;
-
+
@@ -229,18 +231,18 @@ bool WindowCapturerLinux::FocusOnSelectedSource() {
return true;
}
-
+
-void WindowCapturerLinux::Start(Callback* callback) {
+void WindowCapturerX11::Start(Callback* callback) {
assert(!callback_);
assert(callback);
-
+
callback_ = callback;
}
-
+
-void WindowCapturerLinux::Stop() {
+void WindowCapturerX11::Stop() {
callback_ = NULL;
}
-
+
-void WindowCapturerLinux::CaptureFrame() {
+void WindowCapturerX11::CaptureFrame() {
x_display_->ProcessPendingXEvents();
-
+
if (!x_server_pixel_buffer_.IsWindowValid()) {
@@ -274,7 +276,7 @@ void WindowCapturerLinux::CaptureFrame() {
callback_->OnCaptureResult(Result::SUCCESS, std::move(frame));
}
-
+
-bool WindowCapturerLinux::HandleXEvent(const XEvent& event) {
+bool WindowCapturerX11::HandleXEvent(const XEvent& event) {
if (event.type == ConfigureNotify) {
@@ -1894,34 +2066,34 @@ index fecb329db546..d478604aa3de 100644
@@ -288,7 +290,7 @@ bool WindowCapturerLinux::HandleXEvent(const XEvent& event) {
return false;
}
-
+
-::Window WindowCapturerLinux::GetApplicationWindow(::Window window) {
+::Window WindowCapturerX11::GetApplicationWindow(::Window window) {
// Get WM_STATE property of the window.
XWindowProperty<uint32_t> window_state(display(), window, wm_state_atom_);
-
+
@@ -326,7 +328,7 @@ bool WindowCapturerLinux::HandleXEvent(const XEvent& event) {
return app_window;
}
-
+
-bool WindowCapturerLinux::IsDesktopElement(::Window window) {
+bool WindowCapturerX11::IsDesktopElement(::Window window) {
if (window == 0)
return false;
-
+
@@ -361,7 +363,7 @@ bool WindowCapturerLinux::IsDesktopElement(::Window window) {
return result;
}
-
+
-bool WindowCapturerLinux::GetWindowTitle(::Window window, std::string* title) {
+bool WindowCapturerX11::GetWindowTitle(::Window window, std::string* title) {
int status;
bool result = false;
XTextProperty window_name;
@@ -392,7 +394,7 @@ bool WindowCapturerLinux::GetWindowTitle(::Window window, std::string* title) {
-
+
} // namespace
-
+
-int WindowCapturerLinux::GetWindowProcessID(::Window window) {
+int WindowCapturerX11::GetWindowProcessID(::Window window) {
// Get _NET_WM_PID property of the window.
@@ -1929,7 +2101,7 @@ index fecb329db546..d478604aa3de 100644
XWindowProperty<uint32_t> process_id(display(), window, process_atom);
@@ -401,11 +403,11 @@ int WindowCapturerLinux::GetWindowProcessID(::Window window) {
}
-
+
// static
-std::unique_ptr<DesktopCapturer> DesktopCapturer::CreateRawWindowCapturer(
+std::unique_ptr<DesktopCapturer> WindowCapturerX11::CreateRawWindowCapturer(
@@ -1939,5 +2111,5 @@ index fecb329db546..d478604aa3de 100644
- return std::unique_ptr<DesktopCapturer>(new WindowCapturerLinux(options));
+ return std::unique_ptr<DesktopCapturer>(new WindowCapturerX11(options));
}
-
+
} // namespace webrtc
bgstack15