diff --git a/src/client/context.c b/src/client/context.c index faedfedb2..ede4bbd1c 100644 --- a/src/client/context.c +++ b/src/client/context.c @@ -137,6 +137,9 @@ pinos_context_finalize (GObject * object) PinosContext *context = PINOS_CONTEXT (object); PinosContextPrivate *priv = context->priv; + if (priv->id) + g_bus_unwatch_name(priv->id); + g_clear_pointer (&priv->context, g_main_context_unref); g_free (priv->name); if (priv->properties) @@ -280,7 +283,7 @@ pinos_context_init (PinosContext * context) * pinos_context_new: * @context: a #GMainContext to run in * @name: an application name - * @properties: optional properties + * @properties: (transfer full): optional properties * * Make a new unconnected #PinosContext * @@ -291,6 +294,8 @@ pinos_context_new (GMainContext *context, const gchar *name, PinosProperties *properties) { + PinosContext *ctx; + g_return_val_if_fail (name != NULL, NULL); if (properties == NULL) @@ -298,11 +303,15 @@ pinos_context_new (GMainContext *context, pinos_fill_context_properties (properties); - return g_object_new (PINOS_TYPE_CONTEXT, - "main-context", context, - "name", name, - "properties", properties, - NULL); + ctx = g_object_new (PINOS_TYPE_CONTEXT, + "main-context", context, + "name", name, + "properties", properties, + NULL); + + pinos_properties_free (properties); + + return ctx; } static gboolean @@ -534,7 +543,9 @@ do_connect (PinosContext *context) on_name_appeared, on_name_vanished, context, - g_object_unref); + NULL); + g_object_unref (context); + return FALSE; } @@ -575,8 +586,10 @@ finish_client_disconnect (PinosContext *context) g_clear_object (&priv->client); g_clear_object (&priv->daemon); - g_bus_unwatch_name(priv->id); - priv->id = 0; + if (priv->id) { + g_bus_unwatch_name(priv->id); + priv->id = 0; + } context_set_state (context, PINOS_CONTEXT_STATE_UNCONNECTED); } diff --git a/src/client/stream.c b/src/client/stream.c index 6bcd6bd81..f726039ba 100644 --- a/src/client/stream.c +++ b/src/client/stream.c @@ -390,7 +390,7 @@ pinos_stream_init (PinosStream * stream) * pinos_stream_new: * @context: a #PinosContext * @name: a stream name - * @properties: stream properties + * @properties: (transfer full): stream properties * * Make a new unconnected #PinosStream * @@ -401,6 +401,8 @@ pinos_stream_new (PinosContext *context, const gchar *name, PinosProperties *props) { + PinosStream *stream; + g_return_val_if_fail (PINOS_IS_CONTEXT (context), NULL); g_return_val_if_fail (name != NULL, NULL); @@ -410,11 +412,15 @@ pinos_stream_new (PinosContext *context, pinos_properties_set (props, "media.name", name); } - return g_object_new (PINOS_TYPE_STREAM, + stream = g_object_new (PINOS_TYPE_STREAM, "context", context, "name", name, "properties", props, NULL); + + pinos_properties_free (props); + + return stream; } /** @@ -572,7 +578,7 @@ do_connect_capture (PinosStream *stream) * @stream: a #PinosStream * @source_path: the source path to connect to * @flags: a #PinosStreamFlags - * @accepted_formats: a #GBytes with accepted formats + * @accepted_formats: (transfer full): a #GBytes with accepted formats * * Connect @stream for capturing from @source_path. * @@ -599,7 +605,7 @@ pinos_stream_connect_capture (PinosStream *stream, priv->source_path = g_strdup (source_path); if (priv->accepted_formats) g_bytes_unref (priv->accepted_formats); - priv->accepted_formats = g_bytes_ref (accepted_formats); + priv->accepted_formats = accepted_formats; priv->provide = FALSE; stream_set_state (stream, PINOS_STREAM_STATE_CONNECTING); @@ -635,7 +641,7 @@ do_connect_provide (PinosStream *stream) * pinos_stream_connect_provide: * @stream: a #PinosStream * @flags: a #PinosStreamFlags - * @possible_formats: a #GBytes + * @possible_formats: (transfer full): a #GBytes * * Connect @stream for providing data for a new source. * @@ -658,7 +664,7 @@ pinos_stream_connect_provide (PinosStream *stream, if (priv->possible_formats) g_bytes_unref (priv->possible_formats); - priv->possible_formats = g_bytes_ref (possible_formats); + priv->possible_formats = possible_formats; priv->provide = TRUE; stream_set_state (stream, PINOS_STREAM_STATE_CONNECTING); @@ -771,6 +777,7 @@ on_socket_condition (GSocket *socket, gint flags = 0; gsize need; GError *error = NULL; + gint i; need = sizeof (PinosStackHeader); @@ -781,6 +788,7 @@ on_socket_condition (GSocket *socket, hdr = priv->buffer.data; + /* read header first */ ivec.buffer = hdr; ivec.size = sizeof (PinosStackHeader); @@ -799,6 +807,7 @@ on_socket_condition (GSocket *socket, if (num_messages == 0) break; + /* now we know the total length */ need += hdr->length; if (priv->buffer.allocated_size < need) { @@ -807,10 +816,7 @@ on_socket_condition (GSocket *socket, } priv->buffer.size = need; - if (priv->buffer.message) - g_object_unref (priv->buffer.message); - priv->buffer.message = messages[0]; - + /* read data */ len = g_socket_receive (socket, (gchar *)priv->buffer.data + sizeof (PinosStackHeader), hdr->length, @@ -818,6 +824,20 @@ on_socket_condition (GSocket *socket, &error); g_assert (len == hdr->length); + /* handle control messages */ + for (i = 0; i < num_messages; i++) { + if (i == 0) { + if (priv->buffer.message) + g_object_unref (priv->buffer.message); + priv->buffer.message = messages[0]; + } + else { + g_warning ("discarding control message %d", i); + g_object_unref (messages[i]); + } + } + g_free (messages); + priv->buffer.magic = PSB_MAGIC; g_signal_emit (stream, signals[SIGNAL_NEW_BUFFER], 0, NULL); @@ -985,9 +1005,10 @@ do_start (PinosStream *stream) /** * pinos_stream_start: * @stream: a #PinosStream + * @format: (transfer full): a #GBytes with format * @mode: a #PinosStreamMode * - * Start capturing from @stream. + * Start capturing from @stream in @format. * * When @mode is #PINOS_STREAM_MODE_SOCKET, you should connect to the notify::socket * signal to obtain a readable socket with metadata and data. @@ -1011,7 +1032,7 @@ pinos_stream_start (PinosStream *stream, g_return_val_if_fail (priv->state == PINOS_STREAM_STATE_READY, FALSE); priv->mode = mode; - priv->format = g_bytes_ref (format); + priv->format = format; stream_set_state (stream, PINOS_STREAM_STATE_STARTING); diff --git a/src/client/subscribe.c b/src/client/subscribe.c index 74949952d..6f581eeb2 100644 --- a/src/client/subscribe.c +++ b/src/client/subscribe.c @@ -578,6 +578,8 @@ pinos_subscribe_finalize (GObject * object) PinosSubscribe *subscribe = PINOS_SUBSCRIBE (object); PinosSubscribePrivate *priv = subscribe->priv; + remove_all_data (subscribe); + g_cancellable_cancel (priv->cancellable); if (priv->manager_proxy) g_object_unref (priv->manager_proxy); diff --git a/src/gst/gstpinossink.c b/src/gst/gstpinossink.c index 6fb76cc38..ac0b1db2a 100644 --- a/src/gst/gstpinossink.c +++ b/src/gst/gstpinossink.c @@ -285,7 +285,7 @@ gst_pinos_sink_setcaps (GstBaseSink * bsink, GstCaps * caps) g_signal_connect (pinossink->stream, "notify::state", (GCallback) on_stream_notify, pinossink); g_signal_connect (pinossink->stream, "new-buffer", (GCallback) on_new_buffer, pinossink); - pinos_stream_connect_provide (pinossink->stream, 0, format); + pinos_stream_connect_provide (pinossink->stream, 0, g_bytes_ref (format)); while (TRUE) { PinosStreamState state = pinos_stream_get_state (pinossink->stream); diff --git a/src/gst/gstpinossrc.c b/src/gst/gstpinossrc.c index 79b1cd0a2..0cc24ec80 100644 --- a/src/gst/gstpinossrc.c +++ b/src/gst/gstpinossrc.c @@ -314,6 +314,7 @@ on_new_buffer (GObject *gobject, /* ERRORS */ no_fds: { + gst_buffer_unref (buf); GST_ELEMENT_ERROR (pinossrc, RESOURCE, FAILED, ("buffer error: %s", error->message), (NULL)); pinos_main_loop_signal (pinossrc->loop, FALSE); @@ -417,10 +418,12 @@ gst_pinos_src_negotiate (GstBaseSrc * basesrc) gchar *str; GST_DEBUG_OBJECT (basesrc, "have caps: %" GST_PTR_FORMAT, caps); + /* open a connection with these caps */ str = gst_caps_to_string (caps); accepted = g_bytes_new_take (str, strlen (str) + 1); + /* first disconnect */ pinos_main_loop_lock (pinossrc->loop); if (pinos_stream_get_state (pinossrc->stream) != PINOS_STREAM_STATE_UNCONNECTED) { GST_DEBUG_OBJECT (basesrc, "disconnect capture"); @@ -431,12 +434,15 @@ gst_pinos_src_negotiate (GstBaseSrc * basesrc) if (state == PINOS_STREAM_STATE_UNCONNECTED) break; - if (state == PINOS_STREAM_STATE_ERROR) + if (state == PINOS_STREAM_STATE_ERROR) { + g_bytes_unref (accepted); goto connect_error; + } pinos_main_loop_wait (pinossrc->loop); } } + GST_DEBUG_OBJECT (basesrc, "connect capture with path %s", pinossrc->path); pinos_stream_connect_capture (pinossrc->stream, pinossrc->path, 0, accepted); @@ -460,6 +466,8 @@ gst_pinos_src_negotiate (GstBaseSrc * basesrc) newcaps = gst_caps_from_string (g_bytes_get_data (possible, NULL)); if (newcaps) caps = newcaps; + + g_bytes_unref (possible); } /* now fixate */ GST_DEBUG_OBJECT (basesrc, "server fixated caps: %" GST_PTR_FORMAT, caps); @@ -668,7 +676,13 @@ gst_pinos_src_close (GstPinosSrc * pinossrc) { pinos_main_loop_stop (pinossrc->loop); g_clear_object (&pinossrc->loop); + g_clear_object (&pinossrc->ctx); g_main_context_unref (pinossrc->context); + g_clear_object (&pinossrc->stream); + + if (pinossrc->current) + gst_buffer_unref (pinossrc->current); + pinossrc->current = NULL; } static GstStateChangeReturn diff --git a/src/tests/test-client.c b/src/tests/test-client.c index bde8b5259..49ef5035b 100644 --- a/src/tests/test-client.c +++ b/src/tests/test-client.c @@ -107,7 +107,6 @@ on_stream_notify (GObject *gobject, format = g_bytes_new_static (str, strlen (str) + 1); pinos_stream_start (s, format, PINOS_STREAM_MODE_SOCKET); - g_bytes_unref (format); break; }