/pidgin/main: d76b1d242829: VV: add another method of probing de...

Tomasz Wasilczyk tomkiewicz at cpw.pidgin.im
Fri Jun 7 10:30:49 EDT 2013


Changeset: d76b1d242829bc28f0d7fcfd0f7bda3b15be69eb
Author:	 Tomasz Wasilczyk <tomkiewicz at cpw.pidgin.im>
Date:	 2013-06-07 16:30 +0200
Branch:	 default
URL: https://hg.pidgin.im/pidgin/main/rev/d76b1d242829

Description:

VV: add another method of probing devices (by device-name), fix memleak

diffstat:

 pidgin/gtkmedia.c |   18 ++++-
 pidgin/gtkprefs.c |  157 +++++++++++++++++++++++++++++++++++------------------
 2 files changed, 118 insertions(+), 57 deletions(-)

diffs (254 lines):

diff --git a/pidgin/gtkmedia.c b/pidgin/gtkmedia.c
--- a/pidgin/gtkmedia.c
+++ b/pidgin/gtkmedia.c
@@ -1059,7 +1059,7 @@ pidgin_media_new_cb(PurpleMediaManager *
 static GstElement *
 create_vv_element(const gchar *plugin, const gchar *device)
 {
-	GstElement *element;
+	GstElement *element, *source;
 
 	g_return_val_if_fail(plugin != NULL, NULL);
 	g_return_val_if_fail(plugin[0] != '\0', NULL);
@@ -1098,15 +1098,25 @@ create_vv_element(const gchar *plugin, c
 		gst_element_add_pad(ksv_bin, ksv_ghost);
 
 		element = ksv_bin;
+		source = ksv_src;
 	}
 	else
-		element = gst_element_factory_make(plugin, NULL);
+		element = source = gst_element_factory_make(plugin, NULL);
 
 	if (element == NULL)
 		return NULL;
 
-	if (device != NULL)
-		g_object_set(G_OBJECT(element), "device", device, NULL);
+	if (device != NULL) {
+		GObjectClass *klass = G_OBJECT_GET_CLASS(source);
+		if (g_object_class_find_property(klass, "device"))
+			g_object_set(G_OBJECT(source), "device", device, NULL);
+		else if (g_object_class_find_property(klass, "device-index"))
+			g_object_set(G_OBJECT(source), "device-index",
+				g_ascii_strtoull(device, NULL, 10), NULL);
+		else
+			purple_debug_warning("gtkmedia", "No possibility to "
+				"set device\n");
+	}
 
 	if (g_strcmp0(plugin, "videotestsrc") == 0)
 		g_object_set(G_OBJECT(element), "is-live", TRUE, NULL);
diff --git a/pidgin/gtkprefs.c b/pidgin/gtkprefs.c
--- a/pidgin/gtkprefs.c
+++ b/pidgin/gtkprefs.c
@@ -3105,18 +3105,25 @@ get_vv_element_devices(const gchar *elem
 #if !GST_CHECK_VERSION(1,0,0)
 	GstPropertyProbe *probe;
 	const GParamSpec *pspec;
+	gint i;
+	GValueArray *array;
+	enum {
+		PROBE_NONE,
+		PROBE_DEVICE,
+		PROBE_NAME
+	} probe_attr;
 #endif
 
-	ret = g_list_prepend(ret, (gpointer)_("Default"));
-	ret = g_list_prepend(ret, "");
+	ret = g_list_prepend(ret, g_strdup(_("Default")));
+	ret = g_list_prepend(ret, g_strdup(""));
 
 	if (!strcmp(element_name, "<custom>") || (*element_name == '\0')) {
 		return g_list_reverse(ret);
 	}
 
 	if (g_strcmp0(element_name, "videodisabledsrc") == 0) {
-		ret = g_list_prepend(ret, (gpointer)_("Random noise"));
-		ret = g_list_prepend(ret, "snow");
+		ret = g_list_prepend(ret, g_strdup(_("Random noise")));
+		ret = g_list_prepend(ret, g_strdup("snow"));
 
 		return g_list_reverse(ret);
 	}
@@ -3124,70 +3131,114 @@ get_vv_element_devices(const gchar *elem
 	element = gst_element_factory_make(element_name, "test");
 	if (!element) {
 		purple_debug_info("vvconfig", "'%s' - unable to find element\n",
-		                  element_name);
+			element_name);
 		return g_list_reverse(ret);
 	}
 
 	klass = G_OBJECT_GET_CLASS (element);
 	if (!klass) {
-		purple_debug_info("vvconfig", "'%s' - unable to find GObject Class\n",
-		                  element_name);
+		purple_debug_info("vvconfig", "'%s' - unable to find GObject "
+			"Class\n", element_name);
 		return g_list_reverse(ret);
 	}
 
 #if GST_CHECK_VERSION(1,0,0)
-	purple_debug_info("vvconfig", "'%s' - no device\n", element_name);
+	purple_debug_info("vvconfig", "'%s' - gstreamer-1.0 doesn't suport "
+		"property probing\n", element_name);
 #else
-	if (!g_object_class_find_property(klass, "device") ||
-			!GST_IS_PROPERTY_PROBE(element) ||
-			!(probe = GST_PROPERTY_PROBE(element)) ||
-			!(pspec = gst_property_probe_get_property(probe, "device"))) {
-		purple_debug_info("vvconfig", "'%s' - no device\n", element_name);
-	} else {
-		gint n;
-		GValueArray *array;
-
-		/* Set autoprobe[-fps] to FALSE to avoid delays when probing. */
-		if (g_object_class_find_property(klass, "autoprobe")) {
-			g_object_set(G_OBJECT(element), "autoprobe", FALSE, NULL);
-			if (g_object_class_find_property(klass, "autoprobe-fps")) {
-				g_object_set(G_OBJECT(element), "autoprobe-fps", FALSE, NULL);
-			}
-		}
-
-		array = gst_property_probe_probe_and_get_values(probe, pspec);
-		if (array == NULL) {
-			purple_debug_info("vvconfig", "'%s' has no devices\n", element_name);
-			return g_list_reverse(ret);
-		}
-
-		for (n = 0; n < array->n_values; ++n) {
-			GValue *device;
-			const gchar *name;
-			const gchar *device_name;
-
-			device = g_value_array_get_nth(array, n);
-			g_object_set_property(G_OBJECT(element), "device", device);
-			if (gst_element_set_state(element, GST_STATE_READY) != GST_STATE_CHANGE_SUCCESS) {
-				purple_debug_warning("vvconfig", "Error changing state of %s\n",
-				                     element_name);
+	if (g_object_class_find_property(klass, "device"))
+		probe_attr = PROBE_DEVICE;
+	else if (g_object_class_find_property(klass, "device-index") &&
+		g_object_class_find_property(klass, "device-name"))
+		probe_attr = PROBE_NAME;
+	else
+		probe_attr = PROBE_NONE;
+	
+	if (!GST_IS_PROPERTY_PROBE(element))
+		probe_attr = PROBE_NONE;
+	
+	if (probe_attr == PROBE_NONE)
+	{
+		purple_debug_info("vvconfig", "'%s' - no possibility to probe "
+			"for devices\n", element_name);
+		gst_object_unref(element);
+		return g_list_reverse(ret);
+	}
+
+	probe = GST_PROPERTY_PROBE(element);
+
+	if (probe_attr == PROBE_DEVICE)
+		pspec = gst_property_probe_get_property(probe, "device");
+	else /* probe_attr == PROBE_NAME */
+		pspec = gst_property_probe_get_property(probe, "device-name");
+
+	if (!pspec) {
+		purple_debug_info("vvconfig", "'%s' - creating probe failed\n",
+			element_name);
+		gst_object_unref(element);
+		return g_list_reverse(ret);
+	}
+
+	/* Set autoprobe[-fps] to FALSE to avoid delays when probing. */
+	if (g_object_class_find_property(klass, "autoprobe"))
+		g_object_set(G_OBJECT(element), "autoprobe", FALSE, NULL);
+	if (g_object_class_find_property(klass, "autoprobe-fps"))
+		g_object_set(G_OBJECT(element), "autoprobe-fps", FALSE, NULL);
+
+	array = gst_property_probe_probe_and_get_values(probe, pspec);
+	if (array == NULL) {
+		purple_debug_info("vvconfig", "'%s' has no devices\n",
+			element_name);
+		gst_object_unref(element);
+		return g_list_reverse(ret);
+	}
+
+	for (i = 0; i < array->n_values; i++) {
+		GValue *device;
+		const gchar *name;
+		const gchar *device_name;
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+		/* GValueArray is in gstreamer-0.10 API */
+		device = g_value_array_get_nth(array, i);
+#pragma GCC diagnostic pop
+
+		if (probe_attr == PROBE_DEVICE) {
+			g_object_set_property(G_OBJECT(element), "device",
+				device);
+			if (gst_element_set_state(element, GST_STATE_READY)
+				!= GST_STATE_CHANGE_SUCCESS)
+			{
+				purple_debug_warning("vvconfig", "Error "
+					"changing state of %s\n", element_name);
 				continue;
 			}
 
-			g_object_get(G_OBJECT(element), "device-name", &name, NULL);
-			device_name = g_value_get_string(device);
-			if (name == NULL)
-				name = _("Unknown");
-			purple_debug_info("vvconfig", "Found device %s : %s for %s\n",
-			                  device_name, name, element_name);
-			ret = g_list_prepend(ret, (gpointer)name);
-			ret = g_list_prepend(ret, (gpointer)device_name);
-			gst_element_set_state(element, GST_STATE_NULL);
+			g_object_get(G_OBJECT(element), "device-name", &name,
+				NULL);
+			device_name = g_strdup(g_value_get_string(device));
+		} else /* probe_attr == PROBE_NAME */ {
+			name = g_strdup(g_value_get_string(device));
+			device_name = g_strdup_printf("%d", i);
 		}
+
+		if (name == NULL)
+			name = _("Unknown");
+		purple_debug_info("vvconfig", "Found device %s: %s for %s\n",
+			device_name, name, element_name);
+		ret = g_list_prepend(ret, (gpointer)name);
+		ret = g_list_prepend(ret, (gpointer)device_name);
+		gst_element_set_state(element, GST_STATE_NULL);
 	}
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+	/* GValueArray is in gstreamer-0.10 API */
+	g_value_array_free(array);
+#pragma GCC diagnostic pop
 #endif
+
 	gst_object_unref(element);
-
 	return g_list_reverse(ret);
 }
 
@@ -3237,7 +3288,7 @@ vv_plugin_changed_cb(const gchar *name, 
 		purple_prefs_set_string(pref, g_list_next(devices)->data);
 	widget = pidgin_prefs_dropdown_from_list(vbox, _("_Device"),
 	                                         PURPLE_PREF_STRING, pref, devices);
-	g_list_free(devices);
+	g_list_free_full(devices, g_free);
 	gtk_size_group_add_widget(sg, widget);
 	gtk_misc_set_alignment(GTK_MISC(widget), 0, 0.5);
 
@@ -3273,7 +3324,7 @@ make_vv_frame(GtkWidget *parent, GtkSize
 	widget = pidgin_prefs_dropdown_from_list(vbox, _("_Device"),
 	                                         PURPLE_PREF_STRING, device_pref,
 	                                         devices);
-	g_list_free(devices);
+	g_list_free_full(devices, g_free);
 	gtk_size_group_add_widget(sg, widget);
 	gtk_misc_set_alignment(GTK_MISC(widget), 0, 0.5);
 



More information about the Commits mailing list