mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	fix various leaks
This commit is contained in:
		
							parent
							
								
									bc73610dd0
								
							
						
					
					
						commit
						6b19e7a2d8
					
				
					 6 changed files with 92 additions and 45 deletions
				
			
		| 
						 | 
				
			
			@ -118,6 +118,8 @@ do_allocation (GstPinosPay *pay, GstCaps *caps)
 | 
			
		|||
      GST_NET_CONTROL_MESSAGE_META_API_TYPE, NULL))
 | 
			
		||||
    goto no_meta;
 | 
			
		||||
 | 
			
		||||
  gst_query_unref (query);
 | 
			
		||||
 | 
			
		||||
  return TRUE;
 | 
			
		||||
 | 
			
		||||
  /* ERRORS */
 | 
			
		||||
| 
						 | 
				
			
			@ -126,6 +128,7 @@ no_meta:
 | 
			
		|||
    GST_ELEMENT_ERROR (pay, STREAM, FORMAT,
 | 
			
		||||
        ("Incompatible downstream element"),
 | 
			
		||||
        ("The downstream element does not handle control-message metadata API"));
 | 
			
		||||
    gst_query_unref (query);
 | 
			
		||||
    return FALSE;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -163,6 +166,13 @@ gst_pinos_pay_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
 | 
			
		|||
  return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
