# HG changeset patch
# Node ID eaae49b47375
# Parent  a9f32316d828
diff --git a/ChangeLog.API b/ChangeLog.API
--- a/ChangeLog.API
+++ b/ChangeLog.API
@@ -181,6 +181,12 @@ version 3.0.0 (??/??/????):
 		* PurpleLog, purple_log_new, purple_log_write and
 		  PurpleLogLogger->write take a GDateTime instead of a time_t
 		  and struct tm
+		* purple_media_add_stream and purple_media_backend_add_stream
+		  (and its interface vfunc) and take a hash table of
+		  string->GValue parameters instead of an array of GParameter
+		* purple_media_set_params and purple_media_backend_set_params
+		  (and its interface vfunc) take a hash table of
+		  string->GValue parameters instead of an array of GParameter
 		* PurpleNotifyMsgType renamed to PurpleNotifyMessageType
 		* purple_notify_user_info_add_pair renamed to
 		  purple_notify_user_info_add_pair_html
diff --git a/libpurple/media.h b/libpurple/media.h
--- a/libpurple/media.h
+++ b/libpurple/media.h
@@ -175,8 +175,8 @@ void purple_media_stream_info(PurpleMedi
 /**
  * purple_media_set_params:
  * @media: The media object to set the parameters on.
- * @num_params: The number of parameters to pass
- * @params: Array of @c GParameter to pass
+ * @params: (element-type utf8 GObject.Value) (transfer none): Hash table of
+ *          parameters to pass.
  *
  * Sets various optional parameters of the media call.
  *
@@ -189,10 +189,7 @@ void purple_media_stream_info(PurpleMedi
  *   - "sdes-note"     : The NOTE to put in SDES messages
  *   - "sdes-phone"    : The PHONE to put in SDES messages
  */
-G_GNUC_BEGIN_IGNORE_DEPRECATIONS
-void purple_media_set_params(PurpleMedia *media,
-		guint num_params, GParameter *params);
-G_GNUC_END_IGNORE_DEPRECATIONS
+void purple_media_set_params(PurpleMedia *media, GHashTable *params);
 
 /**
  * purple_media_get_available_params:
@@ -226,8 +223,8 @@ gboolean purple_media_param_is_supported
  * @type: The type of stream to create.
  * @initiator: Whether or not the local user initiated the stream.
  * @transmitter: The transmitter to use for the stream.
- * @num_params: The number of parameters to pass to Farstream.
- * @params: The parameters to pass to Farstream.
+ * @params: (element-type utf8 GObject.Value) (transfer none): The stream
+ *          parameters to pass to Farstream.
  *
  * Adds a stream to a session.
  *
@@ -236,12 +233,9 @@ gboolean purple_media_param_is_supported
  *
  * Returns: %TRUE The stream was added successfully, %FALSE otherwise.
  */
-G_GNUC_BEGIN_IGNORE_DEPRECATIONS
 gboolean purple_media_add_stream(PurpleMedia *media, const gchar *sess_id,
-		const gchar *who, PurpleMediaSessionType type,
-		gboolean initiator, const gchar *transmitter,
-		guint num_params, GParameter *params);
-G_GNUC_END_IGNORE_DEPRECATIONS
+		const gchar *who, PurpleMediaSessionType type, gboolean initiator,
+		const gchar *transmitter, GHashTable *params);
 
 /**
  * purple_media_get_session_type:
diff --git a/libpurple/media.c b/libpurple/media.c
--- a/libpurple/media.c
+++ b/libpurple/media.c
@@ -852,13 +852,12 @@ purple_media_stream_info(PurpleMedia *me
 }
 
 void
-purple_media_set_params(PurpleMedia *media,
-		guint num_params, GParameter *params)
+purple_media_set_params(PurpleMedia *media, GHashTable *params)
 {
 #ifdef USE_VV
 	g_return_if_fail(PURPLE_IS_MEDIA(media));
 
-	purple_media_backend_set_params(media->priv->backend, num_params, params);
+	purple_media_backend_set_params(media->priv->backend, params);
 #endif
 }
 
@@ -990,9 +989,8 @@ purple_media_codecs_changed_cb(PurpleMed
 
 gboolean
 purple_media_add_stream(PurpleMedia *media, const gchar *sess_id,
-		const gchar *who, PurpleMediaSessionType type,
-		gboolean initiator, const gchar *transmitter,
-		guint num_params, GParameter *params)
+		const gchar *who, PurpleMediaSessionType type, gboolean initiator,
+		const gchar *transmitter, GHashTable *params)
 {
 #ifdef USE_VV
 	PurpleMediaSession *session;
@@ -1000,8 +998,8 @@ purple_media_add_stream(PurpleMedia *med
 	g_return_val_if_fail(PURPLE_IS_MEDIA(media), FALSE);
 
 	if (!purple_media_backend_add_stream(media->priv->backend,
-			sess_id, who, type, initiator, transmitter,
-			num_params, params)) {
+			sess_id, who, type, initiator, transmitter, params))
+	{
 		purple_debug_error("media", "Error adding stream.\n");
 		return FALSE;
 	}
diff --git a/libpurple/media/backend-fs2.c b/libpurple/media/backend-fs2.c
--- a/libpurple/media/backend-fs2.c
+++ b/libpurple/media/backend-fs2.c
@@ -32,7 +32,10 @@
 #include "media-gst.h"
 #include <purplekeyvaluepair.h>
 
+/* Ignore deprecations of GParameter in FarStream's headers. */
+G_GNUC_BEGIN_IGNORE_DEPRECATIONS
 #include <farstream/fs-conference.h>
