From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Athul Iddya <athul@iddya.com>
Date: Tue, 12 Sep 2023 22:19:46 -0700
Subject: fix: Handle PipeWire capturer initialization and management

This patch handles several fixes related to PipeWire capturer initialization
and management.

1. Mark PipeWire capturer as failed after session is closed

After a PipeWire screencast session is successfully started, the
consumer is expected to keep calling CaptureFrame() from the
DesktopCapturer interface in a loop to pull frames. A PipeWire
screencast session can be closed by the server on user action. Once the
session is closed, there's no point in calling CaptureFrame() again as
the capture has to be restarted. Inform the caller of the failure by
returning Result::ERROR_PERMANENT on the next invocation of
CaptureFrame().

2. Check PipeWire init before creating generic capturer

Check if PipeWire can be initialized before creating generic capturer.
This harmonizes the conditions with the ones used in Linux
implementations of DesktopCapturer::CreateRawScreenCapturer and
DesktopCapturer::CreateRawWindowCapturer.

3. Establishes fallback to X11 capturer when PipeWire fails to start

CL: https://webrtc-review.googlesource.com/c/src/+/279163

Desktop Capturer behaves inconsistently on Wayland. PipeWire does not
always successfully start; if it does not, we return a nullptr rather
than falling back on the X11 capturer, crashing the application. If the
X11 capturer is enabled, we should at minimum try to fallback to X11
for desktop capturer. This change re-enables that fallback, which was
previously default behavior.

diff --git a/modules/desktop_capture/desktop_capturer.cc b/modules/desktop_capture/desktop_capturer.cc
index 7fd0fc31d81bf4d5eca5f8aa7106388ea4c518e4..51dde063a78be7aade1953fbee8bb2db71b72ce5 100644
--- a/modules/desktop_capture/desktop_capturer.cc
+++ b/modules/desktop_capture/desktop_capturer.cc
@@ -113,7 +113,7 @@ std::unique_ptr<DesktopCapturer> DesktopCapturer::CreateGenericCapturer(
   std::unique_ptr<DesktopCapturer> capturer;
 
 #if defined(WEBRTC_USE_PIPEWIRE)
-  if (options.allow_pipewire() && DesktopCapturer::IsRunningUnderWayland()) {
+  if (options.allow_pipewire() && BaseCapturerPipeWire::IsSupported()) {
     capturer = std::make_unique<BaseCapturerPipeWire>(
         options, CaptureType::kAnyScreenContent);
   }
diff --git a/modules/desktop_capture/linux/wayland/base_capturer_pipewire.cc b/modules/desktop_capture/linux/wayland/base_capturer_pipewire.cc
index 81caa9bd2d97ec73120c07c17d7290b2c3c5d598..3ba5267bf5c7de420131b2c14fcadffd1f5b1326 100644
--- a/modules/desktop_capture/linux/wayland/base_capturer_pipewire.cc
+++ b/modules/desktop_capture/linux/wayland/base_capturer_pipewire.cc
@@ -111,6 +111,7 @@ void BaseCapturerPipeWire::OnScreenCastRequestResult(RequestResponse result,
 void BaseCapturerPipeWire::OnScreenCastSessionClosed() {
   if (!capturer_failed_) {
     options_.screencast_stream()->StopScreenCastStream();
+    capturer_failed_ = true;
   }
   capturer_failed_ = true;
 }
diff --git a/modules/desktop_capture/screen_capturer_linux.cc b/modules/desktop_capture/screen_capturer_linux.cc
index 44993837e8bbd84a11ec9d187349a95f83258910..cd9f8b0be6a19d057fe9150382fb72bc4032b343 100644
--- a/modules/desktop_capture/screen_capturer_linux.cc
+++ b/modules/desktop_capture/screen_capturer_linux.cc
@@ -34,11 +34,10 @@ std::unique_ptr<DesktopCapturer> DesktopCapturer::CreateRawScreenCapturer(
 #endif  // defined(WEBRTC_USE_PIPEWIRE)
 
 #if defined(WEBRTC_USE_X11)
-  if (!DesktopCapturer::IsRunningUnderWayland())
-    return ScreenCapturerX11::CreateRawScreenCapturer(options);
-#endif  // defined(WEBRTC_USE_X11)
-
+  return ScreenCapturerX11::CreateRawScreenCapturer(options);
+#else
   return nullptr;
+#endif  // defined(WEBRTC_USE_X11)
 }
 
 }  // namespace webrtc
diff --git a/modules/desktop_capture/window_capturer_linux.cc b/modules/desktop_capture/window_capturer_linux.cc
index 4205bf9bc0eede48cdc39353c77ceb6e7529fd51..785dc01a1911fd027401b1461223668333e05558 100644
--- a/modules/desktop_capture/window_capturer_linux.cc
+++ b/modules/desktop_capture/window_capturer_linux.cc
@@ -34,11 +34,10 @@ std::unique_ptr<DesktopCapturer> DesktopCapturer::CreateRawWindowCapturer(
 #endif  // defined(WEBRTC_USE_PIPEWIRE)
 
 #if defined(WEBRTC_USE_X11)
-  if (!DesktopCapturer::IsRunningUnderWayland())
-    return WindowCapturerX11::CreateRawWindowCapturer(options);
-#endif  // defined(WEBRTC_USE_X11)
-
+  return WindowCapturerX11::CreateRawWindowCapturer(options);
+#else
   return nullptr;
+#endif  // defined(WEBRTC_USE_X11)
 }
 
 }  // namespace webrtc
