package/weston: add patch to support pipewire 0.3 API
authorJames Hilliard <james.hilliard1@gmail.com>
Sun, 25 Apr 2021 21:24:59 +0000 (23:24 +0200)
committerArnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
Mon, 26 Apr 2021 19:05:20 +0000 (21:05 +0200)
This is required when building weston against the latest pipewire
release.

Signed-off-by: James Hilliard <james.hilliard1@gmail.com>
Signed-off-by: Fabrice Fontaine <fontaine.fabrice@gmail.com>
Signed-off-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
package/weston/0003-pipewire-add-support-for-0.3-API.patch [new file with mode: 0644]
package/weston/0004-pipewire-fix-null-deref-in-0-3-API.patch [new file with mode: 0644]

diff --git a/package/weston/0003-pipewire-add-support-for-0.3-API.patch b/package/weston/0003-pipewire-add-support-for-0.3-API.patch
new file mode 100644 (file)
index 0000000..b486b3d
--- /dev/null
@@ -0,0 +1,391 @@
+From cc08737e3fd174ec3c4c208ea4f2a3a6a9e8af3e Mon Sep 17 00:00:00 2001
+From: James Hilliard <james.hilliard1@gmail.com>
+Date: Mon, 6 Jul 2020 00:58:02 -0600
+Subject: [PATCH] pipewire: add support for 0.3 API
+
+Fixes: #369
+
+Signed-off-by: James Hilliard <james.hilliard1@gmail.com>
+[james.hilliard1@gmail.com: backport from upstream commit
+80b585f8d2a31e780b4de41fbd187a742bea7e1a]
+---
+ .gitlab-ci.yml               |   2 +-
+ .gitlab-ci/debian-install.sh |  16 ++++-
+ pipewire/meson.build         |  28 ++++++---
+ pipewire/pipewire-plugin.c   | 118 ++++++++++++++++++++++++++++++++++-
+ 4 files changed, 151 insertions(+), 13 deletions(-)
+
+diff --git a/pipewire/meson.build b/pipewire/meson.build
+index 3d3374b8..e30a0b62 100644
+--- a/pipewire/meson.build
++++ b/pipewire/meson.build
+@@ -5,17 +5,25 @@ if get_option('pipewire')
+               error('Attempting to build the pipewire plugin without the required DRM backend. ' + user_hint)
+       endif
+-      depnames = [
+-              'libpipewire-0.2', 'libspa-0.1'
+-      ]
+       deps_pipewire = [ dep_libweston_private ]
+-      foreach depname : depnames
+-              dep = dependency(depname, required: false)
+-              if not dep.found()
+-                      error('Pipewire plugin requires @0@ which was not found. '.format(depname) + user_hint)
+-              endif
+-              deps_pipewire += dep
+-      endforeach
++
++      dep_libpipewire = dependency('libpipewire-0.3', required: false)
++      if not dep_libpipewire.found()
++              dep_libpipewire = dependency('libpipewire-0.2', required: false)
++      endif
++      if not dep_libpipewire.found()
++              error('Pipewire plugin requires libpipewire which was not found. ' + user_hint)
++      endif
++      deps_pipewire += dep_libpipewire
++
++      dep_libspa = dependency('libspa-0.2', required: false)
++      if not dep_libspa.found()
++              dep_libspa = dependency('libspa-0.1', required: false)
++      endif
++      if not dep_libspa.found()
++              error('Pipewire plugin requires libspa which was not found. ' + user_hint)
++      endif
++      deps_pipewire += dep_libspa
+       plugin_pipewire = shared_library(
+               'pipewire-plugin',
+diff --git a/pipewire/pipewire-plugin.c b/pipewire/pipewire-plugin.c
+index 6f892574..ce70ea63 100644
+--- a/pipewire/pipewire-plugin.c
++++ b/pipewire/pipewire-plugin.c
+@@ -34,20 +34,27 @@
+ #include <errno.h>
+ #include <unistd.h>
++#include <pipewire/pipewire.h>
++
+ #include <spa/param/format-utils.h>
+ #include <spa/param/video/format-utils.h>
+ #include <spa/utils/defs.h>
+-#include <pipewire/pipewire.h>
++#if PW_CHECK_VERSION(0, 2, 90)
++#include <spa/buffer/meta.h>
++#include <spa/utils/result.h>
++#endif
+ #define PROP_RANGE(min, max) 2, (min), (max)
++#if !PW_CHECK_VERSION(0, 2, 90)
+ struct type {
+       struct spa_type_media_type media_type;
+       struct spa_type_media_subtype media_subtype;
+       struct spa_type_format_video format_video;
+       struct spa_type_video_format video_format;
+ };
++#endif
+ struct weston_pipewire {
+       struct weston_compositor *compositor;
+@@ -60,12 +67,19 @@ struct weston_pipewire {
+       struct pw_loop *loop;
+       struct wl_event_source *loop_source;
++#if PW_CHECK_VERSION(0, 2, 90)
++      struct pw_context *context;
++#endif
+       struct pw_core *core;
+       struct pw_type *t;
++#if PW_CHECK_VERSION(0, 2, 90)
++      struct spa_hook core_listener;
++#else
+       struct type type;
+       struct pw_remote *remote;
+       struct spa_hook remote_listener;
++#endif
+ };
+ struct pipewire_output {
+@@ -100,6 +114,7 @@ struct pipewire_frame_data {
+       struct wl_event_source *fence_sync_event_source;
+ };
++#if !PW_CHECK_VERSION(0, 2, 90)
+ static inline void init_type(struct type *type, struct spa_type_map *map)
+ {
+       spa_type_media_type_map(map, &type->media_type);
+@@ -107,6 +122,7 @@ static inline void init_type(struct type *type, struct spa_type_map *map)
+       spa_type_format_video_map(map, &type->format_video);
+       spa_type_video_format_map(map, &type->video_format);
+ }
++#endif
+ static void
+ pipewire_debug_impl(struct weston_pipewire *pipewire,
+@@ -141,6 +157,7 @@ pipewire_debug_impl(struct weston_pipewire *pipewire,
+       free(logstr);
+ }
++#if !PW_CHECK_VERSION(0, 2, 90)
+ static void
+ pipewire_debug(struct weston_pipewire *pipewire, const char *fmt, ...)
+ {
+@@ -150,6 +167,7 @@ pipewire_debug(struct weston_pipewire *pipewire, const char *fmt, ...)
+       pipewire_debug_impl(pipewire, NULL, fmt, ap);
+       va_end(ap);
+ }
++#endif
+ static void
+ pipewire_output_debug(struct pipewire_output *output, const char *fmt, ...)
+@@ -185,7 +203,9 @@ pipewire_output_handle_frame(struct pipewire_output *output, int fd,
+       const struct weston_drm_virtual_output_api *api =
+               output->pipewire->virtual_output_api;
+       size_t size = output->output->height * stride;
++#if !PW_CHECK_VERSION(0, 2, 90)
+       struct pw_type *t = output->pipewire->t;
++#endif
+       struct pw_buffer *buffer;
+       struct spa_buffer *spa_buffer;
+       struct spa_meta_header *h;
+@@ -203,7 +223,12 @@ pipewire_output_handle_frame(struct pipewire_output *output, int fd,
+       spa_buffer = buffer->buffer;
++#if PW_CHECK_VERSION(0, 2, 90)
++      if ((h = spa_buffer_find_meta_data(spa_buffer, SPA_META_Header,
++                                   sizeof(struct spa_meta_header)))) {
++#else
+       if ((h = spa_buffer_find_meta(spa_buffer, t->meta.Header))) {
++#endif
+               h->pts = -1;
+               h->flags = 0;
+               h->seq = output->seq++;
+@@ -375,18 +400,40 @@ pipewire_set_dpms(struct weston_output *base_output, enum dpms_enum level)
+ static int
+ pipewire_output_connect(struct pipewire_output *output)
+ {
++#if !PW_CHECK_VERSION(0, 2, 90)
+       struct weston_pipewire *pipewire = output->pipewire;
+       struct type *type = &pipewire->type;
++#endif
+       uint8_t buffer[1024];
+       struct spa_pod_builder builder =
+               SPA_POD_BUILDER_INIT(buffer, sizeof(buffer));
+       const struct spa_pod *params[1];
++#if !PW_CHECK_VERSION(0, 2, 90)
+       struct pw_type *t = pipewire->t;
++#endif
+       int frame_rate = output->output->current_mode->refresh / 1000;
+       int width = output->output->width;
+       int height = output->output->height;
+       int ret;
++#if PW_CHECK_VERSION(0, 2, 90)
++      params[0] = spa_pod_builder_add_object(&builder,
++              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_Rectangle(&SPA_RECTANGLE(width, height)),
++              SPA_FORMAT_VIDEO_framerate, SPA_POD_Fraction(&SPA_FRACTION (0, 1)),
++              SPA_FORMAT_VIDEO_maxFramerate,
++              SPA_POD_CHOICE_RANGE_Fraction(&SPA_FRACTION(frame_rate, 1),
++                      &SPA_FRACTION(1, 1),
++                      &SPA_FRACTION(frame_rate, 1)));
++
++      ret = pw_stream_connect(output->stream, PW_DIRECTION_OUTPUT, SPA_ID_INVALID,
++                              (PW_STREAM_FLAG_DRIVER |
++                               PW_STREAM_FLAG_MAP_BUFFERS),
++                              params, 1);
++#else
+       params[0] = spa_pod_builder_object(&builder,
+               t->param.idEnumFormat, t->spa_format,
+               "I", type->media_type.video,
+@@ -406,6 +453,7 @@ pipewire_output_connect(struct pipewire_output *output)
+                               (PW_STREAM_FLAG_DRIVER |
+                                PW_STREAM_FLAG_MAP_BUFFERS),
+                               params, 1);
++#endif
+       if (ret != 0) {
+               weston_log("Failed to connect pipewire stream: %s",
+                          spa_strerror(ret));
+@@ -482,26 +530,42 @@ pipewire_output_stream_state_changed(void *data, enum pw_stream_state old,
+ }
+ static void
++#if PW_CHECK_VERSION(0, 2, 90)
++pipewire_output_stream_param_changed(void *data, uint32_t id, const struct spa_pod *format)
++#else
+ pipewire_output_stream_format_changed(void *data, const struct spa_pod *format)
++#endif
+ {
+       struct pipewire_output *output = data;
++#if !PW_CHECK_VERSION(0, 2, 90)
+       struct weston_pipewire *pipewire = output->pipewire;
++#endif
+       uint8_t buffer[1024];
+       struct spa_pod_builder builder =
+               SPA_POD_BUILDER_INIT(buffer, sizeof(buffer));
+       const struct spa_pod *params[2];
++#if !PW_CHECK_VERSION(0, 2, 90)
+       struct pw_type *t = pipewire->t;
++#endif
+       int32_t width, height, stride, size;
+       const int bpp = 4;
+       if (!format) {
+               pipewire_output_debug(output, "format = None");
++#if PW_CHECK_VERSION(0, 2, 90)
++              pw_stream_update_params(output->stream, NULL, 0);
++#else
+               pw_stream_finish_format(output->stream, 0, NULL, 0);
++#endif
+               return;
+       }
++#if PW_CHECK_VERSION(0, 2, 90)
++      spa_format_video_raw_parse(format, &output->video_format);
++#else
+       spa_format_video_raw_parse(format, &output->video_format,
+                                  &pipewire->type.format_video);
++#endif
+       width = output->video_format.size.width;
+       height = output->video_format.size.height;
+@@ -510,6 +574,21 @@ pipewire_output_stream_format_changed(void *data, const struct spa_pod *format)
+       pipewire_output_debug(output, "format = %dx%d", width, height);
++#if PW_CHECK_VERSION(0, 2, 90)
++      params[0] = spa_pod_builder_add_object(&builder,
++              SPA_TYPE_OBJECT_ParamBuffers, SPA_PARAM_Buffers,
++              SPA_PARAM_BUFFERS_size, SPA_POD_Int(size),
++              SPA_PARAM_BUFFERS_stride, SPA_POD_Int(stride),
++              SPA_PARAM_BUFFERS_buffers, SPA_POD_CHOICE_RANGE_Int(4, 2, 8),
++              SPA_PARAM_BUFFERS_align, SPA_POD_Int(16));
++
++      params[1] = 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(output->stream, params, 2);
++#else
+       params[0] = spa_pod_builder_object(&builder,
+               t->param.idBuffers, t->param_buffers.Buffers,
+               ":", t->param_buffers.size,
+@@ -527,12 +606,17 @@ pipewire_output_stream_format_changed(void *data, const struct spa_pod *format)
+               ":", t->param_meta.size, "i", sizeof(struct spa_meta_header));
+       pw_stream_finish_format(output->stream, 0, params, 2);
++#endif
+ }
+ static const struct pw_stream_events stream_events = {
+       PW_VERSION_STREAM_EVENTS,
+       .state_changed = pipewire_output_stream_state_changed,
++#if PW_CHECK_VERSION(0, 2, 90)
++      .param_changed = pipewire_output_stream_param_changed,
++#else
+       .format_changed = pipewire_output_stream_format_changed,
++#endif
+ };
+ static struct weston_output *
+@@ -560,7 +644,11 @@ pipewire_output_create(struct weston_compositor *c, char *name)
+       if (!head)
+               goto err;
++#if PW_CHECK_VERSION(0, 2, 90)
++      output->stream = pw_stream_new(pipewire->core, name, NULL);
++#else
+       output->stream = pw_stream_new(pipewire->remote, name, NULL);
++#endif
+       if (!output->stream) {
+               weston_log("Cannot initialize pipewire stream\n");
+               goto err;
+@@ -704,6 +792,14 @@ weston_pipewire_loop_handler(int fd, uint32_t mask, void *data)
+       return 0;
+ }
++#if PW_CHECK_VERSION(0, 2, 90)
++static void
++weston_pipewire_error(void *data, uint32_t id, int seq, int res,
++                            const char *error)
++{
++      weston_log("pipewire remote error: %s\n", error);
++}
++#else
+ static void
+ weston_pipewire_state_changed(void *data, enum pw_remote_state old,
+                             enum pw_remote_state state, const char *error)
+@@ -725,12 +821,20 @@ weston_pipewire_state_changed(void *data, enum pw_remote_state old,
+               break;
+       }
+ }
++#endif
++#if PW_CHECK_VERSION(0, 2, 90)
++static const struct pw_core_events core_events = {
++      PW_VERSION_CORE_EVENTS,
++      .error = weston_pipewire_error,
++};
++#else
+ static const struct pw_remote_events remote_events = {
+       PW_VERSION_REMOTE_EVENTS,
+       .state_changed = weston_pipewire_state_changed,
+ };
++#endif
+ static int
+ weston_pipewire_init(struct weston_pipewire *pipewire)
+@@ -745,10 +849,19 @@ weston_pipewire_init(struct weston_pipewire *pipewire)
+       pw_loop_enter(pipewire->loop);
++#if PW_CHECK_VERSION(0, 2, 90)
++      pipewire->context = pw_context_new(pipewire->loop, NULL, 0);
++#else
+       pipewire->core = pw_core_new(pipewire->loop, NULL);
+       pipewire->t = pw_core_get_type(pipewire->core);
+       init_type(&pipewire->type, pipewire->t->map);
++#endif
++#if PW_CHECK_VERSION(0, 2, 90)
++      pw_core_add_listener(pipewire->core,
++                             &pipewire->core_listener,
++                             &core_events, pipewire);
++#else
+       pipewire->remote = pw_remote_new(pipewire->core, NULL, 0);
+       pw_remote_add_listener(pipewire->remote,
+                              &pipewire->remote_listener,
+@@ -777,6 +890,7 @@ weston_pipewire_init(struct weston_pipewire *pipewire)
+                       goto err;
+               }
+       }
++#endif
+       loop = wl_display_get_event_loop(pipewire->compositor->wl_display);
+       pipewire->loop_source =
+@@ -786,12 +900,14 @@ weston_pipewire_init(struct weston_pipewire *pipewire)
+                                    pipewire);
+       return 0;
++#if !PW_CHECK_VERSION(0, 2, 90)
+ err:
+       if (pipewire->remote)
+               pw_remote_destroy(pipewire->remote);
+       pw_loop_leave(pipewire->loop);
+       pw_loop_destroy(pipewire->loop);
+       return -1;
++#endif
+ }
+ static const struct weston_pipewire_api pipewire_api = {
+-- 
+2.25.1
+
diff --git a/package/weston/0004-pipewire-fix-null-deref-in-0-3-API.patch b/package/weston/0004-pipewire-fix-null-deref-in-0-3-API.patch
new file mode 100644 (file)
index 0000000..f65348e
--- /dev/null
@@ -0,0 +1,28 @@
+From a67393c353e0f25b142910a817be5a7754d436c3 Mon Sep 17 00:00:00 2001
+From: Ambareesh Balaji <ambareeshbalaji@gmail.com>
+Date: Sat, 5 Dec 2020 20:49:55 -0500
+Subject: [PATCH] pipewire: fix null deref in 0.3 API
+
+Signed-off-by: Ambareesh Balaji <ambareeshbalaji@gmail.com>
+[Retrieved from:
+https://gitlab.freedesktop.org/wayland/weston/-/commit/a67393c353e0f25b142910a817be5a7754d436c3]
+Signed-off-by: Fabrice Fontaine <fontaine.fabrice@gmail.com>
+---
+ pipewire/pipewire-plugin.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/pipewire/pipewire-plugin.c b/pipewire/pipewire-plugin.c
+index ca5cbfec1..55705acfc 100644
+--- a/pipewire/pipewire-plugin.c
++++ b/pipewire/pipewire-plugin.c
+@@ -856,6 +856,7 @@ weston_pipewire_init(struct weston_pipewire *pipewire)
+ #if PW_CHECK_VERSION(0, 2, 90)
+       pipewire->context = pw_context_new(pipewire->loop, NULL, 0);
++      pipewire->core = pw_context_connect(pipewire->context, NULL, 0);
+ #else
+       pipewire->core = pw_core_new(pipewire->loop, NULL);
+       pipewire->t = pw_core_get_type(pipewire->core);
+-- 
+GitLab
+