Revert "PipeWire capturer: advertise DMA-BUF support when really supported"

This reverts commit e51937dfc5567b6ce53bd1211799dbdaff8b268e.

Reason for revert: This change was not intended to land yet.

Original change's description:
> PipeWire capturer: advertise DMA-BUF support when really supported
>
> We need to check the PipeWire server version in order to be sure we can
> advertise DMA-BUF support, because it doesn't mean the version of
> PipeWire we built our code against will run against the same PipeWire
> version. Also do not announce DMA-BUF support for PipeWire older than
> 0.3.24 as this will not be working. For DMA-BUF modifiers support we
> need the PipeWire version to be at least 0.3.33 on both sides (client
> and server). Last but not least minor fix is not to announce
> modifier-less DMA-BUF support when we don't have required extension.
>
> Bug: chromium:1233417
> Change-Id: Iee035d61bbc9d5878621555c365751ee4edc9d28
> Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/239649
> Reviewed-by: Mark Foltz <mfoltz@chromium.org>
> Commit-Queue: Jan Grulich <grulja@gmail.com>
> Cr-Commit-Position: refs/heads/main@{#35696}

TBR=tommi@webrtc.org,jansson@google.com,sprang@chromium.org,grulja@gmail.com,mfoltz@chromium.org,webrtc-scoped@luci-project-accounts.iam.gserviceaccount.com

Change-Id: I2aff8ca2650aa14932c0bd15bdc4f30f406f91de
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: chromium:1233417
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/246401
Bot-Commit: rubber-stamper@appspot.gserviceaccount.com <rubber-stamper@appspot.gserviceaccount.com>
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Owners-Override: Christoffer Jansson <jansson@google.com>
Commit-Queue: Christoffer Jansson <jansson@google.com>
Cr-Commit-Position: refs/heads/main@{#35697}
diff --git a/modules/desktop_capture/linux/wayland/base_capturer_pipewire.cc b/modules/desktop_capture/linux/wayland/base_capturer_pipewire.cc
index 3f93393..aea6cdf 100644
--- a/modules/desktop_capture/linux/wayland/base_capturer_pipewire.cc
+++ b/modules/desktop_capture/linux/wayland/base_capturer_pipewire.cc
@@ -12,7 +12,6 @@
 
 #include <gio/gunixfdlist.h>
 #include <glib-object.h>
-#include <libdrm/drm_fourcc.h>
 #include <spa/param/format-utils.h>
 #include <spa/param/props.h>
 #include <sys/ioctl.h>
@@ -30,7 +29,6 @@
 #include "rtc_base/checks.h"
 #include "rtc_base/logging.h"
 #include "rtc_base/string_encode.h"
-#include "rtc_base/string_to_number.h"
 
 #if defined(WEBRTC_DLOPEN_PIPEWIRE)
 #include "modules/desktop_capture/linux/wayland/pipewire_stubs.h"
@@ -57,10 +55,6 @@
 const char kDrmLib[] = "libdrm.so.2";
 #endif
 
-constexpr BaseCapturerPipeWire::PipeWireVersion kDmaBufMinVersion = {0, 3, 24};
-constexpr BaseCapturerPipeWire::PipeWireVersion kDmaBufModifierMinVersion = {
-    0, 3, 33};
-
 #if !PW_CHECK_VERSION(0, 3, 29)
 #define SPA_POD_PROP_FLAG_MANDATORY (1u << 3)
 #endif
@@ -68,25 +62,31 @@
 #define SPA_POD_PROP_FLAG_DONT_FIXATE (1u << 4)
 #endif
 
-BaseCapturerPipeWire::PipeWireVersion ParsePipeWireVersion(
-    const char* version) {
+struct pw_version {
+  int major = 0;
+  int minor = 0;
+  int micro = 0;
+};
+
+bool CheckPipeWireVersion(pw_version required_version) {
   std::vector<std::string> parsed_version;
-  rtc::split(version, '.', &parsed_version);
+  std::string version_string = pw_get_library_version();
+  rtc::split(version_string, '.', &parsed_version);
 
   if (parsed_version.size() != 3) {
-    return {};
+    return false;
   }
 
-  absl::optional<int> major = rtc::StringToNumber<int>(parsed_version.at(0));
-  absl::optional<int> minor = rtc::StringToNumber<int>(parsed_version.at(1));
-  absl::optional<int> micro = rtc::StringToNumber<int>(parsed_version.at(2));
+  pw_version current_version = {std::stoi(parsed_version.at(0)),
+                                std::stoi(parsed_version.at(1)),
+                                std::stoi(parsed_version.at(2))};
 
-  // Return invalid version if we failed to parse it
-  if (!major || !minor || !micro) {
-    return {0, 0, 0};
-  }
-
-  return {major.value(), micro.value(), micro.value()};
+  return (current_version.major > required_version.major) ||
+         (current_version.major == required_version.major &&
+          current_version.minor > required_version.minor) ||
+         (current_version.major == required_version.major &&
+          current_version.minor == required_version.minor &&
+          current_version.micro >= required_version.micro);
 }
 
 spa_pod* BuildFormat(spa_pod_builder* builder,
@@ -106,9 +106,15 @@
   spa_pod_builder_add(builder, SPA_FORMAT_VIDEO_format, SPA_POD_Id(format), 0);
 
   if (modifiers.size()) {
-    spa_pod_builder_prop(
-        builder, SPA_FORMAT_VIDEO_modifier,
-        SPA_POD_PROP_FLAG_MANDATORY | SPA_POD_PROP_FLAG_DONT_FIXATE);
+    // SPA_POD_PROP_FLAG_DONT_FIXATE can be used with PipeWire >= 0.3.33
+    if (CheckPipeWireVersion(pw_version{0, 3, 33})) {
+      spa_pod_builder_prop(
+          builder, SPA_FORMAT_VIDEO_modifier,
+          SPA_POD_PROP_FLAG_MANDATORY | SPA_POD_PROP_FLAG_DONT_FIXATE);
+    } else {
+      spa_pod_builder_prop(builder, SPA_FORMAT_VIDEO_modifier,
+                           SPA_POD_PROP_FLAG_MANDATORY);
+    }
     spa_pod_builder_push_choice(builder, &frames[1], SPA_CHOICE_Enum, 0);
     // modifiers from the array
     for (int64_t val : modifiers) {
@@ -159,17 +165,6 @@
   int fd_;
 };
 
-class PipeWireThreadLoopLock {
- public:
-  explicit PipeWireThreadLoopLock(pw_thread_loop* loop) : loop_(loop) {
-    pw_thread_loop_lock(loop_);
-  }
-  ~PipeWireThreadLoopLock() { pw_thread_loop_unlock(loop_); }
-
- private:
-  pw_thread_loop* const loop_;
-};
-
 template <class T>
 class Scoped {
  public:
@@ -239,34 +234,6 @@
   }
 }
 
-bool operator>=(
-    const BaseCapturerPipeWire::PipeWireVersion& current_pw_version,
-    const BaseCapturerPipeWire::PipeWireVersion& required_pw_version) {
-  if (!current_pw_version.major && !current_pw_version.minor &&
-      !current_pw_version.micro) {
-    return false;
-  }
-
-  return std::tie(current_pw_version.major, current_pw_version.minor,
-                  current_pw_version.micro) >=
-         std::tie(required_pw_version.major, required_pw_version.minor,
-                  required_pw_version.micro);
-}
-
-bool operator<=(
-    const BaseCapturerPipeWire::PipeWireVersion& current_pw_version,
-    const BaseCapturerPipeWire::PipeWireVersion& required_pw_version) {
-  if (!current_pw_version.major && !current_pw_version.minor &&
-      !current_pw_version.micro) {
-    return false;
-  }
-
-  return std::tie(current_pw_version.major, current_pw_version.minor,
-                  current_pw_version.micro) <=
-         std::tie(required_pw_version.major, required_pw_version.minor,
-                  required_pw_version.micro);
-}
-
 void BaseCapturerPipeWire::OnCoreError(void* data,
                                        uint32_t id,
                                        int seq,
@@ -278,23 +245,6 @@
   RTC_LOG(LS_ERROR) << "PipeWire remote error: " << message;
 }
 
-void BaseCapturerPipeWire::OnCoreInfo(void* data, const pw_core_info* info) {
-  BaseCapturerPipeWire* capturer = static_cast<BaseCapturerPipeWire*>(data);
-  RTC_DCHECK(capturer);
-
-  capturer->pw_server_version_ = ParsePipeWireVersion(info->version);
-}
-
-void BaseCapturerPipeWire::OnCoreDone(void* data, uint32_t id, int seq) {
-  const BaseCapturerPipeWire* capturer =
-      static_cast<BaseCapturerPipeWire*>(data);
-  RTC_DCHECK(capturer);
-
-  if (id == PW_ID_CORE && capturer->server_version_sync_ == seq) {
-    pw_thread_loop_signal(capturer->pw_main_loop_, false);
-  }
-}
-
 // static
 void BaseCapturerPipeWire::OnStreamStateChanged(void* data,
                                                 pw_stream_state old_state,
@@ -336,27 +286,20 @@
   auto size = height * stride;
 
   that->desktop_size_ = DesktopSize(width, height);
+#if PW_CHECK_VERSION(0, 3, 0)
+  that->modifier_ = that->spa_video_format_.modifier;
+#endif
 
   uint8_t buffer[1024] = {};
   auto builder = spa_pod_builder{buffer, sizeof(buffer)};
 
   // Setup buffers and meta header for new format.
-
-  // When SPA_FORMAT_VIDEO_modifier is present we can use DMA-BUFs as
-  // the server announces support for it.
-  // See https://github.com/PipeWire/pipewire/blob/master/doc/dma-buf.dox
-  const bool has_modifier =
-      spa_pod_find_prop(format, nullptr, SPA_FORMAT_VIDEO_modifier);
-  that->modifier_ =
-      has_modifier ? that->spa_video_format_.modifier : DRM_FORMAT_MOD_INVALID;
-
   const struct spa_pod* params[3];
   const int buffer_types =
-      has_modifier || (that->pw_server_version_ >= kDmaBufMinVersion)
+      spa_pod_find_prop(format, nullptr, SPA_FORMAT_VIDEO_modifier)
           ? (1 << SPA_DATA_DmaBuf) | (1 << SPA_DATA_MemFd) |
                 (1 << SPA_DATA_MemPtr)
           : (1 << SPA_DATA_MemFd) | (1 << SPA_DATA_MemPtr);
-
   params[0] = reinterpret_cast<spa_pod*>(spa_pod_builder_add_object(
       &builder, SPA_TYPE_OBJECT_ParamBuffers, SPA_PARAM_Buffers,
       SPA_PARAM_BUFFERS_size, SPA_POD_Int(size), SPA_PARAM_BUFFERS_stride,
@@ -501,6 +444,8 @@
 
   pw_main_loop_ = pw_thread_loop_new("pipewire-main-loop", nullptr);
 
+  pw_thread_loop_lock(pw_main_loop_);
+
   pw_context_ =
       pw_context_new(pw_thread_loop_get_loop(pw_main_loop_), nullptr, 0);
   if (!pw_context_) {
@@ -508,18 +453,14 @@
     return;
   }
 
-  if (pw_thread_loop_start(pw_main_loop_) < 0) {
-    RTC_LOG(LS_ERROR) << "Failed to start main PipeWire loop";
-    portal_init_failed_ = true;
+  pw_core_ = pw_context_connect_fd(pw_context_, pw_fd_, nullptr, 0);
+  if (!pw_core_) {
+    RTC_LOG(LS_ERROR) << "Failed to connect PipeWire context";
     return;
   }
 
-  pw_client_version_ = ParsePipeWireVersion(pw_get_library_version());
-
   // Initialize event handlers, remote end and stream-related.
   pw_core_events_.version = PW_VERSION_CORE_EVENTS;
-  pw_core_events_.info = &OnCoreInfo;
-  pw_core_events_.done = &OnCoreDone;
   pw_core_events_.error = &OnCoreError;
 
   pw_stream_events_.version = PW_VERSION_STREAM_EVENTS;
@@ -527,32 +468,22 @@
   pw_stream_events_.param_changed = &OnStreamParamChanged;
   pw_stream_events_.process = &OnStreamProcess;
 
-  {
-    PipeWireThreadLoopLock thread_loop_lock(pw_main_loop_);
+  pw_core_add_listener(pw_core_, &spa_core_listener_, &pw_core_events_, this);
 
-    pw_core_ = pw_context_connect_fd(pw_context_, pw_fd_, nullptr, 0);
-    if (!pw_core_) {
-      RTC_LOG(LS_ERROR) << "Failed to connect PipeWire context";
-      portal_init_failed_ = true;
-      return;
-    }
-
-    pw_core_add_listener(pw_core_, &spa_core_listener_, &pw_core_events_, this);
-
-    server_version_sync_ =
-        pw_core_sync(pw_core_, PW_ID_CORE, server_version_sync_);
-
-    pw_thread_loop_wait(pw_main_loop_);
-
-    pw_stream_ = CreateReceivingStream();
-    if (!pw_stream_) {
-      RTC_LOG(LS_ERROR) << "Failed to create PipeWire stream";
-      portal_init_failed_ = true;
-      return;
-    }
-
-    RTC_LOG(LS_INFO) << "PipeWire remote opened.";
+  pw_stream_ = CreateReceivingStream();
+  if (!pw_stream_) {
+    RTC_LOG(LS_ERROR) << "Failed to create PipeWire stream";
+    return;
   }
+
+  if (pw_thread_loop_start(pw_main_loop_) < 0) {
+    RTC_LOG(LS_ERROR) << "Failed to start main PipeWire loop";
+    portal_init_failed_ = true;
+  }
+
+  pw_thread_loop_unlock(pw_main_loop_);
+
+  RTC_LOG(LS_INFO) << "PipeWire remote opened.";
 }
 
 pw_stream* BaseCapturerPipeWire::CreateReceivingStream() {
@@ -566,14 +497,12 @@
   spa_pod_builder builder = spa_pod_builder{buffer, sizeof(buffer)};
 
   std::vector<const spa_pod*> params;
-  const bool has_required_pw_client_version =
-      pw_client_version_ >= kDmaBufModifierMinVersion;
-  const bool has_required_pw_server_version =
-      pw_server_version_ >= kDmaBufModifierMinVersion;
+  const bool has_required_pw_version =
+      CheckPipeWireVersion(pw_version{0, 3, 29});
   for (uint32_t format : {SPA_VIDEO_FORMAT_BGRA, SPA_VIDEO_FORMAT_RGBA,
                           SPA_VIDEO_FORMAT_BGRx, SPA_VIDEO_FORMAT_RGBx}) {
-    // Modifiers can be used with PipeWire >= 0.3.33
-    if (has_required_pw_client_version && has_required_pw_server_version) {
+    // Modifiers can be used with PipeWire >= 0.3.29
+    if (has_required_pw_version) {
       modifiers = egl_dmabuf_->QueryDmaBufModifiers(format);
 
       if (!modifiers.empty()) {
diff --git a/modules/desktop_capture/linux/wayland/base_capturer_pipewire.h b/modules/desktop_capture/linux/wayland/base_capturer_pipewire.h
index 91c863e..238439e 100644
--- a/modules/desktop_capture/linux/wayland/base_capturer_pipewire.h
+++ b/modules/desktop_capture/linux/wayland/base_capturer_pipewire.h
@@ -44,12 +44,6 @@
     kMetadata = 0b100
   };
 
-  struct PipeWireVersion {
-    int major = 0;
-    int minor = 0;
-    int micro = 0;
-  };
-
   explicit BaseCapturerPipeWire(CaptureSourceType source_type);
   ~BaseCapturerPipeWire() override;
 
@@ -72,14 +66,6 @@
   spa_hook spa_core_listener_;
   spa_hook spa_stream_listener_;
 
-  // A number used to verify all previous methods and the resulting
-  // events have been handled.
-  int server_version_sync_ = 0;
-  // Version of the running PipeWire server we communicate with
-  PipeWireVersion pw_server_version_;
-  // Version of the library used to run our code
-  PipeWireVersion pw_client_version_;
-
   // event handlers
   pw_core_events pw_core_events_ = {};
   pw_stream_events pw_stream_events_ = {};
@@ -132,8 +118,6 @@
                           int seq,
                           int res,
                           const char* message);
-  static void OnCoreDone(void* user_data, uint32_t id, int seq);
-  static void OnCoreInfo(void* user_data, const pw_core_info* info);
   static void OnStreamParamChanged(void* data,
                                    uint32_t id,
                                    const struct spa_pod* format);
diff --git a/modules/desktop_capture/linux/wayland/egl_dmabuf.cc b/modules/desktop_capture/linux/wayland/egl_dmabuf.cc
index 881c40b..e872636 100644
--- a/modules/desktop_capture/linux/wayland/egl_dmabuf.cc
+++ b/modules/desktop_capture/linux/wayland/egl_dmabuf.cc
@@ -349,11 +349,12 @@
     egl_.extensions.push_back(std::string(extension));
   }
 
+  bool has_image_dma_buf_import_ext = false;
   bool has_image_dma_buf_import_modifiers_ext = false;
 
   for (const auto& extension : egl_.extensions) {
     if (extension == "EGL_EXT_image_dma_buf_import") {
-      has_image_dma_buf_import_ext_ = true;
+      has_image_dma_buf_import_ext = true;
       continue;
     } else if (extension == "EGL_EXT_image_dma_buf_import_modifiers") {
       has_image_dma_buf_import_modifiers_ext = true;
@@ -361,7 +362,7 @@
     }
   }
 
-  if (has_image_dma_buf_import_ext_ && has_image_dma_buf_import_modifiers_ext) {
+  if (has_image_dma_buf_import_ext && has_image_dma_buf_import_modifiers_ext) {
     EglQueryDmaBufFormatsEXT = (eglQueryDmaBufFormatsEXT_func)EglGetProcAddress(
         "eglQueryDmaBufFormatsEXT");
     EglQueryDmaBufModifiersEXT =
@@ -500,20 +501,18 @@
     return {};
   }
 
-  // Explicit modifiers not supported, return just DRM_FORMAT_MOD_INVALID as we
-  // can still use modifier-less DMA-BUFs if we have required extension
+  // Modifiers not supported, return just DRM_FORMAT_MOD_INVALID as we can still
+  // use modifier-less DMA-BUFs
   if (EglQueryDmaBufFormatsEXT == nullptr ||
       EglQueryDmaBufModifiersEXT == nullptr) {
-    if (has_image_dma_buf_import_ext_) {
-      return {DRM_FORMAT_MOD_INVALID};
-    } else {
-      return {};
-    }
+    return {DRM_FORMAT_MOD_INVALID};
   }
 
   uint32_t drm_format = SpaPixelFormatToDrmFormat(format);
-  // Should never happen as it's us who controls the list of supported formats
-  RTC_DCHECK(drm_format != DRM_FORMAT_INVALID);
+  if (drm_format == DRM_FORMAT_INVALID) {
+    RTC_LOG(LS_ERROR) << "Failed to find matching DRM format.";
+    return {DRM_FORMAT_MOD_INVALID};
+  }
 
   EGLint count = 0;
   EGLBoolean success =
diff --git a/modules/desktop_capture/linux/wayland/egl_dmabuf.h b/modules/desktop_capture/linux/wayland/egl_dmabuf.h
index 75a8d81..bc512a3 100644
--- a/modules/desktop_capture/linux/wayland/egl_dmabuf.h
+++ b/modules/desktop_capture/linux/wayland/egl_dmabuf.h
@@ -52,7 +52,6 @@
 
  private:
   bool egl_initialized_ = false;
-  bool has_image_dma_buf_import_ext_ = false;
   int32_t drm_fd_ = -1;               // for GBM buffer mmap
   gbm_device* gbm_device_ = nullptr;  // for passed GBM buffer retrieval
 
diff --git a/modules/desktop_capture/linux/wayland/pipewire.sigs b/modules/desktop_capture/linux/wayland/pipewire.sigs
index a488af37..ffcd077 100644
--- a/modules/desktop_capture/linux/wayland/pipewire.sigs
+++ b/modules/desktop_capture/linux/wayland/pipewire.sigs
@@ -39,8 +39,6 @@
 void pw_thread_loop_lock(pw_thread_loop *loop);
 void pw_thread_loop_unlock(pw_thread_loop *loop);
 pw_loop * pw_thread_loop_get_loop(pw_thread_loop *loop);
-void pw_thread_loop_signal(pw_thread_loop* loop, bool wait_for_accept);
-void pw_thread_loop_wait(pw_thread_loop *loop);
 
 // context.h
 void pw_context_destroy(pw_context *context);