From c063d43be84dd445a02700c7bb1bf77aea65bb61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Wed, 24 Jan 2018 15:25:59 +0800 Subject: [PATCH] screen-cast: Update to pipewire 0.1.8 API Remove per micro version code, the API changed too much to keep both in place. https://bugzilla.gnome.org/show_bug.cgi?id=792854 --- configure.ac | 6 +- src/backends/meta-screen-cast-stream-src.c | 151 ++++++++------------- 2 files changed, 56 insertions(+), 101 deletions(-) diff --git a/configure.ac b/configure.ac index 7399f741a..78d9d3362 100644 --- a/configure.ac +++ b/configure.ac @@ -245,11 +245,7 @@ AC_ARG_ENABLE(remote-desktop, enable_remote_desktop=no ) AS_IF([test "$enable_remote_desktop" = "yes"], [ - MUTTER_PC_MODULES="$MUTTER_PC_MODULES libpipewire-0.1 >= 0.1.4" - PKG_CHECK_EXISTS([libpipewire-0.1], [ - pw_micro=`$PKG_CONFIG --modversion libpipewire-0.1 | cut -d. -f3` - AC_DEFINE_UNQUOTED([PIPEWIRE_VERSION_MICRO],[$pw_micro], [Pipewire micro version used]) - ]) + MUTTER_PC_MODULES="$MUTTER_PC_MODULES libpipewire-0.1 >= 0.1.8" AC_DEFINE([HAVE_REMOTE_DESKTOP],[1], [Defined if screen cast and remote desktop support is enabled]) ]) AM_CONDITIONAL([HAVE_REMOTE_DESKTOP],[test "$enable_remote_desktop" = "yes"]) diff --git a/src/backends/meta-screen-cast-stream-src.c b/src/backends/meta-screen-cast-stream-src.c index 0343ea458..cef49a13a 100644 --- a/src/backends/meta-screen-cast-stream-src.c +++ b/src/backends/meta-screen-cast-stream-src.c @@ -26,11 +26,9 @@ #include #include -#include -#include -#include -#include -#include +#include +#include +#include #include #include @@ -61,10 +59,6 @@ static guint signals[N_SIGNALS]; typedef struct _MetaSpaType { - uint32_t format; - uint32_t props; - struct spa_type_meta meta; - struct spa_type_data data; struct spa_type_media_type media_type; struct spa_type_media_subtype media_subtype; struct spa_type_format_video format_video; @@ -94,7 +88,6 @@ typedef struct _MetaScreenCastStreamSrcPrivate struct spa_hook pipewire_stream_listener; MetaSpaType spa_type; - uint8_t params_buffer[1024]; struct spa_video_info_raw video_format; uint64_t last_frame_timestamp_us; @@ -110,12 +103,7 @@ G_DEFINE_TYPE_WITH_CODE (MetaScreenCastStreamSrc, meta_screen_cast_stream_src_init_initable_iface) G_ADD_PRIVATE (MetaScreenCastStreamSrc)) -#define PROP(f, key, type, ...) \ - SPA_POD_PROP (f, key, 0, type, 1, __VA_ARGS__) -#define PROP_U_MM(f, key, type, ...) \ - SPA_POD_PROP (f, key, (SPA_POD_PROP_FLAG_UNSET | \ - SPA_POD_PROP_RANGE_MIN_MAX), \ - type, 3, __VA_ARGS__) +#define PROP_RANGE(min, max) 2, (min), (max) static void meta_screen_cast_stream_src_get_specs (MetaScreenCastStreamSrc *src, @@ -166,7 +154,7 @@ meta_screen_cast_stream_src_maybe_record_frame (MetaScreenCastStreamSrc *src) buffer = pw_stream_peek_buffer (priv->pipewire_stream, buffer_id); - if (buffer->datas[0].type == priv->spa_type.data.MemFd) + if (buffer->datas[0].type == priv->pipewire_type->data.MemFd) { map = mmap (NULL, buffer->datas[0].maxsize + buffer->datas[0].mapoffset, PROT_READ | PROT_WRITE, MAP_SHARED, @@ -180,7 +168,7 @@ meta_screen_cast_stream_src_maybe_record_frame (MetaScreenCastStreamSrc *src) data = SPA_MEMBER (map, buffer->datas[0].mapoffset, uint8_t); } - else if (buffer->datas[0].type == priv->spa_type.data.MemPtr) + else if (buffer->datas[0].type == priv->pipewire_type->data.MemPtr) { data = buffer->datas[0].data; } @@ -195,6 +183,8 @@ meta_screen_cast_stream_src_maybe_record_frame (MetaScreenCastStreamSrc *src) if (map) munmap (map, buffer->datas[0].maxsize + buffer->datas[0].mapoffset); + buffer->datas[0].chunk->size = buffer->datas[0].maxsize; + pw_stream_send_buffer (priv->pipewire_stream, buffer_id); } @@ -271,23 +261,22 @@ on_stream_state_changed (void *data, } static void -on_stream_format_changed (void *data, - struct spa_format *format) +on_stream_format_changed (void *data, + struct spa_pod *format) { MetaScreenCastStreamSrc *src = data; MetaScreenCastStreamSrcPrivate *priv = meta_screen_cast_stream_src_get_instance_private (src); struct pw_type *pipewire_type = priv->pipewire_type; - struct spa_type_param_alloc_buffers *param_alloc_buffers; - struct spa_pod_builder pod_builder = { NULL }; - struct spa_pod_frame object_frame; - struct spa_pod_frame prop_frame; - struct spa_param *params[1]; + uint8_t params_buffer[1024]; + int32_t width, height, stride, size; + struct spa_pod_builder pod_builder; + struct spa_pod *params[1]; const int bpp = 4; if (!format) { - pw_stream_finish_format (priv->pipewire_stream, SPA_RESULT_OK, NULL, 0); + pw_stream_finish_format (priv->pipewire_stream, 0, NULL, 0); return; } @@ -295,31 +284,22 @@ on_stream_format_changed (void *data, &priv->video_format, &priv->spa_type.format_video); - spa_pod_builder_init (&pod_builder, - priv->params_buffer, - sizeof (priv->params_buffer)); + width = priv->video_format.size.width; + height = priv->video_format.size.height; + stride = SPA_ROUND_UP_N (width * bpp, 4); + size = height * stride; - param_alloc_buffers = &pipewire_type->param_alloc_buffers; - spa_pod_builder_object (&pod_builder, &object_frame, 0, - param_alloc_buffers->Buffers, - PROP (&prop_frame, param_alloc_buffers->size, - SPA_POD_TYPE_INT, - (priv->video_format.size.width * - priv->video_format.size.height * - bpp)), - PROP (&prop_frame, param_alloc_buffers->stride, - SPA_POD_TYPE_INT, - priv->video_format.size.width * bpp), - PROP_U_MM (&prop_frame, param_alloc_buffers->buffers, - SPA_POD_TYPE_INT, - 16, 2, 16), - PROP (&prop_frame, param_alloc_buffers->align, - SPA_POD_TYPE_INT, - 16)); - params[0] = SPA_POD_BUILDER_DEREF (&pod_builder, object_frame.ref, - struct spa_param); + pod_builder = SPA_POD_BUILDER_INIT (params_buffer, sizeof (params_buffer)); - pw_stream_finish_format (priv->pipewire_stream, SPA_RESULT_OK, + params[0] = spa_pod_builder_object ( + &pod_builder, + pipewire_type->param.idBuffers, pipewire_type->param_buffers.Buffers, + ":", pipewire_type->param_buffers.size, "i", size, + ":", pipewire_type->param_buffers.stride, "i", stride, + ":", pipewire_type->param_buffers.buffers, "iru", 16, PROP_RANGE (2, 16), + ":", pipewire_type->param_buffers.align, "i", 16); + + pw_stream_finish_format (priv->pipewire_stream, 0, params, G_N_ELEMENTS (params)); } @@ -336,16 +316,17 @@ create_pipewire_stream (MetaScreenCastStreamSrc *src, MetaScreenCastStreamSrcPrivate *priv = meta_screen_cast_stream_src_get_instance_private (src); struct pw_stream *pipewire_stream; - const struct spa_format *format; uint8_t buffer[1024]; struct spa_pod_builder pod_builder = SPA_POD_BUILDER_INIT (buffer, sizeof (buffer)); - struct spa_pod_frame format_frame; - struct spa_pod_frame prop_frame; MetaSpaType *spa_type = &priv->spa_type; + struct pw_type *pipewire_type = priv->pipewire_type; int width, height; float frame_rate; MetaFraction frame_rate_fraction; + struct spa_fraction max_framerate; + struct spa_fraction min_framerate; + const struct spa_pod *params[1]; pipewire_stream = pw_stream_new (priv->pipewire_remote, "meta-screen-cast-src", @@ -354,42 +335,32 @@ create_pipewire_stream (MetaScreenCastStreamSrc *src, meta_screen_cast_stream_src_get_specs (src, &width, &height, &frame_rate); frame_rate_fraction = meta_fraction_from_double (frame_rate); - spa_pod_builder_format (&pod_builder, &format_frame, - spa_type->format, - spa_type->media_type.video, - spa_type->media_subtype.raw, - PROP (&prop_frame, - spa_type->format_video.format, - SPA_POD_TYPE_ID, spa_type->video_format.BGRx), - PROP (&prop_frame, - spa_type->format_video.size, - SPA_POD_TYPE_RECTANGLE, - width, height), - PROP (&prop_frame, - spa_type->format_video.framerate, - SPA_POD_TYPE_FRACTION, - 0, 1), - PROP_U_MM (&prop_frame, - spa_type->format_video.max_framerate, - SPA_POD_TYPE_FRACTION, - frame_rate_fraction.num, - frame_rate_fraction.denom, - 1, 1, - frame_rate_fraction.num, - frame_rate_fraction.denom)); - format = SPA_POD_BUILDER_DEREF (&pod_builder, format_frame.ref, struct spa_format); + min_framerate = SPA_FRACTION (1, 1); + max_framerate = SPA_FRACTION (frame_rate_fraction.num, + frame_rate_fraction.denom); + + params[0] = spa_pod_builder_object ( + &pod_builder, + pipewire_type->param.idEnumFormat, pipewire_type->spa_format, + "I", spa_type->media_type.video, + "I", spa_type->media_subtype.raw, + ":", spa_type->format_video.format, "I", spa_type->video_format.BGRx, + ":", spa_type->format_video.size, "R", &SPA_RECTANGLE (width, height), + ":", spa_type->format_video.framerate, "F", &SPA_FRACTION (0, 1), + ":", spa_type->format_video.max_framerate, "Fr", &max_framerate, + PROP_RANGE (&min_framerate, + &max_framerate)); pw_stream_add_listener (pipewire_stream, &priv->pipewire_stream_listener, &stream_events, src); - if (!pw_stream_connect (pipewire_stream, - PW_DIRECTION_OUTPUT, - PW_STREAM_MODE_BUFFER, - NULL, - PW_STREAM_FLAG_NONE, - 1, &format)) + if (pw_stream_connect (pipewire_stream, + PW_DIRECTION_OUTPUT, + NULL, + PW_STREAM_FLAG_NONE, + params, G_N_ELEMENTS (¶ms)) != 0) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Could not connect"); @@ -453,10 +424,8 @@ pipewire_loop_source_dispatch (GSource *source, int result; result = pw_loop_iterate (pipewire_source->pipewire_loop, 0); - if (result == SPA_RESULT_ERRNO) - g_warning ("pipewire_loop_iterate failed: %s", strerror (errno)); - else if (result != SPA_RESULT_OK) - g_warning ("pipewire_loop_iterate failed: %d", result); + if (result < 0) + g_warning ("pipewire_loop_iterate failed: %s", spa_strerror (result)); return TRUE; } @@ -482,10 +451,6 @@ static void init_spa_type (MetaSpaType *type, struct spa_type_map *map) { - type->format = spa_type_map_get_id (map, SPA_TYPE__Format); - type->props = spa_type_map_get_id (map, SPA_TYPE__Props); - spa_type_meta_map (map, &type->meta); - spa_type_data_map (map, &type->data); spa_type_media_type_map (map, &type->media_type); spa_type_media_subtype_map (map, &type->media_subtype); spa_type_format_video_map (map, &type->format_video); @@ -535,13 +500,7 @@ meta_screen_cast_stream_src_initable_init (GInitable *initable, return FALSE; } -#if PIPEWIRE_VERSION_MICRO == 4 - priv->pipewire_remote = pw_remote_new (priv->pipewire_core, NULL); -#elif PIPEWIRE_VERSION_MICRO >= 5 priv->pipewire_remote = pw_remote_new (priv->pipewire_core, NULL, 0); -#else - priv->pipewire_remote = NULL; -#endif if (!priv->pipewire_remote) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,