mirror of
https://gitlab.freedesktop.org/pipewire/pipewire
synced 2024-10-14 20:02:38 +00:00
more work on cleanup
This commit is contained in:
parent
e632540983
commit
7e5fcf6771
|
@ -405,6 +405,12 @@ subscription_cb (PvSubscribe *subscribe,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PV_SUBSCRIPTION_FLAGS_CLIENT:
|
case PV_SUBSCRIPTION_FLAGS_CLIENT:
|
||||||
|
if (event == PV_SUBSCRIPTION_EVENT_REMOVE) {
|
||||||
|
if (object == priv->client) {
|
||||||
|
priv->error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_CLOSED, "Client disappeared");
|
||||||
|
context_set_state (context, PV_CONTEXT_STATE_ERROR);
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PV_SUBSCRIPTION_FLAGS_SOURCE:
|
case PV_SUBSCRIPTION_FLAGS_SOURCE:
|
||||||
|
|
|
@ -34,6 +34,8 @@ struct _PvStreamPrivate
|
||||||
gchar *name;
|
gchar *name;
|
||||||
GVariant *properties;
|
GVariant *properties;
|
||||||
|
|
||||||
|
guint id;
|
||||||
|
|
||||||
PvStreamState state;
|
PvStreamState state;
|
||||||
GError *error;
|
GError *error;
|
||||||
|
|
||||||
|
@ -152,6 +154,54 @@ pv_stream_set_property (GObject *_object,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
stream_set_state (PvStream *stream, PvStreamState state)
|
||||||
|
{
|
||||||
|
if (stream->priv->state != state) {
|
||||||
|
stream->priv->state = state;
|
||||||
|
g_object_notify (G_OBJECT (stream), "state");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
subscription_cb (PvSubscribe *subscribe,
|
||||||
|
PvSubscriptionEvent event,
|
||||||
|
PvSubscriptionFlags flags,
|
||||||
|
GDBusProxy *object,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
PvStream *stream = PV_STREAM (user_data);
|
||||||
|
PvStreamPrivate *priv = stream->priv;
|
||||||
|
|
||||||
|
switch (flags) {
|
||||||
|
case PV_SUBSCRIPTION_FLAGS_SOURCE_OUTPUT:
|
||||||
|
if (event == PV_SUBSCRIPTION_EVENT_REMOVE) {
|
||||||
|
if (object == priv->source_output) {
|
||||||
|
priv->error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_CLOSED, "output disappeared");
|
||||||
|
stream_set_state (stream, PV_STREAM_STATE_ERROR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
pv_stream_constructed (GObject * object)
|
||||||
|
{
|
||||||
|
PvStream *stream = PV_STREAM (object);
|
||||||
|
PvStreamPrivate *priv = stream->priv;
|
||||||
|
|
||||||
|
priv->id = g_signal_connect (priv->context->priv->subscribe,
|
||||||
|
"subscription-event",
|
||||||
|
(GCallback) subscription_cb,
|
||||||
|
stream);
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (pv_stream_parent_class)->constructed (object);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
pv_stream_finalize (GObject * object)
|
pv_stream_finalize (GObject * object)
|
||||||
{
|
{
|
||||||
|
@ -173,6 +223,7 @@ pv_stream_finalize (GObject * object)
|
||||||
|
|
||||||
if (priv->properties)
|
if (priv->properties)
|
||||||
g_variant_unref (priv->properties);
|
g_variant_unref (priv->properties);
|
||||||
|
g_signal_handler_disconnect (priv->context->priv->subscribe, priv->id);
|
||||||
g_clear_object (&priv->context);
|
g_clear_object (&priv->context);
|
||||||
g_free (priv->name);
|
g_free (priv->name);
|
||||||
|
|
||||||
|
@ -186,6 +237,7 @@ pv_stream_class_init (PvStreamClass * klass)
|
||||||
|
|
||||||
g_type_class_add_private (klass, sizeof (PvStreamPrivate));
|
g_type_class_add_private (klass, sizeof (PvStreamPrivate));
|
||||||
|
|
||||||
|
gobject_class->constructed = pv_stream_constructed;
|
||||||
gobject_class->finalize = pv_stream_finalize;
|
gobject_class->finalize = pv_stream_finalize;
|
||||||
gobject_class->set_property = pv_stream_set_property;
|
gobject_class->set_property = pv_stream_set_property;
|
||||||
gobject_class->get_property = pv_stream_get_property;
|
gobject_class->get_property = pv_stream_get_property;
|
||||||
|
@ -338,15 +390,6 @@ pv_stream_new (PvContext * context, const gchar *name, GVariant *props)
|
||||||
return g_object_new (PV_TYPE_STREAM, "context", context, "name", name, "properties", props, NULL);
|
return g_object_new (PV_TYPE_STREAM, "context", context, "name", name, "properties", props, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
stream_set_state (PvStream *stream, PvStreamState state)
|
|
||||||
{
|
|
||||||
if (stream->priv->state != state) {
|
|
||||||
stream->priv->state = state;
|
|
||||||
g_object_notify (G_OBJECT (stream), "state");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* pv_stream_get_state:
|
* pv_stream_get_state:
|
||||||
* @stream: a #PvStream
|
* @stream: a #PvStream
|
||||||
|
@ -379,17 +422,6 @@ pv_stream_get_error (PvStream *stream)
|
||||||
return stream->priv->error;
|
return stream->priv->error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
on_source_output_signal (GDBusProxy *proxy,
|
|
||||||
gchar *sender_name,
|
|
||||||
gchar *signal_name,
|
|
||||||
GVariant *parameters,
|
|
||||||
gpointer user_data)
|
|
||||||
{
|
|
||||||
g_print ("on source output signal %s %s\n", sender_name, signal_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_source_output_proxy (GObject *source_object,
|
on_source_output_proxy (GObject *source_object,
|
||||||
GAsyncResult *res,
|
GAsyncResult *res,
|
||||||
|
@ -420,11 +452,6 @@ on_source_output_proxy (GObject *source_object,
|
||||||
g_object_notify (G_OBJECT (stream), "possible-formats");
|
g_object_notify (G_OBJECT (stream), "possible-formats");
|
||||||
}
|
}
|
||||||
|
|
||||||
g_signal_connect (priv->source_output,
|
|
||||||
"g-signal",
|
|
||||||
(GCallback) on_source_output_signal,
|
|
||||||
stream);
|
|
||||||
|
|
||||||
stream_set_state (stream, PV_STREAM_STATE_READY);
|
stream_set_state (stream, PV_STREAM_STATE_READY);
|
||||||
g_object_unref (stream);
|
g_object_unref (stream);
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,7 @@ struct _PvClientSourcePrivate
|
||||||
GstElement *src;
|
GstElement *src;
|
||||||
GstElement *filter;
|
GstElement *filter;
|
||||||
GstElement *sink;
|
GstElement *sink;
|
||||||
|
guint id;
|
||||||
|
|
||||||
GSocket *socket;
|
GSocket *socket;
|
||||||
|
|
||||||
|
@ -89,7 +90,7 @@ setup_pipeline (PvClientSource *source)
|
||||||
priv->src = gst_bin_get_by_name (GST_BIN (priv->pipeline), "src");
|
priv->src = gst_bin_get_by_name (GST_BIN (priv->pipeline), "src");
|
||||||
|
|
||||||
bus = gst_pipeline_get_bus (GST_PIPELINE (priv->pipeline));
|
bus = gst_pipeline_get_bus (GST_PIPELINE (priv->pipeline));
|
||||||
gst_bus_add_watch (bus, bus_handler, source);
|
priv->id = gst_bus_add_watch (bus, bus_handler, source);
|
||||||
gst_object_unref (bus);
|
gst_object_unref (bus);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -235,6 +236,7 @@ client_source_dispose (GObject * object)
|
||||||
{
|
{
|
||||||
PvClientSourcePrivate *priv = PV_CLIENT_SOURCE (object)->priv;
|
PvClientSourcePrivate *priv = PV_CLIENT_SOURCE (object)->priv;
|
||||||
|
|
||||||
|
g_source_remove (priv->id);
|
||||||
gst_element_set_state (priv->pipeline, GST_STATE_NULL);
|
gst_element_set_state (priv->pipeline, GST_STATE_NULL);
|
||||||
|
|
||||||
G_OBJECT_CLASS (pv_client_source_parent_class)->dispose (object);
|
G_OBJECT_CLASS (pv_client_source_parent_class)->dispose (object);
|
||||||
|
|
|
@ -35,6 +35,8 @@ struct _PvClientPrivate
|
||||||
GVariant *properties;
|
GVariant *properties;
|
||||||
|
|
||||||
PvClient1 *client1;
|
PvClient1 *client1;
|
||||||
|
|
||||||
|
GList *outputs;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define PV_CLIENT_GET_PRIVATE(obj) \
|
#define PV_CLIENT_GET_PRIVATE(obj) \
|
||||||
|
@ -129,8 +131,11 @@ static void
|
||||||
handle_remove_source_output (PvSourceOutput *output,
|
handle_remove_source_output (PvSourceOutput *output,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
g_object_steal_data (G_OBJECT (user_data),
|
PvClient *client = user_data;
|
||||||
pv_source_output_get_object_path (output));
|
PvClientPrivate *priv = client->priv;
|
||||||
|
|
||||||
|
priv->outputs = g_list_remove (priv->outputs, output);
|
||||||
|
g_object_unref (output);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
@ -172,16 +177,13 @@ handle_create_source_output (PvClient1 *interface,
|
||||||
|
|
||||||
object_path = pv_source_output_get_object_path (output);
|
object_path = pv_source_output_get_object_path (output);
|
||||||
|
|
||||||
|
priv->outputs = g_list_prepend (priv->outputs, output);
|
||||||
|
|
||||||
g_signal_connect (output,
|
g_signal_connect (output,
|
||||||
"remove",
|
"remove",
|
||||||
(GCallback) handle_remove_source_output,
|
(GCallback) handle_remove_source_output,
|
||||||
client);
|
client);
|
||||||
|
|
||||||
g_object_set_data_full (G_OBJECT (client),
|
|
||||||
object_path,
|
|
||||||
output,
|
|
||||||
g_object_unref);
|
|
||||||
|
|
||||||
g_dbus_method_invocation_return_value (invocation,
|
g_dbus_method_invocation_return_value (invocation,
|
||||||
g_variant_new ("(o)", object_path));
|
g_variant_new ("(o)", object_path));
|
||||||
|
|
||||||
|
@ -251,15 +253,12 @@ handle_create_source_input (PvClient1 *interface,
|
||||||
|
|
||||||
source_input_path = pv_source_output_get_object_path (input);
|
source_input_path = pv_source_output_get_object_path (input);
|
||||||
|
|
||||||
|
priv->outputs = g_list_prepend (priv->outputs, input);
|
||||||
|
|
||||||
g_signal_connect (input,
|
g_signal_connect (input,
|
||||||
"remove",
|
"remove",
|
||||||
(GCallback) handle_remove_source_output,
|
(GCallback) handle_remove_source_output,
|
||||||
source);
|
client);
|
||||||
|
|
||||||
g_object_set_data_full (G_OBJECT (source),
|
|
||||||
source_input_path,
|
|
||||||
input,
|
|
||||||
g_object_unref);
|
|
||||||
|
|
||||||
g_dbus_method_invocation_return_value (invocation,
|
g_dbus_method_invocation_return_value (invocation,
|
||||||
g_variant_new ("(o)",
|
g_variant_new ("(o)",
|
||||||
|
@ -343,11 +342,19 @@ client_unregister_object (PvClient *client)
|
||||||
g_free (priv->object_path);
|
g_free (priv->object_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
do_remove_output (PvSourceOutput *output, PvClient *client)
|
||||||
|
{
|
||||||
|
pv_source_output_remove (output);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
pv_client_dispose (GObject * object)
|
pv_client_dispose (GObject * object)
|
||||||
{
|
{
|
||||||
PvClient *client = PV_CLIENT (object);
|
PvClient *client = PV_CLIENT (object);
|
||||||
|
PvClientPrivate *priv = client->priv;
|
||||||
|
|
||||||
|
g_list_foreach (priv->outputs, (GFunc) do_remove_output, client);
|
||||||
client_unregister_object (client);
|
client_unregister_object (client);
|
||||||
|
|
||||||
G_OBJECT_CLASS (pv_client_parent_class)->dispose (object);
|
G_OBJECT_CLASS (pv_client_parent_class)->dispose (object);
|
||||||
|
|
|
@ -437,6 +437,14 @@ pv_source_output_init (PvSourceOutput * output)
|
||||||
g_signal_connect (priv->iface, "handle-remove", (GCallback) handle_remove, output);
|
g_signal_connect (priv->iface, "handle-remove", (GCallback) handle_remove, output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
pv_source_output_remove (PvSourceOutput *output)
|
||||||
|
{
|
||||||
|
stop_transfer (output);
|
||||||
|
|
||||||
|
g_signal_emit (output, signals[SIGNAL_REMOVE], 0, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
const gchar *
|
const gchar *
|
||||||
pv_source_output_get_object_path (PvSourceOutput *output)
|
pv_source_output_get_object_path (PvSourceOutput *output)
|
||||||
{
|
{
|
||||||
|
|
|
@ -60,7 +60,8 @@ struct _PvSourceOutputClass {
|
||||||
/* normal GObject stuff */
|
/* normal GObject stuff */
|
||||||
GType pv_source_output_get_type (void);
|
GType pv_source_output_get_type (void);
|
||||||
|
|
||||||
const gchar * pv_source_output_get_sender (PvSourceOutput *output);
|
void pv_source_output_remove (PvSourceOutput *output);
|
||||||
|
|
||||||
const gchar * pv_source_output_get_object_path (PvSourceOutput *output);
|
const gchar * pv_source_output_get_object_path (PvSourceOutput *output);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
|
@ -38,10 +38,12 @@ struct _PvSourcePrivate
|
||||||
gchar *object_path;
|
gchar *object_path;
|
||||||
|
|
||||||
gchar *name;
|
gchar *name;
|
||||||
PvSourceState state;
|
|
||||||
GVariant *properties;
|
GVariant *properties;
|
||||||
|
|
||||||
|
PvSourceState state;
|
||||||
GError *error;
|
GError *error;
|
||||||
|
|
||||||
|
GList *outputs;
|
||||||
};
|
};
|
||||||
|
|
||||||
G_DEFINE_ABSTRACT_TYPE (PvSource, pv_source, G_TYPE_OBJECT);
|
G_DEFINE_ABSTRACT_TYPE (PvSource, pv_source, G_TYPE_OBJECT);
|
||||||
|
@ -171,11 +173,20 @@ pv_source_constructed (GObject * object)
|
||||||
G_OBJECT_CLASS (pv_source_parent_class)->constructed (object);
|
G_OBJECT_CLASS (pv_source_parent_class)->constructed (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
do_remove_output (PvSourceOutput *output,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
pv_source_output_remove (output);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
pv_source_dispose (GObject * object)
|
pv_source_dispose (GObject * object)
|
||||||
{
|
{
|
||||||
PvSource *source = PV_SOURCE (object);
|
PvSource *source = PV_SOURCE (object);
|
||||||
|
PvSourcePrivate *priv = source->priv;
|
||||||
|
|
||||||
|
g_list_foreach (priv->outputs, (GFunc) do_remove_output, source);
|
||||||
source_unregister_object (source);
|
source_unregister_object (source);
|
||||||
|
|
||||||
G_OBJECT_CLASS (pv_source_parent_class)->dispose (object);
|
G_OBJECT_CLASS (pv_source_parent_class)->dispose (object);
|
||||||
|
@ -229,14 +240,24 @@ default_create_source_output (PvSource *source,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
g_signal_connect (output, "remove", (GCallback) handle_remove_output, source);
|
g_signal_connect (output, "remove", (GCallback) handle_remove_output, source);
|
||||||
|
priv->outputs = g_list_prepend (priv->outputs, output);
|
||||||
|
|
||||||
return output;
|
return g_object_ref (output);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
default_release_source_output (PvSource *source, PvSourceOutput *output)
|
default_release_source_output (PvSource *source, PvSourceOutput *output)
|
||||||
{
|
{
|
||||||
|
PvSourcePrivate *priv = source->priv;
|
||||||
|
GList *find;
|
||||||
|
|
||||||
|
find = g_list_find (priv->outputs, output);
|
||||||
|
if (find == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
priv->outputs = g_list_delete_link (priv->outputs, find);
|
||||||
g_object_unref (output);
|
g_object_unref (output);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue