mirror of
https://github.com/brl/mutter.git
synced 2024-11-23 16:40:41 -05:00
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
This commit is contained in:
parent
f5a28aa9e4
commit
c5d2fc856a
@ -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
|
||||
|
@ -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')
|
||||
|
@ -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,
|
||||
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);
|
||||
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);
|
||||
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_object (
|
||||
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);
|
||||
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);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
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 context");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
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,
|
||||
"Failed to create pipewire core");
|
||||
"Couldn't connect pipewire context");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
priv->pipewire_remote = pw_remote_new (priv->pipewire_core, NULL, 0);
|
||||
if (!priv->pipewire_remote)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"Couldn't creat pipewire remote");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pw_remote_add_listener (priv->pipewire_remote,
|
||||
&priv->pipewire_remote_listener,
|
||||
&remote_events,
|
||||
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");
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user