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}
This commit is contained in:
3
BUILD.gn
3
BUILD.gn
@ -132,6 +132,9 @@ config("common_inherited_config") {
|
|||||||
# Allow includes to be prefixed with webrtc/ in case it is not an
|
# Allow includes to be prefixed with webrtc/ in case it is not an
|
||||||
# immediate subdirectory of the top-level.
|
# immediate subdirectory of the top-level.
|
||||||
".",
|
".",
|
||||||
|
|
||||||
|
# Allow the generated files to be found.
|
||||||
|
target_gen_dir,
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
if (is_posix || is_fuchsia) {
|
if (is_posix || is_fuchsia) {
|
||||||
|
@ -166,18 +166,65 @@ if (rtc_include_tests) {
|
|||||||
|
|
||||||
if (is_linux) {
|
if (is_linux) {
|
||||||
if (rtc_use_pipewire) {
|
if (rtc_use_pipewire) {
|
||||||
pkg_config("pipewire") {
|
|
||||||
packages = [ "libpipewire-0.2" ]
|
|
||||||
|
|
||||||
defines = [ "WEBRTC_USE_PIPEWIRE" ]
|
|
||||||
}
|
|
||||||
|
|
||||||
pkg_config("gio") {
|
pkg_config("gio") {
|
||||||
packages = [
|
packages = [
|
||||||
"gio-2.0",
|
"gio-2.0",
|
||||||
"gio-unix-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.
|
||||||
|
action("pipewire_generate_stubs") {
|
||||||
|
extra_header = "linux/pipewire_stub_header.fragment"
|
||||||
|
|
||||||
|
script = "//tools/generate_stubs/generate_stubs.py"
|
||||||
|
sources = [
|
||||||
|
"linux/pipewire.sigs",
|
||||||
|
]
|
||||||
|
inputs = [
|
||||||
|
extra_header,
|
||||||
|
]
|
||||||
|
stubs_filename_root = "pipewire_stubs"
|
||||||
|
|
||||||
|
outputs = [
|
||||||
|
"$target_gen_dir/linux/$stubs_filename_root.cc",
|
||||||
|
"$target_gen_dir/linux/$stubs_filename_root.h",
|
||||||
|
]
|
||||||
|
args = [
|
||||||
|
"-i",
|
||||||
|
rebase_path("$target_gen_dir/linux", root_build_dir),
|
||||||
|
"-o",
|
||||||
|
rebase_path("$target_gen_dir/linux", root_build_dir),
|
||||||
|
"-t",
|
||||||
|
"posix_stubs",
|
||||||
|
"-e",
|
||||||
|
rebase_path(extra_header, root_build_dir),
|
||||||
|
"-s",
|
||||||
|
stubs_filename_root,
|
||||||
|
"-p",
|
||||||
|
"modules/desktop_capture/linux",
|
||||||
|
"-l",
|
||||||
|
"RTC_LOG(LS_VERBOSE)",
|
||||||
|
"-n",
|
||||||
|
"rtc_base/logging.h",
|
||||||
|
]
|
||||||
|
|
||||||
|
args += rebase_path(sources, root_build_dir)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
config("pipewire_config") {
|
||||||
|
defines = [ "WEBRTC_USE_PIPEWIRE" ]
|
||||||
|
if (!rtc_link_pipewire) {
|
||||||
|
defines += [ "WEBRTC_DLOPEN_PIPEWIRE" ]
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -384,22 +431,6 @@ rtc_static_library("desktop_capture_generic") {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
if (!is_win && !is_mac && !rtc_use_x11 && !rtc_use_pipewire) {
|
||||||
sources += [
|
sources += [
|
||||||
"mouse_cursor_monitor_null.cc",
|
"mouse_cursor_monitor_null.cc",
|
||||||
@ -438,6 +469,30 @@ rtc_static_library("desktop_capture_generic") {
|
|||||||
if (use_desktop_capture_differ_sse2) {
|
if (use_desktop_capture_differ_sse2) {
|
||||||
deps += [ ":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 {
|
||||||
|
libs = [ "dl" ]
|
||||||
|
deps += [ ":pipewire_generate_stubs" ]
|
||||||
|
sources += get_target_outputs(":pipewire_generate_stubs")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (use_desktop_capture_differ_sse2) {
|
if (use_desktop_capture_differ_sse2) {
|
||||||
|
@ -27,6 +27,14 @@
|
|||||||
#include "rtc_base/checks.h"
|
#include "rtc_base/checks.h"
|
||||||
#include "rtc_base/logging.h"
|
#include "rtc_base/logging.h"
|
||||||
|
|
||||||
|
#if defined(WEBRTC_DLOPEN_PIPEWIRE)
|
||||||
|
#include "modules/desktop_capture/linux/pipewire_stubs.h"
|
||||||
|
|
||||||
|
using modules_desktop_capture_linux::kModulePipewire;
|
||||||
|
using modules_desktop_capture_linux::InitializeStubs;
|
||||||
|
using modules_desktop_capture_linux::StubPathMap;
|
||||||
|
#endif // defined(WEBRTC_DLOPEN_PIPEWIRE)
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
|
||||||
const char kDesktopBusName[] = "org.freedesktop.portal.Desktop";
|
const char kDesktopBusName[] = "org.freedesktop.portal.Desktop";
|
||||||
@ -39,6 +47,10 @@ const char kScreenCastInterfaceName[] = "org.freedesktop.portal.ScreenCast";
|
|||||||
|
|
||||||
const int kBytesPerPixel = 4;
|
const int kBytesPerPixel = 4;
|
||||||
|
|
||||||
|
#if defined(WEBRTC_DLOPEN_PIPEWIRE)
|
||||||
|
const char kPipeWireLib[] = "libpipewire-0.2.so.1";
|
||||||
|
#endif
|
||||||
|
|
||||||
// static
|
// static
|
||||||
void BaseCapturerPipeWire::OnStateChanged(void* data,
|
void BaseCapturerPipeWire::OnStateChanged(void* data,
|
||||||
pw_remote_state old_state,
|
pw_remote_state old_state,
|
||||||
@ -251,6 +263,18 @@ void BaseCapturerPipeWire::InitPortal() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void BaseCapturerPipeWire::InitPipeWire() {
|
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_init(/*argc=*/nullptr, /*argc=*/nullptr);
|
||||||
|
|
||||||
pw_loop_ = pw_loop_new(/*properties=*/nullptr);
|
pw_loop_ = pw_loop_new(/*properties=*/nullptr);
|
||||||
@ -279,6 +303,8 @@ void BaseCapturerPipeWire::InitPipeWire() {
|
|||||||
RTC_LOG(LS_ERROR) << "Failed to start main PipeWire loop";
|
RTC_LOG(LS_ERROR) << "Failed to start main PipeWire loop";
|
||||||
portal_init_failed_ = true;
|
portal_init_failed_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RTC_LOG(LS_INFO) << "PipeWire remote opened.";
|
||||||
}
|
}
|
||||||
|
|
||||||
void BaseCapturerPipeWire::InitPipeWireTypes() {
|
void BaseCapturerPipeWire::InitPipeWireTypes() {
|
||||||
@ -300,8 +326,8 @@ void BaseCapturerPipeWire::CreateReceivingStream() {
|
|||||||
spa_fraction pwFrameRateMin = spa_fraction{0, 1};
|
spa_fraction pwFrameRateMin = spa_fraction{0, 1};
|
||||||
spa_fraction pwFrameRateMax = spa_fraction{60, 1};
|
spa_fraction pwFrameRateMax = spa_fraction{60, 1};
|
||||||
|
|
||||||
pw_properties* reuseProps = pw_properties_new("pipewire.client.reuse", "1",
|
pw_properties* reuseProps =
|
||||||
/*end of varargs*/ nullptr);
|
pw_properties_new_string("pipewire.client.reuse=1");
|
||||||
pw_stream_ = pw_stream_new(pw_remote_, "webrtc-consume-stream", reuseProps);
|
pw_stream_ = pw_stream_new(pw_remote_, "webrtc-consume-stream", reuseProps);
|
||||||
|
|
||||||
uint8_t buffer[1024] = {};
|
uint8_t buffer[1024] = {};
|
||||||
@ -793,7 +819,6 @@ void BaseCapturerPipeWire::OnOpenPipeWireRemoteRequested(
|
|||||||
g_object_unref(outlist);
|
g_object_unref(outlist);
|
||||||
|
|
||||||
that->InitPipeWire();
|
that->InitPipeWire();
|
||||||
RTC_LOG(LS_INFO) << "PipeWire remote opened.";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BaseCapturerPipeWire::Start(Callback* callback) {
|
void BaseCapturerPipeWire::Start(Callback* callback) {
|
||||||
|
44
modules/desktop_capture/linux/pipewire.sigs
Normal file
44
modules/desktop_capture/linux/pipewire.sigs
Normal file
@ -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);
|
@ -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>
|
||||||
|
|
||||||
|
}
|
@ -109,7 +109,10 @@ declare_args() {
|
|||||||
rtc_use_x11 = use_x11
|
rtc_use_x11 = use_x11
|
||||||
|
|
||||||
# Set this to use PipeWire on the Wayland display server.
|
# Set this to use PipeWire on the Wayland display server.
|
||||||
rtc_use_pipewire = false
|
rtc_use_pipewire = is_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.
|
# Enable to use the Mozilla internal settings.
|
||||||
build_with_mozilla = false
|
build_with_mozilla = false
|
||||||
|
Reference in New Issue
Block a user