changeset 29172:f600903f7811

Transfer creating Farsight 2 streams to the Fs2 media backend.
author maiku@pidgin.im
date Mon, 26 Oct 2009 21:35:11 +0000
parents eef5ec04a5bf
children 983af0970bb2
files libpurple/media/backend-fs2.c libpurple/media/backend-fs2.h libpurple/media/media.c
diffstat 3 files changed, 186 insertions(+), 85 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/media/backend-fs2.c	Mon Oct 26 20:17:35 2009 +0000
+++ b/libpurple/media/backend-fs2.c	Mon Oct 26 21:35:11 2009 +0000
@@ -30,6 +30,7 @@
 
 #include "backend-iface.h"
 #include "debug.h"
+#include "network.h"
 #include "media-gst.h"
 
 #include <gst/farsight/fs-conference-iface.h>
@@ -41,6 +42,8 @@
 typedef struct _PurpleMediaBackendFs2Private PurpleMediaBackendFs2Private;
 /** @copydoc _PurpleMediaBackendFs2Session */
 typedef struct _PurpleMediaBackendFs2Session PurpleMediaBackendFs2Session;
+/** @copydoc _PurpleMediaBackendFs2Stream */
+typedef struct _PurpleMediaBackendFs2Stream PurpleMediaBackendFs2Stream;
 
 #define PURPLE_MEDIA_BACKEND_FS2_GET_PRIVATE(obj) \
 		(G_TYPE_INSTANCE_GET_PRIVATE((obj), \
@@ -93,6 +96,25 @@
 		G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE(
 		PURPLE_TYPE_MEDIA_BACKEND, purple_media_backend_iface_init));
 
+struct _PurpleMediaBackendFs2Stream
+{
+	PurpleMediaBackendFs2Session *session;
+	gchar *participant;
+	FsStream *stream;
+
+	GList *local_candidates;
+	GList *remote_candidates;
+
+	GList *active_local_candidates;
+	GList *active_remote_candidates;
+
+	guint connected_cb_id;
+
+	gboolean initiator;
+	gboolean accepted;
+	gboolean candidates_prepared;
+};
+
 struct _PurpleMediaBackendFs2Session
 {
 	PurpleMediaBackendFs2 *backend;
@@ -111,6 +133,8 @@
 
 	GHashTable *sessions;
 	GHashTable *participants;
+
+	GList *streams;
 };
 
 enum {
@@ -323,7 +347,6 @@
 		return 0;
 }
 
-#if 0
 static FsStreamDirection
 _session_type_to_fs_stream_direction(PurpleMediaSessionType type)
 {
@@ -340,6 +363,7 @@
 		return FS_DIRECTION_NONE;
 }
 
+#if 0
 static PurpleMediaSessionType
 _session_type_from_fs(FsMediaType type, FsStreamDirection direction)
 {
@@ -463,6 +487,28 @@
 	return participant;
 }
 
+static PurpleMediaBackendFs2Stream *
+_get_stream(PurpleMediaBackendFs2 *self,
+		const gchar *sess_id, const gchar *name)
+{
+	PurpleMediaBackendFs2Private *priv;
+	GList *streams;
+
+	g_return_val_if_fail(PURPLE_IS_MEDIA_BACKEND_FS2(self), NULL);
+
+	priv = PURPLE_MEDIA_BACKEND_FS2_GET_PRIVATE(self);
+	streams = priv->streams;
+
+	for (; streams; streams = g_list_next(streams)) {
+		PurpleMediaBackendFs2Stream *stream = streams->data;
+		if (!strcmp(stream->session->id, sess_id) &&
+				!strcmp(stream->participant, name))
+			return stream;
+	}
+
+	return NULL;
+}
+
 static PurpleMediaBackendFs2Session *
 _get_session_from_fs_stream(PurpleMediaBackendFs2 *self, FsStream *stream)
 {
@@ -1023,6 +1069,122 @@
 }
 
 static gboolean
+_create_stream(PurpleMediaBackendFs2 *self,
+		const gchar *sess_id, const gchar *who,
+		PurpleMediaSessionType type, gboolean initiator,
+		const gchar *transmitter,
+		guint num_params, GParameter *params)
+{
+	PurpleMediaBackendFs2Private *priv =
+			PURPLE_MEDIA_BACKEND_FS2_GET_PRIVATE(self);
+	GError *err = NULL;
+	FsStream *fsstream = NULL;
+	const gchar *stun_ip = purple_network_get_stun_ip();
+	const gchar *turn_ip = purple_network_get_turn_ip();
+	guint _num_params = num_params;
+	GParameter *_params = g_new0(GParameter, num_params + 2);
+	FsStreamDirection type_direction =
+			_session_type_to_fs_stream_direction(type);
+	PurpleMediaBackendFs2Session *session;
+	PurpleMediaBackendFs2Stream *stream;
+	FsParticipant *participant;
+
+	memcpy(_params, params, sizeof(GParameter) * num_params);
+
+	if (stun_ip) {
+		purple_debug_info("backend-fs2", 
+			"Setting stun-ip on new stream: %s\n", stun_ip);
+
+		_params[_num_params].name = "stun-ip";
+		g_value_init(&_params[_num_params].value, G_TYPE_STRING);
+		g_value_set_string(&_params[_num_params].value, stun_ip);
+		++_num_params;
+	}
+
+	if (turn_ip && !strcmp("nice", transmitter)) {
+		GValueArray *relay_info = g_value_array_new(0);
+		GValue value;
+		gint turn_port = purple_prefs_get_int(
+				"/purple/network/turn_port");
+		const gchar *username =	purple_prefs_get_string(
+				"/purple/network/turn_username");
+		const gchar *password = purple_prefs_get_string(
+				"/purple/network/turn_password");
+		GstStructure *turn_setup = gst_structure_new("relay-info",
+				"ip", G_TYPE_STRING, turn_ip, 
+				"port", G_TYPE_UINT, turn_port,
+				"username", G_TYPE_STRING, username,
+				"password", G_TYPE_STRING, password,
+				NULL);
+
+		if (!turn_setup) {
+			purple_debug_error("backend-fs2",
+					"Error creating relay info structure");
+			return FALSE;
+		}
+
+		memset(&value, 0, sizeof(GValue));
+		g_value_init(&value, GST_TYPE_STRUCTURE);
+		gst_value_set_structure(&value, turn_setup);
+		relay_info = g_value_array_append(relay_info, &value);
+		gst_structure_free(turn_setup);
+
+		purple_debug_info("backend-fs2",
+			"Setting relay-info on new stream\n");
+		_params[_num_params].name = "relay-info";
+		g_value_init(&_params[_num_params].value, 
+			G_TYPE_VALUE_ARRAY);
+		g_value_set_boxed(&_params[_num_params].value,
+			relay_info);
+		g_value_array_free(relay_info);
+	}
+
+	session = _get_session(self, sess_id);
+
+	if (session == NULL) {
+		purple_debug_error("backend-fs2",
+				"Couldn't find session to create stream.\n");
+		return FALSE;
+	}
+
+	participant = _get_participant(self, who);
+
+	if (participant == NULL) {
+		purple_debug_error("backend-fs2", "Couldn't find "
+				"participant to create stream.\n");
+		return FALSE;
+	}
+
+	fsstream = fs_session_new_stream(session->session, participant,
+			type_direction & FS_DIRECTION_RECV, transmitter,
+			_num_params, _params, &err);
+	g_free(_params);
+
+	if (fsstream == NULL) {
+		if (err) {
+			purple_debug_error("backend-fs2",
+					"Error creating stream: %s\n",
+					err && err->message ?
+					err->message : "NULL");
+			g_error_free(err);
+		} else
+			purple_debug_error("backend-fs2",
+					"Error creating stream\n");
+		return FALSE;
+	}
+
+	stream = g_new0(PurpleMediaBackendFs2Stream, 1);
+	stream->initiator = initiator;
+	stream->participant = g_strdup(who);
+	stream->session = session;
+	stream->stream = fsstream;
+
+	priv->streams =	g_list_append(priv->streams, stream);
+
+	return TRUE;
+}
+
+static gboolean
 purple_media_backend_fs2_add_stream(PurpleMediaBackend *self,
 		const gchar *sess_id, const gchar *who,
 		PurpleMediaSessionType type, gboolean initiator,
@@ -1054,6 +1216,14 @@
 		return FALSE;
 	}
 
+	if (_get_stream(backend, sess_id, who) == NULL &&
+			!_create_stream(backend, sess_id, who, type,
+			initiator, transmitter, num_params, params)) {
+		purple_debug_error("backend-fs2",
+				"Error creating the stream.\n");
+		return FALSE;
+	}
+
 	return TRUE;
 }
 
