changeset 26106:ac4d7695dbc7

Wrap FsCodec and remove the Farsight2 include from media.h.
author Mike Ruprecht <maiku@soc.pidgin.im>
date Mon, 12 Jan 2009 01:09:20 +0000
parents ce904eb43e22
children 4859b0b82289
files libpurple/media.c libpurple/media.h libpurple/protocols/jabber/google.c libpurple/protocols/jabber/jingle/rtp.c
diffstat 4 files changed, 358 insertions(+), 27 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/media.c	Sun Jan 11 22:53:08 2009 +0000
+++ b/libpurple/media.c	Mon Jan 12 01:09:20 2009 +0000
@@ -622,6 +622,232 @@
 	return result;
 }
 
+void
+purple_media_codec_add_optional_parameter(PurpleMediaCodec *codec,
+		const gchar *name, const gchar *value)
+{
+	PurpleMediaCodecParameter *new_param;
+
+	g_return_if_fail(name != NULL && value != NULL);
+
+	new_param = g_new0(PurpleMediaCodecParameter, 1);
+	new_param->name = g_strdup(name);
+	new_param->value = g_strdup(value);
+	codec->optional_params = g_list_append(
+			codec->optional_params, new_param);
+}
+
+void
+purple_media_codec_remove_optional_parameter(PurpleMediaCodec *codec,
+		PurpleMediaCodecParameter *param)
+{
+	g_free(param->name);
+	g_free(param->value);
+	g_free(param);
+	codec->optional_params =
+			g_list_remove(codec->optional_params, param);
+}
+
+PurpleMediaCodecParameter *
+purple_media_codec_get_optional_parameter(PurpleMediaCodec *codec,
+		const gchar *name, const gchar *value)
+{
+	GList *iter;
+
+	g_return_val_if_fail(codec != NULL, NULL);
+	g_return_val_if_fail(name != NULL, NULL);
+
+	for (iter = codec->optional_params; iter; iter = g_list_next(iter)) {
+		PurpleMediaCodecParameter *param = iter->data;
+		if (!g_ascii_strcasecmp(param->name, name) &&
+				(value == NULL ||
+				!g_ascii_strcasecmp(param->value, value)))
+			return param;
+	}
+
+	return NULL;
+}
+
+PurpleMediaCodec *
+purple_media_codec_new(int id, const char *encoding_name,
+		PurpleMediaSessionType media_type, guint clock_rate)
+{
+	PurpleMediaCodec *codec = g_new0(PurpleMediaCodec, 1);
+
+	codec->id = id;
+	codec->encoding_name = g_strdup(encoding_name);
+	codec->media_type = media_type;
+	codec->clock_rate = clock_rate;
+	return codec;
+}
+
+static PurpleMediaCodec *
+purple_media_codec_copy(PurpleMediaCodec *codec)
+{
+	PurpleMediaCodec *new_codec;
+	GList *iter;
+
+	if (codec == NULL)
+		return NULL;
+
+	new_codec = purple_media_codec_new(codec->id, codec->encoding_name,
+			codec->media_type, codec->clock_rate);
+	new_codec->channels = codec->channels;
+
+	for (iter = codec->optional_params; iter; iter = g_list_next(iter)) {
+		PurpleMediaCodecParameter *param =
+				(PurpleMediaCodecParameter*)iter;
+		purple_media_codec_add_optional_parameter(new_codec,
+				param->name, param->value);
+	}
+
+	return new_codec;
+}
+
+static void
+purple_media_codec_free(PurpleMediaCodec *codec)
+{
+	if (codec == NULL)
+		return;
+
+	g_free(codec->encoding_name);
+
+	for (; codec->optional_params; codec->optional_params =
+			g_list_delete_link(codec->optional_params,
+			codec->optional_params)) {
+		purple_media_codec_remove_optional_parameter(codec,
+				codec->optional_params->data);
+	}
+
+	g_free(codec);
+}
+
+static FsCodec *
+purple_media_codec_to_fs(const PurpleMediaCodec *codec)
+{
+	FsCodec *new_codec;
+	GList *iter;
+
+	if (codec == NULL)
+		return NULL;
+
+	new_codec = fs_codec_new(codec->id, codec->encoding_name,
+			purple_media_to_fs_media_type(codec->media_type),
+			codec->clock_rate);
+	new_codec->channels = codec->channels;
+
+	for (iter = codec->optional_params; iter; iter = g_list_next(iter)) {
+		PurpleMediaCodecParameter *param =
+				(PurpleMediaCodecParameter*)iter;
+		fs_codec_add_optional_parameter(new_codec,
+				param->name, param->value);
+	}
+
+	return new_codec;
+}
+
+static PurpleMediaCodec *
+purple_media_codec_from_fs(const FsCodec *codec)
+{
+	PurpleMediaCodec *new_codec;
+	GList *iter;
+
+	if (codec == NULL)
+		return NULL;
+
+	new_codec = purple_media_codec_new(codec->id, codec->encoding_name,
+			purple_media_from_fs(codec->media_type,
+			FS_DIRECTION_BOTH), codec->clock_rate);
+	new_codec->channels = codec->channels;
+
+	for (iter = codec->optional_params; iter; iter = g_list_next(iter)) {
+		FsCodecParameter *param = (FsCodecParameter*)iter;
+		purple_media_codec_add_optional_parameter(new_codec,
+				param->name, param->value);
+	}
+
+	return new_codec;
+}
+
+gchar *
+purple_media_codec_to_string(const PurpleMediaCodec *codec)
+{
+	FsCodec *fscodec = purple_media_codec_to_fs(codec);
+	gchar *str = fs_codec_to_string(fscodec);
+	fs_codec_destroy(fscodec);
+	return str;
+}
+
+static GList *
+purple_media_codec_list_from_fs(GList *codecs)
+{
+	GList *new_list = NULL;
+
+	for (; codecs; codecs = g_list_next(codecs)) {
+		new_list = g_list_prepend(new_list,
+				purple_media_codec_from_fs(
+				codecs->data));
+	}
+
+	new_list = g_list_reverse(new_list);
+	return new_list;
+}
+
+static GList *
+purple_media_codec_list_to_fs(GList *codecs)
+{
+	GList *new_list = NULL;
+
+	for (; codecs; codecs = g_list_next(codecs)) {
+		new_list = g_list_prepend(new_list,
+				purple_media_codec_to_fs(
+				codecs->data));
+	}
+
+	new_list = g_list_reverse(new_list);
+	return new_list;
+}
+
+GList *
+purple_media_codec_list_copy(GList *codecs)
+{
+	GList *new_list = NULL;
+
+	for (; codecs; codecs = g_list_next(codecs)) {
+		new_list = g_list_prepend(new_list, g_boxed_copy(
+				PURPLE_TYPE_MEDIA_CODEC,
+				codecs->data));
+	}
+
+	new_list = g_list_reverse(new_list);
+	return new_list;
+}
+
+void
+purple_media_codec_list_free(GList *codecs)
+{
+	for (; codecs; codecs =
+			g_list_delete_link(codecs, codecs)) {
+		g_boxed_free(PURPLE_TYPE_MEDIA_CODEC,
+				codecs->data);
+	}
+}
+
+GType
+purple_media_codec_get_type()
+{
+	static GType type = 0;
+
+	if (type == 0) {
+		type = g_boxed_type_register_static("PurpleMediaCodec",
+				(GBoxedCopyFunc)purple_media_codec_copy,
+				(GBoxedFreeFunc)purple_media_codec_free);
+	}
+	return type;
+}
+
+
+
 PurpleMediaSessionType
 purple_media_get_overall_type(PurpleMedia *media)
 {
@@ -1642,9 +1868,12 @@
 GList *
 purple_media_get_codecs(PurpleMedia *media, const gchar *sess_id)
 {
+	GList *fscodecs;
 	GList *codecs;
 	g_object_get(G_OBJECT(purple_media_get_session(media, sess_id)->session),
-		     "codecs", &codecs, NULL);
+		     "codecs", &fscodecs, NULL);
+	codecs = purple_media_codec_list_from_fs(fscodecs);
+	fs_codec_list_destroy(fscodecs);
 	return codecs;
 }
 
