File build-with-pipewire-0.3.patch of Package chromium
Index: chromium-81.0.4044.83/third_party/webrtc/modules/desktop_capture/BUILD.gn
===================================================================
--- chromium-81.0.4044.83.orig/third_party/webrtc/modules/desktop_capture/BUILD.gn
+++ chromium-81.0.4044.83/third_party/webrtc/modules/desktop_capture/BUILD.gn
@@ -196,7 +196,7 @@ if (is_linux) {
if (rtc_link_pipewire) {
pkg_config("pipewire") {
- packages = [ "libpipewire-0.2" ]
+ packages = [ "libpipewire-${rtc_use_pipewire_version}" ]
}
} else {
# When libpipewire is not directly linked, use stubs to allow for dlopening of
Index: chromium-81.0.4044.83/third_party/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.cc
===================================================================
--- chromium-81.0.4044.83.orig/third_party/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.cc
+++ chromium-81.0.4044.83/third_party/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.cc
@@ -14,8 +14,13 @@
#include <glib-object.h>
#include <spa/param/format-utils.h>
#include <spa/param/props.h>
+#if PW_CHECK_VERSION(0, 2, 90)
+#include <spa/utils/result.h>
+#include <spa/utils/defs.h>
+#else
#include <spa/param/video/raw-utils.h>
#include <spa/support/type-map.h>
+#endif
#include <memory>
#include <utility>
@@ -51,6 +56,21 @@ const char kPipeWireLib[] = "libpipewire
#endif
// static
+#if PW_CHECK_VERSION(0, 2, 90)
+void BaseCapturerPipeWire::OnCoreError(void* data,
+ uint32_t id,
+ int seq,
+ int res,
+ const char *message) {
+ BaseCapturerPipeWire* that = static_cast<BaseCapturerPipeWire*>(data);
+ RTC_DCHECK(that);
+
+ RTC_LOG(LS_WARNING) << "PipeWire core error: id:" << id << " : " << message;
+
+ if (id == PW_ID_CORE && res == -EPIPE)
+ RTC_LOG(LS_WARNING) << "PipeWire core error: Pipe closed.";
+};
+#else
void BaseCapturerPipeWire::OnStateChanged(void* data,
pw_remote_state old_state,
pw_remote_state state,
@@ -64,7 +84,7 @@ void BaseCapturerPipeWire::OnStateChange
break;
case PW_REMOTE_STATE_CONNECTED:
RTC_LOG(LS_INFO) << "PipeWire remote state: connected.";
- that->CreateReceivingStream();
+ that->pw_stream_ = that->CreateReceivingStream();
break;
case PW_REMOTE_STATE_CONNECTING:
RTC_LOG(LS_INFO) << "PipeWire remote state: connecting.";
@@ -74,6 +94,7 @@ void BaseCapturerPipeWire::OnStateChange
break;
}
}
+#endif
// static
void BaseCapturerPipeWire::OnStreamStateChanged(void* data,
@@ -87,12 +108,16 @@ void BaseCapturerPipeWire::OnStreamState
case PW_STREAM_STATE_ERROR:
RTC_LOG(LS_ERROR) << "PipeWire stream state error: " << error_message;
break;
+#if !PW_CHECK_VERSION(0, 2, 90)
case PW_STREAM_STATE_CONFIGURE:
- pw_stream_set_active(that->pw_stream_, true);
+ pw_stream_set_active(that->pw_stream_, true); // TODO FIXME Removing this might cause problems?
break;
+#endif
case PW_STREAM_STATE_UNCONNECTED:
case PW_STREAM_STATE_CONNECTING:
+#if !PW_CHECK_VERSION(0, 2, 90)
case PW_STREAM_STATE_READY:
+#endif
case PW_STREAM_STATE_PAUSED:
case PW_STREAM_STATE_STREAMING:
break;
@@ -100,22 +125,39 @@ void BaseCapturerPipeWire::OnStreamState
}
// static
+
+
+#if PW_CHECK_VERSION(0, 2, 90)
+void BaseCapturerPipeWire::OnStreamParamChanged(void* data,
+ uint32_t id,
+ const struct spa_pod* format) {
+#else
void BaseCapturerPipeWire::OnStreamFormatChanged(void* data,
const struct spa_pod* format) {
+#endif
BaseCapturerPipeWire* that = static_cast<BaseCapturerPipeWire*>(data);
RTC_DCHECK(that);
RTC_LOG(LS_INFO) << "PipeWire stream format changed.";
+#if PW_CHECK_VERSION(0, 2, 90)
+ if (!format || id != SPA_PARAM_Format)
+ return;
+#else
if (!format) {
pw_stream_finish_format(that->pw_stream_, /*res=*/0, /*params=*/nullptr,
/*n_params=*/0);
return;
}
+#endif
that->spa_video_format_ = new spa_video_info_raw();
+#if PW_CHECK_VERSION(0, 2, 90)
+ spa_format_video_raw_parse(format, that->spa_video_format_);
+#else
spa_format_video_raw_parse(format, that->spa_video_format_,
&that->pw_type_->format_video);
+#endif
auto width = that->spa_video_format_->size.width;
auto height = that->spa_video_format_->size.height;
@@ -127,6 +169,16 @@ void BaseCapturerPipeWire::OnStreamForma
// Setup buffers and meta header for new format.
const struct spa_pod* params[2];
+#if PW_CHECK_VERSION(0, 2, 90)
+ params[0] = reinterpret_cast<spa_pod*>(spa_pod_builder_add_object(
+ &builder,
+ SPA_TYPE_OBJECT_ParamBuffers, SPA_PARAM_Buffers,
+ SPA_PARAM_BUFFERS_buffers, SPA_POD_CHOICE_RANGE_Int (8, 1, 32),
+ SPA_PARAM_BUFFERS_blocks, SPA_POD_Int (1),
+ SPA_PARAM_BUFFERS_size, SPA_POD_Int (size),
+ SPA_PARAM_BUFFERS_stride, SPA_POD_Int (stride),
+ SPA_PARAM_BUFFERS_align, SPA_POD_Int (16)));
+#else
params[0] = reinterpret_cast<spa_pod*>(spa_pod_builder_object(
&builder,
// id to enumerate buffer requirements
@@ -145,6 +197,19 @@ void BaseCapturerPipeWire::OnStreamForma
// Align: memory alignment of the buffer, set as integer (i) to specified
// value
":", that->pw_core_type_->param_buffers.align, "i", 16));
+#endif
+
+
+
+#if PW_CHECK_VERSION(0, 2, 90)
+ params[1] = reinterpret_cast<spa_pod*>(spa_pod_builder_add_object(
+ &builder,
+ SPA_TYPE_OBJECT_ParamMeta, SPA_PARAM_Meta,
+ SPA_PARAM_META_type, SPA_POD_Id (SPA_META_Header),
+ SPA_PARAM_META_size, SPA_POD_Int (sizeof (struct spa_meta_header))));
+
+ pw_stream_update_params(that->pw_stream_, params, /*n_params=*/2);
+#else
params[1] = reinterpret_cast<spa_pod*>(spa_pod_builder_object(
&builder,
// id to enumerate supported metadata
@@ -157,6 +222,7 @@ void BaseCapturerPipeWire::OnStreamForma
sizeof(struct spa_meta_header)));
pw_stream_finish_format(that->pw_stream_, /*res=*/0, params, /*n_params=*/2);
+#endif
}
// static
@@ -183,9 +249,11 @@ BaseCapturerPipeWire::~BaseCapturerPipeW
pw_thread_loop_stop(pw_main_loop_);
}
+#if !PW_CHECK_VERSION(0, 2, 90)
if (pw_type_) {
delete pw_type_;
}
+#endif
if (spa_video_format_) {
delete spa_video_format_;
@@ -195,6 +263,16 @@ BaseCapturerPipeWire::~BaseCapturerPipeW
pw_stream_destroy(pw_stream_);
}
+
+#if PW_CHECK_VERSION(0, 2, 90)
+ if (pw_core_) {
+ pw_core_disconnect(pw_core_);
+ }
+
+ if (pw_context_) {
+ pw_context_destroy(pw_context_);
+ }
+#else
if (pw_remote_) {
pw_remote_destroy(pw_remote_);
}
@@ -202,14 +280,17 @@ BaseCapturerPipeWire::~BaseCapturerPipeW
if (pw_core_) {
pw_core_destroy(pw_core_);
}
+#endif
if (pw_main_loop_) {
pw_thread_loop_destroy(pw_main_loop_);
}
+#if !PW_CHECK_VERSION(0, 2, 90)
if (pw_loop_) {
pw_loop_destroy(pw_loop_);
}
+#endif
if (current_frame_) {
free(current_frame_);
@@ -284,6 +365,27 @@ void BaseCapturerPipeWire::InitPipeWire(
pw_init(/*argc=*/nullptr, /*argc=*/nullptr);
+#if PW_CHECK_VERSION(0, 2, 90)
+ pw_main_loop_ = pw_thread_loop_new("pipewire-main-loop", nullptr);
+
+ pw_context_ = pw_context_new(pw_thread_loop_get_loop(pw_main_loop_), /*properties=*/nullptr, /*user_data_size=*/0);
+ if (!pw_context_)
+ {
+ RTC_LOG(LS_ERROR) << "Failed to create PipeWire context.";
+ portal_init_failed_ = true;
+ return;
+ }
+
+ pw_core_ = pw_context_connect(pw_context_, nullptr, /*user_data_size=*/0);
+ if (!pw_core_)
+ {
+ RTC_LOG(LS_ERROR) << "Failed to connect PipeWire context.";
+ portal_init_failed_ = true;
+ return;
+ }
+ pw_core_events_.version = PW_VERSION_CORE_EVENTS;
+ pw_core_events_.error = &OnCoreError;
+#else
pw_loop_ = pw_loop_new(/*properties=*/nullptr);
pw_main_loop_ = pw_thread_loop_new(pw_loop_, "pipewire-main-loop");
@@ -296,15 +398,30 @@ void BaseCapturerPipeWire::InitPipeWire(
// Initialize event handlers, remote end and stream-related.
pw_remote_events_.version = PW_VERSION_REMOTE_EVENTS;
pw_remote_events_.state_changed = &OnStateChanged;
+#endif
pw_stream_events_.version = PW_VERSION_STREAM_EVENTS;
pw_stream_events_.state_changed = &OnStreamStateChanged;
+#if PW_CHECK_VERSION(0, 2, 90)
+ pw_stream_events_.param_changed = &OnStreamParamChanged;
+#else
pw_stream_events_.format_changed = &OnStreamFormatChanged;
+#endif
pw_stream_events_.process = &OnStreamProcess;
+#if PW_CHECK_VERSION(0, 2, 90)
+ pw_core_add_listener (pw_core_,
+ &pw_core_listener_,
+ &pw_core_events_,
+ this);
+ pw_stream_ = CreateReceivingStream ();
+ if (!pw_stream_)
+ return;
+#else
pw_remote_add_listener(pw_remote_, &spa_remote_listener_, &pw_remote_events_,
this);
pw_remote_connect_fd(pw_remote_, pw_fd_);
+#endif
if (pw_thread_loop_start(pw_main_loop_) < 0) {
RTC_LOG(LS_ERROR) << "Failed to start main PipeWire loop";
@@ -314,6 +431,7 @@ void BaseCapturerPipeWire::InitPipeWire(
RTC_LOG(LS_INFO) << "PipeWire remote opened.";
}
+#if !PW_CHECK_VERSION(0, 2, 90)
void BaseCapturerPipeWire::InitPipeWireTypes() {
spa_type_map* map = pw_core_type_->map;
pw_type_ = new PipeWireType();
@@ -323,23 +441,41 @@ void BaseCapturerPipeWire::InitPipeWireT
spa_type_format_video_map(map, &pw_type_->format_video);
spa_type_video_format_map(map, &pw_type_->video_format);
}
+#endif
-void BaseCapturerPipeWire::CreateReceivingStream() {
- spa_rectangle pwMinScreenBounds = spa_rectangle{1, 1};
+pw_stream *BaseCapturerPipeWire::CreateReceivingStream() {
+ spa_rectangle pwMinScreenBounds = SPA_RECTANGLE(1, 1);
spa_rectangle pwScreenBounds =
- spa_rectangle{static_cast<uint32_t>(desktop_size_.width()),
- static_cast<uint32_t>(desktop_size_.height())};
+ SPA_RECTANGLE(static_cast<uint32_t>(desktop_size_.width()),
+ static_cast<uint32_t>(desktop_size_.height()));
+
+ spa_fraction pwFrameRateMin = SPA_FRACTION(0, 1);
+ spa_fraction pwFrameRateMax = SPA_FRACTION(60, 1);
- spa_fraction pwFrameRateMin = spa_fraction{0, 1};
- spa_fraction pwFrameRateMax = spa_fraction{60, 1};
pw_properties* reuseProps =
pw_properties_new_string("pipewire.client.reuse=1");
- pw_stream_ = pw_stream_new(pw_remote_, "webrtc-consume-stream", reuseProps);
+#if PW_CHECK_VERSION(0, 2, 90)
+ pw_stream *stream = pw_stream_new(pw_core_, "webrtc-consume-stream", reuseProps);
+#else
+ pw_stream *stream = pw_stream_new(pw_remote_, "webrtc-consume-stream", reuseProps);
+#endif
uint8_t buffer[1024] = {};
const spa_pod* params[1];
spa_pod_builder builder = spa_pod_builder{buffer, sizeof(buffer)};
+#if PW_CHECK_VERSION(0, 2, 90)
+ params[0] = reinterpret_cast<spa_pod*>(spa_pod_builder_add_object(
+ &builder,
+ // id to enumerate formats
+ SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat,
+ SPA_FORMAT_mediaType, SPA_POD_Id (SPA_MEDIA_TYPE_video),
+ SPA_FORMAT_mediaSubtype, SPA_POD_Id (SPA_MEDIA_SUBTYPE_raw),
+ SPA_FORMAT_VIDEO_format, SPA_POD_Id (SPA_VIDEO_FORMAT_BGRx),
+ SPA_FORMAT_VIDEO_size, SPA_POD_CHOICE_RANGE_Rectangle(&pwScreenBounds, &pwMinScreenBounds, &pwScreenBounds),
+ SPA_FORMAT_VIDEO_framerate, SPA_POD_Fraction(&pwFrameRateMin),
+ SPA_FORMAT_VIDEO_maxFramerate, SPA_POD_CHOICE_RANGE_Fraction(&pwFrameRateMax, &pwFrameRateMin, &pwFrameRateMax)));
+#else
params[0] = reinterpret_cast<spa_pod*>(spa_pod_builder_object(
&builder,
// id to enumerate formats
@@ -364,19 +500,28 @@ void BaseCapturerPipeWire::CreateReceivi
// min and max values and it is undecided (u) to allow negotiation
":", pw_type_->format_video.max_framerate, "Fru", &pwFrameRateMax, 2,
&pwFrameRateMin, &pwFrameRateMax));
-
- pw_stream_add_listener(pw_stream_, &spa_stream_listener_, &pw_stream_events_,
+ pw_stream_add_listener(stream, &spa_stream_listener_, &pw_stream_events_,
this);
+#endif
+
pw_stream_flags flags = static_cast<pw_stream_flags>(
PW_STREAM_FLAG_AUTOCONNECT | PW_STREAM_FLAG_INACTIVE |
PW_STREAM_FLAG_MAP_BUFFERS);
- if (pw_stream_connect(pw_stream_, PW_DIRECTION_INPUT, /*port_path=*/nullptr,
+
+#if PW_CHECK_VERSION(0, 2, 90)
+ if (pw_stream_connect(stream, PW_DIRECTION_INPUT, PW_ID_ANY,
+ flags, params,
+ /*n_params=*/1) != 0) {
+#else
+ if (pw_stream_connect(stream, PW_DIRECTION_INPUT, /*port_path=*/nullptr,
flags, params,
/*n_params=*/1) != 0) {
+#endif
RTC_LOG(LS_ERROR) << "Could not connect receiving stream.";
portal_init_failed_ = true;
- return;
}
+
+ return stream;
}
void BaseCapturerPipeWire::HandleBuffer(pw_buffer* buffer) {
@@ -404,7 +549,11 @@ void BaseCapturerPipeWire::HandleBuffer(
// If both sides decided to go with the RGBx format we need to convert it to
// BGRx to match color format expected by WebRTC.
+#if PW_CHECK_VERSION(0, 2, 90)
+ if (spa_video_format_->format == SPA_VIDEO_FORMAT_RGBx) {
+#else
if (spa_video_format_->format == pw_type_->video_format.RGBx) {
+#endif
uint8_t* tempFrame = static_cast<uint8_t*>(malloc(maxSize));
std::memcpy(tempFrame, src, maxSize);
ConvertRGBxToBGRx(tempFrame, maxSize);
Index: chromium-81.0.4044.83/third_party/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.h
===================================================================
--- chromium-81.0.4044.83.orig/third_party/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.h
+++ chromium-81.0.4044.83/third_party/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.h
@@ -22,6 +22,7 @@
namespace webrtc {
+#if !PW_CHECK_VERSION(0, 2, 90)
class PipeWireType {
public:
spa_type_media_type media_type;
@@ -29,6 +30,7 @@ class PipeWireType {
spa_type_format_video format_video;
spa_type_video_format video_format;
};
+#endif
class BaseCapturerPipeWire : public DesktopCapturer {
public:
@@ -45,6 +47,18 @@ class BaseCapturerPipeWire : public Desk
private:
// PipeWire types -->
+#if PW_CHECK_VERSION(0, 2, 90)
+ pw_context* pw_context_ = nullptr;
+ pw_core* pw_core_ = nullptr;
+ pw_stream* pw_stream_ = nullptr;
+ pw_thread_loop* pw_main_loop_ = nullptr;
+
+ spa_hook pw_core_listener_ = {};
+ spa_hook spa_stream_listener_ = {};
+
+ pw_core_events pw_core_events_ = {};
+ pw_stream_events pw_stream_events_ = {};
+#else
pw_core* pw_core_ = nullptr;
pw_type* pw_core_type_ = nullptr;
pw_stream* pw_stream_ = nullptr;
@@ -58,6 +72,7 @@ class BaseCapturerPipeWire : public Desk
pw_stream_events pw_stream_events_ = {};
pw_remote_events pw_remote_events_ = {};
+#endif
spa_video_info_raw* spa_video_format_ = nullptr;
@@ -89,23 +104,38 @@ class BaseCapturerPipeWire : public Desk
void InitPortal();
void InitPipeWire();
+#if !PW_CHECK_VERSION(0, 2, 90)
void InitPipeWireTypes();
+#endif
- void CreateReceivingStream();
+ pw_stream *CreateReceivingStream();
void HandleBuffer(pw_buffer* buffer);
void ConvertRGBxToBGRx(uint8_t* frame, uint32_t size);
+#if PW_CHECK_VERSION(0, 2, 90)
+ static void OnCoreError(void* data,
+ uint32_t id,
+ int seq,
+ int res,
+ const char *message);
+#else
static void OnStateChanged(void* data,
pw_remote_state old_state,
pw_remote_state state,
const char* error);
+#endif
static void OnStreamStateChanged(void* data,
pw_stream_state old_state,
pw_stream_state state,
const char* error_message);
+#if PW_CHECK_VERSION(0, 2, 90)
+ static void OnStreamParamChanged(void* data, uint32_t id, const struct spa_pod* format);
+#else
static void OnStreamFormatChanged(void* data, const struct spa_pod* format);
+#endif
+
static void OnStreamProcess(void* data);
static void OnNewBuffer(void* data, uint32_t id);
Index: chromium-81.0.4044.83/third_party/webrtc/webrtc.gni
===================================================================
--- chromium-81.0.4044.83.orig/third_party/webrtc/webrtc.gni
+++ chromium-81.0.4044.83/third_party/webrtc/webrtc.gni
@@ -114,6 +114,9 @@ declare_args() {
# supported Ubuntu and Debian distributions.
rtc_use_pipewire = is_desktop_linux && use_sysroot
+ # Sets the pipewire pkg-config version to use if rtc_use_pipewire is true
+ rtc_use_pipewire_version = "0.2"
+
# Set this to link PipeWire directly instead of using the dlopen.
rtc_link_pipewire = false