[mutter] screen-cast: Update to PipeWire 0.3 API



commit c5d2fc856a28b3a4f26ffffa420cbd9ff92875bb
Author: Wim Taymans <wtaymans redhat com>
Date:   Tue Jan 14 09:44:45 2020 +0100

    screen-cast: Update to PipeWire 0.3 API
    
    Update to 0.3 API
    
    [jadahl: update Dockerfile to include new enough pipewire]
    
    Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/1051
    
    https://gitlab.gnome.org/GNOME/mutter/merge_requests/1062

 .gitlab-ci/Dockerfile                      |   3 +
 meson.build                                |   4 +-
 src/backends/meta-screen-cast-stream-src.c | 255 +++++++++++------------------
 3 files changed, 104 insertions(+), 158 deletions(-)
---
diff --git a/.gitlab-ci/Dockerfile b/.gitlab-ci/Dockerfile
index 9accc9756..393c76394 100644
--- a/.gitlab-ci/Dockerfile
+++ b/.gitlab-ci/Dockerfile
@@ -11,6 +11,7 @@ RUN dnf -y update && dnf -y upgrade && \
     dnf install -y 'dnf-command(builddep)' && \
     dnf install -y 'dnf-command(copr)' && \
     dnf copr enable -y fmuellner/gnome-shell-ci && \
+    dnf copr enable -y jadahl/mutter-ci && \
     dnf -y update && dnf -y upgrade && \
 
     dnf builddep -y mutter && \
@@ -26,4 +27,6 @@ RUN dnf -y update && dnf -y upgrade && \
     dnf remove -y gnome-bluetooth-libs-devel dbus-glib-devel upower-devel python3-devel && \
     dnf remove -y --noautoremove mutter mutter-devel && \
 
+    dnf upgrade -y 'pkgconfig(libpipewire-0.3)' && \
+
     dnf clean all
diff --git a/meson.build b/meson.build
index daa6cc6fb..e071a5e40 100644
--- a/meson.build
+++ b/meson.build
@@ -50,7 +50,7 @@ libinput_req = '>= 1.7'
 gbm_req = '>= 10.3'
 
 # screen cast version requirements
-libpipewire_req = '>= 0.2.5'
+libpipewire_req = '>= 0.3.0'
 
 gnome = import('gnome')
 pkg = import('pkgconfig')
@@ -241,7 +241,7 @@ endif
 
 have_remote_desktop = get_option('remote_desktop')
 if have_remote_desktop
-  libpipewire_dep = dependency('libpipewire-0.2', version: libpipewire_req)
+  libpipewire_dep = dependency('libpipewire-0.3', version: libpipewire_req)
 endif
 
 have_introspection = get_option('introspection')
diff --git a/src/backends/meta-screen-cast-stream-src.c b/src/backends/meta-screen-cast-stream-src.c
index 82c5cba43..ba1ce94a7 100644
--- a/src/backends/meta-screen-cast-stream-src.c
+++ b/src/backends/meta-screen-cast-stream-src.c
@@ -29,6 +29,7 @@
 #include <spa/param/props.h>
 #include <spa/param/format-utils.h>
 #include <spa/param/video/format-utils.h>
+#include <spa/utils/result.h>
 #include <stdint.h>
 #include <sys/mman.h>
 
@@ -62,15 +63,6 @@ enum
 
 static guint signals[N_SIGNALS];
 
