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 ae9aba26ee56e8a0d48f81994f964b278c9019d3..758f1b44e01adb6807bc7c5f673d06fffbac5865 100644
--- a/modules/desktop_capture/desktop_capturer.cc
+++ b/modules/desktop_capture/desktop_capturer.cc
@@ -123,7 +123,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 b2864eeee599c2932b33cf380cd614977da80143..4148907763eeb3567fcb3424a80d7c21d28bd16c 100644
--- a/modules/desktop_capture/linux/wayland/base_capturer_pipewire.cc
+++ b/modules/desktop_capture/linux/wayland/base_capturer_pipewire.cc
@@ -123,6 +123,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 94726750c5762e22b517445b23254513eb207aae..85946a6c7eef56a66c0ee2ec06bdc5f2ba49c53c 100644
--- a/modules/desktop_capture/screen_capturer_linux.cc
+++ b/modules/desktop_capture/screen_capturer_linux.cc
@@ -35,11 +35,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 f621a63e72131fd8426361a078a55d1e07c0e436..91394503da5e7f6d090e2eaede02316cf51ad7b2 100644
--- a/modules/desktop_capture/window_capturer_linux.cc
+++ b/modules/desktop_capture/window_capturer_linux.cc
@@ -35,11 +35,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