@@ -1686,9 +1915,11 @@
 purple_media_set_remote_codecs(PurpleMedia *media, const gchar *sess_id, const gchar *name, GList *codecs)
 {
 	FsStream *stream = purple_media_get_stream(media, sess_id, name)->stream;
+	GList *fscodecs = purple_media_codec_list_to_fs(codecs);
 	GError *err = NULL;
 
-	fs_stream_set_remote_codecs(stream, codecs, &err);
+	fs_stream_set_remote_codecs(stream, fscodecs, &err);
+	fs_codec_list_destroy(fscodecs);
 
 	if (err) {
 		purple_debug_error("media", "Error setting remote codecs: %s\n",
@@ -1715,12 +1946,14 @@
 }
 
 gboolean
-purple_media_set_send_codec(PurpleMedia *media, const gchar *sess_id, FsCodec *codec)
+purple_media_set_send_codec(PurpleMedia *media, const gchar *sess_id, PurpleMediaCodec *codec)
 {
 	PurpleMediaSession *session = purple_media_get_session(media, sess_id);
+	FsCodec *fscodec = purple_media_codec_to_fs(codec);
 	GError *err = NULL;
 
-	fs_session_set_send_codec(session->session, codec, &err);
+	fs_session_set_send_codec(session->session, fscodec, &err);
+	fs_codec_destroy(fscodec);
 
 	if (err) {
 		purple_debug_error("media", "Error setting send codec\n");
--- a/libpurple/media.h	Sun Jan 11 22:53:08 2009 +0000
+++ b/libpurple/media.h	Mon Jan 12 01:09:20 2009 +0000
@@ -30,7 +30,6 @@
 #ifdef USE_VV
 
 #include <gst/gst.h>
-#include <gst/farsight/fs-stream.h>
 #include <glib.h>
 #include <glib-object.h>
 
@@ -38,6 +37,7 @@
 
 #define PURPLE_TYPE_MEDIA            (purple_media_get_type())
 #define PURPLE_TYPE_MEDIA_CANDIDATE  (purple_media_candidate_get_type())
+#define PURPLE_TYPE_MEDIA_CODEC      (purple_media_codec_get_type())
 #define PURPLE_MEDIA(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), PURPLE_TYPE_MEDIA, PurpleMedia))
 #define PURPLE_MEDIA_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), PURPLE_TYPE_MEDIA, PurpleMediaClass))
 #define PURPLE_IS_MEDIA(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), PURPLE_TYPE_MEDIA))
@@ -54,6 +54,10 @@
 typedef struct _PurpleMediaPrivate PurpleMediaPrivate;
 /** @copydoc _PurpleMediaCandidate */
 typedef struct _PurpleMediaCandidate PurpleMediaCandidate;
+/** @copydoc _PurpleMediaCodec */
+typedef struct _PurpleMediaCodec PurpleMediaCodec;
+/** @copydoc _PurpleMediaCodecParameter */
+typedef struct _PurpleMediaCodecParameter PurpleMediaCodecParameter;
 
 #else
 
@@ -129,6 +133,22 @@
 	guint ttl;
 };
 
+struct _PurpleMediaCodecParameter
+{
+	gchar *name;
+	gchar *value;
+};
+
+struct _PurpleMediaCodec
+{
+	gint id;
+	char *encoding_name;
+	PurpleMediaSessionType media_type;
+	guint clock_rate;
+	guint channels;
+	GList *optional_params;
+};
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -189,6 +209,83 @@
 void purple_media_candidate_list_free(GList *candidates);
 
 /**
+ * Gets the type of the media codec structure.
+ *
+ * @return The media codec's GType
+ */
+GType purple_media_codec_get_type(void);
+
+/**
+ * Creates a new PurpleMediaCodec instance.
+ *
+ * @param id Codec identifier.
+ * @param encoding_name Name of the media type this encodes.
+ * @param media_type PurpleMediaSessionType of this codec.
+ * @param clock_rate The clock rate this codec encodes at, if applicable.
+ *
+ * @return The newly created PurpleMediaCodec.
+ */
+PurpleMediaCodec *purple_media_codec_new(int id, const char *encoding_name,
+		PurpleMediaSessionType media_type, guint clock_rate);
+
+/**
+ * Creates a string representation of the codec.
+ *
+ * @param codec The codec to create the string of.
+ *
+ * @return The new string representation.
+ */
+gchar *purple_media_codec_to_string(const PurpleMediaCodec *codec);
+
+/**
+ * Adds an optional parameter to the codec.
+ *
+ * @param codec The codec to add the parameter to.
+ * @param name The name of the parameter to add.
+ * @param value The value of the parameter to add.
+ */
+void purple_media_codec_add_optional_parameter(PurpleMediaCodec *codec,
+		const gchar *name, const gchar *value);
+
+/**
+ * Removes an optional parameter from the codec.
+ *
+ * @param codec The codec to remove the parameter from.
+ * @param param A pointer to the parameter to remove.
+ */
+void purple_media_codec_remove_optional_parameter(PurpleMediaCodec *codec,
+		PurpleMediaCodecParameter *param);
+
+/**
+ * Gets an optional parameter based on the values given.
+ *
+ * @param codec The codec to find the parameter in.
+ * @param name The name of the parameter to search for.
+ * @param value The value to search for or NULL.
+ *
+ * @return The value found or NULL.
+ */
+PurpleMediaCodecParameter *purple_media_codec_get_optional_parameter(
+		PurpleMediaCodec *codec, const gchar *name,
+		const gchar *value);
+
+/**
+ * Copies a GList of PurpleMediaCodec and its contents.
+ *
+ * @param codecs The list of codecs to be copied.
+ *
+ * @return The copy of the GList.
+ */
+GList *purple_media_codec_list_copy(GList *codecs);
+
+/**
+ * Frees a GList of PurpleMediaCodec and its contents.
+ *
+ * @param codecs The list of codecs to be freed.
+ */
+void purple_media_codec_list_free(GList *codecs);
+
+/**
  * Combines all the separate session types into a single PurpleMediaSessionType.
  *
  * @param media The media session to retrieve session types from.
@@ -513,7 +610,7 @@
  *
  * @return @c TRUE The codec was successfully changed, or @c FALSE otherwise.
  */
-gboolean purple_media_set_send_codec(PurpleMedia *media, const gchar *sess_id, FsCodec *codec);
+gboolean purple_media_set_send_codec(PurpleMedia *media, const gchar *sess_id, PurpleMediaCodec *codec);
 
 /**
  * Gets whether a session's codecs are ready to be used.
--- a/libpurple/protocols/jabber/google.c	Sun Jan 11 22:53:08 2009 +0000
+++ b/libpurple/protocols/jabber/google.c	Mon Jan 12 01:09:20 2009 +0000
@@ -111,7 +111,7 @@
 	xmlnode_set_namespace(desc, "http://www.google.com/session/phone");
 
 	for (;codecs; codecs = codecs->next) {
-		FsCodec *codec = (FsCodec*)codecs->data;
+		PurpleMediaCodec *codec = (PurpleMediaCodec*)codecs->data;
 		char id[8], clockrate[10];
 		payload = xmlnode_new_child(desc, "payload-type");
 		g_snprintf(id, sizeof(id), "%d", codec->id);
@@ -121,7 +121,7 @@
 		xmlnode_set_attrib(payload, "clockrate", clockrate);
 	}
 
-	fs_codec_list_destroy(codecs);
+	purple_media_codec_list_free(codecs);
 	jabber_iq_send(iq);
 }
 
@@ -234,7 +234,7 @@
 			codecs = purple_media_get_codecs(media, "google-voice");
 	
 			for (iter = codecs; iter; iter = g_list_next(iter)) {
-				FsCodec *codec = (FsCodec*)iter->data;
+				PurpleMediaCodec *codec = (PurpleMediaCodec*)iter->data;
 				gchar *id = g_strdup_printf("%d", codec->id);
 				gchar *clock_rate = g_strdup_printf("%d", codec->clock_rate);
 				payload = xmlnode_new_child(desc, "payload-type");
@@ -244,7 +244,7 @@
 				g_free(clock_rate);
 				g_free(id);
 			}
-			fs_codec_list_destroy(codecs);
+			purple_media_codec_list_free(codecs);
 
 			jabber_iq_send(iq);
 	
@@ -333,7 +333,7 @@
 	JabberIq *result;
 	GList *codecs = NULL;
 	xmlnode *desc_element, *codec_element;
-	FsCodec *codec;
+	PurpleMediaCodec *codec;
 	const char *id, *encoding_name,  *clock_rate;
 	GParameter param;
 		
@@ -368,7 +368,7 @@
 		id = xmlnode_get_attrib(codec_element, "id");
 		clock_rate = xmlnode_get_attrib(codec_element, "clockrate");
 
-		codec = fs_codec_new(atoi(id), encoding_name, FS_MEDIA_TYPE_AUDIO,
+		codec = purple_media_codec_new(atoi(id), encoding_name, PURPLE_MEDIA_AUDIO,
 				     clock_rate ? atoi(clock_rate) : 0);
 		codecs = g_list_append(codecs, codec);
 	}
@@ -385,7 +385,7 @@
 			 G_CALLBACK(google_session_candidates_prepared), session);
 	purple_media_ready(session->media);
 
-	fs_codec_list_destroy(codecs);
+	purple_media_codec_list_free(codecs);
 	
 	result = jabber_iq_new(js, JABBER_IQ_RESULT);
 	jabber_iq_set_id(result, xmlnode_get_attrib(packet, "id"));
@@ -449,9 +449,9 @@
 		const gchar *clock_rate =
 				xmlnode_get_attrib(codec_element, "clockrate");
 
-		FsCodec *codec = fs_codec_new(atoi(id), encoding_name,
-				FS_MEDIA_TYPE_AUDIO, clock_rate ?
-				atoi(clock_rate) : 0);
+		PurpleMediaCodec *codec = purple_media_codec_new(atoi(id),
+				encoding_name, PURPLE_MEDIA_AUDIO,
+				clock_rate ? atoi(clock_rate) : 0);
 		codecs = g_list_append(codecs, codec);
 	}
 
--- a/libpurple/protocols/jabber/jingle/rtp.c	Sun Jan 11 22:53:08 2009 +0000
+++ b/libpurple/protocols/jabber/jingle/rtp.c	Mon Jan 12 01:09:20 2009 +0000
@@ -434,10 +434,11 @@
 	GList *codecs = NULL;
 	xmlnode *codec_element = NULL;
 	const char *encoding_name,*id, *clock_rate;
-	FsCodec *codec;
+	PurpleMediaCodec *codec;
 	const gchar *media = xmlnode_get_attrib(description, "media");
-	FsMediaType type = !strcmp(media, "video") ? FS_MEDIA_TYPE_VIDEO :
-			!strcmp(media, "audio") ? FS_MEDIA_TYPE_AUDIO : 0;
+	PurpleMediaSessionType type =
+			!strcmp(media, "video") ? PURPLE_MEDIA_VIDEO :
+			!strcmp(media, "audio") ? PURPLE_MEDIA_AUDIO : 0;
 
 	for (codec_element = xmlnode_get_child(description, "payload-type") ;
 		 codec_element ;
@@ -449,18 +450,18 @@
 		id = xmlnode_get_attrib(codec_element, "id");
 		clock_rate = xmlnode_get_attrib(codec_element, "clockrate");
 
-		codec = fs_codec_new(atoi(id), encoding_name, 
+		codec = purple_media_codec_new(atoi(id), encoding_name, 
 				     type, 
 				     clock_rate ? atoi(clock_rate) : 0);
 
 		for (param = xmlnode_get_child(codec_element, "parameter");
 				param; param = xmlnode_get_next_twin(param)) {
-			fs_codec_add_optional_parameter(codec,
+			purple_media_codec_add_optional_parameter(codec,
 					xmlnode_get_attrib(param, "name"),
 					xmlnode_get_attrib(param, "value"));
 		}
 
-		codec_str = fs_codec_to_string(codec);
+		codec_str = purple_media_codec_to_string(codec);
 		purple_debug_info("jingle-rtp", "received codec: %s\n", codec_str);
 		g_free(codec_str);
 
@@ -484,7 +485,7 @@
 jingle_rtp_add_payloads(xmlnode *description, GList *codecs)
 {
 	for (; codecs ; codecs = codecs->next) {
-		FsCodec *codec = (FsCodec*)codecs->data;
+		PurpleMediaCodec *codec = (PurpleMediaCodec*)codecs->data;
 		GList *iter = codec->optional_params;
 		char id[8], clockrate[10], channels[10];
 		gchar *codec_str;
@@ -500,13 +501,13 @@
 		xmlnode_set_attrib(payload, "channels", channels);
 
 		for (; iter; iter = g_list_next(iter)) {
-			FsCodecParameter *fsparam = iter->data;
+			PurpleMediaCodecParameter *mparam = iter->data;
 			xmlnode *param = xmlnode_new_child(payload, "parameter");
-			xmlnode_set_attrib(param, "name", fsparam->name);
-			xmlnode_set_attrib(param, "value", fsparam->value);
+			xmlnode_set_attrib(param, "name", mparam->name);
+			xmlnode_set_attrib(param, "value", mparam->value);
 		}
 
-		codec_str = fs_codec_to_string(codec);
+		codec_str = purple_media_codec_to_string(codec);
 		purple_debug_info("jingle", "adding codec: %s\n", codec_str);
 		g_free(codec_str);
 	}