]> git.pld-linux.org Git - packages/qt5-qtwebengine.git/blob - qt5-webengine-pipewire-0.3.patch
- patches from chromium and archlinux to get qtwebengine to build with ffmpeg 5+
[packages/qt5-qtwebengine.git] / qt5-webengine-pipewire-0.3.patch
1 diff --git a/chromium/third_party/webrtc/modules/desktop_capture/BUILD.gn b/chromium/third_party/webrtc/modules/desktop_capture/BUILD.gn
2 index 5235512735d..8259442f811 100644
3 --- a/chromium/third_party/webrtc/modules/desktop_capture/BUILD.gn
4 +++ b/chromium/third_party/webrtc/modules/desktop_capture/BUILD.gn
5 @@ -11,6 +11,11 @@ import("//build/config/ui.gni")
6  import("//tools/generate_stubs/rules.gni")
7  import("../../webrtc.gni")
8  
9 +if (rtc_use_pipewire) {
10 +  assert(rtc_pipewire_version == "0.2" || rtc_pipewire_version == "0.3",
11 +         "Unsupported PipeWire version")
12 +}
13 +
14  use_desktop_capture_differ_sse2 = current_cpu == "x86" || current_cpu == "x64"
15  
16  config("x11_config") {
17 @@ -200,22 +205,41 @@ if (is_linux || is_chromeos) {
18        ]
19      }
20  
21 -    if (rtc_link_pipewire) {
22 +    if (rtc_pipewire_version == "0.3") {
23        pkg_config("pipewire") {
24 -        packages = [ "libpipewire-0.2" ]
25 +        packages = [ "libpipewire-0.3" ]
26 +        if (!rtc_link_pipewire) {
27 +          ignore_libs = true
28 +        }
29        }
30      } else {
31 +      pkg_config("pipewire") {
32 +        packages = [ "libpipewire-0.2" ]
33 +        if (!rtc_link_pipewire) {
34 +          ignore_libs = true
35 +        }
36 +      }
37 +    }
38 +
39 +    if (!rtc_link_pipewire) {
40        # When libpipewire is not directly linked, use stubs to allow for dlopening of
41        # the binary.
42        generate_stubs("pipewire_stubs") {
43 -        configs = [ "../../:common_config" ]
44 +        configs = [
45 +          "../../:common_config",
46 +          ":pipewire",
47 +        ]
48          deps = [ "../../rtc_base" ]
49          extra_header = "linux/pipewire_stub_header.fragment"
50          logging_function = "RTC_LOG(LS_VERBOSE)"
51          logging_include = "rtc_base/logging.h"
52          output_name = "linux/pipewire_stubs"
53          path_from_source = "modules/desktop_capture/linux"
54 -        sigs = [ "linux/pipewire.sigs" ]
55 +        if (rtc_pipewire_version == "0.3") {
56 +          sigs = [ "linux/pipewire03.sigs" ]
57 +        } else {
58 +          sigs = [ "linux/pipewire02.sigs" ]
59 +        }
60        }
61      }
62  
63 @@ -506,6 +530,7 @@ rtc_library("desktop_capture_generic") {
64    absl_deps = [
65      "//third_party/abseil-cpp/absl/memory",
66      "//third_party/abseil-cpp/absl/strings",
67 +    "//third_party/abseil-cpp/absl/types:optional",
68    ]
69  
70    if (rtc_use_x11_extensions) {
71 @@ -526,20 +551,15 @@ rtc_library("desktop_capture_generic") {
72      sources += [
73        "linux/base_capturer_pipewire.cc",
74        "linux/base_capturer_pipewire.h",
75 -      "linux/screen_capturer_pipewire.cc",
76 -      "linux/screen_capturer_pipewire.h",
77 -      "linux/window_capturer_pipewire.cc",
78 -      "linux/window_capturer_pipewire.h",
79      ]
80  
81      configs += [
82        ":pipewire_config",
83        ":gio",
84 +      ":pipewire",
85      ]
86  
87 -    if (rtc_link_pipewire) {
88 -      configs += [ ":pipewire" ]
89 -    } else {
90 +    if (!rtc_link_pipewire) {
91        deps += [ ":pipewire_stubs" ]
92      }
93    }
94 diff --git a/chromium/third_party/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.cc b/chromium/third_party/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.cc
95 index 2640e93aa98..c302a086ead 100644
96 --- a/chromium/third_party/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.cc
97 +++ b/chromium/third_party/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.cc
98 @@ -14,8 +14,14 @@
99  #include <glib-object.h>
100  #include <spa/param/format-utils.h>
101  #include <spa/param/props.h>
102 +#if !PW_CHECK_VERSION(0, 3, 0)
103  #include <spa/param/video/raw-utils.h>
104  #include <spa/support/type-map.h>
105 +#endif
106 +
107 +#include <sys/ioctl.h>
108 +#include <sys/mman.h>
109 +#include <sys/syscall.h>
110  
111  #include <memory>
112  #include <utility>
113 @@ -30,7 +36,11 @@
114  #include "modules/desktop_capture/linux/pipewire_stubs.h"
115  
116  using modules_desktop_capture_linux::InitializeStubs;
117 -using modules_desktop_capture_linux::kModulePipewire;
118 +#if PW_CHECK_VERSION(0, 3, 0)
119 +using modules_desktop_capture_linux::kModulePipewire03;
120 +#else
121 +using modules_desktop_capture_linux::kModulePipewire02;
122 +#endif
123  using modules_desktop_capture_linux::StubPathMap;
124  #endif  // defined(WEBRTC_DLOPEN_PIPEWIRE)
125  
126 @@ -47,9 +57,156 @@ const char kScreenCastInterfaceName[] = "org.freedesktop.portal.ScreenCast";
127  const int kBytesPerPixel = 4;
128  
129  #if defined(WEBRTC_DLOPEN_PIPEWIRE)
130 +#if PW_CHECK_VERSION(0, 3, 0)
131 +const char kPipeWireLib[] = "libpipewire-0.3.so.0";
132 +#else
133  const char kPipeWireLib[] = "libpipewire-0.2.so.1";
134  #endif
135 +#endif
136  
137 +// static
138 +struct dma_buf_sync {
139 +  uint64_t flags;
140 +};
141 +#define DMA_BUF_SYNC_READ (1 << 0)
142 +#define DMA_BUF_SYNC_START (0 << 2)
143 +#define DMA_BUF_SYNC_END (1 << 2)
144 +#define DMA_BUF_BASE 'b'
145 +#define DMA_BUF_IOCTL_SYNC _IOW(DMA_BUF_BASE, 0, struct dma_buf_sync)
146 +
147 +static void SyncDmaBuf(int fd, uint64_t start_or_end) {
148 +  struct dma_buf_sync sync = {0};
149 +
150 +  sync.flags = start_or_end | DMA_BUF_SYNC_READ;
151 +
152 +  while (true) {
153 +    int ret;
154 +    ret = ioctl(fd, DMA_BUF_IOCTL_SYNC, &sync);
155 +    if (ret == -1 && errno == EINTR) {
156 +      continue;
157 +    } else if (ret == -1) {
158 +      RTC_LOG(LS_ERROR) << "Failed to synchronize DMA buffer: "
159 +                        << g_strerror(errno);
160 +      break;
161 +    } else {
162 +      break;
163 +    }
164 +  }
165 +}
166 +
167 +class ScopedBuf {
168 + public:
169 +  ScopedBuf() {}
170 +  ScopedBuf(unsigned char* map, int map_size, bool is_dma_buf, int fd)
171 +      : map_(map), map_size_(map_size), is_dma_buf_(is_dma_buf), fd_(fd) {}
172 +  ~ScopedBuf() {
173 +    if (map_ != MAP_FAILED) {
174 +      if (is_dma_buf_) {
175 +        SyncDmaBuf(fd_, DMA_BUF_SYNC_END);
176 +      }
177 +      munmap(map_, map_size_);
178 +    }
179 +  }
180 +
181 +  operator bool() { return map_ != MAP_FAILED; }
182 +
183 +  void initialize(unsigned char* map, int map_size, bool is_dma_buf, int fd) {
184 +    map_ = map;
185 +    map_size_ = map_size;
186 +    is_dma_buf_ = is_dma_buf;
187 +    fd_ = fd;
188 +  }
189 +
190 +  unsigned char* get() { return map_; }
191 +
192 + protected:
193 +  unsigned char* map_ = nullptr;
194 +  int map_size_;
195 +  bool is_dma_buf_;
196 +  int fd_;
197 +};
198 +
199 +template <class T>
200 +class Scoped {
201 + public:
202 +  Scoped() {}
203 +  explicit Scoped(T* val) { ptr_ = val; }
204 +  ~Scoped() { RTC_NOTREACHED(); }
205 +
206 +  T* operator->() { return ptr_; }
207 +
208 +  bool operator!() { return ptr_ == nullptr; }
209 +
210 +  T* get() { return ptr_; }
211 +
212 +  T** receive() {
213 +    RTC_CHECK(!ptr_);
214 +    return &ptr_;
215 +  }
216 +
217 +  Scoped& operator=(T* val) {
218 +    ptr_ = val;
219 +    return *this;
220 +  }
221 +
222 + protected:
223 +  T* ptr_ = nullptr;
224 +};
225 +
226 +template <>
227 +Scoped<GError>::~Scoped() {
228 +  if (ptr_) {
229 +    g_error_free(ptr_);
230 +  }
231 +}
232 +
233 +template <>
234 +Scoped<gchar>::~Scoped() {
235 +  if (ptr_) {
236 +    g_free(ptr_);
237 +  }
238 +}
239 +
240 +template <>
241 +Scoped<GVariant>::~Scoped() {
242 +  if (ptr_) {
243 +    g_variant_unref(ptr_);
244 +  }
245 +}
246 +
247 +template <>
248 +Scoped<GVariantIter>::~Scoped() {
249 +  if (ptr_) {
250 +    g_variant_iter_free(ptr_);
251 +  }
252 +}
253 +
254 +template <>
255 +Scoped<GDBusMessage>::~Scoped() {
256 +  if (ptr_) {
257 +    g_object_unref(ptr_);
258 +  }
259 +}
260 +
261 +template <>
262 +Scoped<GUnixFDList>::~Scoped() {
263 +  if (ptr_) {
264 +    g_object_unref(ptr_);
265 +  }
266 +}
267 +
268 +#if PW_CHECK_VERSION(0, 3, 0)
269 +void BaseCapturerPipeWire::OnCoreError(void* data,
270 +                                       uint32_t id,
271 +                                       int seq,
272 +                                       int res,
273 +                                       const char* message) {
274 +  BaseCapturerPipeWire* that = static_cast<BaseCapturerPipeWire*>(data);
275 +  RTC_DCHECK(that);
276 +
277 +  RTC_LOG(LS_ERROR) << "PipeWire remote error: " << message;
278 +}
279 +#else
280  // static
281  void BaseCapturerPipeWire::OnStateChanged(void* data,
282                                            pw_remote_state old_state,
283 @@ -64,7 +221,7 @@ void BaseCapturerPipeWire::OnStateChanged(void* data,
284        break;
285      case PW_REMOTE_STATE_CONNECTED:
286        RTC_LOG(LS_INFO) << "PipeWire remote state: connected.";
287 -      that->CreateReceivingStream();
288 +      that->pw_stream_ = that->CreateReceivingStream();
289        break;
290      case PW_REMOTE_STATE_CONNECTING:
291        RTC_LOG(LS_INFO) << "PipeWire remote state: connecting.";
292 @@ -74,6 +231,7 @@ void BaseCapturerPipeWire::OnStateChanged(void* data,
293        break;
294    }
295  }
296 +#endif
297  
298  // static
299  void BaseCapturerPipeWire::OnStreamStateChanged(void* data,
300 @@ -83,6 +241,18 @@ void BaseCapturerPipeWire::OnStreamStateChanged(void* data,
301    BaseCapturerPipeWire* that = static_cast<BaseCapturerPipeWire*>(data);
302    RTC_DCHECK(that);
303  
304 +#if PW_CHECK_VERSION(0, 3, 0)
305 +  switch (state) {
306 +    case PW_STREAM_STATE_ERROR:
307 +      RTC_LOG(LS_ERROR) << "PipeWire stream state error: " << error_message;
308 +      break;
309 +    case PW_STREAM_STATE_PAUSED:
310 +    case PW_STREAM_STATE_STREAMING:
311 +    case PW_STREAM_STATE_UNCONNECTED:
312 +    case PW_STREAM_STATE_CONNECTING:
313 +      break;
314 +  }
315 +#else
316    switch (state) {
317      case PW_STREAM_STATE_ERROR:
318        RTC_LOG(LS_ERROR) << "PipeWire stream state error: " << error_message;
319 @@ -97,36 +267,74 @@ void BaseCapturerPipeWire::OnStreamStateChanged(void* data,
320      case PW_STREAM_STATE_STREAMING:
321        break;
322    }
323 +#endif
324  }
325  
326  // static
327 +#if PW_CHECK_VERSION(0, 3, 0)
328 +void BaseCapturerPipeWire::OnStreamParamChanged(void* data,
329 +                                                uint32_t id,
330 +                                                const struct spa_pod* format) {
331 +#else
332  void BaseCapturerPipeWire::OnStreamFormatChanged(void* data,
333                                                   const struct spa_pod* format) {
334 +#endif
335    BaseCapturerPipeWire* that = static_cast<BaseCapturerPipeWire*>(data);
336    RTC_DCHECK(that);
337  
338    RTC_LOG(LS_INFO) << "PipeWire stream format changed.";
339  
340 +#if PW_CHECK_VERSION(0, 3, 0)
341 +  if (!format || id != SPA_PARAM_Format) {
342 +#else
343    if (!format) {
344      pw_stream_finish_format(that->pw_stream_, /*res=*/0, /*params=*/nullptr,
345                              /*n_params=*/0);
346 +#endif
347      return;
348    }
349  
350 +#if PW_CHECK_VERSION(0, 3, 0)
351 +  spa_format_video_raw_parse(format, &that->spa_video_format_);
352 +#else
353    that->spa_video_format_ = new spa_video_info_raw();
354    spa_format_video_raw_parse(format, that->spa_video_format_,
355                               &that->pw_type_->format_video);
356 +#endif
357  
358 +#if PW_CHECK_VERSION(0, 3, 0)
359 +  auto width = that->spa_video_format_.size.width;
360 +  auto height = that->spa_video_format_.size.height;
361 +#else
362    auto width = that->spa_video_format_->size.width;
363    auto height = that->spa_video_format_->size.height;
364 +#endif
365    auto stride = SPA_ROUND_UP_N(width * kBytesPerPixel, 4);
366    auto size = height * stride;
367  
368 +  that->desktop_size_ = DesktopSize(width, height);
369 +
370    uint8_t buffer[1024] = {};
371    auto builder = spa_pod_builder{buffer, sizeof(buffer)};
372  
373    // Setup buffers and meta header for new format.
374 -  const struct spa_pod* params[2];
375 +  const struct spa_pod* params[3];
376 +#if PW_CHECK_VERSION(0, 3, 0)
377 +  params[0] = reinterpret_cast<spa_pod*>(spa_pod_builder_add_object(
378 +      &builder, SPA_TYPE_OBJECT_ParamBuffers, SPA_PARAM_Buffers,
379 +      SPA_PARAM_BUFFERS_size, SPA_POD_Int(size), SPA_PARAM_BUFFERS_stride,
380 +      SPA_POD_Int(stride), SPA_PARAM_BUFFERS_buffers,
381 +      SPA_POD_CHOICE_RANGE_Int(8, 1, 32)));
382 +  params[1] = reinterpret_cast<spa_pod*>(spa_pod_builder_add_object(
383 +      &builder, SPA_TYPE_OBJECT_ParamMeta, SPA_PARAM_Meta, SPA_PARAM_META_type,
384 +      SPA_POD_Id(SPA_META_Header), SPA_PARAM_META_size,
385 +      SPA_POD_Int(sizeof(struct spa_meta_header))));
386 +  params[2] = reinterpret_cast<spa_pod*>(spa_pod_builder_add_object(
387 +      &builder, SPA_TYPE_OBJECT_ParamMeta, SPA_PARAM_Meta, SPA_PARAM_META_type,
388 +      SPA_POD_Id(SPA_META_VideoCrop), SPA_PARAM_META_size,
389 +      SPA_POD_Int(sizeof(struct spa_meta_region))));
390 +  pw_stream_update_params(that->pw_stream_, params, 3);
391 +#else
392    params[0] = reinterpret_cast<spa_pod*>(spa_pod_builder_object(
393        &builder,
394        // id to enumerate buffer requirements
395 @@ -155,8 +363,18 @@ void BaseCapturerPipeWire::OnStreamFormatChanged(void* data,
396        // Size: size of the metadata, specified as integer (i)
397        ":", that->pw_core_type_->param_meta.size, "i",
398        sizeof(struct spa_meta_header)));
399 -
400 -  pw_stream_finish_format(that->pw_stream_, /*res=*/0, params, /*n_params=*/2);
401 +  params[2] = reinterpret_cast<spa_pod*>(spa_pod_builder_object(
402 +      &builder,
403 +      // id to enumerate supported metadata
404 +      that->pw_core_type_->param.idMeta, that->pw_core_type_->param_meta.Meta,
405 +      // Type: specified as id or enum (I)
406 +      ":", that->pw_core_type_->param_meta.type, "I",
407 +      that->pw_core_type_->meta.VideoCrop,
408 +      // Size: size of the metadata, specified as integer (i)
409 +      ":", that->pw_core_type_->param_meta.size, "i",
410 +      sizeof(struct spa_meta_video_crop)));
411 +  pw_stream_finish_format(that->pw_stream_, /*res=*/0, params, /*n_params=*/3);
412 +#endif
413  }
414  
415  // static
416 @@ -164,15 +382,26 @@ void BaseCapturerPipeWire::OnStreamProcess(void* data) {
417    BaseCapturerPipeWire* that = static_cast<BaseCapturerPipeWire*>(data);
418    RTC_DCHECK(that);
419  
420 -  pw_buffer* buf = nullptr;
421 +  struct pw_buffer* next_buffer;
422 +  struct pw_buffer* buffer = nullptr;
423 +
424 +  next_buffer = pw_stream_dequeue_buffer(that->pw_stream_);
425 +  while (next_buffer) {
426 +    buffer = next_buffer;
427 +    next_buffer = pw_stream_dequeue_buffer(that->pw_stream_);
428  
429 -  if (!(buf = pw_stream_dequeue_buffer(that->pw_stream_))) {
430 +    if (next_buffer) {
431 +      pw_stream_queue_buffer(that->pw_stream_, buffer);
432 +    }
433 +  }
434 +
435 +  if (!buffer) {
436      return;
437    }
438  
439 -  that->HandleBuffer(buf);
440 +  that->HandleBuffer(buffer);
441  
442 -  pw_stream_queue_buffer(that->pw_stream_, buf);
443 +  pw_stream_queue_buffer(that->pw_stream_, buffer);
444  }
445  
446  BaseCapturerPipeWire::BaseCapturerPipeWire(CaptureSourceType source_type)
447 @@ -183,6 +412,7 @@ BaseCapturerPipeWire::~BaseCapturerPipeWire() {
448      pw_thread_loop_stop(pw_main_loop_);
449    }
450  
451 +#if !PW_CHECK_VERSION(0, 3, 0)
452    if (pw_type_) {
453      delete pw_type_;
454    }
455 @@ -190,30 +420,41 @@ BaseCapturerPipeWire::~BaseCapturerPipeWire() {
456    if (spa_video_format_) {
457      delete spa_video_format_;
458    }
459 +#endif
460  
461    if (pw_stream_) {
462      pw_stream_destroy(pw_stream_);
463    }
464  
465 +#if !PW_CHECK_VERSION(0, 3, 0)
466    if (pw_remote_) {
467      pw_remote_destroy(pw_remote_);
468    }
469 +#endif
470  
471 +#if PW_CHECK_VERSION(0, 3, 0)
472 +  if (pw_core_) {
473 +    pw_core_disconnect(pw_core_);
474 +  }
475 +
476 +  if (pw_context_) {
477 +    pw_context_destroy(pw_context_);
478 +  }
479 +#else
480    if (pw_core_) {
481      pw_core_destroy(pw_core_);
482    }
483 +#endif
484  
485    if (pw_main_loop_) {
486      pw_thread_loop_destroy(pw_main_loop_);
487    }
488  
489 +#if !PW_CHECK_VERSION(0, 3, 0)
490    if (pw_loop_) {
491      pw_loop_destroy(pw_loop_);
492    }
493 -
494 -  if (current_frame_) {
495 -    free(current_frame_);
496 -  }
497 +#endif
498  
499    if (start_request_signal_id_) {
500      g_dbus_connection_signal_unsubscribe(connection_, start_request_signal_id_);
501 @@ -228,18 +469,16 @@ BaseCapturerPipeWire::~BaseCapturerPipeWire() {
502    }
503  
504    if (session_handle_) {
505 -    GDBusMessage* message = g_dbus_message_new_method_call(
506 -        kDesktopBusName, session_handle_, kSessionInterfaceName, "Close");
507 -    if (message) {
508 -      GError* error = nullptr;
509 -      g_dbus_connection_send_message(connection_, message,
510 +    Scoped<GDBusMessage> message(g_dbus_message_new_method_call(
511 +        kDesktopBusName, session_handle_, kSessionInterfaceName, "Close"));
512 +    if (message.get()) {
513 +      Scoped<GError> error;
514 +      g_dbus_connection_send_message(connection_, message.get(),
515                                       G_DBUS_SEND_MESSAGE_FLAGS_NONE,
516 -                                     /*out_serial=*/nullptr, &error);
517 -      if (error) {
518 +                                     /*out_serial=*/nullptr, error.receive());
519 +      if (error.get()) {
520          RTC_LOG(LS_ERROR) << "Failed to close the session: " << error->message;
521 -        g_error_free(error);
522        }
523 -      g_object_unref(message);
524      }
525    }
526  
527 @@ -274,7 +513,11 @@ void BaseCapturerPipeWire::InitPipeWire() {
528    StubPathMap paths;
529  
530    // Check if the PipeWire library is available.
531 -  paths[kModulePipewire].push_back(kPipeWireLib);
532 +#if PW_CHECK_VERSION(0, 3, 0)
533 +  paths[kModulePipewire03].push_back(kPipeWireLib);
534 +#else
535 +  paths[kModulePipewire02].push_back(kPipeWireLib);
536 +#endif
537    if (!InitializeStubs(paths)) {
538      RTC_LOG(LS_ERROR) << "Failed to load the PipeWire library and symbols.";
539      portal_init_failed_ = true;
540 @@ -284,16 +527,46 @@ void BaseCapturerPipeWire::InitPipeWire() {
541  
542    pw_init(/*argc=*/nullptr, /*argc=*/nullptr);
543  
544 +#if PW_CHECK_VERSION(0, 3, 0)
545 +  pw_main_loop_ = pw_thread_loop_new("pipewire-main-loop", nullptr);
546 +
547 +  pw_thread_loop_lock(pw_main_loop_);
548 +
549 +  pw_context_ =
550 +      pw_context_new(pw_thread_loop_get_loop(pw_main_loop_), nullptr, 0);
551 +  if (!pw_context_) {
552 +    RTC_LOG(LS_ERROR) << "Failed to create PipeWire context";
553 +    return;
554 +  }
555 +
556 +  pw_core_ = pw_context_connect(pw_context_, nullptr, 0);
557 +  if (!pw_core_) {
558 +    RTC_LOG(LS_ERROR) << "Failed to connect PipeWire context";
559 +    return;
560 +  }
561 +#else
562    pw_loop_ = pw_loop_new(/*properties=*/nullptr);
563    pw_main_loop_ = pw_thread_loop_new(pw_loop_, "pipewire-main-loop");
564  
565 +  pw_thread_loop_lock(pw_main_loop_);
566 +
567    pw_core_ = pw_core_new(pw_loop_, /*properties=*/nullptr);
568    pw_core_type_ = pw_core_get_type(pw_core_);
569    pw_remote_ = pw_remote_new(pw_core_, nullptr, /*user_data_size=*/0);
570  
571    InitPipeWireTypes();
572 +#endif
573  
574    // Initialize event handlers, remote end and stream-related.
575 +#if PW_CHECK_VERSION(0, 3, 0)
576 +  pw_core_events_.version = PW_VERSION_CORE_EVENTS;
577 +  pw_core_events_.error = &OnCoreError;
578 +
579 +  pw_stream_events_.version = PW_VERSION_STREAM_EVENTS;
580 +  pw_stream_events_.state_changed = &OnStreamStateChanged;
581 +  pw_stream_events_.param_changed = &OnStreamParamChanged;
582 +  pw_stream_events_.process = &OnStreamProcess;
583 +#else
584    pw_remote_events_.version = PW_VERSION_REMOTE_EVENTS;
585    pw_remote_events_.state_changed = &OnStateChanged;
586  
587 @@ -301,19 +574,33 @@ void BaseCapturerPipeWire::InitPipeWire() {
588    pw_stream_events_.state_changed = &OnStreamStateChanged;
589    pw_stream_events_.format_changed = &OnStreamFormatChanged;
590    pw_stream_events_.process = &OnStreamProcess;
591 +#endif
592  
593 +#if PW_CHECK_VERSION(0, 3, 0)
594 +  pw_core_add_listener(pw_core_, &spa_core_listener_, &pw_core_events_, this);
595 +
596 +  pw_stream_ = CreateReceivingStream();
597 +  if (!pw_stream_) {
598 +    RTC_LOG(LS_ERROR) << "Failed to create PipeWire stream";
599 +    return;
600 +  }
601 +#else
602    pw_remote_add_listener(pw_remote_, &spa_remote_listener_, &pw_remote_events_,
603                           this);
604    pw_remote_connect_fd(pw_remote_, pw_fd_);
605 +#endif
606  
607    if (pw_thread_loop_start(pw_main_loop_) < 0) {
608      RTC_LOG(LS_ERROR) << "Failed to start main PipeWire loop";
609      portal_init_failed_ = true;
610    }
611  
612 +  pw_thread_loop_unlock(pw_main_loop_);
613 +
614    RTC_LOG(LS_INFO) << "PipeWire remote opened.";
615  }
616  
617 +#if !PW_CHECK_VERSION(0, 3, 0)
618  void BaseCapturerPipeWire::InitPipeWireTypes() {
619    spa_type_map* map = pw_core_type_->map;
620    pw_type_ = new PipeWireType();
621 @@ -323,23 +610,44 @@ void BaseCapturerPipeWire::InitPipeWireTypes() {
622    spa_type_format_video_map(map, &pw_type_->format_video);
623    spa_type_video_format_map(map, &pw_type_->video_format);
624  }
625 +#endif
626  
627 -void BaseCapturerPipeWire::CreateReceivingStream() {
628 +pw_stream* BaseCapturerPipeWire::CreateReceivingStream() {
629 +#if !PW_CHECK_VERSION(0, 3, 0)
630 +  if (pw_remote_get_state(pw_remote_, nullptr) != PW_REMOTE_STATE_CONNECTED) {
631 +    RTC_LOG(LS_ERROR) << "Cannot create pipewire stream";
632 +    return nullptr;
633 +  }
634 +#endif
635    spa_rectangle pwMinScreenBounds = spa_rectangle{1, 1};
636 -  spa_rectangle pwScreenBounds =
637 -      spa_rectangle{static_cast<uint32_t>(desktop_size_.width()),
638 -                    static_cast<uint32_t>(desktop_size_.height())};
639 -
640 -  spa_fraction pwFrameRateMin = spa_fraction{0, 1};
641 -  spa_fraction pwFrameRateMax = spa_fraction{60, 1};
642 +  spa_rectangle pwMaxScreenBounds = spa_rectangle{UINT32_MAX, UINT32_MAX};
643  
644    pw_properties* reuseProps =
645        pw_properties_new_string("pipewire.client.reuse=1");
646 -  pw_stream_ = pw_stream_new(pw_remote_, "webrtc-consume-stream", reuseProps);
647 +#if PW_CHECK_VERSION(0, 3, 0)
648 +  auto stream = pw_stream_new(pw_core_, "webrtc-consume-stream", reuseProps);
649 +#else
650 +  auto stream = pw_stream_new(pw_remote_, "webrtc-consume-stream", reuseProps);
651 +#endif
652  
653    uint8_t buffer[1024] = {};
654    const spa_pod* params[1];
655    spa_pod_builder builder = spa_pod_builder{buffer, sizeof(buffer)};
656 +
657 +#if PW_CHECK_VERSION(0, 3, 0)
658 +  params[0] = reinterpret_cast<spa_pod*>(spa_pod_builder_add_object(
659 +      &builder, SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat,
660 +      SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_video),
661 +      SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_raw),
662 +      SPA_FORMAT_VIDEO_format,
663 +      SPA_POD_CHOICE_ENUM_Id(5, SPA_VIDEO_FORMAT_BGRx, SPA_VIDEO_FORMAT_RGBx,
664 +                             SPA_VIDEO_FORMAT_RGBA, SPA_VIDEO_FORMAT_BGRx,
665 +                             SPA_VIDEO_FORMAT_BGRA),
666 +      SPA_FORMAT_VIDEO_size,
667 +      SPA_POD_CHOICE_RANGE_Rectangle(&pwMinScreenBounds, &pwMinScreenBounds,
668 +                                     &pwMaxScreenBounds),
669 +      0));
670 +#else
671    params[0] = reinterpret_cast<spa_pod*>(spa_pod_builder_object(
672        &builder,
673        // id to enumerate formats
674 @@ -349,69 +657,218 @@ void BaseCapturerPipeWire::CreateReceivingStream() {
675        // then allowed formats are enumerated (e) and the format is undecided (u)
676        // to allow negotiation
677        ":", pw_type_->format_video.format, "Ieu", pw_type_->video_format.BGRx,
678 -      SPA_POD_PROP_ENUM(2, pw_type_->video_format.RGBx,
679 -                        pw_type_->video_format.BGRx),
680 +      SPA_POD_PROP_ENUM(
681 +          4, pw_type_->video_format.RGBx, pw_type_->video_format.BGRx,
682 +          pw_type_->video_format.RGBA, pw_type_->video_format.BGRA),
683        // Video size: specified as rectangle (R), preferred size is specified as
684        // first parameter, then allowed size is defined as range (r) from min and
685        // max values and the format is undecided (u) to allow negotiation
686 -      ":", pw_type_->format_video.size, "Rru", &pwScreenBounds, 2,
687 -      &pwMinScreenBounds, &pwScreenBounds,
688 -      // Frame rate: specified as fraction (F) and set to minimum frame rate
689 -      // value
690 -      ":", pw_type_->format_video.framerate, "F", &pwFrameRateMin,
691 -      // Max frame rate: specified as fraction (F), preferred frame rate is set
692 -      // to maximum value, then allowed frame rate is defined as range (r) from
693 -      // min and max values and it is undecided (u) to allow negotiation
694 -      ":", pw_type_->format_video.max_framerate, "Fru", &pwFrameRateMax, 2,
695 -      &pwFrameRateMin, &pwFrameRateMax));
696 -
697 -  pw_stream_add_listener(pw_stream_, &spa_stream_listener_, &pw_stream_events_,
698 +      ":", pw_type_->format_video.size, "Rru", &pwMinScreenBounds,
699 +      SPA_POD_PROP_MIN_MAX(&pwMinScreenBounds, &pwMaxScreenBounds)));
700 +#endif
701 +
702 +  pw_stream_add_listener(stream, &spa_stream_listener_, &pw_stream_events_,
703                           this);
704 +#if PW_CHECK_VERSION(0, 3, 0)
705 +  if (pw_stream_connect(stream, PW_DIRECTION_INPUT, pw_stream_node_id_,
706 +                        PW_STREAM_FLAG_AUTOCONNECT, params, 1) != 0) {
707 +#else
708    pw_stream_flags flags = static_cast<pw_stream_flags>(
709 -      PW_STREAM_FLAG_AUTOCONNECT | PW_STREAM_FLAG_INACTIVE |
710 -      PW_STREAM_FLAG_MAP_BUFFERS);
711 -  if (pw_stream_connect(pw_stream_, PW_DIRECTION_INPUT, /*port_path=*/nullptr,
712 +      PW_STREAM_FLAG_AUTOCONNECT | PW_STREAM_FLAG_INACTIVE);
713 +  if (pw_stream_connect(stream, PW_DIRECTION_INPUT, /*port_path=*/nullptr,
714                          flags, params,
715                          /*n_params=*/1) != 0) {
716 +#endif
717      RTC_LOG(LS_ERROR) << "Could not connect receiving stream.";
718      portal_init_failed_ = true;
719 -    return;
720 +    return nullptr;
721    }
722 +
723 +  return stream;
724  }
725  
726  void BaseCapturerPipeWire::HandleBuffer(pw_buffer* buffer) {
727    spa_buffer* spaBuffer = buffer->buffer;
728 -  void* src = nullptr;
729 +  ScopedBuf map;
730 +  uint8_t* src = nullptr;
731 +
732 +  if (spaBuffer->datas[0].chunk->size == 0) {
733 +    RTC_LOG(LS_ERROR) << "Failed to get video stream: Zero size.";
734 +    return;
735 +  }
736 +
737 +#if PW_CHECK_VERSION(0, 3, 0)
738 +  if (spaBuffer->datas[0].type == SPA_DATA_MemFd ||
739 +      spaBuffer->datas[0].type == SPA_DATA_DmaBuf) {
740 +#else
741 +  if (spaBuffer->datas[0].type == pw_core_type_->data.MemFd ||
742 +      spaBuffer->datas[0].type == pw_core_type_->data.DmaBuf) {
743 +#endif
744 +    map.initialize(
745 +        static_cast<uint8_t*>(
746 +            mmap(nullptr,
747 +                 spaBuffer->datas[0].maxsize + spaBuffer->datas[0].mapoffset,
748 +                 PROT_READ, MAP_PRIVATE, spaBuffer->datas[0].fd, 0)),
749 +        spaBuffer->datas[0].maxsize + spaBuffer->datas[0].mapoffset,
750 +#if PW_CHECK_VERSION(0, 3, 0)
751 +        spaBuffer->datas[0].type == SPA_DATA_DmaBuf,
752 +#else
753 +        spaBuffer->datas[0].type == pw_core_type_->data.DmaBuf,
754 +#endif
755 +        spaBuffer->datas[0].fd);
756 +
757 +    if (!map) {
758 +      RTC_LOG(LS_ERROR) << "Failed to mmap the memory: "
759 +                        << std::strerror(errno);
760 +      return;
761 +    }
762 +
763 +#if PW_CHECK_VERSION(0, 3, 0)
764 +    if (spaBuffer->datas[0].type == SPA_DATA_DmaBuf) {
765 +#else
766 +    if (spaBuffer->datas[0].type == pw_core_type_->data.DmaBuf) {
767 +#endif
768 +      SyncDmaBuf(spaBuffer->datas[0].fd, DMA_BUF_SYNC_START);
769 +    }
770 +
771 +    src = SPA_MEMBER(map.get(), spaBuffer->datas[0].mapoffset, uint8_t);
772 +#if PW_CHECK_VERSION(0, 3, 0)
773 +  } else if (spaBuffer->datas[0].type == SPA_DATA_MemPtr) {
774 +#else
775 +  } else if (spaBuffer->datas[0].type == pw_core_type_->data.MemPtr) {
776 +#endif
777 +    src = static_cast<uint8_t*>(spaBuffer->datas[0].data);
778 +  }
779  
780 -  if (!(src = spaBuffer->datas[0].data)) {
781 +  if (!src) {
782 +    return;
783 +  }
784 +
785 +#if PW_CHECK_VERSION(0, 3, 0)
786 +  struct spa_meta_region* video_metadata =
787 +      static_cast<struct spa_meta_region*>(spa_buffer_find_meta_data(
788 +          spaBuffer, SPA_META_VideoCrop, sizeof(*video_metadata)));
789 +#else
790 +  struct spa_meta_video_crop* video_metadata =
791 +      static_cast<struct spa_meta_video_crop*>(
792 +          spa_buffer_find_meta(spaBuffer, pw_core_type_->meta.VideoCrop));
793 +#endif
794 +
795 +  // Video size from metadata is bigger than an actual video stream size.
796 +  // The metadata are wrong or we should up-scale the video...in both cases
797 +  // just quit now.
798 +#if PW_CHECK_VERSION(0, 3, 0)
799 +  if (video_metadata && (video_metadata->region.size.width >
800 +                             static_cast<uint32_t>(desktop_size_.width()) ||
801 +                         video_metadata->region.size.height >
802 +                             static_cast<uint32_t>(desktop_size_.height()))) {
803 +#else
804 +  if (video_metadata && (video_metadata->width > desktop_size_.width() ||
805 +                         video_metadata->height > desktop_size_.height())) {
806 +#endif
807 +    RTC_LOG(LS_ERROR) << "Stream metadata sizes are wrong!";
808      return;
809    }
810  
811 -  uint32_t maxSize = spaBuffer->datas[0].maxsize;
812 -  int32_t srcStride = spaBuffer->datas[0].chunk->stride;
813 -  if (srcStride != (desktop_size_.width() * kBytesPerPixel)) {
814 +  // Use video metadata when video size from metadata is set and smaller than
815 +  // video stream size, so we need to adjust it.
816 +  bool video_is_full_width = true;
817 +  bool video_is_full_height = true;
818 +#if PW_CHECK_VERSION(0, 3, 0)
819 +  if (video_metadata && video_metadata->region.size.width != 0 &&
820 +      video_metadata->region.size.height != 0) {
821 +    if (video_metadata->region.size.width <
822 +        static_cast<uint32_t>(desktop_size_.width())) {
823 +      video_is_full_width = false;
824 +    } else if (video_metadata->region.size.height <
825 +               static_cast<uint32_t>(desktop_size_.height())) {
826 +      video_is_full_height = false;
827 +    }
828 +  }
829 +#else
830 +  if (video_metadata && video_metadata->width != 0 &&
831 +      video_metadata->height != 0) {
832 +    if (video_metadata->width < desktop_size_.width()) {
833 +    } else if (video_metadata->height < desktop_size_.height()) {
834 +      video_is_full_height = false;
835 +    }
836 +  }
837 +#endif
838 +
839 +  DesktopSize video_size_prev = video_size_;
840 +  if (!video_is_full_height || !video_is_full_width) {
841 +#if PW_CHECK_VERSION(0, 3, 0)
842 +    video_size_ = DesktopSize(video_metadata->region.size.width,
843 +                              video_metadata->region.size.height);
844 +#else
845 +    video_size_ = DesktopSize(video_metadata->width, video_metadata->height);
846 +#endif
847 +  } else {
848 +    video_size_ = desktop_size_;
849 +  }
850 +
851 +  webrtc::MutexLock lock(&current_frame_lock_);
852 +  if (!current_frame_ || !video_size_.equals(video_size_prev)) {
853 +    current_frame_ = std::make_unique<uint8_t[]>(
854 +        video_size_.width() * video_size_.height() * kBytesPerPixel);
855 +  }
856 +
857 +  const int32_t dst_stride = video_size_.width() * kBytesPerPixel;
858 +  const int32_t src_stride = spaBuffer->datas[0].chunk->stride;
859 +
860 +  if (src_stride != (desktop_size_.width() * kBytesPerPixel)) {
861      RTC_LOG(LS_ERROR) << "Got buffer with stride different from screen stride: "
862 -                      << srcStride
863 +                      << src_stride
864                        << " != " << (desktop_size_.width() * kBytesPerPixel);
865      portal_init_failed_ = true;
866 +
867      return;
868    }
869  
870 -  if (!current_frame_) {
871 -    current_frame_ = static_cast<uint8_t*>(malloc(maxSize));
872 -  }
873 -  RTC_DCHECK(current_frame_ != nullptr);
874 -
875 -  // If both sides decided to go with the RGBx format we need to convert it to
876 -  // BGRx to match color format expected by WebRTC.
877 -  if (spa_video_format_->format == pw_type_->video_format.RGBx) {
878 -    uint8_t* tempFrame = static_cast<uint8_t*>(malloc(maxSize));
879 -    std::memcpy(tempFrame, src, maxSize);
880 -    ConvertRGBxToBGRx(tempFrame, maxSize);
881 -    std::memcpy(current_frame_, tempFrame, maxSize);
882 -    free(tempFrame);
883 -  } else {
884 -    std::memcpy(current_frame_, src, maxSize);
885 +  // Adjust source content based on metadata video position
886 +#if PW_CHECK_VERSION(0, 3, 0)
887 +  if (!video_is_full_height &&
888 +      (video_metadata->region.position.y + video_size_.height() <=
889 +       desktop_size_.height())) {
890 +    src += src_stride * video_metadata->region.position.y;
891 +  }
892 +  const int x_offset =
893 +      !video_is_full_width &&
894 +              (video_metadata->region.position.x + video_size_.width() <=
895 +               desktop_size_.width())
896 +          ? video_metadata->region.position.x * kBytesPerPixel
897 +          : 0;
898 +#else
899 +  if (!video_is_full_height &&
900 +      (video_metadata->y + video_size_.height() <= desktop_size_.height())) {
901 +    src += src_stride * video_metadata->y;
902 +  }
903 +
904 +  const int x_offset =
905 +      !video_is_full_width &&
906 +              (video_metadata->x + video_size_.width() <= desktop_size_.width())
907 +          ? video_metadata->x * kBytesPerPixel
908 +          : 0;
909 +#endif
910 +
911 +  uint8_t* dst = current_frame_.get();
912 +  for (int i = 0; i < video_size_.height(); ++i) {
913 +    // Adjust source content based on crop video position if needed
914 +    src += x_offset;
915 +    std::memcpy(dst, src, dst_stride);
916 +    // If both sides decided to go with the RGBx format we need to convert it to
917 +    // BGRx to match color format expected by WebRTC.
918 +#if PW_CHECK_VERSION(0, 3, 0)
919 +    if (spa_video_format_.format == SPA_VIDEO_FORMAT_RGBx ||
920 +        spa_video_format_.format == SPA_VIDEO_FORMAT_RGBA) {
921 +#else
922 +    if (spa_video_format_->format == pw_type_->video_format.RGBx ||
923 +        spa_video_format_->format == pw_type_->video_format.RGBA) {
924 +#endif
925 +      ConvertRGBxToBGRx(dst, dst_stride);
926 +    }
927 +    src += src_stride - x_offset;
928 +    dst += dst_stride;
929    }
930  }
931  
932 @@ -441,14 +898,13 @@ void BaseCapturerPipeWire::OnProxyRequested(GObject* /*object*/,
933    BaseCapturerPipeWire* that = static_cast<BaseCapturerPipeWire*>(user_data);
934    RTC_DCHECK(that);
935  
936 -  GError* error = nullptr;
937 -  GDBusProxy *proxy = g_dbus_proxy_new_finish(result, &error);
938 +  Scoped<GError> error;
939 +  GDBusProxy* proxy = g_dbus_proxy_new_finish(result, error.receive());
940    if (!proxy) {
941 -    if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
942 +    if (g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED))
943        return;
944      RTC_LOG(LS_ERROR) << "Failed to create a proxy for the screen cast portal: "
945                        << error->message;
946 -    g_error_free(error);
947      that->portal_init_failed_ = true;
948      return;
949    }
950 @@ -462,38 +918,36 @@ void BaseCapturerPipeWire::OnProxyRequested(GObject* /*object*/,
951  // static
952  gchar* BaseCapturerPipeWire::PrepareSignalHandle(GDBusConnection* connection,
953                                                   const gchar* token) {
954 -  gchar* sender = g_strdup(g_dbus_connection_get_unique_name(connection) + 1);
955 -  for (int i = 0; sender[i]; i++) {
956 -    if (sender[i] == '.') {
957 -      sender[i] = '_';
958 +  Scoped<gchar> sender(
959 +      g_strdup(g_dbus_connection_get_unique_name(connection) + 1));
960 +  for (int i = 0; sender.get()[i]; i++) {
961 +    if (sender.get()[i] == '.') {
962 +      sender.get()[i] = '_';
963      }
964    }
965  
966 -  gchar* handle = g_strconcat(kDesktopRequestObjectPath, "/", sender, "/",
967 +  gchar* handle = g_strconcat(kDesktopRequestObjectPath, "/", sender.get(), "/",
968                                token, /*end of varargs*/ nullptr);
969 -  g_free(sender);
970  
971    return handle;
972  }
973  
974  void BaseCapturerPipeWire::SessionRequest() {
975    GVariantBuilder builder;
976 -  gchar* variant_string;
977 +  Scoped<gchar> variant_string;
978  
979    g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT);
980    variant_string =
981        g_strdup_printf("webrtc_session%d", g_random_int_range(0, G_MAXINT));
982    g_variant_builder_add(&builder, "{sv}", "session_handle_token",
983 -                        g_variant_new_string(variant_string));
984 -  g_free(variant_string);
985 +                        g_variant_new_string(variant_string.get()));
986    variant_string = g_strdup_printf("webrtc%d", g_random_int_range(0, G_MAXINT));
987    g_variant_builder_add(&builder, "{sv}", "handle_token",
988 -                        g_variant_new_string(variant_string));
989 +                        g_variant_new_string(variant_string.get()));
990  
991 -  portal_handle_ = PrepareSignalHandle(connection_, variant_string);
992 +  portal_handle_ = PrepareSignalHandle(connection_, variant_string.get());
993    session_request_signal_id_ = SetupRequestResponseSignal(
994        portal_handle_, OnSessionRequestResponseSignal);
995 -  g_free(variant_string);
996  
997    RTC_LOG(LS_INFO) << "Screen cast session requested.";
998    g_dbus_proxy_call(
999 @@ -509,22 +963,21 @@ void BaseCapturerPipeWire::OnSessionRequested(GDBusProxy *proxy,
1000    BaseCapturerPipeWire* that = static_cast<BaseCapturerPipeWire*>(user_data);
1001    RTC_DCHECK(that);
1002  
1003 -  GError* error = nullptr;
1004 -  GVariant* variant = g_dbus_proxy_call_finish(proxy, result, &error);
1005 +  Scoped<GError> error;
1006 +  Scoped<GVariant> variant(
1007 +      g_dbus_proxy_call_finish(proxy, result, error.receive()));
1008    if (!variant) {
1009 -    if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
1010 +    if (g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED))
1011        return;
1012      RTC_LOG(LS_ERROR) << "Failed to create a screen cast session: "
1013                        << error->message;
1014 -    g_error_free(error);
1015      that->portal_init_failed_ = true;
1016      return;
1017    }
1018    RTC_LOG(LS_INFO) << "Initializing the screen cast session.";
1019  
1020 -  gchar* handle = nullptr;
1021 -  g_variant_get_child(variant, 0, "o", &handle);
1022 -  g_variant_unref(variant);
1023 +  Scoped<gchar> handle;
1024 +  g_variant_get_child(variant.get(), 0, "o", &handle);
1025    if (!handle) {
1026      RTC_LOG(LS_ERROR) << "Failed to initialize the screen cast session.";
1027      if (that->session_request_signal_id_) {
1028 @@ -536,8 +989,6 @@ void BaseCapturerPipeWire::OnSessionRequested(GDBusProxy *proxy,
1029      return;
1030    }
1031  
1032 -  g_free(handle);
1033 -
1034    RTC_LOG(LS_INFO) << "Subscribing to the screen cast session.";
1035  }
1036  
1037 @@ -557,11 +1008,11 @@ void BaseCapturerPipeWire::OnSessionRequestResponseSignal(
1038        << "Received response for the screen cast session subscription.";
1039  
1040    guint32 portal_response;
1041 -  GVariant* response_data;
1042 -  g_variant_get(parameters, "(u@a{sv})", &portal_response, &response_data);
1043 -  g_variant_lookup(response_data, "session_handle", "s",
1044 +  Scoped<GVariant> response_data;
1045 +  g_variant_get(parameters, "(u@a{sv})", &portal_response,
1046 +                response_data.receive());
1047 +  g_variant_lookup(response_data.get(), "session_handle", "s",
1048                     &that->session_handle_);
1049 -  g_variant_unref(response_data);
1050  
1051    if (!that->session_handle_ || portal_response) {
1052      RTC_LOG(LS_ERROR)
1053 @@ -575,23 +1026,23 @@ void BaseCapturerPipeWire::OnSessionRequestResponseSignal(
1054  
1055  void BaseCapturerPipeWire::SourcesRequest() {
1056    GVariantBuilder builder;
1057 -  gchar* variant_string;
1058 +  Scoped<gchar> variant_string;
1059  
1060    g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT);
1061    // We want to record monitor content.
1062 -  g_variant_builder_add(&builder, "{sv}", "types",
1063 -                        g_variant_new_uint32(capture_source_type_));
1064 +  g_variant_builder_add(
1065 +      &builder, "{sv}", "types",
1066 +      g_variant_new_uint32(static_cast<uint32_t>(capture_source_type_)));
1067    // We don't want to allow selection of multiple sources.
1068    g_variant_builder_add(&builder, "{sv}", "multiple",
1069                          g_variant_new_boolean(false));
1070    variant_string = g_strdup_printf("webrtc%d", g_random_int_range(0, G_MAXINT));
1071    g_variant_builder_add(&builder, "{sv}", "handle_token",
1072 -                        g_variant_new_string(variant_string));
1073 +                        g_variant_new_string(variant_string.get()));
1074  
1075 -  sources_handle_ = PrepareSignalHandle(connection_, variant_string);
1076 +  sources_handle_ = PrepareSignalHandle(connection_, variant_string.get());
1077    sources_request_signal_id_ = SetupRequestResponseSignal(
1078        sources_handle_, OnSourcesRequestResponseSignal);
1079 -  g_free(variant_string);
1080  
1081    RTC_LOG(LS_INFO) << "Requesting sources from the screen cast session.";
1082    g_dbus_proxy_call(
1083 @@ -608,22 +1059,21 @@ void BaseCapturerPipeWire::OnSourcesRequested(GDBusProxy *proxy,
1084    BaseCapturerPipeWire* that = static_cast<BaseCapturerPipeWire*>(user_data);
1085    RTC_DCHECK(that);
1086  
1087 -  GError* error = nullptr;
1088 -  GVariant* variant = g_dbus_proxy_call_finish(proxy, result, &error);
1089 +  Scoped<GError> error;
1090 +  Scoped<GVariant> variant(
1091 +      g_dbus_proxy_call_finish(proxy, result, error.receive()));
1092    if (!variant) {
1093 -    if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
1094 +    if (g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED))
1095        return;
1096      RTC_LOG(LS_ERROR) << "Failed to request the sources: " << error->message;
1097 -    g_error_free(error);
1098      that->portal_init_failed_ = true;
1099      return;
1100    }
1101  
1102    RTC_LOG(LS_INFO) << "Sources requested from the screen cast session.";
1103  
1104 -  gchar* handle = nullptr;
1105 -  g_variant_get_child(variant, 0, "o", &handle);
1106 -  g_variant_unref(variant);
1107 +  Scoped<gchar> handle;
1108 +  g_variant_get_child(variant.get(), 0, "o", handle.receive());
1109    if (!handle) {
1110      RTC_LOG(LS_ERROR) << "Failed to initialize the screen cast session.";
1111      if (that->sources_request_signal_id_) {
1112 @@ -635,8 +1085,6 @@ void BaseCapturerPipeWire::OnSourcesRequested(GDBusProxy *proxy,
1113      return;
1114    }
1115  
1116 -  g_free(handle);
1117 -
1118    RTC_LOG(LS_INFO) << "Subscribed to sources signal.";
1119  }
1120  
1121 @@ -668,17 +1116,16 @@ void BaseCapturerPipeWire::OnSourcesRequestResponseSignal(
1122  
1123  void BaseCapturerPipeWire::StartRequest() {
1124    GVariantBuilder builder;
1125 -  gchar* variant_string;
1126 +  Scoped<gchar> variant_string;
1127  
1128    g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT);
1129    variant_string = g_strdup_printf("webrtc%d", g_random_int_range(0, G_MAXINT));
1130    g_variant_builder_add(&builder, "{sv}", "handle_token",
1131 -                        g_variant_new_string(variant_string));
1132 +                        g_variant_new_string(variant_string.get()));
1133  
1134 -  start_handle_ = PrepareSignalHandle(connection_, variant_string);
1135 +  start_handle_ = PrepareSignalHandle(connection_, variant_string.get());
1136    start_request_signal_id_ =
1137        SetupRequestResponseSignal(start_handle_, OnStartRequestResponseSignal);
1138 -  g_free(variant_string);
1139  
1140    // "Identifier for the application window", this is Wayland, so not "x11:...".
1141    const gchar parent_window[] = "";
1142 @@ -698,23 +1145,22 @@ void BaseCapturerPipeWire::OnStartRequested(GDBusProxy *proxy,
1143    BaseCapturerPipeWire* that = static_cast<BaseCapturerPipeWire*>(user_data);
1144    RTC_DCHECK(that);
1145  
1146 -  GError* error = nullptr;
1147 -  GVariant* variant = g_dbus_proxy_call_finish(proxy, result, &error);
1148 +  Scoped<GError> error;
1149 +  Scoped<GVariant> variant(
1150 +      g_dbus_proxy_call_finish(proxy, result, error.receive()));
1151    if (!variant) {
1152 -    if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
1153 +    if (g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED))
1154        return;
1155      RTC_LOG(LS_ERROR) << "Failed to start the screen cast session: "
1156                        << error->message;
1157 -    g_error_free(error);
1158      that->portal_init_failed_ = true;
1159      return;
1160    }
1161  
1162    RTC_LOG(LS_INFO) << "Initializing the start of the screen cast session.";
1163  
1164 -  gchar* handle = nullptr;
1165 -  g_variant_get_child(variant, 0, "o", &handle);
1166 -  g_variant_unref(variant);
1167 +  Scoped<gchar> handle;
1168 +  g_variant_get_child(variant.get(), 0, "o", handle.receive());
1169    if (!handle) {
1170      RTC_LOG(LS_ERROR)
1171          << "Failed to initialize the start of the screen cast session.";
1172 @@ -727,8 +1173,6 @@ void BaseCapturerPipeWire::OnStartRequested(GDBusProxy *proxy,
1173      return;
1174    }
1175  
1176 -  g_free(handle);
1177 -
1178    RTC_LOG(LS_INFO) << "Subscribed to the start signal.";
1179  }
1180  
1181 @@ -746,9 +1190,10 @@ void BaseCapturerPipeWire::OnStartRequestResponseSignal(
1182  
1183    RTC_LOG(LS_INFO) << "Start signal received.";
1184    guint32 portal_response;
1185 -  GVariant* response_data;
1186 -  GVariantIter* iter = nullptr;
1187 -  g_variant_get(parameters, "(u@a{sv})", &portal_response, &response_data);
1188 +  Scoped<GVariant> response_data;
1189 +  Scoped<GVariantIter> iter;
1190 +  g_variant_get(parameters, "(u@a{sv})", &portal_response,
1191 +                response_data.receive());
1192    if (portal_response || !response_data) {
1193      RTC_LOG(LS_ERROR) << "Failed to start the screen cast session.";
1194      that->portal_init_failed_ = true;
1195 @@ -758,28 +1203,28 @@ void BaseCapturerPipeWire::OnStartRequestResponseSignal(
1196    // Array of PipeWire streams. See
1197    // https://github.com/flatpak/xdg-desktop-portal/blob/master/data/org.freedesktop.portal.ScreenCast.xml
1198    // documentation for <method name="Start">.
1199 -  if (g_variant_lookup(response_data, "streams", "a(ua{sv})", &iter)) {
1200 -    GVariant* variant;
1201 +  if (g_variant_lookup(response_data.get(), "streams", "a(ua{sv})",
1202 +                       iter.receive())) {
1203 +    Scoped<GVariant> variant;
1204  
1205 -    while (g_variant_iter_next(iter, "@(ua{sv})", &variant)) {
1206 +    while (g_variant_iter_next(iter.get(), "@(ua{sv})", variant.receive())) {
1207        guint32 stream_id;
1208 -      gint32 width;
1209 -      gint32 height;
1210 -      GVariant* options;
1211 +      guint32 type;
1212 +      Scoped<GVariant> options;
1213  
1214 -      g_variant_get(variant, "(u@a{sv})", &stream_id, &options);
1215 -      RTC_DCHECK(options != nullptr);
1216 +      g_variant_get(variant.get(), "(u@a{sv})", &stream_id, options.receive());
1217 +      RTC_DCHECK(options.get());
1218  
1219 -      g_variant_lookup(options, "size", "(ii)", &width, &height);
1220 +      if (g_variant_lookup(options.get(), "source_type", "u", &type)) {
1221 +        that->capture_source_type_ =
1222 +            static_cast<BaseCapturerPipeWire::CaptureSourceType>(type);
1223 +      }
1224  
1225 -      that->desktop_size_.set(width, height);
1226 +      that->pw_stream_node_id_ = stream_id;
1227  
1228 -      g_variant_unref(options);
1229 -      g_variant_unref(variant);
1230 +      break;
1231      }
1232    }
1233 -  g_variant_iter_free(iter);
1234 -  g_variant_unref(response_data);
1235  
1236    that->OpenPipeWireRemote();
1237  }
1238 @@ -807,35 +1252,30 @@ void BaseCapturerPipeWire::OnOpenPipeWireRemoteRequested(
1239    BaseCapturerPipeWire* that = static_cast<BaseCapturerPipeWire*>(user_data);
1240    RTC_DCHECK(that);
1241  
1242 -  GError* error = nullptr;
1243 -  GUnixFDList* outlist = nullptr;
1244 -  GVariant* variant = g_dbus_proxy_call_with_unix_fd_list_finish(
1245 -      proxy, &outlist, result, &error);
1246 +  Scoped<GError> error;
1247 +  Scoped<GUnixFDList> outlist;
1248 +  Scoped<GVariant> variant(g_dbus_proxy_call_with_unix_fd_list_finish(
1249 +      proxy, outlist.receive(), result, error.receive()));
1250    if (!variant) {
1251 -    if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
1252 +    if (g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED))
1253        return;
1254      RTC_LOG(LS_ERROR) << "Failed to open the PipeWire remote: "
1255                        << error->message;
1256 -    g_error_free(error);
1257      that->portal_init_failed_ = true;
1258      return;
1259    }
1260  
1261    gint32 index;
1262 -  g_variant_get(variant, "(h)", &index);
1263 +  g_variant_get(variant.get(), "(h)", &index);
1264  
1265 -  if ((that->pw_fd_ = g_unix_fd_list_get(outlist, index, &error)) == -1) {
1266 +  if ((that->pw_fd_ =
1267 +           g_unix_fd_list_get(outlist.get(), index, error.receive())) == -1) {
1268      RTC_LOG(LS_ERROR) << "Failed to get file descriptor from the list: "
1269                        << error->message;
1270 -    g_error_free(error);
1271 -    g_variant_unref(variant);
1272      that->portal_init_failed_ = true;
1273      return;
1274    }
1275  
1276 -  g_variant_unref(variant);
1277 -  g_object_unref(outlist);
1278 -
1279    that->InitPipeWire();
1280  }
1281  
1282 @@ -854,15 +1294,18 @@ void BaseCapturerPipeWire::CaptureFrame() {
1283      return;
1284    }
1285  
1286 +  webrtc::MutexLock lock(&current_frame_lock_);
1287    if (!current_frame_) {
1288      callback_->OnCaptureResult(Result::ERROR_TEMPORARY, nullptr);
1289      return;
1290    }
1291  
1292 -  std::unique_ptr<DesktopFrame> result(new BasicDesktopFrame(desktop_size_));
1293 +  DesktopSize frame_size = video_size_;
1294 +
1295 +  std::unique_ptr<DesktopFrame> result(new BasicDesktopFrame(frame_size));
1296    result->CopyPixelsFrom(
1297 -      current_frame_, (desktop_size_.width() * kBytesPerPixel),
1298 -      DesktopRect::MakeWH(desktop_size_.width(), desktop_size_.height()));
1299 +      current_frame_.get(), (frame_size.width() * kBytesPerPixel),
1300 +      DesktopRect::MakeWH(frame_size.width(), frame_size.height()));
1301    if (!result) {
1302      callback_->OnCaptureResult(Result::ERROR_TEMPORARY, nullptr);
1303      return;
1304 @@ -887,4 +1330,11 @@ bool BaseCapturerPipeWire::SelectSource(SourceId id) {
1305    return true;
1306  }
1307  
1308 +// static
1309 +std::unique_ptr<DesktopCapturer> BaseCapturerPipeWire::CreateRawCapturer(
1310 +    const DesktopCaptureOptions& options) {
1311 +  return std::make_unique<BaseCapturerPipeWire>(
1312 +      BaseCapturerPipeWire::CaptureSourceType::kAny);
1313 +}
1314 +
1315  }  // namespace webrtc
1316 diff --git a/chromium/third_party/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.h b/chromium/third_party/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.h
1317 index f28d7a558bc..75d20dbf1db 100644
1318 --- a/chromium/third_party/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.h
1319 +++ b/chromium/third_party/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.h
1320 @@ -10,18 +10,23 @@
1321  
1322  #ifndef MODULES_DESKTOP_CAPTURE_LINUX_BASE_CAPTURER_PIPEWIRE_H_
1323  #define MODULES_DESKTOP_CAPTURE_LINUX_BASE_CAPTURER_PIPEWIRE_H_
1324 -
1325  #include <gio/gio.h>
1326  #define typeof __typeof__
1327  #include <pipewire/pipewire.h>
1328  #include <spa/param/video/format-utils.h>
1329 +#if PW_CHECK_VERSION(0, 3, 0)
1330 +#include <spa/utils/result.h>
1331 +#endif
1332  
1333 +#include "absl/types/optional.h"
1334  #include "modules/desktop_capture/desktop_capture_options.h"
1335  #include "modules/desktop_capture/desktop_capturer.h"
1336  #include "rtc_base/constructor_magic.h"
1337 +#include "rtc_base/synchronization/mutex.h"
1338  
1339  namespace webrtc {
1340  
1341 +#if !PW_CHECK_VERSION(0, 3, 0)
1342  class PipeWireType {
1343   public:
1344    spa_type_media_type media_type;
1345 @@ -29,14 +34,25 @@ class PipeWireType {
1346    spa_type_format_video format_video;
1347    spa_type_video_format video_format;
1348  };
1349 +#endif
1350  
1351  class BaseCapturerPipeWire : public DesktopCapturer {
1352   public:
1353 -  enum CaptureSourceType { Screen = 1, Window };
1354 +  // Values are set based on source type property in
1355 +  // xdg-desktop-portal/screencast
1356 +  // https://github.com/flatpak/xdg-desktop-portal/blob/master/data/org.freedesktop.portal.ScreenCast.xml
1357 +  enum class CaptureSourceType : uint32_t {
1358 +    kScreen = 0b01,
1359 +    kWindow = 0b10,
1360 +    kAny = 0b11
1361 +  };
1362  
1363    explicit BaseCapturerPipeWire(CaptureSourceType source_type);
1364    ~BaseCapturerPipeWire() override;
1365  
1366 +  static std::unique_ptr<DesktopCapturer> CreateRawCapturer(
1367 +      const DesktopCaptureOptions& options);
1368 +
1369    // DesktopCapturer interface.
1370    void Start(Callback* delegate) override;
1371    void CaptureFrame() override;
1372 @@ -45,6 +61,21 @@ class BaseCapturerPipeWire : public DesktopCapturer {
1373  
1374   private:
1375    // PipeWire types -->
1376 +#if PW_CHECK_VERSION(0, 3, 0)
1377 +  struct pw_context* pw_context_ = nullptr;
1378 +  struct pw_core* pw_core_ = nullptr;
1379 +  struct pw_stream* pw_stream_ = nullptr;
1380 +  struct pw_thread_loop* pw_main_loop_ = nullptr;
1381 +
1382 +  spa_hook spa_core_listener_;
1383 +  spa_hook spa_stream_listener_;
1384 +
1385 +  // event handlers
1386 +  pw_core_events pw_core_events_ = {};
1387 +  pw_stream_events pw_stream_events_ = {};
1388 +
1389 +  struct spa_video_info_raw spa_video_format_;
1390 +#else
1391    pw_core* pw_core_ = nullptr;
1392    pw_type* pw_core_type_ = nullptr;
1393    pw_stream* pw_stream_ = nullptr;
1394 @@ -60,11 +91,13 @@ class BaseCapturerPipeWire : public DesktopCapturer {
1395    pw_remote_events pw_remote_events_ = {};
1396  
1397    spa_video_info_raw* spa_video_format_ = nullptr;
1398 +#endif
1399  
1400 +  guint32 pw_stream_node_id_ = 0;
1401    gint32 pw_fd_ = -1;
1402  
1403    CaptureSourceType capture_source_type_ =
1404 -      BaseCapturerPipeWire::CaptureSourceType::Screen;
1405 +      BaseCapturerPipeWire::CaptureSourceType::kScreen;
1406  
1407    // <-- end of PipeWire types
1408  
1409 @@ -79,10 +112,12 @@ class BaseCapturerPipeWire : public DesktopCapturer {
1410    guint sources_request_signal_id_ = 0;
1411    guint start_request_signal_id_ = 0;
1412  
1413 +  DesktopSize video_size_;
1414    DesktopSize desktop_size_ = {};
1415    DesktopCaptureOptions options_ = {};
1416  
1417 -  uint8_t* current_frame_ = nullptr;
1418 +  webrtc::Mutex current_frame_lock_;
1419 +  std::unique_ptr<uint8_t[]> current_frame_;
1420    Callback* callback_ = nullptr;
1421  
1422    bool portal_init_failed_ = false;
1423 @@ -91,21 +126,32 @@ class BaseCapturerPipeWire : public DesktopCapturer {
1424    void InitPipeWire();
1425    void InitPipeWireTypes();
1426  
1427 -  void CreateReceivingStream();
1428 +  pw_stream* CreateReceivingStream();
1429    void HandleBuffer(pw_buffer* buffer);
1430  
1431    void ConvertRGBxToBGRx(uint8_t* frame, uint32_t size);
1432  
1433 +#if PW_CHECK_VERSION(0, 3, 0)
1434 +  static void OnCoreError(void* data,
1435 +                          uint32_t id,
1436 +                          int seq,
1437 +                          int res,
1438 +                          const char* message);
1439 +  static void OnStreamParamChanged(void* data,
1440 +                                   uint32_t id,
1441 +                                   const struct spa_pod* format);
1442 +#else
1443    static void OnStateChanged(void* data,
1444                               pw_remote_state old_state,
1445                               pw_remote_state state,
1446                               const char* error);
1447 +  static void OnStreamFormatChanged(void* data, const struct spa_pod* format);
1448 +#endif
1449    static void OnStreamStateChanged(void* data,
1450                                     pw_stream_state old_state,
1451                                     pw_stream_state state,
1452                                     const char* error_message);
1453  
1454 -  static void OnStreamFormatChanged(void* data, const struct spa_pod* format);
1455    static void OnStreamProcess(void* data);
1456    static void OnNewBuffer(void* data, uint32_t id);
1457  
1458 diff --git a/chromium/third_party/webrtc/modules/desktop_capture/linux/pipewire.sigs b/chromium/third_party/webrtc/modules/desktop_capture/linux/pipewire.sigs
1459 deleted file mode 100644
1460 index 3e21e9dc07c..00000000000
1461 --- a/chromium/third_party/webrtc/modules/desktop_capture/linux/pipewire.sigs
1462 +++ /dev/null
1463 @@ -1,44 +0,0 @@
1464 -// Copyright 2018 The WebRTC project authors. All rights reserved.
1465 -// Use of this source code is governed by a BSD-style license that can be
1466 -// found in the LICENSE file.
1467 -
1468 -//------------------------------------------------
1469 -// Functions from PipeWire used in capturer code.
1470 -//------------------------------------------------
1471 -
1472 -// core.h
1473 -void pw_core_destroy(pw_core *core);
1474 -pw_type *pw_core_get_type(pw_core *core);
1475 -pw_core * pw_core_new(pw_loop *main_loop, pw_properties *props);
1476 -
1477 -// loop.h
1478 -void pw_loop_destroy(pw_loop *loop);
1479 -pw_loop * pw_loop_new(pw_properties *properties);
1480 -
1481 -// pipewire.h
1482 -void pw_init(int *argc, char **argv[]);
1483 -
1484 -// properties.h
1485 -pw_properties * pw_properties_new_string(const char *args);
1486 -
1487 -// remote.h
1488 -void pw_remote_add_listener(pw_remote *remote, spa_hook *listener, const pw_remote_events *events, void *data);
1489 -int pw_remote_connect_fd(pw_remote *remote, int fd);
1490 -void pw_remote_destroy(pw_remote *remote);
1491 -pw_remote * pw_remote_new(pw_core *core, pw_properties *properties, size_t user_data_size);
1492 -
1493 -// stream.h
1494 -void pw_stream_add_listener(pw_stream *stream, spa_hook *listener, const pw_stream_events *events, void *data);
1495 -int pw_stream_connect(pw_stream *stream, enum pw_direction direction, const char *port_path, enum pw_stream_flags flags, const spa_pod **params, uint32_t n_params);
1496 -pw_buffer *pw_stream_dequeue_buffer(pw_stream *stream);
1497 -void pw_stream_destroy(pw_stream *stream);
1498 -void pw_stream_finish_format(pw_stream *stream, int res, const spa_pod **params, uint32_t n_params);
1499 -pw_stream * pw_stream_new(pw_remote *remote, const char *name, pw_properties *props);
1500 -int pw_stream_queue_buffer(pw_stream *stream, pw_buffer *buffer);
1501 -int pw_stream_set_active(pw_stream *stream, bool active);
1502 -
1503 -// thread-loop.h
1504 -void pw_thread_loop_destroy(pw_thread_loop *loop);
1505 -pw_thread_loop * pw_thread_loop_new(pw_loop *loop, const char *name);
1506 -int pw_thread_loop_start(pw_thread_loop *loop);
1507 -void pw_thread_loop_stop(pw_thread_loop *loop);
1508 diff --git a/chromium/third_party/webrtc/modules/desktop_capture/linux/screen_capturer_pipewire.cc b/chromium/third_party/webrtc/modules/desktop_capture/linux/screen_capturer_pipewire.cc
1509 deleted file mode 100644
1510 index fe672140cca..00000000000
1511 --- a/chromium/third_party/webrtc/modules/desktop_capture/linux/screen_capturer_pipewire.cc
1512 +++ /dev/null
1513 @@ -1,29 +0,0 @@
1514 -/*
1515 - *  Copyright 2018 The WebRTC project authors. All Rights Reserved.
1516 - *
1517 - *  Use of this source code is governed by a BSD-style license
1518 - *  that can be found in the LICENSE file in the root of the source
1519 - *  tree. An additional intellectual property rights grant can be found
1520 - *  in the file PATENTS.  All contributing project authors may
1521 - *  be found in the AUTHORS file in the root of the source tree.
1522 - */
1523 -
1524 -#include "modules/desktop_capture/linux/screen_capturer_pipewire.h"
1525 -
1526 -#include <memory>
1527 -
1528 -
1529 -namespace webrtc {
1530 -
1531 -ScreenCapturerPipeWire::ScreenCapturerPipeWire()
1532 -    : BaseCapturerPipeWire(BaseCapturerPipeWire::CaptureSourceType::Screen) {}
1533 -ScreenCapturerPipeWire::~ScreenCapturerPipeWire() {}
1534 -
1535 -// static
1536 -std::unique_ptr<DesktopCapturer>
1537 -ScreenCapturerPipeWire::CreateRawScreenCapturer(
1538 -    const DesktopCaptureOptions& options) {
1539 -  return std::make_unique<ScreenCapturerPipeWire>();
1540 -}
1541 -
1542 -}  // namespace webrtc
1543 diff --git a/chromium/third_party/webrtc/modules/desktop_capture/linux/screen_capturer_pipewire.h b/chromium/third_party/webrtc/modules/desktop_capture/linux/screen_capturer_pipewire.h
1544 deleted file mode 100644
1545 index 66dcd680e06..00000000000
1546 --- a/chromium/third_party/webrtc/modules/desktop_capture/linux/screen_capturer_pipewire.h
1547 +++ /dev/null
1548 @@ -1,33 +0,0 @@
1549 -/*
1550 - *  Copyright 2018 The WebRTC project authors. All Rights Reserved.
1551 - *
1552 - *  Use of this source code is governed by a BSD-style license
1553 - *  that can be found in the LICENSE file in the root of the source
1554 - *  tree. An additional intellectual property rights grant can be found
1555 - *  in the file PATENTS.  All contributing project authors may
1556 - *  be found in the AUTHORS file in the root of the source tree.
1557 - */
1558 -
1559 -#ifndef MODULES_DESKTOP_CAPTURE_LINUX_SCREEN_CAPTURER_PIPEWIRE_H_
1560 -#define MODULES_DESKTOP_CAPTURE_LINUX_SCREEN_CAPTURER_PIPEWIRE_H_
1561 -
1562 -#include <memory>
1563 -
1564 -#include "modules/desktop_capture/linux/base_capturer_pipewire.h"
1565 -
1566 -namespace webrtc {
1567 -
1568 -class ScreenCapturerPipeWire : public BaseCapturerPipeWire {
1569 - public:
1570 -  ScreenCapturerPipeWire();
1571 -  ~ScreenCapturerPipeWire() override;
1572 -
1573 -  static std::unique_ptr<DesktopCapturer> CreateRawScreenCapturer(
1574 -      const DesktopCaptureOptions& options);
1575 -
1576 -  RTC_DISALLOW_COPY_AND_ASSIGN(ScreenCapturerPipeWire);
1577 -};
1578 -
1579 -}  // namespace webrtc
1580 -
1581 -#endif  // MODULES_DESKTOP_CAPTURE_LINUX_SCREEN_CAPTURER_PIPEWIRE_H_
1582 diff --git a/chromium/third_party/webrtc/modules/desktop_capture/linux/window_capturer_pipewire.cc b/chromium/third_party/webrtc/modules/desktop_capture/linux/window_capturer_pipewire.cc
1583 deleted file mode 100644
1584 index b4559156dce..00000000000
1585 --- a/chromium/third_party/webrtc/modules/desktop_capture/linux/window_capturer_pipewire.cc
1586 +++ /dev/null
1587 @@ -1,29 +0,0 @@
1588 -/*
1589 - *  Copyright 2018 The WebRTC project authors. All Rights Reserved.
1590 - *
1591 - *  Use of this source code is governed by a BSD-style license
1592 - *  that can be found in the LICENSE file in the root of the source
1593 - *  tree. An additional intellectual property rights grant can be found
1594 - *  in the file PATENTS.  All contributing project authors may
1595 - *  be found in the AUTHORS file in the root of the source tree.
1596 - */
1597 -
1598 -#include "modules/desktop_capture/linux/window_capturer_pipewire.h"
1599 -
1600 -#include <memory>
1601 -
1602 -
1603 -namespace webrtc {
1604 -
1605 -WindowCapturerPipeWire::WindowCapturerPipeWire()
1606 -    : BaseCapturerPipeWire(BaseCapturerPipeWire::CaptureSourceType::Window) {}
1607 -WindowCapturerPipeWire::~WindowCapturerPipeWire() {}
1608 -
1609 -// static
1610 -std::unique_ptr<DesktopCapturer>
1611 -WindowCapturerPipeWire::CreateRawWindowCapturer(
1612 -    const DesktopCaptureOptions& options) {
1613 -  return std::make_unique<WindowCapturerPipeWire>();
1614 -}
1615 -
1616 -}  // namespace webrtc
1617 diff --git a/chromium/third_party/webrtc/modules/desktop_capture/linux/window_capturer_pipewire.h b/chromium/third_party/webrtc/modules/desktop_capture/linux/window_capturer_pipewire.h
1618 deleted file mode 100644
1619 index 7f184ef2999..00000000000
1620 --- a/chromium/third_party/webrtc/modules/desktop_capture/linux/window_capturer_pipewire.h
1621 +++ /dev/null
1622 @@ -1,33 +0,0 @@
1623 -/*
1624 - *  Copyright 2018 The WebRTC project authors. All Rights Reserved.
1625 - *
1626 - *  Use of this source code is governed by a BSD-style license
1627 - *  that can be found in the LICENSE file in the root of the source
1628 - *  tree. An additional intellectual property rights grant can be found
1629 - *  in the file PATENTS.  All contributing project authors may
1630 - *  be found in the AUTHORS file in the root of the source tree.
1631 - */
1632 -
1633 -#ifndef MODULES_DESKTOP_CAPTURE_LINUX_WINDOW_CAPTURER_PIPEWIRE_H_
1634 -#define MODULES_DESKTOP_CAPTURE_LINUX_WINDOW_CAPTURER_PIPEWIRE_H_
1635 -
1636 -#include <memory>
1637 -
1638 -#include "modules/desktop_capture/linux/base_capturer_pipewire.h"
1639 -
1640 -namespace webrtc {
1641 -
1642 -class WindowCapturerPipeWire : public BaseCapturerPipeWire {
1643 - public:
1644 -  WindowCapturerPipeWire();
1645 -  ~WindowCapturerPipeWire() override;
1646 -
1647 -  static std::unique_ptr<DesktopCapturer> CreateRawWindowCapturer(
1648 -      const DesktopCaptureOptions& options);
1649 -
1650 -  RTC_DISALLOW_COPY_AND_ASSIGN(WindowCapturerPipeWire);
1651 -};
1652 -
1653 -}  // namespace webrtc
1654 -
1655 -#endif  // MODULES_DESKTOP_CAPTURE_LINUX_WINDOW_CAPTURER_PIPEWIRE_H_
1656 diff --git a/chromium/third_party/webrtc/modules/desktop_capture/screen_capturer_linux.cc b/chromium/third_party/webrtc/modules/desktop_capture/screen_capturer_linux.cc
1657 index 82dbae48137..ed48b7d6d59 100644
1658 --- a/chromium/third_party/webrtc/modules/desktop_capture/screen_capturer_linux.cc
1659 +++ b/chromium/third_party/webrtc/modules/desktop_capture/screen_capturer_linux.cc
1660 @@ -14,7 +14,7 @@
1661  #include "modules/desktop_capture/desktop_capturer.h"
1662  
1663  #if defined(WEBRTC_USE_PIPEWIRE)
1664 -#include "modules/desktop_capture/linux/screen_capturer_pipewire.h"
1665 +#include "modules/desktop_capture/linux/base_capturer_pipewire.h"
1666  #endif  // defined(WEBRTC_USE_PIPEWIRE)
1667  
1668  #if defined(WEBRTC_USE_X11)
1669 @@ -28,7 +28,7 @@ std::unique_ptr<DesktopCapturer> DesktopCapturer::CreateRawScreenCapturer(
1670      const DesktopCaptureOptions& options) {
1671  #if defined(WEBRTC_USE_PIPEWIRE)
1672    if (options.allow_pipewire() && DesktopCapturer::IsRunningUnderWayland()) {
1673 -    return ScreenCapturerPipeWire::CreateRawScreenCapturer(options);
1674 +    return BaseCapturerPipeWire::CreateRawCapturer(options);
1675    }
1676  #endif  // defined(WEBRTC_USE_PIPEWIRE)
1677  
1678 diff --git a/chromium/third_party/webrtc/modules/desktop_capture/window_capturer_linux.cc b/chromium/third_party/webrtc/modules/desktop_capture/window_capturer_linux.cc
1679 index 41dbf836b03..2b142ae3b92 100644
1680 --- a/chromium/third_party/webrtc/modules/desktop_capture/window_capturer_linux.cc
1681 +++ b/chromium/third_party/webrtc/modules/desktop_capture/window_capturer_linux.cc
1682 @@ -14,7 +14,7 @@
1683  #include "modules/desktop_capture/desktop_capturer.h"
1684  
1685  #if defined(WEBRTC_USE_PIPEWIRE)
1686 -#include "modules/desktop_capture/linux/window_capturer_pipewire.h"
1687 +#include "modules/desktop_capture/linux/base_capturer_pipewire.h"
1688  #endif  // defined(WEBRTC_USE_PIPEWIRE)
1689  
1690  #if defined(WEBRTC_USE_X11)
1691 @@ -28,7 +28,7 @@ std::unique_ptr<DesktopCapturer> DesktopCapturer::CreateRawWindowCapturer(
1692      const DesktopCaptureOptions& options) {
1693  #if defined(WEBRTC_USE_PIPEWIRE)
1694    if (options.allow_pipewire() && DesktopCapturer::IsRunningUnderWayland()) {
1695 -    return WindowCapturerPipeWire::CreateRawWindowCapturer(options);
1696 +    return BaseCapturerPipeWire::CreateRawCapturer(options);
1697    }
1698  #endif  // defined(WEBRTC_USE_PIPEWIRE)
1699  
1700 diff --git a/chromium/third_party/webrtc/webrtc.gni b/chromium/third_party/webrtc/webrtc.gni
1701 index ca8acdbf259..505c975cece 100644
1702 --- a/chromium/third_party/webrtc/webrtc.gni
1703 +++ b/chromium/third_party/webrtc/webrtc.gni
1704 @@ -117,6 +117,10 @@ declare_args() {
1705    # Set this to link PipeWire directly instead of using the dlopen.
1706    rtc_link_pipewire = false
1707  
1708 +  # Set this to use certain PipeWire version
1709 +  # Currently we support PipeWire 0.2 (default) and PipeWire 0.3
1710 +  rtc_pipewire_version = "0.3"
1711 +
1712    # Enable to use the Mozilla internal settings.
1713    build_with_mozilla = false
1714  
1715 diff --git a/chromium/third_party/webrtc/modules/desktop_capture/linux/pipewire02.sigs b/chromium/third_party/webrtc/modules/desktop_capture/linux/pipewire02.sigs
1716 new file mode 100644
1717 index 00000000000..5ac3d1d22b8
1718 --- /dev/null
1719 +++ b/chromium/third_party/webrtc/modules/desktop_capture/linux/pipewire02.sigs
1720 @@ -0,0 +1,47 @@
1721 +// Copyright 2018 The WebRTC project authors. All rights reserved.
1722 +// Use of this source code is governed by a BSD-style license that can be
1723 +// found in the LICENSE file.
1724 +
1725 +//------------------------------------------------
1726 +// Functions from PipeWire used in capturer code.
1727 +//------------------------------------------------
1728 +
1729 +// core.h
1730 +void pw_core_destroy(pw_core *core);
1731 +pw_type *pw_core_get_type(pw_core *core);
1732 +pw_core * pw_core_new(pw_loop *main_loop, pw_properties *props);
1733 +
1734 +// loop.h
1735 +void pw_loop_destroy(pw_loop *loop);
1736 +pw_loop * pw_loop_new(pw_properties *properties);
1737 +
1738 +// pipewire.h
1739 +void pw_init(int *argc, char **argv[]);
1740 +
1741 +// properties.h
1742 +pw_properties * pw_properties_new_string(const char *args);
1743 +
1744 +// remote.h
1745 +void pw_remote_add_listener(pw_remote *remote, spa_hook *listener, const pw_remote_events *events, void *data);
1746 +int pw_remote_connect_fd(pw_remote *remote, int fd);
1747 +void pw_remote_destroy(pw_remote *remote);
1748 +pw_remote * pw_remote_new(pw_core *core, pw_properties *properties, size_t user_data_size);
1749 +enum pw_remote_state pw_remote_get_state(pw_remote *remote, const char **error);
1750 +
1751 +// stream.h
1752 +void pw_stream_add_listener(pw_stream *stream, spa_hook *listener, const pw_stream_events *events, void *data);
1753 +int pw_stream_connect(pw_stream *stream, enum pw_direction direction, const char *port_path, enum pw_stream_flags flags, const spa_pod **params, uint32_t n_params);
1754 +pw_buffer *pw_stream_dequeue_buffer(pw_stream *stream);
1755 +void pw_stream_destroy(pw_stream *stream);
1756 +void pw_stream_finish_format(pw_stream *stream, int res, const spa_pod **params, uint32_t n_params);
1757 +pw_stream * pw_stream_new(pw_remote *remote, const char *name, pw_properties *props);
1758 +int pw_stream_queue_buffer(pw_stream *stream, pw_buffer *buffer);
1759 +int pw_stream_set_active(pw_stream *stream, bool active);
1760 +
1761 +// thread-loop.h
1762 +void pw_thread_loop_destroy(pw_thread_loop *loop);
1763 +pw_thread_loop * pw_thread_loop_new(pw_loop *loop, const char *name);
1764 +int pw_thread_loop_start(pw_thread_loop *loop);
1765 +void pw_thread_loop_stop(pw_thread_loop *loop);
1766 +void pw_thread_loop_lock(struct pw_thread_loop *loop);
1767 +void pw_thread_loop_unlock(struct pw_thread_loop *loop);
1768 diff --git a/chromium/third_party/webrtc/modules/desktop_capture/linux/pipewire03.sigs b/chromium/third_party/webrtc/modules/desktop_capture/linux/pipewire03.sigs
1769 new file mode 100644
1770 index 00000000000..78d241f40c6
1771 --- /dev/null
1772 +++ b/chromium/third_party/webrtc/modules/desktop_capture/linux/pipewire03.sigs
1773 @@ -0,0 +1,46 @@
1774 +// Copyright 2018 The WebRTC project authors. All rights reserved.
1775 +// Use of this source code is governed by a BSD-style license that can be
1776 +// found in the LICENSE file.
1777 +
1778 +//------------------------------------------------
1779 +// Functions from PipeWire used in capturer code.
1780 +//------------------------------------------------
1781 +
1782 +// core.h
1783 +int pw_core_disconnect(pw_core *core);
1784 +
1785 +// loop.h
1786 +void pw_loop_destroy(pw_loop *loop);
1787 +pw_loop * pw_loop_new(const spa_dict *props);
1788 +
1789 +
1790 +// pipewire.h
1791 +void pw_init(int *argc, char **argv[]);
1792 +
1793 +// properties.h
1794 +pw_properties * pw_properties_new_string(const char *args);
1795 +
1796 +// stream.h
1797 +void pw_stream_add_listener(pw_stream *stream, spa_hook *listener, const pw_stream_events *events, void *data);
1798 +int pw_stream_connect(pw_stream *stream, enum pw_direction direction, uint32_t target_id, enum pw_stream_flags flags, const spa_pod **params, uint32_t n_params);
1799 +pw_buffer *pw_stream_dequeue_buffer(pw_stream *stream);
1800 +void pw_stream_destroy(pw_stream *stream);
1801 +pw_stream * pw_stream_new(pw_core *core, const char *name, pw_properties *props);
1802 +int pw_stream_queue_buffer(pw_stream *stream, pw_buffer *buffer);
1803 +int pw_stream_set_active(pw_stream *stream, bool active);
1804 +int pw_stream_update_params(pw_stream *stream, const spa_pod **params, uint32_t n_params);
1805 +
1806 +// thread-loop.h
1807 +void pw_thread_loop_destroy(pw_thread_loop *loop);
1808 +pw_thread_loop * pw_thread_loop_new(const char *name, const spa_dict *props);
1809 +int pw_thread_loop_start(pw_thread_loop *loop);
1810 +void pw_thread_loop_stop(pw_thread_loop *loop);
1811 +void pw_thread_loop_lock(pw_thread_loop *loop);
1812 +void pw_thread_loop_unlock(pw_thread_loop *loop);
1813 +pw_loop * pw_thread_loop_get_loop(pw_thread_loop *loop);
1814 +
1815 +
1816 +// context.h
1817 +void pw_context_destroy(pw_context *context);
1818 +pw_context *pw_context_new(pw_loop *main_loop, pw_properties *props, size_t user_data_size);
1819 +pw_core * pw_context_connect(pw_context *context, pw_properties *properties, size_t user_data_size);
This page took 0.211569 seconds and 3 git commands to generate.