From 0e9556a90cec52c2375c9250269f3abc21e8ca0c Mon Sep 17 00:00:00 2001 From: Jan Grulich Date: Wed, 12 Jul 2023 13:15:40 +0200 Subject: [PATCH] Desktop capture: introduce capturer requesting both screen and windows When PipeWire and xdg-desktop-portals are used, we can actually combine both source types into one request. Make this part of the API for those who want to use it this way, e.g. Firefox or Electron, otherwise they will end up making two simultaneous requests, resulting into two dialogs at the same time asking, while they can be combined into just one. Bug: webrtc:15363 Change-Id: Ib6e1e47f66cb01d5c65096aec378b44c3af5f387 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/311549 Reviewed-by: Alexander Cooper Commit-Queue: Jan Grulich Cr-Commit-Position: refs/heads/main@{#40425} --- .../desktop_capture/desktop_capture_types.h | 2 +- modules/desktop_capture/desktop_capturer.cc | 23 +++++++++++++++++++ modules/desktop_capture/desktop_capturer.h | 5 ++++ .../linux/wayland/screencast_portal.cc | 2 ++ 4 files changed, 31 insertions(+), 1 deletion(-) diff --git a/modules/desktop_capture/desktop_capture_types.h b/modules/desktop_capture/desktop_capture_types.h index 9627076eea..a4e3e897fd 100644 --- a/modules/desktop_capture/desktop_capture_types.h +++ b/modules/desktop_capture/desktop_capture_types.h @@ -15,7 +15,7 @@ namespace webrtc { -enum class CaptureType { kWindow, kScreen }; +enum class CaptureType { kWindow, kScreen, kAnyScreenContent }; // Type used to identify windows on the desktop. Values are platform-specific: // - On Windows: HWND cast to intptr_t. diff --git a/modules/desktop_capture/desktop_capturer.cc b/modules/desktop_capture/desktop_capturer.cc index f9efd93a64..a52a76c262 100644 --- a/modules/desktop_capture/desktop_capturer.cc +++ b/modules/desktop_capture/desktop_capturer.cc @@ -26,6 +26,10 @@ #include "rtc_base/win/windows_version.h" #endif // defined(RTC_ENABLE_WIN_WGC) +#if defined(WEBRTC_USE_PIPEWIRE) +#include "modules/desktop_capture/linux/wayland/base_capturer_pipewire.h" +#endif + namespace webrtc { void LogDesktopCapturerFullscreenDetectorUsage() { @@ -103,6 +107,25 @@ std::unique_ptr DesktopCapturer::CreateScreenCapturer( return capturer; } +// static +std::unique_ptr DesktopCapturer::CreateGenericCapturer( + const DesktopCaptureOptions& options) { + std::unique_ptr capturer; + +#if defined(WEBRTC_USE_PIPEWIRE) + if (options.allow_pipewire() && DesktopCapturer::IsRunningUnderWayland()) { + capturer = std::make_unique( + options, CaptureType::kAnyScreenContent); + } + + if (capturer && options.detect_updated_region()) { + capturer.reset(new DesktopCapturerDifferWrapper(std::move(capturer))); + } +#endif // defined(WEBRTC_USE_PIPEWIRE) + + return capturer; +} + #if defined(WEBRTC_USE_PIPEWIRE) || defined(WEBRTC_USE_X11) bool DesktopCapturer::IsRunningUnderWayland() { const char* xdg_session_type = getenv("XDG_SESSION_TYPE"); diff --git a/modules/desktop_capture/desktop_capturer.h b/modules/desktop_capture/desktop_capturer.h index fd884f13ff..9c7ecc78f4 100644 --- a/modules/desktop_capture/desktop_capturer.h +++ b/modules/desktop_capture/desktop_capturer.h @@ -186,6 +186,11 @@ class RTC_EXPORT DesktopCapturer { static std::unique_ptr CreateScreenCapturer( const DesktopCaptureOptions& options); + // Creates a DesktopCapturer instance which targets to capture windows and + // screens. + static std::unique_ptr CreateGenericCapturer( + const DesktopCaptureOptions& options); + #if defined(WEBRTC_USE_PIPEWIRE) || defined(WEBRTC_USE_X11) static bool IsRunningUnderWayland(); diff --git a/modules/desktop_capture/linux/wayland/screencast_portal.cc b/modules/desktop_capture/linux/wayland/screencast_portal.cc index a473802176..61ed84ebb5 100644 --- a/modules/desktop_capture/linux/wayland/screencast_portal.cc +++ b/modules/desktop_capture/linux/wayland/screencast_portal.cc @@ -41,6 +41,8 @@ ScreenCastPortal::CaptureSourceType ScreenCastPortal::ToCaptureSourceType( return ScreenCastPortal::CaptureSourceType::kScreen; case CaptureType::kWindow: return ScreenCastPortal::CaptureSourceType::kWindow; + case CaptureType::kAnyScreenContent: + return ScreenCastPortal::CaptureSourceType::kAnyScreenContent; } }