changeset 29158:ae81f8baa148

Transfer some GStreamer message handling to the Farsight 2 media backend.
author maiku@pidgin.im
date Fri, 23 Oct 2009 19:59:12 +0000
parents e85df0170905
children efeb21092ed2
files libpurple/media/backend-fs2.c libpurple/media/media.c
diffstat 2 files changed, 268 insertions(+), 101 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/media/backend-fs2.c	Fri Oct 23 18:20:54 2009 +0000
+++ b/libpurple/media/backend-fs2.c	Fri Oct 23 19:59:12 2009 +0000
@@ -26,6 +26,8 @@
 
 #include "backend-fs2.h"
 
+#include "internal.h"
+
 #include "backend-iface.h"
 #include "debug.h"
 #include "media-gst.h"
@@ -257,9 +259,274 @@
 	iface->set_send_codec = purple_media_backend_fs2_set_send_codec;
 }
 
+static void
+_gst_handle_message_element(GstBus *bus, GstMessage *msg,
+		PurpleMediaBackend *self)
+{
+	PurpleMediaBackendFs2Private *priv =
+			PURPLE_MEDIA_BACKEND_FS2_GET_PRIVATE(self);
+	GstElement *src = GST_ELEMENT(GST_MESSAGE_SRC(msg));
+
+	if (!FS_IS_CONFERENCE(src) || !PURPLE_IS_MEDIA_BACKEND(self) ||
+			priv->conference != FS_CONFERENCE(src))
+		return;
+
+	if (gst_structure_has_name(msg->structure, "farsight-error")) {
+		FsError error_no;
+		gst_structure_get_enum(msg->structure, "error-no",
+				FS_TYPE_ERROR, (gint*)&error_no);
+		switch (error_no) {
+			case FS_ERROR_NO_CODECS:
+				purple_media_error(priv->media, _("No codecs"
+						" found. Install some"
+						" GStreamer codecs found"
+						" in GStreamer plugins"
+						" packages."));
+				purple_media_end(priv->media, NULL, NULL);
+				break;
+			case FS_ERROR_NO_CODECS_LEFT:
+				purple_media_error(priv->media, _("No codecs"
+						" left. Your codec"
+						" preferences in"
+						" fs-codecs.conf are too"
+						" strict."));
+				purple_media_end(priv->media, NULL, NULL);
+				break;
+			case FS_ERROR_UNKNOWN_CNAME:
+			/*
+			 * Unknown CName is only a problem for the
+			 * multicast transmitter which isn't used.
+			 * It is also deprecated.
+			 */
+				break;
+			default:
+				purple_debug_error("backend-fs2",
+						"farsight-error: %i: %s\n",
+						error_no,
+					  	gst_structure_get_string(
+						msg->structure, "error-msg"));
+				break;
+		}
+
+		if (FS_ERROR_IS_FATAL(error_no)) {
+			purple_media_error(priv->media, _("A non-recoverable "
+					"Farsight2 error has occurred."));
+			purple_media_end(priv->media, NULL, NULL);
+		}
+	} else if (gst_structure_has_name(msg->structure,
+			"farsight-new-local-candidate")) {
+		const GValue *value;
+		FsStream *stream;
+		FsCandidate *local_candidate;
+#if 0
+		PurpleMediaSession *session;
+#endif
+
+		value = gst_structure_get_value(msg->structure, "stream");
+		stream = g_value_get_object(value);
+		value = gst_structure_get_value(msg->structure, "candidate");
+		local_candidate = g_value_get_boxed(value);
+#if 0
+		session = purple_media_session_from_fs_stream(media, stream);
+		_new_local_candidate_cb(stream,	local_candidate, session);
+#endif
+	} else if (gst_structure_has_name(msg->structure,
+			"farsight-local-candidates-prepared")) {
+		const GValue *value;
+		FsStream *stream;
+#if 0
+		PurpleMediaSession *session;
+#endif
+
+		value = gst_structure_get_value(msg->structure, "stream");
+		stream = g_value_get_object(value);
+#if 0
+		session = purple_media_session_from_fs_stream(media, stream);
+		_candidates_prepared_cb(stream, session);
+#endif
+	} else if (gst_structure_has_name(msg->structure,
+			"farsight-new-active-candidate-pair")) {
+		const GValue *value;
+		FsStream *stream;
+		FsCandidate *local_candidate;
+		FsCandidate *remote_candidate;
+#if 0
+		PurpleMediaSession *session;
+#endif
+
+		value = gst_structure_get_value(msg->structure, "stream");
+		stream = g_value_get_object(value);
+		value = gst_structure_get_value(msg->structure,
+				"local-candidate");
+		local_candidate = g_value_get_boxed(value);
+		value = gst_structure_get_value(msg->structure,
+				"remote-candidate");
+		remote_candidate = g_value_get_boxed(value);
+#if 0
+		session = purple_media_session_from_fs_stream(media, stream);
+		_candidate_pair_established_cb(stream, local_candidate,
+				remote_candidate, session);
+#endif
+	} else if (gst_structure_has_name(msg->structure,
+			"farsight-recv-codecs-changed")) {
+		const GValue *value;
+		GList *codecs;
+		FsCodec *codec;
+
+		value = gst_structure_get_value(msg->structure, "codecs");
+		codecs = g_value_get_boxed(value);
+		codec = codecs->data;
+
+		purple_debug_info("backend-fs2",
+				"farsight-recv-codecs-changed: %s\n",
+				codec->encoding_name);
+	} else if (gst_structure_has_name(msg->structure,
+			"farsight-component-state-changed")) {
+		const GValue *value;
+		FsStreamState fsstate;
+		guint component;
+		const gchar *state;
+
+		value = gst_structure_get_value(msg->structure, "state");
+		fsstate = g_value_get_enum(value);
+		value = gst_structure_get_value(msg->structure, "component");
+		component = g_value_get_uint(value);
+
+		switch (fsstate) {
+			case FS_STREAM_STATE_FAILED:
+				state = "FAILED";
+				break;
+			case FS_STREAM_STATE_DISCONNECTED:
+				state = "DISCONNECTED";
+				break;
+			case FS_STREAM_STATE_GATHERING:
+				state = "GATHERING";
+				break;
+			case FS_STREAM_STATE_CONNECTING:
+				state = "CONNECTING";
+				break;
+			case FS_STREAM_STATE_CONNECTED:
+				state = "CONNECTED";
+				break;
+			case FS_STREAM_STATE_READY:
+				state = "READY";
+				break;
+			default:
+				state = "UNKNOWN";
+				break;
+		}
+
+		purple_debug_info("backend-fs2",
+				"farsight-component-state-changed: "
+				"component: %u state: %s\n",
+				component, state);
+	} else if (gst_structure_has_name(msg->structure,
+			"farsight-send-codec-changed")) {
+		const GValue *value;
+		FsCodec *codec;
+		gchar *codec_str;
+
+		value = gst_structure_get_value(msg->structure, "codec");
+		codec = g_value_get_boxed(value);
+		codec_str = fs_codec_to_string(codec);
+
+		purple_debug_info("backend-fs2",
+				"farsight-send-codec-changed: codec: %s\n",
+				codec_str);
+
+		g_free(codec_str);
+	} else if (gst_structure_has_name(msg->structure,
+			"farsight-codecs-changed")) {
+		const GValue *value;
+		FsSession *fssession;
+#if 0
+		GList *sessions;
+#endif
+
+		value = gst_structure_get_value(msg->structure, "session");
+		fssession = g_value_get_object(value);
+#if 0
+		sessions = g_hash_table_get_values(priv->sessions);
+
+		for (; sessions; sessions =
+				g_list_delete_link(sessions, sessions)) {
+			PurpleMediaBackendFs2Session *session = sessions->data;
+			gchar *session_id;
+
+			if (session->session != fssession)
+				continue;
+
+			session_id = g_strdup(session->id);
+			g_signal_emit(media,
+					purple_media_backend_fs2_signals[
+					CODECS_CHANGED], 0, session_id);
+			g_free(session_id);
+			g_list_free(sessions);
+			break;
+		}
+#endif
+	}
+}
+
+static void
+_gst_handle_message_error(GstBus *bus, GstMessage *msg,
+		PurpleMediaBackend *self)
+{
+	PurpleMediaBackendFs2Private *priv =
+			PURPLE_MEDIA_BACKEND_FS2_GET_PRIVATE(self);
+	GstElement *element = GST_ELEMENT(GST_MESSAGE_SRC(msg));
+	GstElement *lastElement = NULL;
+	GList *sessions;
+
+	while (!GST_IS_PIPELINE(element)) {
+		if (element == priv->confbin)
+			break;
+
+		lastElement = element;
+		element = GST_ELEMENT_PARENT(element);
+	}
+
+	if (!GST_IS_PIPELINE(element))
+		return;
+
+	sessions = purple_media_get_session_ids(priv->media);
+
+	for (; sessions; sessions = g_list_delete_link(sessions, sessions)) {
+		if (purple_media_get_src(priv->media, sessions->data)
+				!= lastElement)
+			continue;
+
+		if (purple_media_get_session_type(priv->media, sessions->data)
+				& PURPLE_MEDIA_AUDIO)
+			purple_media_error(priv->media,
+					_("Error with your microphone"));
+		else
+			purple_media_error(priv->media,
+					_("Error with your webcam"));
+
+		break;
+	}
+
+	g_list_free(sessions);
+
+	purple_media_error(priv->media, _("Conference error"));
+	purple_media_end(priv->media, NULL, NULL);
+}
+
 static gboolean
 _gst_bus_cb(GstBus *bus, GstMessage *msg, PurpleMediaBackend *self)
 {
+	switch(GST_MESSAGE_TYPE(msg)) {
+		case GST_MESSAGE_ELEMENT:
+			_gst_handle_message_element(bus, msg, self);
+			break;
+		case GST_MESSAGE_ERROR:
+			_gst_handle_message_error(bus, msg, self);
+			break;
+		default:
+			break;
+	}
+
 	return TRUE;
 }
 