@@ -1113,3 +1283,12 @@
 {
 	return _get_participant(self, name);
 }
+
+FsStream *
+purple_media_backend_fs2_get_stream(PurpleMediaBackendFs2 *self,
+		const gchar *sess_id, const gchar *who)
+{
+	PurpleMediaBackendFs2Stream *stream =
+			_get_stream(self, sess_id, who);
+	return stream != NULL? stream->stream : NULL;
+}
--- a/libpurple/media/backend-fs2.h	Mon Oct 26 20:17:35 2009 +0000
+++ b/libpurple/media/backend-fs2.h	Mon Oct 26 21:35:11 2009 +0000
@@ -68,6 +68,9 @@
 FsParticipant *purple_media_backend_fs2_get_participant(
 		PurpleMediaBackendFs2 *self,
 		const gchar *name);
+FsStream *purple_media_backend_fs2_get_stream(
+		PurpleMediaBackendFs2 *self,
+		const gchar *sess_id, const gchar *who);
 /* end tmp */
 
 G_END_DECLS
--- a/libpurple/media/media.c	Mon Oct 26 20:17:35 2009 +0000
+++ b/libpurple/media/media.c	Mon Oct 26 21:35:11 2009 +0000
@@ -1352,7 +1352,6 @@
 	FsMediaType media_type = purple_media_to_fs_media_type(type);
 	FsStreamDirection type_direction =
 			purple_media_to_fs_stream_direction(type);
