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 243919ba101c637887b2a964e45be0096798873b..c1597ee84a3a84a1c5e556eb31c4d3e19a6e4c84 100644
--- a/modules/desktop_capture/desktop_capturer.cc
+++ b/modules/desktop_capture/desktop_capturer.cc
@@ -138,7 +138,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 6cb394f9430f88c5036d19587e4655b8d0760c76..613c3fa6380828dd6537e20c87aac764bfdcd6c8 100644
--- a/modules/desktop_capture/linux/wayland/base_capturer_pipewire.cc
+++ b/modules/desktop_capture/linux/wayland/base_capturer_pipewire.cc
@@ -126,6 +126,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 aeab70c9f7f7511af04c4831b4d81c8a4e4261aa..ad9efad3af5b4ce21a0a2b21a783af0c4f468494 100644
--- a/modules/desktop_capture/screen_capturer_linux.cc
+++ b/modules/desktop_capture/screen_capturer_linux.cc
@@ -38,11 +38,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 6df928913f4ef73db3d6377682f4f40bcd58c4d9..befd9f7a6a00778ebe5b3fa9da25fcbcaf91ef79 100644
--- a/modules/desktop_capture/window_capturer_linux.cc
+++ b/modules/desktop_capture/window_capturer_linux.cc
@@ -38,11 +38,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