--- a/libpurple/media/media.c	Fri Oct 23 18:20:54 2009 +0000
+++ b/libpurple/media/media.c	Fri Oct 23 19:59:12 2009 +0000
@@ -1065,37 +1065,7 @@
 					FS_CONFERENCE(GST_MESSAGE_SRC(msg)))
 				break;
 
-			if (gst_structure_has_name(msg->structure, "farsight-error")) {
-				FsError error_no;
-				gst_structure_get_enum(msg->structure, "error-no",
-						FS_TYPE_ERROR, (gint*)&error_no);
-				switch (error_no) {
-					case FS_ERROR_NO_CODECS:
-						purple_media_error(media, _("No codecs found. Install some GStreamer codecs found in GStreamer plugins packages."));
-						purple_media_end(media, NULL, NULL);
-						break;
-					case FS_ERROR_NO_CODECS_LEFT:
-						purple_media_error(media, _("No codecs left. Your codec preferences in fs-codecs.conf are too strict."));
-						purple_media_end(media, NULL, NULL);
-						break;
-					case FS_ERROR_UNKNOWN_CNAME:
-					/*
-					 * Unknown CName is only a problem for the
-					 * multicast transmitter which isn't used.
-					 * It is also deprecated.
-					 */
-						break;
-					default:
-						purple_debug_error("media", "farsight-error: %i: %s\n", error_no,
-							  	gst_structure_get_string(msg->structure, "error-msg"));
-						break;
-				}
-
-				if (FS_ERROR_IS_FATAL(error_no)) {
-					purple_media_error(media, _("A non-recoverable Farsight2 error has occurred."));
-					purple_media_end(media, NULL, NULL);
-				}
-			} else if (gst_structure_has_name(msg->structure,
+			if (gst_structure_has_name(msg->structure,
 					"farsight-new-local-candidate")) {
 				FsStream *stream = g_value_get_object(gst_structure_get_value(msg->structure, "stream"));
 				FsCandidate *local_candidate = g_value_get_boxed(gst_structure_get_value(msg->structure, "candidate"));
@@ -1114,47 +1084,6 @@
 				PurpleMediaSession *session = purple_media_session_from_fs_stream(media, stream);
 				purple_media_candidate_pair_established_cb(stream, local_candidate, remote_candidate, session);
 			} else if (gst_structure_has_name(msg->structure,
-					"farsight-recv-codecs-changed")) {
-				GList *codecs = g_value_get_boxed(gst_structure_get_value(msg->structure, "codecs"));
-				FsCodec *codec = codecs->data;
-				purple_debug_info("media", "farsight-recv-codecs-changed: %s\n", codec->encoding_name);
-				
-			} else if (gst_structure_has_name(msg->structure,
-					"farsight-component-state-changed")) {
-				FsStreamState fsstate = g_value_get_enum(gst_structure_get_value(msg->structure, "state"));
-				guint component = g_value_get_uint(gst_structure_get_value(msg->structure, "component"));
-				const gchar *state;
-				switch (fsstate) {
-					case FS_STREAM_STATE_FAILED:
-						state = "FAILED";
-						break;
-					case FS_STREAM_STATE_DISCONNECTED:
-						state = "DISCONNECTED";
-						break;
-					case FS_STREAM_STATE_GATHERING:
-						state = "GATHERING";
-						break;
-					case FS_STREAM_STATE_CONNECTING:
-						state = "CONNECTING";
-						break;
-					case FS_STREAM_STATE_CONNECTED:
-						state = "CONNECTED";
-						break;
-					case FS_STREAM_STATE_READY:
-						state = "READY";
-						break;
-					default:
-						state = "UNKNOWN";
-						break;
-				}
-				purple_debug_info("media", "farsight-component-state-changed: component: %u state: %s\n", component, state);
-			} else if (gst_structure_has_name(msg->structure,
-					"farsight-send-codec-changed")) {
-				FsCodec *codec = g_value_get_boxed(gst_structure_get_value(msg->structure, "codec"));
-				gchar *codec_str = fs_codec_to_string(codec);
-				purple_debug_info("media", "farsight-send-codec-changed: codec: %s\n", codec_str);
-				g_free(codec_str);
-			} else if (gst_structure_has_name(msg->structure,
 					"farsight-codecs-changed")) {
 				GList *sessions = g_hash_table_get_values(PURPLE_MEDIA(media)->priv->sessions);
 				FsSession *fssession = g_value_get_object(gst_structure_get_value(msg->structure, "session"));
@@ -1171,35 +1100,6 @@
 			}
 			break;
 		}
-		case GST_MESSAGE_ERROR: {
-			GstElement *element = GST_ELEMENT(GST_MESSAGE_SRC(msg));
-			GstElement *lastElement = NULL;
-			while (!GST_IS_PIPELINE(element)) {
-				if (element == media->priv->confbin) {
-					purple_media_error(media, _("Conference error"));
-					purple_media_end(media, NULL, NULL);
-					break;
-				}
-				lastElement = element;
-				element = GST_ELEMENT_PARENT(element);
-			}
-			if (GST_IS_PIPELINE(element)) {
-				GList *sessions = g_hash_table_get_values(media->priv->sessions);
-				for (; sessions; sessions = g_list_delete_link(sessions, sessions)) {
-					PurpleMediaSession *session = sessions->data;
-
-					if (session->src == lastElement) {
-						if (session->type & PURPLE_MEDIA_AUDIO)
-							purple_media_error(media, _("Error with your microphone"));
-						else
-							purple_media_error(media, _("Error with your webcam"));
-						purple_media_end(media, NULL, NULL);
-						break;
-					}
-				}
-				g_list_free(sessions);
-			}
-		}
 		default:
 			break;
 	}