-	gboolean is_nice = !strcmp(transmitter, "nice");
 
 	g_return_val_if_fail(PURPLE_IS_MEDIA(media), FALSE);
 
@@ -1432,91 +1431,11 @@
 	stream = purple_media_get_stream(media, sess_id, who);
 
 	if (!stream) {
-		GError *err = NULL;
 		FsStream *fsstream = NULL;
-		const gchar *stun_ip = purple_network_get_stun_ip();
-		const gchar *turn_ip = purple_network_get_turn_ip();
-
-		if (stun_ip || turn_ip) {
-			guint new_num_params = 
-					(stun_ip && is_nice) && turn_ip ?
-					num_params + 2 : num_params + 1;
-			guint next_param_index = num_params;
-			GParameter *param = g_new0(GParameter, new_num_params);
-			memcpy(param, params, sizeof(GParameter) * num_params);
-
-			if (stun_ip) {
-				purple_debug_info("media", 
-					"setting property stun-ip on new stream: %s\n", stun_ip);
-
-				param[next_param_index].name = "stun-ip";
-				g_value_init(&param[next_param_index].value, G_TYPE_STRING);
-				g_value_set_string(&param[next_param_index].value, stun_ip);
-				next_param_index++;
-			}
-
-			if (turn_ip && is_nice) {
-				GValueArray *relay_info = g_value_array_new(0);
-				GValue value;
-				gint turn_port = 
-					purple_prefs_get_int("/purple/network/turn_port");
-				const gchar *username =
-					purple_prefs_get_string("/purple/network/turn_username");
-				const gchar *password =
-					purple_prefs_get_string("/purple/network/turn_password");
-				GstStructure *turn_setup = gst_structure_new("relay-info",
-					"ip", G_TYPE_STRING, turn_ip, 
-					"port", G_TYPE_UINT, turn_port,
-					"username", G_TYPE_STRING, username,
-					"password", G_TYPE_STRING, password,
-					NULL);
 
-				if (turn_setup) {
-					memset(&value, 0, sizeof(GValue));
-					g_value_init(&value, GST_TYPE_STRUCTURE);
-					gst_value_set_structure(&value, turn_setup);
-					relay_info = g_value_array_append(relay_info, &value);
-					gst_structure_free(turn_setup);
-
-					purple_debug_info("media",
-						"setting property relay-info on new stream\n");
-					param[next_param_index].name = "relay-info";
-					g_value_init(&param[next_param_index].value, 
-						G_TYPE_VALUE_ARRAY);
-					g_value_set_boxed(&param[next_param_index].value,
-						relay_info);
-					g_value_array_free(relay_info);
-				} else {
-					purple_debug_error("media", "Error relay info");
-					purple_media_remove_session(media, session);
-					g_free(session);
-					return FALSE;
-				}
-			}
-
-			fsstream = fs_session_new_stream(session->session,
-					participant, type_direction &
-					FS_DIRECTION_RECV, transmitter,
-					new_num_params, param, &err);
-			g_free(param);
-		} else {
-			fsstream = fs_session_new_stream(session->session,
-					participant, type_direction &
-					FS_DIRECTION_RECV, transmitter,
-					num_params, params, &err);
-		}
-
-		if (fsstream == NULL) {
-			purple_debug_error("media",
-					"Error creating stream: %s\n",
-					err && err->message ?
-					err->message : "NULL");
-			if (err)
-				g_error_free(err);
-			purple_media_remove_session(media, session);
-			g_free(session);
-			return FALSE;
-		}
+		fsstream = purple_media_backend_fs2_get_stream(
+				PURPLE_MEDIA_BACKEND_FS2(
+				media->priv->backend), sess_id, who);
 
 		stream = purple_media_insert_stream(session, who, fsstream);
 		stream->initiator = initiator;