|
1 # HG changeset patch |
|
2 # Parent f530b1587cd1c0a79c34f91a9690c4cc4c33ac31 |
|
3 |
1 diff --git a/config/system-headers.mozbuild b/config/system-headers.mozbuild |
4 diff --git a/config/system-headers.mozbuild b/config/system-headers.mozbuild |
2 index 2081d0c683a4..641133bf1ea4 100644 |
|
3 --- a/config/system-headers.mozbuild |
5 --- a/config/system-headers.mozbuild |
4 +++ b/config/system-headers.mozbuild |
6 +++ b/config/system-headers.mozbuild |
5 @@ -314,6 +314,7 @@ system_headers = [ |
7 @@ -309,16 +309,17 @@ system_headers = [ |
|
8 'gdk/gdkkeysyms.h', |
|
9 'gdk/gdkprivate.h', |
|
10 'gdk/gdkwayland.h', |
|
11 'gdk/gdkx.h', |
|
12 'gdk-pixbuf/gdk-pixbuf.h', |
6 'Gestalt.h', |
13 'Gestalt.h', |
7 'getopt.h', |
14 'getopt.h', |
8 'gio/gio.h', |
15 'gio/gio.h', |
9 + 'gio/gunixfdlist.h', |
16 + 'gio/gunixfdlist.h', |
10 'glibconfig.h', |
17 'glibconfig.h', |
11 'glib.h', |
18 'glib.h', |
12 'glib-object.h', |
19 'glib-object.h', |
13 @@ -607,6 +608,7 @@ system_headers = [ |
20 'glob.h', |
|
21 'gmodule.h', |
|
22 'gnome.h', |
|
23 'gnu/libc-version.h', |
|
24 'gps.h', |
|
25 @@ -602,16 +603,17 @@ system_headers = [ |
|
26 'pango/pangoxft.h', |
|
27 'pascal.h', |
|
28 'Patches.h', |
|
29 'Path.h', |
|
30 'pcfs/pc_dir.h', |
14 'Pgenerr.h', |
31 'Pgenerr.h', |
15 'PGenErr.h', |
32 'PGenErr.h', |
16 'Ph.h', |
33 'Ph.h', |
17 + 'pipewire/pipewire.h', |
34 + 'pipewire/pipewire.h', |
18 'pixman.h', |
35 'pixman.h', |
19 'pk11func.h', |
36 'pk11func.h', |
20 'pk11pqg.h', |
37 'pk11pqg.h', |
|
38 'pk11priv.h', |
|
39 'pk11pub.h', |
|
40 'pk11sdr.h', |
|
41 'pkcs11f.h', |
|
42 'pkcs11.h', |
21 diff --git a/media/webrtc/trunk/webrtc/modules/desktop_capture/BUILD.gn b/media/webrtc/trunk/webrtc/modules/desktop_capture/BUILD.gn |
43 diff --git a/media/webrtc/trunk/webrtc/modules/desktop_capture/BUILD.gn b/media/webrtc/trunk/webrtc/modules/desktop_capture/BUILD.gn |
22 index ba885217b3ba..201d3b755221 100644 |
|
23 --- a/media/webrtc/trunk/webrtc/modules/desktop_capture/BUILD.gn |
44 --- a/media/webrtc/trunk/webrtc/modules/desktop_capture/BUILD.gn |
24 +++ b/media/webrtc/trunk/webrtc/modules/desktop_capture/BUILD.gn |
45 +++ b/media/webrtc/trunk/webrtc/modules/desktop_capture/BUILD.gn |
25 @@ -158,7 +158,7 @@ if (rtc_include_tests) { |
46 @@ -153,17 +153,17 @@ if (rtc_include_tests) { |
|
47 "../../test:test_support", |
|
48 ] |
|
49 } |
|
50 } |
|
51 |
26 if (is_linux) { |
52 if (is_linux) { |
27 if (rtc_use_pipewire) { |
53 if (rtc_use_pipewire) { |
28 pkg_config("pipewire") { |
54 pkg_config("pipewire") { |
29 - packages = [ "libpipewire-0.2" ] |
55 - packages = [ "libpipewire-0.2" ] |
30 + packages = [ "libpipewire-0.3" ] |
56 + packages = [ "libpipewire-0.3" ] |
31 |
57 |
32 defines = [ "WEBRTC_USE_PIPEWIRE" ] |
58 defines = [ "WEBRTC_USE_PIPEWIRE" ] |
33 } |
59 } |
|
60 |
|
61 pkg_config("gio") { |
|
62 packages = [ |
|
63 "gio-2.0", |
|
64 "gio-unix-2.0", |
34 diff --git a/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capture_generic_gn/moz.build b/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capture_generic_gn/moz.build |
65 diff --git a/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capture_generic_gn/moz.build b/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capture_generic_gn/moz.build |
35 index 90b40431c7e4..d844aa79d591 100644 |
|
36 --- a/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capture_generic_gn/moz.build |
66 --- a/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capture_generic_gn/moz.build |
37 +++ b/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capture_generic_gn/moz.build |
67 +++ b/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capture_generic_gn/moz.build |
38 @@ -194,6 +194,30 @@ if CONFIG["OS_TARGET"] == "Linux": |
68 @@ -289,16 +289,40 @@ if CONFIG["OS_TARGET"] == "WINNT": |
39 "/media/webrtc/trunk/webrtc/modules/desktop_capture/window_capturer_linux.cc" |
69 "/media/webrtc/trunk/webrtc/modules/desktop_capture/win/screen_capturer_win_directx.cc", |
|
70 "/media/webrtc/trunk/webrtc/modules/desktop_capture/win/screen_capturer_win_magnifier.cc", |
|
71 "/media/webrtc/trunk/webrtc/modules/desktop_capture/win/win_shared.cc", |
|
72 "/media/webrtc/trunk/webrtc/modules/desktop_capture/win/window_capture_utils.cc", |
|
73 "/media/webrtc/trunk/webrtc/modules/desktop_capture/window_capturer_win.cc", |
|
74 "/media/webrtc/trunk/webrtc/modules/desktop_capture/window_finder_win.cc" |
40 ] |
75 ] |
41 |
76 |
42 +# PipeWire specific files |
77 +# PipeWire specific files |
43 +if CONFIG["OS_TARGET"] == "Linux": |
78 +if CONFIG["OS_TARGET"] == "Linux": |
44 + |
79 + |
64 + |
99 + |
65 + |
100 + |
66 if CONFIG["OS_TARGET"] == "NetBSD": |
101 if CONFIG["OS_TARGET"] == "NetBSD": |
67 |
102 |
68 DEFINES["USE_X11"] = "1" |
103 DEFINES["USE_X11"] = "1" |
|
104 DEFINES["WEBRTC_BSD"] = True |
|
105 DEFINES["WEBRTC_POSIX"] = True |
|
106 DEFINES["_FILE_OFFSET_BITS"] = "64" |
|
107 |
|
108 OS_LIBS += [ |
69 diff --git a/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capture_options.h b/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capture_options.h |
109 diff --git a/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capture_options.h b/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capture_options.h |
70 index 1eb8ead26efa..316468eed1fc 100644 |
|
71 --- a/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capture_options.h |
110 --- a/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capture_options.h |
72 +++ b/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capture_options.h |
111 +++ b/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capture_options.h |
73 @@ -141,7 +141,7 @@ class DesktopCaptureOptions { |
112 @@ -136,15 +136,15 @@ class DesktopCaptureOptions { |
|
113 #if defined(USE_X11) |
|
114 bool use_update_notifications_ = false; |
|
115 #else |
|
116 bool use_update_notifications_ = true; |
|
117 #endif |
74 bool disable_effects_ = true; |
118 bool disable_effects_ = true; |
75 bool detect_updated_region_ = false; |
119 bool detect_updated_region_ = false; |
76 #if defined(WEBRTC_USE_PIPEWIRE) |
120 #if defined(WEBRTC_USE_PIPEWIRE) |
77 - bool allow_pipewire_ = false; |
121 - bool allow_pipewire_ = false; |
78 + bool allow_pipewire_ = true; |
122 + bool allow_pipewire_ = true; |
79 #endif |
123 #endif |
80 }; |
124 }; |
81 |
125 |
|
126 } // namespace webrtc |
|
127 |
|
128 #endif // MODULES_DESKTOP_CAPTURE_DESKTOP_CAPTURE_OPTIONS_H_ |
82 diff --git a/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.cc b/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.cc |
129 diff --git a/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.cc b/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.cc |
83 index 379341c833de..76349f1fbd4d 100644 |
|
84 --- a/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.cc |
130 --- a/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.cc |
85 +++ b/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.cc |
131 +++ b/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.cc |
86 @@ -15,8 +15,11 @@ |
132 @@ -10,18 +10,21 @@ |
|
133 |
|
134 #include "modules/desktop_capture/linux/base_capturer_pipewire.h" |
|
135 |
|
136 #include <gio/gunixfdlist.h> |
|
137 #include <glib-object.h> |
87 |
138 |
88 #include <spa/param/format-utils.h> |
139 #include <spa/param/format-utils.h> |
89 #include <spa/param/props.h> |
140 #include <spa/param/props.h> |
90 -#include <spa/param/video/raw-utils.h> |
141 -#include <spa/param/video/raw-utils.h> |
91 -#include <spa/support/type-map.h> |
142 -#include <spa/support/type-map.h> |
95 +#include <sys/ioctl.h> |
146 +#include <sys/ioctl.h> |
96 +#include <sys/syscall.h> |
147 +#include <sys/syscall.h> |
97 |
148 |
98 #include <memory> |
149 #include <memory> |
99 #include <utility> |
150 #include <utility> |
100 @@ -36,31 +39,36 @@ const char kSessionInterfaceName[] = "org.freedesktop.portal.Session"; |
151 |
|
152 #include "modules/desktop_capture/desktop_capture_options.h" |
|
153 #include "modules/desktop_capture/desktop_capturer.h" |
|
154 #include "rtc_base/checks.h" |
|
155 #include "rtc_base/logging.h" |
|
156 @@ -31,181 +34,158 @@ namespace webrtc { |
|
157 const char kDesktopBusName[] = "org.freedesktop.portal.Desktop"; |
|
158 const char kDesktopObjectPath[] = "/org/freedesktop/portal/desktop"; |
|
159 const char kDesktopRequestObjectPath[] = |
|
160 "/org/freedesktop/portal/desktop/request"; |
|
161 const char kSessionInterfaceName[] = "org.freedesktop.portal.Session"; |
101 const char kRequestInterfaceName[] = "org.freedesktop.portal.Request"; |
162 const char kRequestInterfaceName[] = "org.freedesktop.portal.Request"; |
102 const char kScreenCastInterfaceName[] = "org.freedesktop.portal.ScreenCast"; |
163 const char kScreenCastInterfaceName[] = "org.freedesktop.portal.ScreenCast"; |
103 |
164 |
104 -// static |
165 + |
|
166 // static |
105 -void BaseCapturerPipeWire::OnStateChanged(void* data, |
167 -void BaseCapturerPipeWire::OnStateChanged(void* data, |
106 - pw_remote_state old_state, |
168 - pw_remote_state old_state, |
107 - pw_remote_state state, |
169 - pw_remote_state state, |
108 - const char* error_message) { |
170 - const char* error_message) { |
109 - BaseCapturerPipeWire* that = static_cast<BaseCapturerPipeWire*>(data); |
171 - BaseCapturerPipeWire* that = static_cast<BaseCapturerPipeWire*>(data); |
110 - RTC_DCHECK(that); |
172 - RTC_DCHECK(that); |
|
173 +void BaseCapturerPipeWire::SyncDmaBuf(int fd, uint64_t start_or_end) { |
|
174 + struct dma_buf_sync sync = { 0 }; |
|
175 + |
|
176 + sync.flags = start_or_end | DMA_BUF_SYNC_READ; |
111 |
177 |
112 - switch (state) { |
178 - switch (state) { |
113 - case PW_REMOTE_STATE_ERROR: |
179 - case PW_REMOTE_STATE_ERROR: |
114 - RTC_LOG(LS_ERROR) << "PipeWire remote state error: " << error_message; |
180 - RTC_LOG(LS_ERROR) << "PipeWire remote state error: " << error_message; |
115 - break; |
|
116 - case PW_REMOTE_STATE_CONNECTED: |
|
117 - RTC_LOG(LS_INFO) << "PipeWire remote state: connected."; |
|
118 - that->CreateReceivingStream(); |
|
119 - break; |
|
120 - case PW_REMOTE_STATE_CONNECTING: |
|
121 - RTC_LOG(LS_INFO) << "PipeWire remote state: connecting."; |
|
122 +// static |
|
123 +void BaseCapturerPipeWire::SyncDmaBuf(int fd, uint64_t start_or_end) { |
|
124 + struct dma_buf_sync sync = { 0 }; |
|
125 + |
|
126 + sync.flags = start_or_end | DMA_BUF_SYNC_READ; |
|
127 + |
|
128 + while(true) { |
181 + while(true) { |
129 + int ret; |
182 + int ret; |
130 + ret = ioctl (fd, DMA_BUF_IOCTL_SYNC, &sync); |
183 + ret = ioctl (fd, DMA_BUF_IOCTL_SYNC, &sync); |
131 + if (ret == -1 && errno == EINTR) { |
184 + if (ret == -1 && errno == EINTR) { |
132 + continue; |
185 + continue; |
133 + } else if (ret == -1) { |
186 + } else if (ret == -1) { |
134 + RTC_LOG(LS_ERROR) << "Failed to synchronize DMA buffer: " << g_strerror(errno); |
187 + RTC_LOG(LS_ERROR) << "Failed to synchronize DMA buffer: " << g_strerror(errno); |
135 break; |
188 break; |
|
189 - case PW_REMOTE_STATE_CONNECTED: |
|
190 - RTC_LOG(LS_INFO) << "PipeWire remote state: connected."; |
|
191 - that->CreateReceivingStream(); |
|
192 + } else { |
|
193 break; |
|
194 - case PW_REMOTE_STATE_CONNECTING: |
|
195 - RTC_LOG(LS_INFO) << "PipeWire remote state: connecting."; |
|
196 - break; |
136 - case PW_REMOTE_STATE_UNCONNECTED: |
197 - case PW_REMOTE_STATE_UNCONNECTED: |
137 - RTC_LOG(LS_INFO) << "PipeWire remote state: unconnected."; |
198 - RTC_LOG(LS_INFO) << "PipeWire remote state: unconnected."; |
138 + } else { |
199 - break; |
139 break; |
|
140 + } |
200 + } |
141 } |
201 } |
142 } |
202 } |
143 |
203 |
144 +// static |
204 // static |
145 +void BaseCapturerPipeWire::OnCoreError(void *data, |
205 +void BaseCapturerPipeWire::OnCoreError(void *data, |
146 + uint32_t id, |
206 + uint32_t id, |
147 + int seq, |
207 + int seq, |
148 + int res, |
208 + int res, |
149 + const char *message) { |
209 + const char *message) { |
150 + RTC_LOG(LS_ERROR) << "core error: " << message; |
210 + RTC_LOG(LS_ERROR) << "core error: " << message; |
151 +} |
211 +} |
152 + |
212 + |
153 // static |
213 +// static |
154 void BaseCapturerPipeWire::OnStreamStateChanged(void* data, |
214 void BaseCapturerPipeWire::OnStreamStateChanged(void* data, |
155 pw_stream_state old_state, |
215 pw_stream_state old_state, |
156 @@ -73,76 +81,54 @@ void BaseCapturerPipeWire::OnStreamStateChanged(void* data, |
216 pw_stream_state state, |
|
217 const char* error_message) { |
|
218 BaseCapturerPipeWire* that = static_cast<BaseCapturerPipeWire*>(data); |
|
219 RTC_DCHECK(that); |
|
220 |
|
221 switch (state) { |
157 case PW_STREAM_STATE_ERROR: |
222 case PW_STREAM_STATE_ERROR: |
158 RTC_LOG(LS_ERROR) << "PipeWire stream state error: " << error_message; |
223 RTC_LOG(LS_ERROR) << "PipeWire stream state error: " << error_message; |
159 break; |
224 break; |
160 - case PW_STREAM_STATE_CONFIGURE: |
225 - case PW_STREAM_STATE_CONFIGURE: |
161 - pw_stream_set_active(that->pw_stream_, true); |
226 - pw_stream_set_active(that->pw_stream_, true); |
162 - break; |
227 - break; |
163 - case PW_STREAM_STATE_UNCONNECTED: |
228 + case PW_STREAM_STATE_PAUSED: |
164 - case PW_STREAM_STATE_CONNECTING: |
229 + case PW_STREAM_STATE_STREAMING: |
|
230 case PW_STREAM_STATE_UNCONNECTED: |
|
231 case PW_STREAM_STATE_CONNECTING: |
165 - case PW_STREAM_STATE_READY: |
232 - case PW_STREAM_STATE_READY: |
166 case PW_STREAM_STATE_PAUSED: |
233 - case PW_STREAM_STATE_PAUSED: |
167 case PW_STREAM_STATE_STREAMING: |
234 - case PW_STREAM_STATE_STREAMING: |
168 + case PW_STREAM_STATE_UNCONNECTED: |
|
169 + case PW_STREAM_STATE_CONNECTING: |
|
170 break; |
235 break; |
171 } |
236 } |
172 } |
237 } |
173 |
238 |
174 // static |
239 // static |
254 + SPA_PARAM_META_size, SPA_POD_Int (sizeof(struct spa_meta_region)))); |
319 + SPA_PARAM_META_size, SPA_POD_Int (sizeof(struct spa_meta_region)))); |
255 + pw_stream_update_params(that->pw_stream_, params, 3); |
320 + pw_stream_update_params(that->pw_stream_, params, 3); |
256 } |
321 } |
257 |
322 |
258 // static |
323 // static |
259 @@ -150,15 +136,25 @@ void BaseCapturerPipeWire::OnStreamProcess(void* data) { |
324 void BaseCapturerPipeWire::OnStreamProcess(void* data) { |
260 BaseCapturerPipeWire* that = static_cast<BaseCapturerPipeWire*>(data); |
325 BaseCapturerPipeWire* that = static_cast<BaseCapturerPipeWire*>(data); |
261 RTC_DCHECK(that); |
326 RTC_DCHECK(that); |
262 |
327 |
263 - pw_buffer* buf = nullptr; |
328 - pw_buffer* buf = nullptr; |
264 + struct pw_buffer *next_buffer; |
329 + struct pw_buffer *next_buffer; |
265 + struct pw_buffer *buffer = nullptr; |
330 + struct pw_buffer *buffer = nullptr; |
266 + |
331 |
|
332 - if (!(buf = pw_stream_dequeue_buffer(that->pw_stream_))) { |
267 + next_buffer = pw_stream_dequeue_buffer(that->pw_stream_); |
333 + next_buffer = pw_stream_dequeue_buffer(that->pw_stream_); |
268 + while (next_buffer) { |
334 + while (next_buffer) { |
269 + buffer = next_buffer; |
335 + buffer = next_buffer; |
270 + next_buffer = pw_stream_dequeue_buffer(that->pw_stream_); |
336 + next_buffer = pw_stream_dequeue_buffer(that->pw_stream_); |
271 |
337 + |
272 - if (!(buf = pw_stream_dequeue_buffer(that->pw_stream_))) { |
|
273 + if (next_buffer) |
338 + if (next_buffer) |
274 + pw_stream_queue_buffer (that->pw_stream_, buffer); |
339 + pw_stream_queue_buffer (that->pw_stream_, buffer); |
275 + } |
340 + } |
276 + |
341 + |
277 + if (!buffer) { |
342 + if (!buffer) { |
327 - } |
395 - } |
328 - |
396 - |
329 if (start_request_signal_id_) { |
397 if (start_request_signal_id_) { |
330 g_dbus_connection_signal_unsubscribe(connection_, start_request_signal_id_); |
398 g_dbus_connection_signal_unsubscribe(connection_, start_request_signal_id_); |
331 } |
399 } |
332 @@ -250,27 +230,35 @@ void BaseCapturerPipeWire::InitPortal() { |
400 if (sources_request_signal_id_) { |
|
401 g_dbus_connection_signal_unsubscribe(connection_, |
|
402 sources_request_signal_id_); |
|
403 } |
|
404 if (session_request_signal_id_) { |
|
405 @@ -245,142 +225,220 @@ void BaseCapturerPipeWire::InitPortal() |
|
406 kDesktopBusName, kDesktopObjectPath, kScreenCastInterfaceName, |
|
407 /*cancellable=*/nullptr, |
|
408 reinterpret_cast<GAsyncReadyCallback>(OnProxyRequested), this); |
|
409 } |
|
410 |
333 void BaseCapturerPipeWire::InitPipeWire() { |
411 void BaseCapturerPipeWire::InitPipeWire() { |
334 pw_init(/*argc=*/nullptr, /*argc=*/nullptr); |
412 pw_init(/*argc=*/nullptr, /*argc=*/nullptr); |
335 |
413 |
336 - pw_loop_ = pw_loop_new(/*properties=*/nullptr); |
414 - pw_loop_ = pw_loop_new(/*properties=*/nullptr); |
337 - pw_main_loop_ = pw_thread_loop_new(pw_loop_, "pipewire-main-loop"); |
415 - pw_main_loop_ = pw_thread_loop_new(pw_loop_, "pipewire-main-loop"); |
338 - |
|
339 - pw_core_ = pw_core_new(pw_loop_, /*properties=*/nullptr); |
|
340 - pw_core_type_ = pw_core_get_type(pw_core_); |
|
341 - pw_remote_ = pw_remote_new(pw_core_, nullptr, /*user_data_size=*/0); |
|
342 + pw_main_loop_ = pw_thread_loop_new("pipewire-main-loop", nullptr); |
416 + pw_main_loop_ = pw_thread_loop_new("pipewire-main-loop", nullptr); |
343 + pw_context_ = pw_context_new(pw_thread_loop_get_loop(pw_main_loop_), nullptr, 0); |
417 + pw_context_ = pw_context_new(pw_thread_loop_get_loop(pw_main_loop_), nullptr, 0); |
344 + if (!pw_context_) { |
418 + if (!pw_context_) { |
345 + RTC_LOG(LS_ERROR) << "Failed to create PipeWire context"; |
419 + RTC_LOG(LS_ERROR) << "Failed to create PipeWire context"; |
346 + return; |
420 + return; |
347 + } |
421 + } |
348 |
422 |
|
423 - pw_core_ = pw_core_new(pw_loop_, /*properties=*/nullptr); |
|
424 - pw_core_type_ = pw_core_get_type(pw_core_); |
|
425 - pw_remote_ = pw_remote_new(pw_core_, nullptr, /*user_data_size=*/0); |
|
426 - |
349 - InitPipeWireTypes(); |
427 - InitPipeWireTypes(); |
350 + pw_core_ = pw_context_connect(pw_context_, nullptr, 0); |
428 + pw_core_ = pw_context_connect(pw_context_, nullptr, 0); |
351 + if (!pw_core_) { |
429 + if (!pw_core_) { |
352 + RTC_LOG(LS_ERROR) << "Failed to connect PipeWire context"; |
430 + RTC_LOG(LS_ERROR) << "Failed to connect PipeWire context"; |
353 + return; |
431 + return; |
389 - spa_type_media_type_map(map, &pw_type_->media_type); |
467 - spa_type_media_type_map(map, &pw_type_->media_type); |
390 - spa_type_media_subtype_map(map, &pw_type_->media_subtype); |
468 - spa_type_media_subtype_map(map, &pw_type_->media_subtype); |
391 - spa_type_format_video_map(map, &pw_type_->format_video); |
469 - spa_type_format_video_map(map, &pw_type_->format_video); |
392 - spa_type_video_format_map(map, &pw_type_->video_format); |
470 - spa_type_video_format_map(map, &pw_type_->video_format); |
393 -} |
471 -} |
394 - |
472 +pw_stream* BaseCapturerPipeWire::CreateReceivingStream() { |
|
473 + spa_rectangle pwMinScreenBounds = spa_rectangle{1, 1}; |
|
474 + spa_rectangle pwMaxScreenBounds = spa_rectangle{INT32_MAX, INT32_MAX}; |
|
475 |
395 -void BaseCapturerPipeWire::CreateReceivingStream() { |
476 -void BaseCapturerPipeWire::CreateReceivingStream() { |
396 +pw_stream* BaseCapturerPipeWire::CreateReceivingStream() { |
477 - spa_rectangle pwMinScreenBounds = spa_rectangle{1, 1}; |
397 spa_rectangle pwMinScreenBounds = spa_rectangle{1, 1}; |
|
398 - spa_rectangle pwScreenBounds = |
478 - spa_rectangle pwScreenBounds = |
399 - spa_rectangle{static_cast<uint32_t>(desktop_size_.width()), |
479 - spa_rectangle{static_cast<uint32_t>(desktop_size_.width()), |
400 - static_cast<uint32_t>(desktop_size_.height())}; |
480 - static_cast<uint32_t>(desktop_size_.height())}; |
401 + spa_rectangle pwMaxScreenBounds = spa_rectangle{INT32_MAX, INT32_MAX}; |
481 + auto stream = pw_stream_new(pw_core_, "webrtc-pipewire-stream", nullptr); |
402 |
482 |
403 - spa_fraction pwFrameRateMin = spa_fraction{0, 1}; |
483 - spa_fraction pwFrameRateMin = spa_fraction{0, 1}; |
404 - spa_fraction pwFrameRateMax = spa_fraction{60, 1}; |
484 - spa_fraction pwFrameRateMax = spa_fraction{60, 1}; |
405 + auto stream = pw_stream_new(pw_core_, "webrtc-pipewire-stream", nullptr); |
485 - |
406 |
|
407 - pw_properties* reuseProps = pw_properties_new("pipewire.client.reuse", "1", |
486 - pw_properties* reuseProps = pw_properties_new("pipewire.client.reuse", "1", |
408 - /*end of varargs*/ nullptr); |
487 - /*end of varargs*/ nullptr); |
409 - pw_stream_ = pw_stream_new(pw_remote_, "webrtc-consume-stream", reuseProps); |
488 - pw_stream_ = pw_stream_new(pw_remote_, "webrtc-consume-stream", reuseProps); |
410 + if (!stream) { |
489 + if (!stream) { |
411 + RTC_LOG(LS_ERROR) << "Could not create receiving stream."; |
490 + RTC_LOG(LS_ERROR) << "Could not create receiving stream."; |
437 - // Max frame rate: specified as fraction (F), preferred frame rate is set |
516 - // Max frame rate: specified as fraction (F), preferred frame rate is set |
438 - // to maximum value, then allowed frame rate is defined as range (r) from |
517 - // to maximum value, then allowed frame rate is defined as range (r) from |
439 - // min and max values and it is undecided (u) to allow negotiation |
518 - // min and max values and it is undecided (u) to allow negotiation |
440 - ":", pw_type_->format_video.max_framerate, "Fru", &pwFrameRateMax, 2, |
519 - ":", pw_type_->format_video.max_framerate, "Fru", &pwFrameRateMax, 2, |
441 - &pwFrameRateMin, &pwFrameRateMax)); |
520 - &pwFrameRateMin, &pwFrameRateMax)); |
442 - |
521 + const spa_pod* params[2]; |
|
522 + spa_pod_builder builder = SPA_POD_BUILDER_INIT(buffer, sizeof (buffer)); |
|
523 |
443 - pw_stream_add_listener(pw_stream_, &spa_stream_listener_, &pw_stream_events_, |
524 - pw_stream_add_listener(pw_stream_, &spa_stream_listener_, &pw_stream_events_, |
444 - this); |
525 - this); |
445 + const spa_pod* params[2]; |
|
446 + spa_pod_builder builder = SPA_POD_BUILDER_INIT(buffer, sizeof (buffer)); |
|
447 + |
|
448 + params[0] = reinterpret_cast<spa_pod *>(spa_pod_builder_add_object(&builder, |
526 + params[0] = reinterpret_cast<spa_pod *>(spa_pod_builder_add_object(&builder, |
449 + SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat, |
527 + SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat, |
450 + SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_video), |
528 + SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_video), |
451 + SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_raw), |
529 + SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_raw), |
452 + SPA_FORMAT_VIDEO_format, SPA_POD_CHOICE_ENUM_Id(5, SPA_VIDEO_FORMAT_BGRx, SPA_VIDEO_FORMAT_RGBx, SPA_VIDEO_FORMAT_RGBA, |
530 + SPA_FORMAT_VIDEO_format, SPA_POD_CHOICE_ENUM_Id(5, SPA_VIDEO_FORMAT_BGRx, SPA_VIDEO_FORMAT_RGBx, SPA_VIDEO_FORMAT_RGBA, |
492 + |
570 + |
493 + if (map == MAP_FAILED) { |
571 + if (map == MAP_FAILED) { |
494 + RTC_LOG(LS_ERROR) << "Failed to mmap the memory: " << std::strerror(errno); |
572 + RTC_LOG(LS_ERROR) << "Failed to mmap the memory: " << std::strerror(errno); |
495 + return; |
573 + return; |
496 + } |
574 + } |
497 + |
575 |
|
576 - if (!(src = spaBuffer->datas[0].data)) { |
498 + src = SPA_MEMBER(map, spaBuffer->datas[0].mapoffset, uint8_t); |
577 + src = SPA_MEMBER(map, spaBuffer->datas[0].mapoffset, uint8_t); |
499 + } else if (spaBuffer->datas[0].type == SPA_DATA_DmaBuf) { |
578 + } else if (spaBuffer->datas[0].type == SPA_DATA_DmaBuf) { |
500 + int fd; |
579 + int fd; |
501 + fd = spaBuffer->datas[0].fd; |
580 + fd = spaBuffer->datas[0].fd; |
502 |
581 + |
503 - if (!(src = spaBuffer->datas[0].data)) { |
|
504 + map = static_cast<uint8_t*>(mmap( |
582 + map = static_cast<uint8_t*>(mmap( |
505 + nullptr, spaBuffer->datas[0].maxsize + spaBuffer->datas[0].mapoffset, |
583 + nullptr, spaBuffer->datas[0].maxsize + spaBuffer->datas[0].mapoffset, |
506 + PROT_READ, MAP_PRIVATE, fd, 0)); |
584 + PROT_READ, MAP_PRIVATE, fd, 0)); |
507 + |
585 + |
508 + if (map == MAP_FAILED) { |
586 + if (map == MAP_FAILED) { |
567 + const int32_t srcStride = spaBuffer->datas[0].chunk->stride; |
645 + const int32_t srcStride = spaBuffer->datas[0].chunk->stride; |
568 + |
646 + |
569 if (srcStride != (desktop_size_.width() * kBytesPerPixel)) { |
647 if (srcStride != (desktop_size_.width() * kBytesPerPixel)) { |
570 RTC_LOG(LS_ERROR) << "Got buffer with stride different from screen stride: " |
648 RTC_LOG(LS_ERROR) << "Got buffer with stride different from screen stride: " |
571 << srcStride |
649 << srcStride |
572 @@ -361,21 +400,40 @@ void BaseCapturerPipeWire::HandleBuffer(pw_buffer* buffer) { |
650 << " != " << (desktop_size_.width() * kBytesPerPixel); |
|
651 portal_init_failed_ = true; |
573 return; |
652 return; |
574 } |
653 } |
575 |
654 |
576 - if (!current_frame_) { |
655 - if (!current_frame_) { |
577 - current_frame_ = static_cast<uint8_t*>(malloc(maxSize)); |
656 - current_frame_ = static_cast<uint8_t*>(malloc(maxSize)); |
|
657 - } |
|
658 - RTC_DCHECK(current_frame_ != nullptr); |
578 + dst = current_frame_.get(); |
659 + dst = current_frame_.get(); |
579 + |
660 |
|
661 - // If both sides decided to go with the RGBx format we need to convert it to |
|
662 - // BGRx to match color format expected by WebRTC. |
|
663 - if (spa_video_format_->format == pw_type_->video_format.RGBx) { |
|
664 - uint8_t* tempFrame = static_cast<uint8_t*>(malloc(maxSize)); |
|
665 - std::memcpy(tempFrame, src, maxSize); |
|
666 - ConvertRGBxToBGRx(tempFrame, maxSize); |
|
667 - std::memcpy(current_frame_, tempFrame, maxSize); |
|
668 - free(tempFrame); |
|
669 - } else { |
|
670 - std::memcpy(current_frame_, src, maxSize); |
580 + // Adjust source content based on crop video position |
671 + // Adjust source content based on crop video position |
581 + if (video_crop_size_initialized_ && |
672 + if (video_crop_size_initialized_ && |
582 + (video_crop->region.position.y + video_crop_size_.height() <= desktop_size_.height())) { |
673 + (video_crop->region.position.y + video_crop_size_.height() <= desktop_size_.height())) { |
583 + for (int i = 0; i < video_crop->region.position.y; ++i) { |
674 + for (int i = 0; i < video_crop->region.position.y; ++i) { |
584 + src += srcStride; |
675 + src += srcStride; |
600 + spa_video_format_.format == SPA_VIDEO_FORMAT_RGBA) { |
691 + spa_video_format_.format == SPA_VIDEO_FORMAT_RGBA) { |
601 + ConvertRGBxToBGRx(dst, dstStride); |
692 + ConvertRGBxToBGRx(dst, dstStride); |
602 + } |
693 + } |
603 + src += srcStride - xOffset; |
694 + src += srcStride - xOffset; |
604 + dst += dstStride; |
695 + dst += dstStride; |
605 } |
696 + } |
606 - RTC_DCHECK(current_frame_ != nullptr); |
697 + |
607 |
|
608 - // If both sides decided to go with the RGBx format we need to convert it to |
|
609 - // BGRx to match color format expected by WebRTC. |
|
610 - if (spa_video_format_->format == pw_type_->video_format.RGBx) { |
|
611 - uint8_t* tempFrame = static_cast<uint8_t*>(malloc(maxSize)); |
|
612 - std::memcpy(tempFrame, src, maxSize); |
|
613 - ConvertRGBxToBGRx(tempFrame, maxSize); |
|
614 - std::memcpy(current_frame_, tempFrame, maxSize); |
|
615 - free(tempFrame); |
|
616 - } else { |
|
617 - std::memcpy(current_frame_, src, maxSize); |
|
618 + if (map) { |
698 + if (map) { |
619 + if (spaBuffer->datas[0].type == SPA_DATA_DmaBuf) { |
699 + if (spaBuffer->datas[0].type == SPA_DATA_DmaBuf) { |
620 + SyncDmaBuf(spaBuffer->datas[0].fd, DMA_BUF_SYNC_END); |
700 + SyncDmaBuf(spaBuffer->datas[0].fd, DMA_BUF_SYNC_END); |
621 + } |
701 + } |
622 + munmap(map, spaBuffer->datas[0].maxsize + spaBuffer->datas[0].mapoffset); |
702 + munmap(map, spaBuffer->datas[0].maxsize + spaBuffer->datas[0].mapoffset); |
623 } |
703 } |
624 } |
704 } |
625 |
705 |
626 @@ -725,10 +783,7 @@ void BaseCapturerPipeWire::OnStartRequestResponseSignal( |
706 void BaseCapturerPipeWire::ConvertRGBxToBGRx(uint8_t* frame, uint32_t size) { |
|
707 // Change color format for KDE KWin which uses RGBx and not BGRx |
|
708 for (uint32_t i = 0; i < size; i += 4) { |
|
709 uint8_t tempR = frame[i]; |
|
710 uint8_t tempB = frame[i + 2]; |
|
711 @@ -720,20 +778,17 @@ void BaseCapturerPipeWire::OnStartReques |
|
712 guint32 stream_id; |
|
713 gint32 width; |
|
714 gint32 height; |
|
715 GVariant* options; |
|
716 |
627 g_variant_get(variant, "(u@a{sv})", &stream_id, &options); |
717 g_variant_get(variant, "(u@a{sv})", &stream_id, &options); |
628 RTC_DCHECK(options != nullptr); |
718 RTC_DCHECK(options != nullptr); |
629 |
719 |
630 - g_variant_lookup(options, "size", "(ii)", &width, &height); |
720 - g_variant_lookup(options, "size", "(ii)", &width, &height); |
631 - |
721 - |
790 - |
913 - |
791 - static void OnStreamFormatChanged(void* data, const struct spa_pod* format); |
914 - static void OnStreamFormatChanged(void* data, const struct spa_pod* format); |
792 static void OnStreamProcess(void* data); |
915 static void OnStreamProcess(void* data); |
793 static void OnNewBuffer(void* data, uint32_t id); |
916 static void OnNewBuffer(void* data, uint32_t id); |
794 |
917 |
|
918 guint SetupRequestResponseSignal(const gchar* object_path, |
|
919 GDBusSignalCallback callback); |
|
920 |
|
921 static void OnProxyRequested(GObject* object, |
|
922 GAsyncResult* result, |
795 diff --git a/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/screen_capturer_pipewire.cc b/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/screen_capturer_pipewire.cc |
923 diff --git a/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/screen_capturer_pipewire.cc b/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/screen_capturer_pipewire.cc |
796 index 26956fc67dc8..3813d697bb38 100644 |
|
797 --- a/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/screen_capturer_pipewire.cc |
924 --- a/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/screen_capturer_pipewire.cc |
798 +++ b/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/screen_capturer_pipewire.cc |
925 +++ b/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/screen_capturer_pipewire.cc |
799 @@ -15,7 +15,7 @@ |
926 @@ -10,17 +10,17 @@ |
|
927 |
|
928 #include "modules/desktop_capture/linux/screen_capturer_pipewire.h" |
|
929 |
|
930 #include <memory> |
|
931 |
800 namespace webrtc { |
932 namespace webrtc { |
801 |
933 |
802 ScreenCapturerPipeWire::ScreenCapturerPipeWire() |
934 ScreenCapturerPipeWire::ScreenCapturerPipeWire() |
803 - : BaseCapturerPipeWire(BaseCapturerPipeWire::CaptureSourceType::Screen) {} |
935 - : BaseCapturerPipeWire(BaseCapturerPipeWire::CaptureSourceType::Screen) {} |
804 + : BaseCapturerPipeWire(BaseCapturerPipeWire::CaptureSourceType::kScreen) {} |
936 + : BaseCapturerPipeWire(BaseCapturerPipeWire::CaptureSourceType::kScreen) {} |
805 ScreenCapturerPipeWire::~ScreenCapturerPipeWire() {} |
937 ScreenCapturerPipeWire::~ScreenCapturerPipeWire() {} |
806 |
938 |
807 // static |
939 // static |
|
940 std::unique_ptr<DesktopCapturer> |
|
941 ScreenCapturerPipeWire::CreateRawScreenCapturer( |
|
942 const DesktopCaptureOptions& options) { |
|
943 return std::make_unique<ScreenCapturerPipeWire>(); |
|
944 } |
808 diff --git a/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/window_capturer_pipewire.cc b/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/window_capturer_pipewire.cc |
945 diff --git a/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/window_capturer_pipewire.cc b/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/window_capturer_pipewire.cc |
809 index 35436475cb4d..c43a1f1a0c4e 100644 |
|
810 --- a/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/window_capturer_pipewire.cc |
946 --- a/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/window_capturer_pipewire.cc |
811 +++ b/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/window_capturer_pipewire.cc |
947 +++ b/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/window_capturer_pipewire.cc |
812 @@ -15,7 +15,7 @@ |
948 @@ -10,17 +10,17 @@ |
|
949 |
|
950 #include "modules/desktop_capture/linux/window_capturer_pipewire.h" |
|
951 |
|
952 #include <memory> |
|
953 |
813 namespace webrtc { |
954 namespace webrtc { |
814 |
955 |
815 WindowCapturerPipeWire::WindowCapturerPipeWire() |
956 WindowCapturerPipeWire::WindowCapturerPipeWire() |
816 - : BaseCapturerPipeWire(BaseCapturerPipeWire::CaptureSourceType::Window) {} |
957 - : BaseCapturerPipeWire(BaseCapturerPipeWire::CaptureSourceType::Window) {} |
817 + : BaseCapturerPipeWire(BaseCapturerPipeWire::CaptureSourceType::kWindow) {} |
958 + : BaseCapturerPipeWire(BaseCapturerPipeWire::CaptureSourceType::kWindow) {} |
818 WindowCapturerPipeWire::~WindowCapturerPipeWire() {} |
959 WindowCapturerPipeWire::~WindowCapturerPipeWire() {} |
819 |
960 |
820 // static |
961 // static |
|
962 std::unique_ptr<DesktopCapturer> |
|
963 WindowCapturerPipeWire::CreateRawWindowCapturer( |
|
964 const DesktopCaptureOptions& options) { |
|
965 return std::make_unique<WindowCapturerPipeWire>(); |
|
966 } |
821 diff --git a/media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer_linux.cc b/media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer_linux.cc |
967 diff --git a/media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer_linux.cc b/media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer_linux.cc |
822 index cf8a9dd0e0db..d27fab8d28d9 100644 |
|
823 --- a/media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer_linux.cc |
968 --- a/media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer_linux.cc |
824 +++ b/media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer_linux.cc |
969 +++ b/media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer_linux.cc |
825 @@ -26,7 +26,7 @@ std::unique_ptr<DesktopCapturer> DesktopCapturer::CreateRawScreenCapturer( |
970 @@ -21,17 +21,17 @@ |
|
971 |
|
972 namespace webrtc { |
|
973 |
|
974 // static |
|
975 std::unique_ptr<DesktopCapturer> DesktopCapturer::CreateRawScreenCapturer( |
826 const DesktopCaptureOptions& options) { |
976 const DesktopCaptureOptions& options) { |
827 #if defined(WEBRTC_USE_PIPEWIRE) |
977 #if defined(WEBRTC_USE_PIPEWIRE) |
828 if (options.allow_pipewire() && DesktopCapturer::IsRunningUnderWayland()) { |
978 if (options.allow_pipewire() && DesktopCapturer::IsRunningUnderWayland()) { |
829 - return ScreenCapturerPipeWire::CreateRawScreenCapturer(options); |
979 - return ScreenCapturerPipeWire::CreateRawScreenCapturer(options); |
830 + return BaseCapturerPipeWire::CreateRawScreenCapturer(options); |
980 + return BaseCapturerPipeWire::CreateRawScreenCapturer(options); |
831 } |
981 } |
832 #endif // defined(WEBRTC_USE_PIPEWIRE) |
982 #endif // defined(WEBRTC_USE_PIPEWIRE) |
833 |
983 |
|
984 #if defined(USE_X11) |
|
985 return ScreenCapturerX11::CreateRawScreenCapturer(options); |
|
986 #endif // defined(USE_X11) |
|
987 |
|
988 return nullptr; |
834 diff --git a/media/webrtc/trunk/webrtc/modules/desktop_capture/window_capturer_linux.cc b/media/webrtc/trunk/webrtc/modules/desktop_capture/window_capturer_linux.cc |
989 diff --git a/media/webrtc/trunk/webrtc/modules/desktop_capture/window_capturer_linux.cc b/media/webrtc/trunk/webrtc/modules/desktop_capture/window_capturer_linux.cc |
835 index 82359e50c2db..bb9724cf7cc2 100644 |
|
836 --- a/media/webrtc/trunk/webrtc/modules/desktop_capture/window_capturer_linux.cc |
990 --- a/media/webrtc/trunk/webrtc/modules/desktop_capture/window_capturer_linux.cc |
837 +++ b/media/webrtc/trunk/webrtc/modules/desktop_capture/window_capturer_linux.cc |
991 +++ b/media/webrtc/trunk/webrtc/modules/desktop_capture/window_capturer_linux.cc |
838 @@ -26,7 +26,7 @@ std::unique_ptr<DesktopCapturer> DesktopCapturer::CreateRawWindowCapturer( |
992 @@ -21,17 +21,17 @@ |
|
993 |
|
994 namespace webrtc { |
|
995 |
|
996 // static |
|
997 std::unique_ptr<DesktopCapturer> DesktopCapturer::CreateRawWindowCapturer( |
839 const DesktopCaptureOptions& options) { |
998 const DesktopCaptureOptions& options) { |
840 #if defined(WEBRTC_USE_PIPEWIRE) |
999 #if defined(WEBRTC_USE_PIPEWIRE) |
841 if (options.allow_pipewire() && DesktopCapturer::IsRunningUnderWayland()) { |
1000 if (options.allow_pipewire() && DesktopCapturer::IsRunningUnderWayland()) { |
842 - return WindowCapturerPipeWire::CreateRawWindowCapturer(options); |
1001 - return WindowCapturerPipeWire::CreateRawWindowCapturer(options); |
843 + return BaseCapturerPipeWire::CreateRawWindowCapturer(options); |
1002 + return BaseCapturerPipeWire::CreateRawWindowCapturer(options); |
844 } |
1003 } |
845 #endif // defined(WEBRTC_USE_PIPEWIRE) |
1004 #endif // defined(WEBRTC_USE_PIPEWIRE) |
846 |
1005 |
|
1006 #if defined(USE_X11) |
|
1007 return WindowCapturerX11::CreateRawWindowCapturer(options); |
|
1008 #endif // defined(USE_X11) |
|
1009 |
|
1010 return nullptr; |