client_object_destroy (GHashTable *hash)
 | 
			
		||||
{
 | 
			
		||||
  GST_LOG ("%p: hash destroyed", hash);
 | 
			
		||||
  g_hash_table_unref (hash);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
client_buffer_sent (GstPinosPay *pay, GstBuffer *buffer,
 | 
			
		||||
    GObject *obj)
 | 
			
		||||
| 
						 | 
				
			
			@ -182,13 +192,17 @@ client_buffer_sent (GstPinosPay *pay, GstBuffer *buffer,
 | 
			
		|||
    hash = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL,
 | 
			
		||||
        (GDestroyNotify) gst_buffer_unref);
 | 
			
		||||
    g_object_set_qdata_full (obj, fdids_quark, hash,
 | 
			
		||||
        (GDestroyNotify) g_hash_table_unref);
 | 
			
		||||
        (GDestroyNotify) client_object_destroy);
 | 
			
		||||
    GST_LOG ("%p: new hash for object %p", hash, obj);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  for (i = 0; i < fdids->len; i++) {
 | 
			
		||||
    gint id = g_array_index (fdids, guint32, i);
 | 
			
		||||
    gboolean res;
 | 
			
		||||
 | 
			
		||||
    GST_LOG ("%p: fd index %d, increment refcount of buffer %p", hash, id, buffer);
 | 
			
		||||
    g_hash_table_insert (hash, GINT_TO_POINTER (id), gst_buffer_ref (buffer));
 | 
			
		||||
    res = g_hash_table_insert (hash, GINT_TO_POINTER (id), gst_buffer_ref (buffer));
 | 
			
		||||
//    g_assert (res);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -223,7 +237,7 @@ client_buffer_received (GstPinosPay *pay, GstBuffer *buffer,
 | 
			
		|||
 | 
			
		||||
        GST_LOG ("%p: fd index %d is released", hash, id);
 | 
			
		||||
        res = g_hash_table_remove (hash, GINT_TO_POINTER (id));
 | 
			
		||||
        g_assert (res);
 | 
			
		||||
        //g_assert (res);
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
      default:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -529,8 +529,10 @@ parse_clock_info (GstPinosSrc *pinossrc)
 | 
			
		|||
  g_object_get (pinossrc->stream, "properties", &props, NULL);
 | 
			
		||||
 | 
			
		||||
  var = pinos_properties_get (props, "pinos.clock.type");
 | 
			
		||||
  if (var == NULL)
 | 
			
		||||
  if (var == NULL) {
 | 
			
		||||
    pinos_properties_free (props);
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  GST_DEBUG_OBJECT (pinossrc, "got clock type %s", var);
 | 
			
		||||
  if (strcmp (var, "gst.net.time.provider") == 0) {
 | 
			
		||||
| 
						 | 
				
			
			@ -545,6 +547,7 @@ parse_clock_info (GstPinosSrc *pinossrc)
 | 
			
		|||
      gst_object_unref (pinossrc->clock);
 | 
			
		||||
    pinossrc->clock = gst_net_client_clock_new ("pinosclock", address, port, 0);
 | 
			
		||||
  }
 | 
			
		||||
  pinos_properties_free (props);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -62,7 +62,7 @@ device_added (PinosGstManager *manager,
 | 
			
		|||
              GstDevice       *device)
 | 
			
		||||
{
 | 
			
		||||
  PinosGstManagerPrivate *priv = manager->priv;
 | 
			
		||||
  gchar *name;
 | 
			
		||||
  gchar *name, *klass;
 | 
			
		||||
  GstElement *element;
 | 
			
		||||
  PinosSource *source;
 | 
			
		||||
  GstStructure *p;
 | 
			
		||||
| 
						 | 
				
			
			@ -70,20 +70,25 @@ device_added (PinosGstManager *manager,
 | 
			
		|||
  GstCaps *caps;
 | 
			
		||||
 | 
			
		||||
  name = gst_device_get_display_name (device);
 | 
			
		||||
  if (strcmp (name, "gst") == 0)
 | 
			
		||||
  if (g_strcmp0 (name, "gst") == 0) {
 | 
			
		||||
    g_free (name);
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  caps = gst_device_get_caps (device);
 | 
			
		||||
 | 
			
		||||
  g_print("Device added: %s\n", name);
 | 
			
		||||
 | 
			
		||||
  properties = pinos_properties_new (NULL, NULL);
 | 
			
		||||
  if ((p = gst_device_get_properties (device)))
 | 
			
		||||
  if ((p = gst_device_get_properties (device))) {
 | 
			
		||||
    gst_structure_foreach (p, copy_properties, properties);
 | 
			
		||||
    gst_structure_free (p);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  klass = gst_device_get_device_class (device);
 | 
			
		||||
  pinos_properties_set (properties,
 | 
			
		||||
                        "gstreamer.device.class",
 | 
			
		||||
                        gst_device_get_device_class (device));
 | 
			
		||||
                        klass);
 | 
			
		||||
 | 
			
		||||
  element = gst_device_create_element (device, NULL);
 | 
			
		||||
  source = pinos_gst_source_new (priv->daemon,
 | 
			
		||||
| 
						 | 
				
			
			@ -93,8 +98,10 @@ device_added (PinosGstManager *manager,
 | 
			
		|||
                                 caps);
 | 
			
		||||
  g_object_set_data (G_OBJECT (device), "PinosSource", source);
 | 
			
		||||
 | 
			
		||||
  pinos_properties_free (properties);
 | 
			
		||||
  gst_caps_unref (caps);
 | 
			
		||||
  g_free (name);
 | 
			
		||||
  g_free (klass);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -35,8 +35,6 @@ struct _PinosClientSourcePrivate
 | 
			
		|||
  guint id;
 | 
			
		||||
 | 
			
		||||
  GstCaps *format;
 | 
			
		||||
  GSocket *socket;
 | 
			
		||||
 | 
			
		||||
  GBytes *possible_formats;
 | 
			
		||||
 | 
			
		||||
  PinosSourceOutput *input;
 | 
			
		||||
| 
						 | 
				
			
			@ -218,6 +216,10 @@ client_get_formats (PinosSource *source,
 | 
			
		|||
 | 
			
		||||
  str = gst_caps_to_string (caps);
 | 
			
		||||
 | 
			
		||||
  gst_caps_unref (caps);
 | 
			
		||||
  if (cfilter)
 | 
			
		||||
    gst_caps_unref (cfilter);
 | 
			
		||||
 | 
			
		||||
  return g_bytes_new_take (str, strlen (str) + 1);
 | 
			
		||||
 | 
			
		||||
invalid_filter:
 | 
			
		||||
| 
						 | 
				
			
			@ -234,6 +236,8 @@ no_format:
 | 
			
		|||
      *error = g_error_new (G_IO_ERROR,
 | 
			
		||||
                            G_IO_ERROR_NOT_FOUND,
 | 
			
		||||
                            "No compatible format found");
 | 
			
		||||
    if (cfilter)
 | 
			
		||||
      gst_caps_unref (cfilter);
 | 
			
		||||
    return NULL;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -293,6 +297,7 @@ client_create_source_output (PinosSource     *source,
 | 
			
		|||
                                        props,
 | 
			
		||||
                                        prefix,
 | 
			
		||||
                                        error);
 | 
			
		||||
  g_bytes_unref (format_filter);
 | 
			
		||||
 | 
			
		||||
  if (output == NULL)
 | 
			
		||||
    return NULL;
 | 
			
		||||
| 
						 | 
				
			
			@ -330,6 +335,8 @@ client_source_finalize (GObject * object)
 | 
			
		|||
  g_clear_object (&priv->src);
 | 
			
		||||
  g_clear_object (&priv->pipeline);
 | 
			
		||||
 | 
			
		||||
  if (priv->possible_formats)
 | 
			
		||||
    g_bytes_unref (priv->possible_formats);
 | 
			
		||||
  gst_caps_replace (&priv->format, NULL);
 | 
			
		||||
 | 
			
		||||
  G_OBJECT_CLASS (pinos_client_source_parent_class)->finalize (object);
 | 
			
		||||
| 
						 | 
				
			
			@ -365,10 +372,12 @@ on_input_socket_notify (GObject    *gobject,
 | 
			
		|||
  }
 | 
			
		||||
  g_object_set (priv->src, "socket", socket, NULL);
 | 
			
		||||
 | 
			
		||||
  if (socket)
 | 
			
		||||
  if (socket) {
 | 
			
		||||
    gst_element_set_state (priv->pipeline, GST_STATE_PLAYING);
 | 
			
		||||
  else
 | 
			
		||||
    g_object_unref (socket);
 | 
			
		||||
  } else {
 | 
			
		||||
    gst_element_set_state (priv->pipeline, GST_STATE_READY);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -176,6 +176,9 @@ handle_create_source_output (PinosClient1           *interface,
 | 
			
		|||
                                              props,
 | 
			
		||||
                                              priv->object_path,
 | 
			
		||||
                                              &error);
 | 
			
		||||
  pinos_properties_free (props);
 | 
			
		||||
  g_bytes_unref (formats);
 | 
			
		||||
 | 
			
		||||
  if (output == NULL)
 | 
			
		||||
    goto no_output;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -202,15 +205,15 @@ not_allowed:
 | 
			
		|||
no_source:
 | 
			
		||||
  {
 | 
			
		||||
    g_dbus_method_invocation_return_gerror (invocation, error);
 | 
			
		||||
    g_clear_error (&error);
 | 
			
		||||
    pinos_properties_free (props);
 | 
			
		||||
    g_bytes_unref (formats);
 | 
			
		||||
    g_clear_error (&error);
 | 
			
		||||
    return TRUE;
 | 
			
		||||
  }
 | 
			
		||||
no_output:
 | 
			
		||||
  {
 | 
			
		||||
    g_dbus_method_invocation_return_gerror (invocation, error);
 | 
			
		||||
    g_clear_error (&error);
 | 
			
		||||
    g_bytes_unref (formats);
 | 
			
		||||
    return TRUE;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -236,13 +239,13 @@ handle_create_source_input (PinosClient1           *interface,
 | 
			
		|||
    goto not_allowed;
 | 
			
		||||
 | 
			
		||||
  formats = g_bytes_new (arg_possible_formats, strlen (arg_possible_formats) + 1);
 | 
			
		||||
  props = pinos_properties_from_variant (arg_properties);
 | 
			
		||||
 | 
			
		||||
  source = pinos_client_source_new (priv->daemon, formats);
 | 
			
		||||
  if (source == NULL)
 | 
			
		||||
    goto no_source;
 | 
			
		||||
 | 
			
		||||
  sender = g_dbus_method_invocation_get_sender (invocation);
 | 
			
		||||
  props = pinos_properties_from_variant (arg_properties);
 | 
			
		||||
 | 
			
		||||
  input = pinos_client_source_get_source_input (PINOS_CLIENT_SOURCE (source),
 | 
			
		||||
                                                priv->object_path,
 | 
			
		||||
| 
						 | 
				
			
			@ -250,6 +253,8 @@ handle_create_source_input (PinosClient1           *interface,
 | 
			
		|||
                                                props,
 | 
			
		||||
                                                priv->object_path,
 | 
			
		||||
                                                &error);
 | 
			
		||||
  pinos_properties_free (props);
 | 
			
		||||
 | 
			
		||||
  if (input == NULL)
 | 
			
		||||
    goto no_input;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -285,7 +290,6 @@ no_source:
 | 
			
		|||
    g_dbus_method_invocation_return_dbus_error (invocation,
 | 
			
		||||
        "org.pinos.Error", "Can't create source");
 | 
			
		||||
    g_bytes_unref (formats);
 | 
			
		||||
    pinos_properties_free (props);
 | 
			
		||||
    return TRUE;
 | 
			
		||||
  }
 | 
			
		||||
no_input:
 | 
			
		||||
| 
						 | 
				
			
			@ -294,7 +298,6 @@ no_input:
 | 
			
		|||
    g_object_unref (source);
 | 
			
		||||
    g_clear_error (&error);
 | 
			
		||||
    g_bytes_unref (formats);
 | 
			
		||||
    pinos_properties_free (props);
 | 
			
		||||
    return TRUE;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -352,7 +355,7 @@ client_unregister_object (PinosClient *client)
 | 
			
		|||
  g_clear_object (&priv->client1);
 | 
			
		||||
 | 
			
		||||
  pinos_daemon_unexport (daemon, priv->object_path);
 | 
			
		||||
  g_free (priv->object_path);
 | 
			
		||||
  g_clear_pointer (&priv->object_path, g_free);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
| 
						 | 
				
			
			@ -370,6 +373,7 @@ pinos_client_dispose (GObject * object)
 | 
			
		|||
 | 
			
		||||
  g_list_foreach (priv->outputs, (GFunc) do_remove_output, client);
 | 
			
		||||
  client_unregister_object (client);
 | 
			
		||||
  g_clear_object (&priv->daemon);
 | 
			
		||||
 | 
			
		||||
  G_OBJECT_CLASS (pinos_client_parent_class)->dispose (object);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -379,6 +383,7 @@ pinos_client_finalize (GObject * object)
 | 
			
		|||
  PinosClient *client = PINOS_CLIENT (object);
 | 
			
		||||
  PinosClientPrivate *priv = client->priv;
 | 
			
		||||
 | 
			
		||||
  g_free (priv->sender);
 | 
			
		||||
  if (priv->properties)
 | 
			
		||||
    pinos_properties_free (priv->properties);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -187,6 +187,31 @@ pinos_source_output_set_property (GObject      *_object,
 | 
			
		|||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clear_formats (PinosSourceOutput *output)
 | 
			
		||||
{
 | 
			
		||||
  PinosSourceOutputPrivate *priv = output->priv;
 | 
			
		||||
 | 
			
		||||
  g_clear_pointer (&priv->requested_format, g_bytes_unref);
 | 
			
		||||
  g_clear_pointer (&priv->format, g_bytes_unref);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
stop_transfer (PinosSourceOutput *output)
 | 
			
		||||
{
 | 
			
		||||
  PinosSourceOutputPrivate *priv = output->priv;
 | 
			
		||||
 | 
			
		||||
  if (priv->socket) {
 | 
			
		||||
    g_clear_object (&priv->socket);
 | 
			
		||||
    g_object_notify (G_OBJECT (output), "socket");
 | 
			
		||||
  }
 | 
			
		||||
  clear_formats (output);
 | 
			
		||||
  priv->state = PINOS_SOURCE_OUTPUT_STATE_IDLE;
 | 
			
		||||
  g_object_set (priv->iface,
 | 
			
		||||
               "state", priv->state,
 | 
			
		||||
                NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
handle_start (PinosSourceOutput1     *interface,
 | 
			
		||||
              GDBusMethodInvocation  *invocation,
 | 
			
		||||
| 
						 | 
				
			
			@ -204,6 +229,8 @@ handle_start (PinosSourceOutput1     *interface,
 | 
			
		|||
                                        strlen (arg_requested_format) + 1);
 | 
			
		||||
 | 
			
		||||
  socketpair (AF_UNIX, SOCK_STREAM, 0, fd);
 | 
			
		||||
 | 
			
		||||
  g_clear_object (&priv->socket);
 | 
			
		||||
  priv->socket = g_socket_new_from_fd (fd[0], NULL);
 | 
			
		||||
  g_object_notify (G_OBJECT (output), "socket");
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -222,6 +249,8 @@ handle_start (PinosSourceOutput1     *interface,
 | 
			
		|||
                          g_bytes_get_data (priv->format, NULL),
 | 
			
		||||
                          pinos_properties_to_variant (priv->properties)),
 | 
			
		||||
           fdlist);
 | 
			
		||||
  g_object_unref (fdlist);
 | 
			
		||||
  close (fd[1]);
 | 
			
		||||
 | 
			
		||||
  g_object_set (priv->iface,
 | 
			
		||||
               "format", g_bytes_get_data (priv->format, NULL),
 | 
			
		||||
| 
						 | 
				
			
			@ -243,32 +272,6 @@ no_format:
 | 
			
		|||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clear_socket (PinosSourceOutput *output)
 | 
			
		||||
{
 | 
			
		||||
  PinosSourceOutputPrivate *priv = output->priv;
 | 
			
		||||
 | 
			
		||||
  g_clear_object (&priv->socket);
 | 
			
		||||
  g_clear_pointer (&priv->requested_format, g_bytes_unref);
 | 
			
		||||
  g_clear_pointer (&priv->format, g_bytes_unref);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
stop_transfer (PinosSourceOutput *output)
 | 
			
		||||
{
 | 
			
		||||
  PinosSourceOutputPrivate *priv = output->priv;
 | 
			
		||||
 | 
			
		||||
  if (priv->socket) {
 | 
			
		||||
    clear_socket (output);
 | 
			
		||||
    g_object_notify (G_OBJECT (output), "socket");
 | 
			
		||||
  }
 | 
			
		||||
  priv->state = PINOS_SOURCE_OUTPUT_STATE_IDLE;
 | 
			
		||||
  g_object_set (priv->iface,
 | 
			
		||||
               "state", priv->state,
 | 
			
		||||
                NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
handle_stop (PinosSourceOutput1     *interface,
 | 
			
		||||
             GDBusMethodInvocation  *invocation,
 | 
			
		||||
| 
						 | 
				
			
			@ -329,8 +332,10 @@ static void
 | 
			
		|||
pinos_source_output_dispose (GObject * object)
 | 
			
		||||
{
 | 
			
		||||
  PinosSourceOutput *output = PINOS_SOURCE_OUTPUT (object);
 | 
			
		||||
  PinosSourceOutputPrivate *priv = output->priv;
 | 
			
		||||
 | 
			
		||||
  clear_socket (output);
 | 
			
		||||
  clear_formats (output);
 | 
			
		||||
  g_clear_object (&priv->socket);
 | 
			
		||||
  output_unregister_object (output);
 | 
			
		||||
 | 
			
		||||
  G_OBJECT_CLASS (pinos_source_output_parent_class)->dispose (object);
 | 
			
		||||
| 
						 | 
				
			
			@ -342,6 +347,10 @@ pinos_source_output_finalize (GObject * object)
 | 
			
		|||
  PinosSourceOutput *output = PINOS_SOURCE_OUTPUT (object);
 | 
			
		||||
  PinosSourceOutputPrivate *priv = output->priv;
 | 
			
		||||
 | 
			
		||||
  if (priv->possible_formats)
 | 
			
		||||
    g_bytes_unref (priv->possible_formats);
 | 
			
		||||
  if (priv->properties)
 | 
			
		||||
    pinos_properties_free (priv->properties);
 | 
			
		||||
  g_clear_object (&priv->daemon);
 | 
			
		||||
  g_clear_object (&priv->iface);
 | 
			
		||||
  g_free (priv->client_path);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue