Reland "Default to dlopening the PipeWire."
This is a reland of a099877d8946eb942046ca1295cc142e4fa7ea6f
Original change's description:
> Reland "Default to dlopening the PipeWire."
>
> This is a reland of a13be019017449c57f48203d0fb778f34f7553a7
>
> Original change's description:
> > Default to dlopening the PipeWire.
> >
> > Reuse the existing infra from Chromium to do that. Additionally the
> > target_gen_dir needs to the added to the include directories, otherwise
> > the Chromium build will fail as it won't find the generated stubs. Also the
> > pw_properties_new() was replaced with pw_properties_new_string() as it doesn't
> > require a variadic parameter because the //tools/generate_stubs/generate_stubs.py
> > doesn't work with them correctly. With all these changes in place the PipeWire
> > support is enabled when compiling on Linux.
> >
> > Bug: chromium:682122
> > Change-Id: I3bbc5efaecd9a08e20cbcf998b2cb534224eae7d
> > Reviewed-on: https://webrtc-review.googlesource.com/c/111081
> > Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
> > Reviewed-by: Brave Yao <braveyao@webrtc.org>
> > Commit-Queue: Tomáš Popela <tomas.popela@gmail.com>
> > Cr-Commit-Position: refs/heads/master@{#25720}
>
> Bug: chromium:682122
> Change-Id: I3cca3d4d961dc7a088346c8fd3c970d3dfde3b79
> Reviewed-on: https://webrtc-review.googlesource.com/c/113040
> Reviewed-by: Weiyong Yao <braveyao@chromium.org>
> Reviewed-by: Brave Yao <braveyao@webrtc.org>
> Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
> Reviewed-by: Oleh Prypin <oprypin@webrtc.org>
> Commit-Queue: Oleh Prypin <oprypin@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#25981}
Bug: chromium:682122
Change-Id: Ief26c93069f946f981340664a267fcb412229285
Reviewed-on: https://webrtc-review.googlesource.com/c/114163
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Reviewed-by: Brave Yao <braveyao@webrtc.org>
Commit-Queue: Mirko Bonadei <mbonadei@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#26004}
diff --git a/BUILD.gn b/BUILD.gn
index c9249ff..4db6558 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -131,6 +131,14 @@
# Allow includes to be prefixed with webrtc/ in case it is not an
# immediate subdirectory of the top-level.
".",
+
+ # Just like the root WebRTC directory is added to include path, the
+ # corresponding directory tree with generated files needs to be added too.
+ # Note: this path does not change depending on the current target, e.g.
+ # it is always "//gen/third_party/webrtc" when building with Chromium.
+ # See also: http://cs.chromium.org/?q=%5C"default_include_dirs
+ # https://gn.googlesource.com/gn/+/master/docs/reference.md#target_gen_dir
+ target_gen_dir,
]
}
if (is_posix || is_fuchsia) {
diff --git a/modules/desktop_capture/BUILD.gn b/modules/desktop_capture/BUILD.gn
index 390fc0a..0677a79 100644
--- a/modules/desktop_capture/BUILD.gn
+++ b/modules/desktop_capture/BUILD.gn
@@ -8,6 +8,7 @@
import("//build/config/linux/pkg_config.gni")
import("//build/config/ui.gni")
+import("//tools/generate_stubs/rules.gni")
import("../../webrtc.gni")
use_desktop_capture_differ_sse2 = current_cpu == "x86" || current_cpu == "x64"
@@ -166,18 +167,40 @@
if (is_linux) {
if (rtc_use_pipewire) {
- pkg_config("pipewire") {
- packages = [ "libpipewire-0.2" ]
-
- defines = [ "WEBRTC_USE_PIPEWIRE" ]
- }
-
pkg_config("gio") {
packages = [
"gio-2.0",
"gio-unix-2.0",
]
}
+
+ if (rtc_link_pipewire) {
+ pkg_config("pipewire") {
+ packages = [ "libpipewire-0.2" ]
+ }
+ } else {
+ # When libpipewire is not directly linked, use stubs to allow for dlopening of
+ # the binary.
+ generate_stubs("pipewire_stubs") {
+ configs = [ "../../:common_config" ]
+ deps = [
+ "../../rtc_base",
+ ]
+ extra_header = "linux/pipewire_stub_header.fragment"
+ logging_function = "RTC_LOG(LS_VERBOSE)"
+ logging_include = "rtc_base/logging.h"
+ output_name = "linux/pipewire_stubs"
+ path_from_source = "modules/desktop_capture/linux"
+ sigs = [ "linux/pipewire.sigs" ]
+ }
+ }
+
+ config("pipewire_config") {
+ defines = [ "WEBRTC_USE_PIPEWIRE" ]
+ if (!rtc_link_pipewire) {
+ defines += [ "WEBRTC_DLOPEN_PIPEWIRE" ]
+ }
+ }
}
}
@@ -384,22 +407,6 @@
}
}
- if (rtc_use_pipewire) {
- sources += [
- "linux/base_capturer_pipewire.cc",
- "linux/base_capturer_pipewire.h",
- "linux/screen_capturer_pipewire.cc",
- "linux/screen_capturer_pipewire.h",
- "linux/window_capturer_pipewire.cc",
- "linux/window_capturer_pipewire.h",
- ]
-
- configs += [
- ":gio",
- ":pipewire",
- ]
- }
-
if (!is_win && !is_mac && !rtc_use_x11 && !rtc_use_pipewire) {
sources += [
"mouse_cursor_monitor_null.cc",
@@ -438,6 +445,28 @@
if (use_desktop_capture_differ_sse2) {
deps += [ ":desktop_capture_differ_sse2" ]
}
+
+ if (rtc_use_pipewire) {
+ sources += [
+ "linux/base_capturer_pipewire.cc",
+ "linux/base_capturer_pipewire.h",
+ "linux/screen_capturer_pipewire.cc",
+ "linux/screen_capturer_pipewire.h",
+ "linux/window_capturer_pipewire.cc",
+ "linux/window_capturer_pipewire.h",
+ ]
+
+ configs += [
+ ":pipewire_config",
+ ":gio",
+ ]
+
+ if (rtc_link_pipewire) {
+ configs += [ ":pipewire" ]
+ } else {
+ deps += [ ":pipewire_stubs" ]
+ }
+ }
}
if (use_desktop_capture_differ_sse2) {
diff --git a/modules/desktop_capture/linux/base_capturer_pipewire.cc b/modules/desktop_capture/linux/base_capturer_pipewire.cc
index 62d9994..05ad86f 100644
--- a/modules/desktop_capture/linux/base_capturer_pipewire.cc
+++ b/modules/desktop_capture/linux/base_capturer_pipewire.cc
@@ -27,6 +27,14 @@
#include "rtc_base/checks.h"
#include "rtc_base/logging.h"
+#if defined(WEBRTC_DLOPEN_PIPEWIRE)
+#include "modules/desktop_capture/linux/pipewire_stubs.h"
+
+using modules_desktop_capture_linux::InitializeStubs;
+using modules_desktop_capture_linux::kModulePipewire;
+using modules_desktop_capture_linux::StubPathMap;
+#endif // defined(WEBRTC_DLOPEN_PIPEWIRE)
+
namespace webrtc {
const char kDesktopBusName[] = "org.freedesktop.portal.Desktop";
@@ -39,6 +47,10 @@
const int kBytesPerPixel = 4;
+#if defined(WEBRTC_DLOPEN_PIPEWIRE)
+const char kPipeWireLib[] = "libpipewire-0.2.so.1";
+#endif
+
// static
void BaseCapturerPipeWire::OnStateChanged(void* data,
pw_remote_state old_state,
@@ -251,6 +263,18 @@
}
void BaseCapturerPipeWire::InitPipeWire() {
+#if defined(WEBRTC_DLOPEN_PIPEWIRE)
+ StubPathMap paths;
+
+ // Check if the PipeWire library is available.
+ paths[kModulePipewire].push_back(kPipeWireLib);
+ if (!InitializeStubs(paths)) {
+ RTC_LOG(LS_ERROR) << "Failed to load the PipeWire library and symbols.";
+ portal_init_failed_ = true;
+ return;
+ }
+#endif // defined(WEBRTC_DLOPEN_PIPEWIRE)
+
pw_init(/*argc=*/nullptr, /*argc=*/nullptr);
pw_loop_ = pw_loop_new(/*properties=*/nullptr);
@@ -279,6 +303,8 @@
RTC_LOG(LS_ERROR) << "Failed to start main PipeWire loop";
portal_init_failed_ = true;
}
+
+ RTC_LOG(LS_INFO) << "PipeWire remote opened.";
}
void BaseCapturerPipeWire::InitPipeWireTypes() {
@@ -300,8 +326,8 @@
spa_fraction pwFrameRateMin = spa_fraction{0, 1};
spa_fraction pwFrameRateMax = spa_fraction{60, 1};
- pw_properties* reuseProps = pw_properties_new("pipewire.client.reuse", "1",
- /*end of varargs*/ nullptr);
+ pw_properties* reuseProps =
+ pw_properties_new_string("pipewire.client.reuse=1");
pw_stream_ = pw_stream_new(pw_remote_, "webrtc-consume-stream", reuseProps);
uint8_t buffer[1024] = {};
@@ -793,7 +819,6 @@
g_object_unref(outlist);
that->InitPipeWire();
- RTC_LOG(LS_INFO) << "PipeWire remote opened.";
}
void BaseCapturerPipeWire::Start(Callback* callback) {
diff --git a/modules/desktop_capture/linux/pipewire.sigs b/modules/desktop_capture/linux/pipewire.sigs
new file mode 100644
index 0000000..3e21e9d
--- /dev/null
+++ b/modules/desktop_capture/linux/pipewire.sigs
@@ -0,0 +1,44 @@
+// Copyright 2018 The WebRTC project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+//------------------------------------------------
+// Functions from PipeWire used in capturer code.
+//------------------------------------------------
+
+// core.h
+void pw_core_destroy(pw_core *core);
+pw_type *pw_core_get_type(pw_core *core);
+pw_core * pw_core_new(pw_loop *main_loop, pw_properties *props);
+
+// loop.h
+void pw_loop_destroy(pw_loop *loop);
+pw_loop * pw_loop_new(pw_properties *properties);
+
+// pipewire.h
+void pw_init(int *argc, char **argv[]);
+
+// properties.h
+pw_properties * pw_properties_new_string(const char *args);
+
+// remote.h
+void pw_remote_add_listener(pw_remote *remote, spa_hook *listener, const pw_remote_events *events, void *data);
+int pw_remote_connect_fd(pw_remote *remote, int fd);
+void pw_remote_destroy(pw_remote *remote);
+pw_remote * pw_remote_new(pw_core *core, pw_properties *properties, size_t user_data_size);
+
+// stream.h
+void pw_stream_add_listener(pw_stream *stream, spa_hook *listener, const pw_stream_events *events, void *data);
+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);
+pw_buffer *pw_stream_dequeue_buffer(pw_stream *stream);
+void pw_stream_destroy(pw_stream *stream);
+void pw_stream_finish_format(pw_stream *stream, int res, const spa_pod **params, uint32_t n_params);
+pw_stream * pw_stream_new(pw_remote *remote, const char *name, pw_properties *props);
+int pw_stream_queue_buffer(pw_stream *stream, pw_buffer *buffer);
+int pw_stream_set_active(pw_stream *stream, bool active);
+
+// thread-loop.h
+void pw_thread_loop_destroy(pw_thread_loop *loop);
+pw_thread_loop * pw_thread_loop_new(pw_loop *loop, const char *name);
+int pw_thread_loop_start(pw_thread_loop *loop);
+void pw_thread_loop_stop(pw_thread_loop *loop);
diff --git a/modules/desktop_capture/linux/pipewire_stub_header.fragment b/modules/desktop_capture/linux/pipewire_stub_header.fragment
new file mode 100644
index 0000000..9d7dbd27
--- /dev/null
+++ b/modules/desktop_capture/linux/pipewire_stub_header.fragment
@@ -0,0 +1,8 @@
+// The extra include header needed in the generated stub file for defining
+// various PipeWire types.
+
+extern "C" {
+
+#include <pipewire/pipewire.h>
+
+}
diff --git a/webrtc.gni b/webrtc.gni
index 7c24c79..c843c24 100644
--- a/webrtc.gni
+++ b/webrtc.gni
@@ -109,7 +109,13 @@
rtc_use_x11 = use_x11
# Set this to use PipeWire on the Wayland display server.
- rtc_use_pipewire = false
+ # By default it's only enabled on desktop Linux (excludes ChromeOS) and
+ # only when using the sysroot as PipeWire is not available in older and
+ # supported Ubuntu and Debian distributions.
+ rtc_use_pipewire = is_desktop_linux && use_sysroot
+
+ # Set this to link PipeWire directly instead of using the dlopen.
+ rtc_link_pipewire = false
# Enable to use the Mozilla internal settings.
build_with_mozilla = false