screen-cast: Handle PipeWire errors

When the PipeWire context or stream ends up in an error state, signal
that the source has closed. This then triggers the stream and finally
the session to be closed too.

https://bugzilla.gnome.org/show_bug.cgi?id=784199
This commit is contained in:
Jonas Ådahl 2017-06-26 12:50:26 +08:00
parent 97f2c7c161
commit 9d8922764c
2 changed files with 52 additions and 0 deletions

View File

@ -50,6 +50,15 @@ enum
PROP_STREAM_ID,
};
enum
{
CLOSED,
N_SIGNALS
};
static guint signals[N_SIGNALS];
typedef struct _MetaSpaType
{
uint32_t format;
@ -188,12 +197,34 @@ meta_screen_cast_stream_src_maybe_record_frame (MetaScreenCastStreamSrc *src)
pw_stream_send_buffer (priv->pipewire_stream, buffer_id);
}
static void
meta_screen_cast_stream_src_notify_closed (MetaScreenCastStreamSrc *src)
{
g_signal_emit (src, signals[CLOSED], 0);
}
static void
on_stream_state_changed (void *data,
enum pw_stream_state old,
enum pw_stream_state state,
const char *error_message)
{
MetaScreenCastStreamSrc *src = data;
switch (state)
{
case PW_STREAM_STATE_ERROR:
g_warning ("pipewire stream error: %s", error_message);
meta_screen_cast_stream_src_notify_closed (src);
break;
case PW_STREAM_STATE_UNCONNECTED:
case PW_STREAM_STATE_CONNECTING:
case PW_STREAM_STATE_CONFIGURE:
case PW_STREAM_STATE_READY:
case PW_STREAM_STATE_PAUSED:
case PW_STREAM_STATE_STREAMING:
break;
}
}
static void
@ -341,6 +372,7 @@ on_state_changed (void *data,
{
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);
@ -348,6 +380,7 @@ on_state_changed (void *data,
{
g_warning ("Could not create pipewire stream: %s", error->message);
g_error_free (error);
meta_screen_cast_stream_src_notify_closed (src);
}
else
{
@ -594,4 +627,11 @@ meta_screen_cast_stream_src_class_init (MetaScreenCastStreamSrcClass *klass)
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
signals[CLOSED] = g_signal_new ("closed",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL, NULL,
G_TYPE_NONE, 0);
}

View File

@ -70,6 +70,17 @@ meta_screen_cast_stream_create_src (MetaScreenCastStream *stream,
error);
}
static void
on_stream_src_closed (MetaScreenCastStreamSrc *src,
MetaScreenCastStream *stream)
{
MetaScreenCastStreamPrivate *priv =
meta_screen_cast_stream_get_instance_private (stream);
if (priv->src)
meta_screen_cast_stream_close (stream);
}
gboolean
meta_screen_cast_stream_start (MetaScreenCastStream *stream,
GError **error)
@ -87,6 +98,7 @@ meta_screen_cast_stream_start (MetaScreenCastStream *stream,
return FALSE;
priv->src = src;
g_signal_connect (src, "closed", G_CALLBACK (on_stream_src_closed), stream);
meta_dbus_screen_cast_stream_emit_pipewire_stream_added (skeleton, stream_id);