+G_GNUC_END_IGNORE_DEPRECATIONS
 #include <farstream/fs-element-added-notifier.h>
 #include <farstream/fs-utils.h>
 #include <gst/gststructure.h>
@@ -57,8 +60,7 @@ stream_info_cb(PurpleMedia *media, Purpl
 static gboolean purple_media_backend_fs2_add_stream(PurpleMediaBackend *self,
 		const gchar *sess_id, const gchar *who,
 		PurpleMediaSessionType type, gboolean initiator,
-		const gchar *transmitter,
-		guint num_params, GParameter *params);
+		const gchar *transmitter, GHashTable *params);
 static void purple_media_backend_fs2_add_remote_candidates(
 		PurpleMediaBackend *self,
 		const gchar *sess_id, const gchar *participant,
@@ -88,7 +90,7 @@ static gboolean purple_media_backend_fs2
 		PurpleMediaBackend *self, const gchar *sess_id,
 		PurpleMediaCodec *codec);
 static void purple_media_backend_fs2_set_params(PurpleMediaBackend *self,
-		guint num_params, GParameter *params);
+		GHashTable *params);
 static const gchar **purple_media_backend_fs2_get_available_params(void);
 static gboolean purple_media_backend_fs2_send_dtmf(
 		PurpleMediaBackend *self, const gchar *sess_id,
@@ -1859,7 +1861,7 @@ create_stream(PurpleMediaBackendFs2 *sel
 		const gchar *sess_id, const gchar *who,
 		PurpleMediaSessionType type, gboolean initiator,
 		const gchar *transmitter,
-		guint num_params, GParameter *params)
+		GHashTable *params)
 {
 	PurpleMediaBackendFs2Private *priv =
 			purple_media_backend_fs2_get_instance_private(self);
@@ -1867,8 +1869,11 @@ create_stream(PurpleMediaBackendFs2 *sel
 	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;
+	GHashTableIter iter;
+	GHashTable *our_params = NULL;
+	gchar *key = NULL;
+	GValue *value = NULL;
+	GList *our_values = NULL;
 	FsStreamDirection type_direction =
 			session_type_to_fs_stream_direction(type);
 	PurpleMediaBackendFs2Session *session;
@@ -1878,7 +1883,6 @@ create_stream(PurpleMediaBackendFs2 *sel
 	  we need to do this to allow them to override when using non-standard
 	  TURN modes, like Google f.ex. */
 	gboolean got_turn_from_protocol = FALSE;
-	guint i;
 	GPtrArray *relay_info = g_ptr_array_new_full (1, (GDestroyNotify) gst_structure_free);
 	gboolean ret;
 
@@ -1913,30 +1917,33 @@ create_stream(PurpleMediaBackendFs2 *sel
 		return FALSE;
 	}
 
-	for (i = 0 ; i < num_params ; i++) {
-		if (purple_strequal(params[i].name, "relay-info")) {
-			got_turn_from_protocol = TRUE;
-			break;
+	our_params = g_hash_table_new(g_str_hash, g_str_equal);
+	if (params != NULL) {
+		g_hash_table_iter_init(&iter, params);
+		while (g_hash_table_iter_next(&iter, (gpointer)&key, (gpointer)&value)) {
+			if (purple_strequal(key, "relay-info")) {
+				got_turn_from_protocol = TRUE;
+			}
+			g_hash_table_insert(our_params, key, value);
 		}
 	}
 
-	_params = g_new0(GParameter, num_params + 3);
-	memcpy(_params, params, sizeof(GParameter) * num_params);
-
 	/* set the controlling mode parameter */
-	_params[_num_params].name = "controlling-mode";
-	g_value_init(&_params[_num_params].value, G_TYPE_BOOLEAN);
-	g_value_set_boolean(&_params[_num_params].value, initiator);
-	++_num_params;
+	value = g_new(GValue, 1);
+	g_value_init(value, G_TYPE_BOOLEAN);
+	g_value_set_boolean(value, initiator);
+	our_values = g_list_prepend(our_values, value);
+	g_hash_table_insert(our_params, "controlling-mode", value);
 
 	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;
+		value = g_new(GValue, 1);
+		g_value_init(value, G_TYPE_STRING);
+		g_value_set_string(value, stun_ip);
+		our_values = g_list_prepend(our_values, value);
+		g_hash_table_insert(our_params, "stun-ip", value);
 	}
 
 	if (turn_ip && purple_strequal("nice", transmitter) && !got_turn_from_protocol) {
@@ -1977,17 +1984,22 @@ create_stream(PurpleMediaBackendFs2 *sel
 
 		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_PTR_ARRAY);
-		g_value_set_boxed(&_params[_num_params].value, relay_info);
-		_num_params++;
+		value = g_new(GValue, 1);
+		g_value_init(value, G_TYPE_PTR_ARRAY);
+		g_value_set_boxed(value, relay_info);
+		our_values = g_list_prepend(our_values, value);
+		g_hash_table_insert(our_params, "relay-info", value);
 	}
 
-	ret = fs_stream_set_transmitter(fsstream, transmitter,
-			_params, _num_params, &err);
-	for (i = 0 ; i < _num_params ; i++)
-		g_value_unset (&_params[i].value);
-	g_free(_params);
+	ret = fs_stream_set_transmitter_ht(fsstream, transmitter, our_params, &err);
+
+	while (our_values != NULL) {
+		value = (GValue *)our_values->data;
+		g_value_unset(value);
+		g_free(value);
+		our_values = g_list_delete_link(our_values, our_values);
+	}
+	g_hash_table_destroy(our_params);
 	if (relay_info)
 		g_ptr_array_unref (relay_info);
 	if (ret == FALSE) {
@@ -2034,8 +2046,7 @@ static gboolean
 purple_media_backend_fs2_add_stream(PurpleMediaBackend *self,
 		const gchar *sess_id, const gchar *who,
 		PurpleMediaSessionType type, gboolean initiator,
-		const gchar *transmitter,
-		guint num_params, GParameter *params)
+		const gchar *transmitter, GHashTable *params)
 {
 	PurpleMediaBackendFs2 *backend = PURPLE_MEDIA_BACKEND_FS2(self);
 	PurpleMediaBackendFs2Private *priv =
@@ -2076,7 +2087,7 @@ purple_media_backend_fs2_add_stream(Purp
 					type_direction, NULL);
 		}
 	} else if (!create_stream(backend, sess_id, who, type,
-			initiator, transmitter, num_params, params)) {
+			initiator, transmitter, params)) {
 		purple_debug_error("backend-fs2",
 				"Error creating the stream.\n");
 		return FALSE;
@@ -2440,10 +2451,12 @@ param_to_sdes_type(const gchar *param)
 
 static void
 purple_media_backend_fs2_set_params(PurpleMediaBackend *self,
-		guint num_params, GParameter *params)
+		GHashTable *params)
 {
 	PurpleMediaBackendFs2Private *priv;
-	guint i;
+	GHashTableIter iter;
+	gchar *name = NULL;
+	GValue *value = NULL;
 	GstStructure *sdes;
 
 	g_return_if_fail(PURPLE_MEDIA_IS_BACKEND_FS2(self));
@@ -2460,13 +2473,15 @@ purple_media_backend_fs2_set_params(Purp
 
 	g_object_get(G_OBJECT(priv->conference), "sdes", &sdes, NULL);
 
-	for (i = 0; i != num_params; ++i) {
-		const gchar *sdes_type = param_to_sdes_type(params[i].name);
-		if (!sdes_type)
+	g_hash_table_iter_init(&iter, params);
+	while (g_hash_table_iter_next(&iter, (gpointer)&name, (gpointer)&value)) {
+		const gchar *sdes_type = param_to_sdes_type(name);
+		if (!sdes_type) {
 			continue;
+		}
 
 		gst_structure_set(sdes, sdes_type,
-		                  G_TYPE_STRING, g_value_get_string(&params[i].value),
+		                  G_TYPE_STRING, g_value_get_string(value),
 		                  NULL);
 	}
 
diff --git a/libpurple/media/backend-iface.h b/libpurple/media/backend-iface.h
--- a/libpurple/media/backend-iface.h
+++ b/libpurple/media/backend-iface.h
@@ -66,13 +66,10 @@ struct _PurpleMediaBackendInterface
 
 	/*< public >*/
 	/* Implementable functions called with purple_media_backend_* */
-	G_GNUC_BEGIN_IGNORE_DEPRECATIONS
 	gboolean (*add_stream) (PurpleMediaBackend *self,
 		const gchar *sess_id, const gchar *who,
 		PurpleMediaSessionType type, gboolean initiator,
-		const gchar *transmitter,
-		guint num_params, GParameter *params);
-	G_GNUC_END_IGNORE_DEPRECATIONS
+		const gchar *transmitter, GHashTable *params);
 
 	void (*add_remote_candidates) (PurpleMediaBackend *self,
 		const gchar *sess_id, const gchar *participant,
@@ -98,10 +95,7 @@ struct _PurpleMediaBackendInterface
 	gboolean (*set_require_encryption) (PurpleMediaBackend *self,
 		const gchar *sess_id, const gchar *participant,
 		gboolean require_encryption);
-	G_GNUC_BEGIN_IGNORE_DEPRECATIONS
-	void (*set_params) (PurpleMediaBackend *self,
-		guint num_params, GParameter *params);
-	G_GNUC_END_IGNORE_DEPRECATIONS
+	void (*set_params) (PurpleMediaBackend *self, GHashTable *params);
 	const gchar **(*get_available_params) (void);
 	gboolean (*send_dtmf) (PurpleMediaBackend *self,
 		const gchar *sess_id, gchar dtmf, guint8 volume,
@@ -127,20 +121,16 @@ GType purple_media_backend_get_type(void
  * @type: The media type and direction of the stream to add.
  * @initiator: True if the local user initiated the stream.
  * @transmitter: The string id of the tranmsitter to use.
- * @num_params: The number of parameters in the param parameter.
- * @params: The additional parameters to pass when creating the stream.
+ * @params: (element-type utf8 GValue) (transfer none): The additional
+ *          parameters to pass when creating the stream.
  *
  * Creates and adds a stream to the media backend.
  *
  * Returns: True if the stream was successfully created, otherwise False.
  */
-G_GNUC_BEGIN_IGNORE_DEPRECATIONS
 gboolean purple_media_backend_add_stream(PurpleMediaBackend *self,
-		const gchar *sess_id, const gchar *who,
-		PurpleMediaSessionType type, gboolean initiator,
-		const gchar *transmitter,
-		guint num_params, GParameter *params);
-G_GNUC_END_IGNORE_DEPRECATIONS
+		const gchar *sess_id, const gchar *who, PurpleMediaSessionType type,
+		gboolean initiator, const gchar *transmitter, GHashTable *params);
 
 /**
  * purple_media_backend_add_remote_candidates:
@@ -277,15 +267,13 @@ gboolean purple_media_backend_set_requir
 /**
  * purple_media_backend_set_params:
  * @self: The media backend to set the parameters on.
- * @num_params: The number of parameters to pass to backend
- * @params: Array of @c GParameter to pass to backend
+ * @params: (element-type utf8 GObject.Value) (transfer none): Hash table of
+ *          parameters to pass to the backend.
  *
  * Sets various optional parameters of the media backend.
  */
-G_GNUC_BEGIN_IGNORE_DEPRECATIONS
 void purple_media_backend_set_params(PurpleMediaBackend *self,
-		guint num_params, GParameter *params);
-G_GNUC_END_IGNORE_DEPRECATIONS
+		GHashTable *params);
 
 /**
  * purple_media_backend_get_available_params:
diff --git a/libpurple/media/backend-iface.c b/libpurple/media/backend-iface.c
--- a/libpurple/media/backend-iface.c
+++ b/libpurple/media/backend-iface.c
@@ -122,15 +122,12 @@ purple_media_backend_get_type(void)
 
 gboolean
 purple_media_backend_add_stream(PurpleMediaBackend *self,
-		const gchar *sess_id, const gchar *who,
-		PurpleMediaSessionType type, gboolean initiator,
-		const gchar *transmitter,
-		guint num_params, GParameter *params)
+		const gchar *sess_id, const gchar *who, PurpleMediaSessionType type,
+		gboolean initiator, const gchar *transmitter, GHashTable *params)
 {
 	g_return_val_if_fail(PURPLE_MEDIA_IS_BACKEND(self), FALSE);
 	return PURPLE_MEDIA_BACKEND_GET_INTERFACE(self)->add_stream(self,
-			sess_id, who, type, initiator, transmitter,
-			num_params, params);
+			sess_id, who, type, initiator, transmitter, params);
 }
 
 void
@@ -238,11 +235,10 @@ purple_media_backend_set_require_encrypt
 }
 
 void
-purple_media_backend_set_params(PurpleMediaBackend *self,
-		guint num_params, GParameter *params)
+purple_media_backend_set_params(PurpleMediaBackend *self, GHashTable *params)
 {
 	g_return_if_fail(PURPLE_MEDIA_IS_BACKEND(self));
-	PURPLE_MEDIA_BACKEND_GET_INTERFACE(self)->set_params(self, num_params, params);
+	PURPLE_MEDIA_BACKEND_GET_INTERFACE(self)->set_params(self, params);
 }
 
 const gchar **
diff --git a/libpurple/protocols/jabber/jingle/jingle.h b/libpurple/protocols/jabber/jingle/jingle.h
--- a/libpurple/protocols/jabber/jingle/jingle.h
+++ b/libpurple/protocols/jabber/jingle/jingle.h
@@ -75,12 +75,10 @@ void jingle_parse(JabberStream *js, cons
 void jingle_terminate_sessions(JabberStream *js);
 
 #ifdef USE_VV
-/* create a GParam array given autoconfigured STUN (and later perhaps TURN). */
-G_GNUC_BEGIN_IGNORE_DEPRECATIONS
-GParameter *jingle_get_params(JabberStream *js, const gchar *relay_ip,
+/* create a parameter array given autoconfigured STUN (and later perhaps TURN). */
+GHashTable *jingle_get_params(JabberStream *js, const gchar *relay_ip,
 	guint relay_udp, guint relay_tcp, guint relay_ssltcp,
-    const gchar *relay_username, const gchar *relay_password, guint *num_params);
-G_GNUC_END_IGNORE_DEPRECATIONS
+	const gchar *relay_username, const gchar *relay_password);
 #endif
 
 G_END_DECLS
diff --git a/libpurple/protocols/jabber/jingle/jingle.c b/libpurple/protocols/jabber/jingle/jingle.c
--- a/libpurple/protocols/jabber/jingle/jingle.c
+++ b/libpurple/protocols/jabber/jingle/jingle.c
@@ -458,37 +458,43 @@ G_GNUC_END_IGNORE_DEPRECATIONS
 	return relay_info;
 }
 
-GParameter *
+static void
+jingle_param_free(GValue *value)
+{
+	g_value_unset(value);
+	g_free(value);
+}
+
+GHashTable *
 jingle_get_params(JabberStream *js, const gchar *relay_ip, guint relay_udp,
 	guint relay_tcp, guint relay_ssltcp, const gchar *relay_username,
-    const gchar *relay_password, guint *num)
+	const gchar *relay_password)
 {
 	/* don't set a STUN server if one is set globally in prefs, in that case
 	 this will be handled in media.c */
 	gboolean has_account_stun = js->stun_ip && !purple_network_get_stun_ip();
-	guint num_params = has_account_stun ?
-		(relay_ip ? 3 : 2) : (relay_ip ? 1 : 0);
-	GParameter *params = NULL;
-	int next_index = 0;
+	GHashTable *params = NULL;
+	GValue *value = NULL;
 
-	if (num_params > 0) {
-		params = g_new0(GParameter, num_params);
+	if (has_account_stun || relay_ip) {
+		params = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, (GDestroyNotify)jingle_param_free);
 
 		if (has_account_stun) {
 			purple_debug_info("jabber",
 				"setting param stun-ip for stream using auto-config: %s\n",
 				js->stun_ip);
-			params[next_index].name = "stun-ip";
-			g_value_init(&params[next_index].value, G_TYPE_STRING);
-			g_value_set_string(&params[next_index].value, js->stun_ip);
+			value = g_new(GValue, 1);
+			g_value_init(value, G_TYPE_STRING);
+			g_value_set_string(value, js->stun_ip);
+			g_hash_table_insert(params, "stun-ip", value);
+
 			purple_debug_info("jabber",
 				"setting param stun-port for stream using auto-config: %d\n",
 				js->stun_port);
-			next_index++;
-			params[next_index].name = "stun-port";
-			g_value_init(&params[next_index].value, G_TYPE_UINT);
-			g_value_set_uint(&params[next_index].value, js->stun_port);
-			next_index++;
+			value = g_new(GValue, 1);
+			g_value_init(value, G_TYPE_UINT);
+			g_value_set_uint(value, js->stun_port);
+			g_hash_table_insert(params, "stun-port", value);
 		}
 
 		if (relay_ip) {
@@ -511,16 +517,16 @@ G_GNUC_END_IGNORE_DEPRECATIONS
 					jingle_create_relay_info(relay_ip, relay_ssltcp, relay_username,
 						relay_password, "tls", relay_info);
 			}
-			params[next_index].name = "relay-info";
+			value = g_new(GValue, 1);
 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
-			g_value_init(&params[next_index].value, G_TYPE_VALUE_ARRAY);
-			g_value_set_boxed(&params[next_index].value, relay_info);
+			g_value_init(value, G_TYPE_VALUE_ARRAY);
+			g_value_set_boxed(value, relay_info);
 			g_value_array_free(relay_info);
 G_GNUC_END_IGNORE_DEPRECATIONS
+			g_hash_table_insert(params, "relay-info", value);
 		}
 	}
 
-	*num = num_params;
 	return params;
 }
 #endif
diff --git a/libpurple/protocols/jabber/jingle/rtp.c b/libpurple/protocols/jabber/jingle/rtp.c
--- a/libpurple/protocols/jabber/jingle/rtp.c
+++ b/libpurple/protocols/jabber/jingle/rtp.c
@@ -315,8 +315,7 @@ jingle_rtp_init_media(JingleContent *con
 	gboolean is_creator;
 	PurpleMediaSessionType type;
 	JingleTransport *transport;
-	GParameter *params = NULL;
-	guint num_params;
+	GHashTable *params = NULL;
 
 	/* maybe this create ought to just be in initiate and handle initiate */
 	if (media == NULL) {
@@ -360,7 +359,7 @@ jingle_rtp_init_media(JingleContent *con
 
 	params =
 		jingle_get_params(jingle_session_get_js(session), NULL, 0, 0, 0,
-			NULL, NULL, &num_params);
+			NULL, NULL);
 
 	creator = jingle_content_get_creator(content);
 	if (creator == NULL) {
@@ -368,7 +367,7 @@ jingle_rtp_init_media(JingleContent *con
 		g_free(media_type);
 		g_free(remote_jid);
 		g_free(senders);
-		g_free(params);
+		g_hash_table_destroy(params);
 		g_object_unref(session);
 		return FALSE;
 	}
@@ -380,7 +379,7 @@ jingle_rtp_init_media(JingleContent *con
 	g_free(creator);
 
 	if(!purple_media_add_stream(media, name, remote_jid,
-			type, is_creator, transmitter, num_params, params)) {
+			type, is_creator, transmitter, params)) {
 		purple_media_end(media, NULL, NULL);
 		/* TODO: How much clean-up is necessary here? (does calling
 		         purple_media_end lead to cleaning up Jingle structs?) */
@@ -391,7 +390,7 @@ jingle_rtp_init_media(JingleContent *con
 	g_free(media_type);
 	g_free(remote_jid);
 	g_free(senders);
-	g_free(params);
+	g_hash_table_destroy(params);
 	g_object_unref(session);
 
 	return TRUE;