-typedef struct _MetaSpaType
-{
-  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;
-  uint32_t meta_cursor;
-} MetaSpaType;
-
 typedef struct _MetaPipeWireSource
 {
   GSource base;
@@ -82,19 +74,19 @@ typedef struct _MetaScreenCastStreamSrcPrivate
 {
   MetaScreenCastStream *stream;
 
+  struct pw_context *pipewire_context;
   struct pw_core *pipewire_core;
-  struct pw_remote *pipewire_remote;
-  struct pw_type *pipewire_type;
   MetaPipeWireSource *pipewire_source;
-  struct spa_hook pipewire_remote_listener;
+  struct spa_hook pipewire_core_listener;
 
   gboolean is_enabled;
 
   struct pw_stream *pipewire_stream;
   struct spa_hook pipewire_stream_listener;
+  uint32_t node_id;
 
-  MetaSpaType spa_type;
   struct spa_video_info_raw video_format;
+  int video_stride;
 
   uint64_t last_frame_timestamp_us;
 
@@ -112,8 +104,6 @@ G_DEFINE_TYPE_WITH_CODE (MetaScreenCastStreamSrc,
                                                 meta_screen_cast_stream_src_init_initable_iface)
                          G_ADD_PRIVATE (MetaScreenCastStreamSrc))
 
-#define PROP_RANGE(min, max) 2, (min), (max)
-
 static void
 meta_screen_cast_stream_src_get_specs (MetaScreenCastStreamSrc *src,
                                        int                     *width,
@@ -286,9 +276,6 @@ meta_screen_cast_stream_src_set_empty_cursor_sprite_metadata (MetaScreenCastStre
                                                               int                      x,
                                                               int                      y)
 {
-  MetaScreenCastStreamSrcPrivate *priv =
-    meta_screen_cast_stream_src_get_instance_private (src);
-  MetaSpaType *spa_type = &priv->spa_type;
   struct spa_meta_bitmap *spa_meta_bitmap;
 
   spa_meta_cursor->id = 1;
@@ -300,7 +287,7 @@ meta_screen_cast_stream_src_set_empty_cursor_sprite_metadata (MetaScreenCastStre
   spa_meta_bitmap = SPA_MEMBER (spa_meta_cursor,
                                 spa_meta_cursor->bitmap_offset,
                                 struct spa_meta_bitmap);
-  spa_meta_bitmap->format = spa_type->video_format.RGBA;
+  spa_meta_bitmap->format = SPA_VIDEO_FORMAT_RGBA;
   spa_meta_bitmap->offset = sizeof (struct spa_meta_bitmap);
 
   spa_meta_cursor->hotspot.x = 0;
@@ -317,9 +304,6 @@ meta_screen_cast_stream_src_set_cursor_sprite_metadata (MetaScreenCastStreamSrc
                                                         int                      y,
                                                         float                    scale)
 {
-  MetaScreenCastStreamSrcPrivate *priv =
-    meta_screen_cast_stream_src_get_instance_private (src);
-  MetaSpaType *spa_type = &priv->spa_type;
   CoglTexture *cursor_texture;
   struct spa_meta_bitmap *spa_meta_bitmap;
   int hotspot_x, hotspot_y;
@@ -346,7 +330,7 @@ meta_screen_cast_stream_src_set_cursor_sprite_metadata (MetaScreenCastStreamSrc
   spa_meta_bitmap = SPA_MEMBER (spa_meta_cursor,
                                 spa_meta_cursor->bitmap_offset,
                                 struct spa_meta_bitmap);
-  spa_meta_bitmap->format = spa_type->video_format.RGBA;
+  spa_meta_bitmap->format = SPA_VIDEO_FORMAT_RGBA;
   spa_meta_bitmap->offset = sizeof (struct spa_meta_bitmap);
 
   meta_cursor_sprite_get_hotspot (cursor_sprite, &hotspot_x, &hotspot_y);
@@ -382,12 +366,10 @@ static void
 add_cursor_metadata (MetaScreenCastStreamSrc *src,
                      struct spa_buffer       *spa_buffer)
 {
-  MetaScreenCastStreamSrcPrivate *priv =
-    meta_screen_cast_stream_src_get_instance_private (src);
-  MetaSpaType *spa_type = &priv->spa_type;
   struct spa_meta_cursor *spa_meta_cursor;
 
-  spa_meta_cursor = spa_buffer_find_meta (spa_buffer, spa_type->meta_cursor);
+  spa_meta_cursor = spa_buffer_find_meta_data (spa_buffer, SPA_META_Cursor,
+                                               sizeof (*spa_meta_cursor));
   if (spa_meta_cursor)
     meta_screen_cast_stream_src_set_cursor_metadata (src, spa_meta_cursor);
 }
@@ -447,14 +429,14 @@ meta_screen_cast_stream_src_maybe_record_frame (MetaScreenCastStreamSrc *src)
     {
       data = spa_buffer->datas[0].data;
     }
-  else if (spa_buffer->datas[0].type == priv->pipewire_type->data.MemFd)
+  else if (spa_buffer->datas[0].type == SPA_DATA_MemFd)
     {
       map = mmap (NULL, spa_buffer->datas[0].maxsize + spa_buffer->datas[0].mapoffset,
                   PROT_READ | PROT_WRITE, MAP_SHARED,
                   spa_buffer->datas[0].fd, 0);
       if (map == MAP_FAILED)
         {
-          g_warning ("Failed to mmap pipewire stream buffer: %s\n",
+          g_warning ("Failed to mmap pipewire stream buffer: %s",
                      strerror (errno));
           return;
         }
@@ -469,28 +451,30 @@ meta_screen_cast_stream_src_maybe_record_frame (MetaScreenCastStreamSrc *src)
 
   if (meta_screen_cast_stream_src_record_frame (src, data))
     {
-      struct spa_meta_video_crop *spa_meta_video_crop;
+      struct spa_meta_region *spa_meta_video_crop;
 
       spa_buffer->datas[0].chunk->size = spa_buffer->datas[0].maxsize;
+      spa_buffer->datas[0].chunk->stride = priv->video_stride;
 
       /* Update VideoCrop if needed */
       spa_meta_video_crop =
-        spa_buffer_find_meta (spa_buffer, priv->pipewire_type->meta.VideoCrop);
+        spa_buffer_find_meta_data (spa_buffer, SPA_META_VideoCrop,
+                                   sizeof (*spa_meta_video_crop));
       if (spa_meta_video_crop)
         {
           if (meta_screen_cast_stream_src_get_videocrop (src, &crop_rect))
             {
-              spa_meta_video_crop->x = crop_rect.x;
-              spa_meta_video_crop->y = crop_rect.y;
-              spa_meta_video_crop->width = crop_rect.width;
-              spa_meta_video_crop->height = crop_rect.height;
+              spa_meta_video_crop->region.position.x = crop_rect.x;
+              spa_meta_video_crop->region.position.y = crop_rect.y;
+              spa_meta_video_crop->region.size.width = crop_rect.width;
+              spa_meta_video_crop->region.size.height = crop_rect.height;
             }
           else
             {
-              spa_meta_video_crop->x = 0;
-              spa_meta_video_crop->y = 0;
-              spa_meta_video_crop->width = priv->stream_width;
-              spa_meta_video_crop->height = priv->stream_height;
+              spa_meta_video_crop->region.position.x = 0;
+              spa_meta_video_crop->region.position.y = 0;
+              spa_meta_video_crop->region.size.width = priv->stream_width;
+              spa_meta_video_crop->region.size.height = priv->stream_height;
             }
         }
     }
@@ -555,7 +539,6 @@ on_stream_state_changed (void                 *data,
   MetaScreenCastStreamSrc *src = data;
   MetaScreenCastStreamSrcPrivate *priv =
     meta_screen_cast_stream_src_get_instance_private (src);
-  uint32_t node_id;
 
   switch (state)
     {
@@ -563,14 +546,12 @@ on_stream_state_changed (void                 *data,
       g_warning ("pipewire stream error: %s", error_message);
       meta_screen_cast_stream_src_notify_closed (src);
       break;
-    case PW_STREAM_STATE_CONFIGURE:
-      node_id = pw_stream_get_node_id (priv->pipewire_stream);
-      g_signal_emit (src, signals[READY], 0, (unsigned int) node_id);
-      break;
-    case PW_STREAM_STATE_UNCONNECTED:
-    case PW_STREAM_STATE_CONNECTING:
-    case PW_STREAM_STATE_READY:
     case PW_STREAM_STATE_PAUSED:
+      if (priv->node_id == SPA_ID_INVALID && priv->pipewire_stream)
+        {
+          priv->node_id = pw_stream_get_node_id (priv->pipewire_stream);
+          g_signal_emit (src, signals[READY], 0, (unsigned int) priv->node_id);
+        }
       if (meta_screen_cast_stream_src_is_enabled (src))
         meta_screen_cast_stream_src_disable (src);
       break;
@@ -578,68 +559,69 @@ on_stream_state_changed (void                 *data,
       if (!meta_screen_cast_stream_src_is_enabled (src))
         meta_screen_cast_stream_src_enable (src);
       break;
+    case PW_STREAM_STATE_UNCONNECTED:
+    case PW_STREAM_STATE_CONNECTING:
+      break;
     }
 }
 
 static void
-on_stream_format_changed (void                 *data,
-                          const struct spa_pod *format)
+on_stream_param_changed (void                 *data,
+                         uint32_t              id,
+                         const 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;
   uint8_t params_buffer[1024];
   int32_t width, height, stride, size;
   struct spa_pod_builder pod_builder;
   const struct spa_pod *params[3];
   const int bpp = 4;
 
-  if (!format)
-    {
-      pw_stream_finish_format (priv->pipewire_stream, 0, NULL, 0);
-      return;
-    }
+  if (!format || id != SPA_PARAM_Format)
+    return;
 
   spa_format_video_raw_parse (format,
-                              &priv->video_format,
-                              &priv->spa_type.format_video);
+                              &priv->video_format);
 
   width = priv->video_format.size.width;
   height = priv->video_format.size.height;
   stride = SPA_ROUND_UP_N (width * bpp, 4);
   size = height * stride;
 
+  priv->video_stride = stride;
+
   pod_builder = SPA_POD_BUILDER_INIT (params_buffer, sizeof (params_buffer));
 
-  params[0] = spa_pod_builder_object (
+  params[0] = spa_pod_builder_add_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);
-
-  params[1] = spa_pod_builder_object (
+    SPA_TYPE_OBJECT_ParamBuffers, SPA_PARAM_Buffers,
+    SPA_PARAM_BUFFERS_buffers, SPA_POD_CHOICE_RANGE_Int (16, 2, 16),
+    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));
+
+  params[1] = spa_pod_builder_add_object (
     &pod_builder,
-    pipewire_type->param.idMeta, pipewire_type->param_meta.Meta,
-    ":", pipewire_type->param_meta.type, "I", pipewire_type->meta.VideoCrop,
-    ":", pipewire_type->param_meta.size, "i", sizeof (struct spa_meta_video_crop));
+    SPA_TYPE_OBJECT_ParamMeta, SPA_PARAM_Meta,
+    SPA_PARAM_META_type, SPA_POD_Id (SPA_META_VideoCrop),
+    SPA_PARAM_META_size, SPA_POD_Int (sizeof (struct spa_meta_region)));
 
-  params[2] = spa_pod_builder_object (
+  params[2] = spa_pod_builder_add_object (
     &pod_builder,
-    pipewire_type->param.idMeta, pipewire_type->param_meta.Meta,
-    ":", pipewire_type->param_meta.type, "I", priv->spa_type.meta_cursor,
-    ":", pipewire_type->param_meta.size, "i", CURSOR_META_SIZE (64, 64));
+    SPA_TYPE_OBJECT_ParamMeta, SPA_PARAM_Meta,
+    SPA_PARAM_META_type, SPA_POD_Id (SPA_META_Cursor),
+    SPA_PARAM_META_size, SPA_POD_Int (CURSOR_META_SIZE (64, 64)));
 
-  pw_stream_finish_format (priv->pipewire_stream, 0,
-                           params, G_N_ELEMENTS (params));
+  pw_stream_update_params (priv->pipewire_stream, params, G_N_ELEMENTS (params));
 }
 
 static const struct pw_stream_events stream_events = {
   PW_VERSION_STREAM_EVENTS,
   .state_changed = on_stream_state_changed,
-  .format_changed = on_stream_format_changed,
+  .param_changed = on_stream_param_changed,
 };
 
 static struct pw_stream *
@@ -652,8 +634,6 @@ create_pipewire_stream (MetaScreenCastStreamSrc  *src,
   uint8_t buffer[1024];
   struct spa_pod_builder pod_builder =
     SPA_POD_BUILDER_INIT (buffer, sizeof (buffer));
-  MetaSpaType *spa_type = &priv->spa_type;
-  struct pw_type *pipewire_type = priv->pipewire_type;
   float frame_rate;
   MetaFraction frame_rate_fraction;
   struct spa_fraction max_framerate;
@@ -661,7 +641,9 @@ create_pipewire_stream (MetaScreenCastStreamSrc  *src,
   const struct spa_pod *params[1];
   int result;
 
-  pipewire_stream = pw_stream_new (priv->pipewire_remote,
+  priv->node_id = SPA_ID_INVALID;
+
+  pipewire_stream = pw_stream_new (priv->pipewire_core,
                                    "meta-screen-cast-src",
                                    NULL);
   if (!pipewire_stream)
@@ -682,17 +664,17 @@ create_pipewire_stream (MetaScreenCastStreamSrc  *src,
   max_framerate = SPA_FRACTION (frame_rate_fraction.num,
                                 frame_rate_fraction.denom);
 
-  params[0] = spa_pod_builder_object (
+  params[0] = spa_pod_builder_add_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 (priv->stream_width,
-                                                           priv->stream_height),
-    ":", spa_type->format_video.framerate, "F", &SPA_FRACTION (0, 1),
-    ":", spa_type->format_video.max_framerate, "Fru", &max_framerate,
-                                                      PROP_RANGE (&min_framerate,
+    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 (priv->stream_width,
+                                                              priv->stream_height)),
+    SPA_FORMAT_VIDEO_framerate, SPA_POD_Fraction (&SPA_FRACTION (0, 1)),
+    SPA_FORMAT_VIDEO_maxFramerate, SPA_POD_CHOICE_RANGE_Fraction (&max_framerate,
+                                                                  &min_framerate,
                                                                   &max_framerate));
 
   pw_stream_add_listener (pipewire_stream,
@@ -702,7 +684,7 @@ create_pipewire_stream (MetaScreenCastStreamSrc  *src,
 
   result = pw_stream_connect (pipewire_stream,
                               PW_DIRECTION_OUTPUT,
-                              NULL,
+                              SPA_ID_INVALID,
                               (PW_STREAM_FLAG_DRIVER |
                                PW_STREAM_FLAG_MAP_BUFFERS),
                               params, G_N_ELEMENTS (params));
@@ -717,40 +699,18 @@ create_pipewire_stream (MetaScreenCastStreamSrc  *src,
 }
 
 static void
-on_state_changed (void                 *data,
-                  enum pw_remote_state  old,
-                  enum pw_remote_state  state,
-                  const char           *error_message)
+on_core_error (void       *data,
+               uint32_t    id,
+              int         seq,
+              int         res,
+              const char *message)
 {
   MetaScreenCastStreamSrc *src = data;
-  MetaScreenCastStreamSrcPrivate *priv =
-    meta_screen_cast_stream_src_get_instance_private (src);
-  struct pw_stream *pipewire_stream;
-  GError *error = NULL;
 
-  switch (state)
-    {
-    case PW_REMOTE_STATE_ERROR:
-      g_warning ("pipewire remote error: %s\n", error_message);
-      meta_screen_cast_stream_src_notify_closed (src);
-      break;
-    case PW_REMOTE_STATE_CONNECTED:
-      pipewire_stream = create_pipewire_stream (src, &error);
-      if (!pipewire_stream)
-        {
-          g_warning ("Could not create pipewire stream: %s", error->message);
-          g_error_free (error);
-          meta_screen_cast_stream_src_notify_closed (src);
-        }
-      else
-        {
-          priv->pipewire_stream = pipewire_stream;
-        }
-      break;
-    case PW_REMOTE_STATE_UNCONNECTED:
-    case PW_REMOTE_STATE_CONNECTING:
-      break;
-    }
+  g_warning ("pipewire remote error: id:%u %s", id, message);
+
+  if (id == PW_ID_CORE && res == -EPIPE)
+    meta_screen_cast_stream_src_notify_closed (src);
 }
 
 static gboolean
@@ -793,17 +753,6 @@ static GSourceFuncs pipewire_source_funcs =
   pipewire_loop_source_finalize
 };
 
-static void
-init_spa_type (MetaSpaType         *type,
-               struct spa_type_map *map)
-{
-  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);
-  spa_type_video_format_map (map, &type->video_format);
-  type->meta_cursor = spa_type_map_get_id(map, SPA_TYPE_META__Cursor);
-}
-
 static MetaPipeWireSource *
 create_pipewire_source (void)
 {
@@ -829,9 +778,9 @@ create_pipewire_source (void)
   return pipewire_source;
 }
 
-static const struct pw_remote_events remote_events = {
-  PW_VERSION_REMOTE_EVENTS,
-  .state_changed = on_state_changed,
+static const struct pw_core_events core_events = {
+  PW_VERSION_CORE_EVENTS,
+  .error = on_core_error,
 };
 
 static gboolean
@@ -851,37 +800,31 @@ meta_screen_cast_stream_src_initable_init (GInitable     *initable,
       return FALSE;
     }
 
-  priv->pipewire_core = pw_core_new (priv->pipewire_source->pipewire_loop,
-                                     NULL);
-  if (!priv->pipewire_core)
+  priv->pipewire_context = pw_context_new (priv->pipewire_source->pipewire_loop,
+                                           NULL, 0);
+  if (!priv->pipewire_context)
     {
       g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
-                   "Failed to create pipewire core");
+                   "Failed to create pipewire context");
       return FALSE;
     }
 
-  priv->pipewire_remote = pw_remote_new (priv->pipewire_core, NULL, 0);
-  if (!priv->pipewire_remote)
+  priv->pipewire_core = pw_context_connect (priv->pipewire_context, NULL, 0);
+  if (!priv->pipewire_core)
     {
       g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
-                   "Couldn't creat pipewire remote");
+                   "Couldn't connect pipewire context");
       return FALSE;
     }
 
-  pw_remote_add_listener (priv->pipewire_remote,
-                          &priv->pipewire_remote_listener,
-                          &remote_events,
-                          src);
+  pw_core_add_listener (priv->pipewire_core,
+                        &priv->pipewire_core_listener,
+                        &core_events,
+                        src);
 
-  priv->pipewire_type = pw_core_get_type (priv->pipewire_core);
-  init_spa_type (&priv->spa_type, priv->pipewire_type->map);
-
-  if (pw_remote_connect (priv->pipewire_remote) != 0)
-    {
-      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
-                   "Couldn't connect pipewire remote");
-      return FALSE;
-    }
+  priv->pipewire_stream = create_pipewire_stream (src, error);
+  if (!priv->pipewire_stream)
+    return FALSE;
 
   return TRUE;
 }
@@ -912,8 +855,8 @@ meta_screen_cast_stream_src_finalize (GObject *object)
     meta_screen_cast_stream_src_disable (src);
 
   g_clear_pointer (&priv->pipewire_stream, pw_stream_destroy);
-  g_clear_pointer (&priv->pipewire_remote, pw_remote_destroy);
-  g_clear_pointer (&priv->pipewire_core, pw_core_destroy);
+  g_clear_pointer (&priv->pipewire_core, pw_core_disconnect);
+  g_clear_pointer (&priv->pipewire_context, pw_context_destroy);
   g_source_destroy (&priv->pipewire_source->base);
 
   G_OBJECT_CLASS (meta_screen_cast_stream_src_parent_class)->finalize (object);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]