From 920541fa26f667b5cb8d859585067461b2b09e59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Mon, 26 Jun 2017 12:55:48 +0800 Subject: [PATCH] screen-cast-stream-src: Only try to record frames when streaming Only when the PipeWire stream state is 'PW_STREAM_STATE STREAMING' should the signal be connected causing the src to maybe record a frame. https://bugzilla.gnome.org/show_bug.cgi?id=784199 --- .../meta-screen-cast-monitor-stream-src.c | 81 +++++++++---------- src/backends/meta-screen-cast-stream-src.c | 41 ++++++++++ src/backends/meta-screen-cast-stream-src.h | 2 + 3 files changed, 81 insertions(+), 43 deletions(-) diff --git a/src/backends/meta-screen-cast-monitor-stream-src.c b/src/backends/meta-screen-cast-monitor-stream-src.c index dd9196e5e..e5a681b37 100644 --- a/src/backends/meta-screen-cast-monitor-stream-src.c +++ b/src/backends/meta-screen-cast-monitor-stream-src.c @@ -93,6 +93,42 @@ meta_screen_cast_monitor_stream_src_get_specs (MetaScreenCastStreamSrc *src, *frame_rate = meta_monitor_mode_get_refresh_rate (mode); } +static void +stage_painted (ClutterActor *actor, + MetaScreenCastMonitorStreamSrc *monitor_src) +{ + MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (monitor_src); + + meta_screen_cast_stream_src_maybe_record_frame (src); +} + +static void +meta_screen_cast_monitor_stream_src_enable (MetaScreenCastStreamSrc *src) +{ + MetaScreenCastMonitorStreamSrc *monitor_src = + META_SCREEN_CAST_MONITOR_STREAM_SRC (src); + ClutterStage *stage; + + stage = get_stage (monitor_src); + monitor_src->stage_painted_handler_id = + g_signal_connect_after (stage, "paint", + G_CALLBACK (stage_painted), + monitor_src); + clutter_actor_queue_redraw (CLUTTER_ACTOR (stage)); +} + +static void +meta_screen_cast_monitor_stream_src_disable (MetaScreenCastStreamSrc *src) +{ + MetaScreenCastMonitorStreamSrc *monitor_src = + META_SCREEN_CAST_MONITOR_STREAM_SRC (src); + ClutterStage *stage; + + stage = get_stage (monitor_src); + g_signal_handler_disconnect (stage, monitor_src->stage_painted_handler_id); + monitor_src->stage_painted_handler_id = 0; +} + static void meta_screen_cast_monitor_stream_src_record_frame (MetaScreenCastStreamSrc *src, uint8_t *data) @@ -109,15 +145,6 @@ meta_screen_cast_monitor_stream_src_record_frame (MetaScreenCastStreamSrc *src, clutter_stage_capture_into (stage, FALSE, &logical_monitor->rect, data); } -static void -stage_painted (ClutterActor *actor, - MetaScreenCastMonitorStreamSrc *monitor_src) -{ - MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (monitor_src); - - meta_screen_cast_stream_src_maybe_record_frame (src); -} - MetaScreenCastMonitorStreamSrc * meta_screen_cast_monitor_stream_src_new (MetaScreenCastMonitorStream *monitor_stream, const char *stream_id, @@ -131,36 +158,6 @@ meta_screen_cast_monitor_stream_src_new (MetaScreenCastMonitorStream *monitor_s NULL); } -static void -meta_screen_cast_monitor_stream_src_constructed (GObject *object) -{ - MetaScreenCastMonitorStreamSrc *monitor_src = - META_SCREEN_CAST_MONITOR_STREAM_SRC (object); - ClutterStage *stage; - - stage = get_stage (monitor_src); - monitor_src->stage_painted_handler_id = - g_signal_connect_after (stage, "paint", - G_CALLBACK (stage_painted), - monitor_src); - clutter_actor_queue_redraw (CLUTTER_ACTOR (stage)); -} - -static void -meta_screen_cast_monitor_stream_src_finalize (GObject *object) -{ - MetaScreenCastMonitorStreamSrc *monitor_src = - META_SCREEN_CAST_MONITOR_STREAM_SRC (object); - GObjectClass *parent_class = - G_OBJECT_CLASS (meta_screen_cast_monitor_stream_src_parent_class); - ClutterStage *stage; - - stage = get_stage (monitor_src); - g_signal_handler_disconnect (stage, monitor_src->stage_painted_handler_id); - - parent_class->finalize (object); -} - static void meta_screen_cast_monitor_stream_src_init (MetaScreenCastMonitorStreamSrc *monitor_src) { @@ -169,13 +166,11 @@ meta_screen_cast_monitor_stream_src_init (MetaScreenCastMonitorStreamSrc *monito static void meta_screen_cast_monitor_stream_src_class_init (MetaScreenCastMonitorStreamSrcClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); MetaScreenCastStreamSrcClass *src_class = META_SCREEN_CAST_STREAM_SRC_CLASS (klass); - object_class->constructed = meta_screen_cast_monitor_stream_src_constructed; - object_class->finalize = meta_screen_cast_monitor_stream_src_finalize; - src_class->get_specs = meta_screen_cast_monitor_stream_src_get_specs; + src_class->enable = meta_screen_cast_monitor_stream_src_enable; + src_class->disable = meta_screen_cast_monitor_stream_src_disable; src_class->record_frame = meta_screen_cast_monitor_stream_src_record_frame; } diff --git a/src/backends/meta-screen-cast-stream-src.c b/src/backends/meta-screen-cast-stream-src.c index 214fdbed6..9204635a8 100644 --- a/src/backends/meta-screen-cast-stream-src.c +++ b/src/backends/meta-screen-cast-stream-src.c @@ -89,6 +89,8 @@ typedef struct _MetaScreenCastStreamSrcPrivate MetaPipeWireSource *pipewire_source; struct spa_hook pipewire_remote_listener; + gboolean is_enabled; + struct pw_stream *pipewire_stream; struct spa_hook pipewire_stream_listener; @@ -197,6 +199,37 @@ meta_screen_cast_stream_src_maybe_record_frame (MetaScreenCastStreamSrc *src) pw_stream_send_buffer (priv->pipewire_stream, buffer_id); } +static gboolean +meta_screen_cast_stream_src_is_enabled (MetaScreenCastStreamSrc *src) +{ + MetaScreenCastStreamSrcPrivate *priv = + meta_screen_cast_stream_src_get_instance_private (src); + + return priv->is_enabled; +} + +static void +meta_screen_cast_stream_src_enable (MetaScreenCastStreamSrc *src) +{ + MetaScreenCastStreamSrcPrivate *priv = + meta_screen_cast_stream_src_get_instance_private (src); + + META_SCREEN_CAST_STREAM_SRC_GET_CLASS (src)->enable (src); + + priv->is_enabled = TRUE; +} + +static void +meta_screen_cast_stream_src_disable (MetaScreenCastStreamSrc *src) +{ + MetaScreenCastStreamSrcPrivate *priv = + meta_screen_cast_stream_src_get_instance_private (src); + + META_SCREEN_CAST_STREAM_SRC_GET_CLASS (src)->disable (src); + + priv->is_enabled = FALSE; +} + static void meta_screen_cast_stream_src_notify_closed (MetaScreenCastStreamSrc *src) { @@ -222,7 +255,12 @@ on_stream_state_changed (void *data, case PW_STREAM_STATE_CONFIGURE: case PW_STREAM_STATE_READY: case PW_STREAM_STATE_PAUSED: + if (meta_screen_cast_stream_src_is_enabled (src)) + meta_screen_cast_stream_src_disable (src); + break; case PW_STREAM_STATE_STREAMING: + if (!meta_screen_cast_stream_src_is_enabled (src)) + meta_screen_cast_stream_src_enable (src); break; } } @@ -540,6 +578,9 @@ meta_screen_cast_stream_src_finalize (GObject *object) MetaScreenCastStreamSrcPrivate *priv = meta_screen_cast_stream_src_get_instance_private (src); + if (meta_screen_cast_stream_src_is_enabled (src)) + meta_screen_cast_stream_src_disable (src); + g_clear_pointer (&priv->pipewire_stream, (GDestroyNotify) pw_stream_destroy); pw_remote_destroy (priv->pipewire_remote); pw_core_destroy (priv->pipewire_core); diff --git a/src/backends/meta-screen-cast-stream-src.h b/src/backends/meta-screen-cast-stream-src.h index 7e7ecb585..ebd5f72fc 100644 --- a/src/backends/meta-screen-cast-stream-src.h +++ b/src/backends/meta-screen-cast-stream-src.h @@ -44,6 +44,8 @@ struct _MetaScreenCastStreamSrcClass int *width, int *height, float *frame_rate); + void (* enable) (MetaScreenCastStreamSrc *src); + void (* disable) (MetaScreenCastStreamSrc *src); void (* record_frame) (MetaScreenCastStreamSrc *src, uint8_t *data); };