Mercurial > pidgin
changeset 29159:efeb21092ed2
Begin transferring FsSession over to the Farsight 2 media backend.
author | maiku@pidgin.im |
---|---|
date | Fri, 23 Oct 2009 21:40:38 +0000 |
parents | ae81f8baa148 |
children | 2460e6774e08 |
files | libpurple/media/backend-fs2.c libpurple/media/backend-fs2.h libpurple/media/media.c |
diffstat | 3 files changed, 245 insertions(+), 101 deletions(-) [+] |
line wrap: on
line diff
--- a/libpurple/media/backend-fs2.c Fri Oct 23 19:59:12 2009 +0000 +++ b/libpurple/media/backend-fs2.c Fri Oct 23 21:40:38 2009 +0000 @@ -33,11 +33,14 @@ #include "media-gst.h" #include <gst/farsight/fs-conference-iface.h> +#include <gst/farsight/fs-element-added-notifier.h> /** @copydoc _PurpleMediaBackendFs2Class */ typedef struct _PurpleMediaBackendFs2Class PurpleMediaBackendFs2Class; /** @copydoc _PurpleMediaBackendFs2Private */ typedef struct _PurpleMediaBackendFs2Private PurpleMediaBackendFs2Private; +/** @copydoc _PurpleMediaBackendFs2Session */ +typedef struct _PurpleMediaBackendFs2Session PurpleMediaBackendFs2Session; #define PURPLE_MEDIA_BACKEND_FS2_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ @@ -90,12 +93,23 @@ G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE( PURPLE_TYPE_MEDIA_BACKEND, purple_media_backend_iface_init)); +struct _PurpleMediaBackendFs2Session +{ + PurpleMediaBackendFs2 *backend; + gchar *id; + gboolean initiator; + FsSession *session; + PurpleMediaSessionType type; +}; + struct _PurpleMediaBackendFs2Private { PurpleMedia *media; GstElement *confbin; FsConference *conference; gchar *conference_type; + + GHashTable *sessions; }; enum { @@ -147,6 +161,21 @@ } + if (priv->sessions) { + GList *sessions = g_hash_table_get_values(priv->sessions); + + for (; sessions; sessions = + g_list_delete_link(sessions, sessions)) { + PurpleMediaBackendFs2Session *session = + sessions->data; + + if (session->session) { + g_object_unref(session->session); + session->session = NULL; + } + } + } + if (priv->media) { g_object_remove_weak_pointer(G_OBJECT(priv->media), (gpointer*)&priv->media); @@ -166,6 +195,20 @@ g_free(priv->conference_type); + if (priv->sessions) { + GList *sessions = g_hash_table_get_values(priv->sessions); + + for (; sessions; sessions = + g_list_delete_link(sessions, sessions)) { + PurpleMediaBackendFs2Session *session = + sessions->data; + g_free(session->id); + g_free(session); + } + + g_hash_table_destroy(priv->sessions); + } + G_OBJECT_CLASS(purple_media_backend_fs2_parent_class)->finalize(obj); } @@ -259,6 +302,69 @@ iface->set_send_codec = purple_media_backend_fs2_set_send_codec; } +static FsMediaType +_session_type_to_fs_media_type(PurpleMediaSessionType type) +{ + if (type & PURPLE_MEDIA_AUDIO) + return FS_MEDIA_TYPE_AUDIO; + else if (type & PURPLE_MEDIA_VIDEO) + return FS_MEDIA_TYPE_VIDEO; + else + return 0; +} + +#if 0 +static FsStreamDirection +_session_type_to_fs_stream_direction(PurpleMediaSessionType type) +{ + if ((type & PURPLE_MEDIA_AUDIO) == PURPLE_MEDIA_AUDIO || + (type & PURPLE_MEDIA_VIDEO) == PURPLE_MEDIA_VIDEO) + return FS_DIRECTION_BOTH; + else if ((type & PURPLE_MEDIA_SEND_AUDIO) || + (type & PURPLE_MEDIA_SEND_VIDEO)) + return FS_DIRECTION_SEND; + else if ((type & PURPLE_MEDIA_RECV_AUDIO) || + (type & PURPLE_MEDIA_RECV_VIDEO)) + return FS_DIRECTION_RECV; + else + return FS_DIRECTION_NONE; +} + +static PurpleMediaSessionType +_session_type_from_fs(FsMediaType type, FsStreamDirection direction) +{ + PurpleMediaSessionType result = PURPLE_MEDIA_NONE; + if (type == FS_MEDIA_TYPE_AUDIO) { + if (direction & FS_DIRECTION_SEND) + result |= PURPLE_MEDIA_SEND_AUDIO; + if (direction & FS_DIRECTION_RECV) + result |= PURPLE_MEDIA_RECV_AUDIO; + } else if (type == FS_MEDIA_TYPE_VIDEO) { + if (direction & FS_DIRECTION_SEND) + result |= PURPLE_MEDIA_SEND_VIDEO; + if (direction & FS_DIRECTION_RECV) + result |= PURPLE_MEDIA_RECV_VIDEO; + } + return result; +} +#endif + +static PurpleMediaBackendFs2Session * +_get_session(PurpleMediaBackendFs2 *self, const gchar *sess_id) +{ + PurpleMediaBackendFs2Private *priv; + PurpleMediaBackendFs2Session *session = NULL; + + g_return_val_if_fail(PURPLE_IS_MEDIA_BACKEND_FS2(self), NULL); + + priv = PURPLE_MEDIA_BACKEND_FS2_GET_PRIVATE(self); + + if (priv->sessions != NULL) + session = g_hash_table_lookup(priv->sessions, sess_id); + + return session; +} + static void _gst_handle_message_element(GstBus *bus, GstMessage *msg, PurpleMediaBackend *self) @@ -544,7 +650,7 @@ } static gboolean -_init_conference(PurpleMediaBackend *self) +_init_conference(PurpleMediaBackendFs2 *self) { PurpleMediaBackendFs2Private *priv = PURPLE_MEDIA_BACKEND_FS2_GET_PRIVATE(self); @@ -614,6 +720,120 @@ return TRUE; } +static void +_gst_element_added_cb(FsElementAddedNotifier *self, + GstBin *bin, GstElement *element, gpointer user_data) +{ + /* + * Hack to make H264 work with Gmail video. + */ + if (!strncmp(GST_ELEMENT_NAME(element), "x264", 4)) { + g_object_set(GST_OBJECT(element), "cabac", FALSE, NULL); + } +} + +static gboolean +_create_session(PurpleMediaBackendFs2 *self, const gchar *sess_id, + PurpleMediaSessionType type, gboolean initiator, + const gchar *transmitter) +{ + PurpleMediaBackendFs2Private *priv = + PURPLE_MEDIA_BACKEND_FS2_GET_PRIVATE(self); + PurpleMediaBackendFs2Session *session; + GError *err = NULL; + GList *codec_conf = NULL, *iter = NULL; + gchar *filename = NULL; + gboolean is_nice = !strcmp(transmitter, "nice"); + + session = g_new0(PurpleMediaBackendFs2Session, 1); + + session->session = fs_conference_new_session(priv->conference, + _session_type_to_fs_media_type(type), &err); + + if (err != NULL) { + purple_media_error(priv->media, + _("Error creating session: %s"), + err->message); + g_error_free(err); + g_free(session); + return FALSE; + } + + filename = g_build_filename(purple_user_dir(), "fs-codec.conf", NULL); + codec_conf = fs_codec_list_from_keyfile(filename, &err); + g_free(filename); + + if (err != NULL) { + if (err->code == 4) + purple_debug_info("media", "Couldn't read " + "fs-codec.conf: %s\n", + err->message); + else + purple_debug_error("media", "Error reading " + "fs-codec.conf: %s\n", + err->message); + g_error_free(err); + } + + /* + * Add SPEEX if the configuration file doesn't exist or + * there isn't a speex entry. + */ + for (iter = codec_conf; iter; iter = g_list_next(iter)) { + FsCodec *codec = iter->data; + if (!g_ascii_strcasecmp(codec->encoding_name, "speex")) + break; + } + + if (iter == NULL) { + codec_conf = g_list_prepend(codec_conf, + fs_codec_new(FS_CODEC_ID_ANY, + "SPEEX", FS_MEDIA_TYPE_AUDIO, 8000)); + codec_conf = g_list_prepend(codec_conf, + fs_codec_new(FS_CODEC_ID_ANY, + "SPEEX", FS_MEDIA_TYPE_AUDIO, 16000)); + } + + fs_session_set_codec_preferences(session->session, codec_conf, NULL); + fs_codec_list_destroy(codec_conf); + + /* + * Removes a 5-7 second delay before + * receiving the src-pad-added signal. + * Only works for non-multicast FsRtpSessions. + */ + if (is_nice || !strcmp(transmitter, "rawudp")) + g_object_set(G_OBJECT(session->session), + "no-rtcp-timeout", 0, NULL); + + /* + * Hack to make x264 work with Gmail video. + */ + if (is_nice && !strcmp(sess_id, "google-video")) { + FsElementAddedNotifier *notifier = + fs_element_added_notifier_new(); + g_signal_connect(G_OBJECT(notifier), "element-added", + G_CALLBACK(_gst_element_added_cb), NULL); + fs_element_added_notifier_add(notifier, + GST_BIN(priv->conference)); + } + + session->id = g_strdup(sess_id); + session->backend = self; + session->type = type; + session->initiator = initiator; + + if (!priv->sessions) { + purple_debug_info("backend-fs2", + "Creating hash table for sessions\n"); + priv->sessions = g_hash_table_new(g_str_hash, g_str_equal); + } + + g_hash_table_insert(priv->sessions, g_strdup(session->id), session); + + return TRUE; +} + static gboolean purple_media_backend_fs2_add_stream(PurpleMediaBackend *self, const gchar *sess_id, const gchar *who, @@ -621,15 +841,24 @@ const gchar *transmitter, guint num_params, GParameter *params) { + PurpleMediaBackendFs2 *backend = PURPLE_MEDIA_BACKEND_FS2(self); PurpleMediaBackendFs2Private *priv = - PURPLE_MEDIA_BACKEND_FS2_GET_PRIVATE(self); + PURPLE_MEDIA_BACKEND_FS2_GET_PRIVATE(backend); - if (priv->conference == NULL && !_init_conference(self)) { + if (priv->conference == NULL && !_init_conference(backend)) { purple_debug_error("backend-fs2", "Error initializing the conference.\n"); return FALSE; } + if (_get_session(backend, sess_id) == NULL && + !_create_session(backend, sess_id, type, + initiator, transmitter)) { + purple_debug_error("backend-fs2", + "Error creating the session.\n"); + return FALSE; + } + return TRUE; } @@ -675,3 +904,10 @@ return priv->conference; } +FsSession * +purple_media_backend_fs2_get_session(PurpleMediaBackendFs2 *self, + const gchar *sess_id) +{ + PurpleMediaBackendFs2Session *session = _get_session(self, sess_id); + return session != NULL? session->session : NULL; +}
--- a/libpurple/media/backend-fs2.h Fri Oct 23 19:59:12 2009 +0000 +++ b/libpurple/media/backend-fs2.h Fri Oct 23 21:40:38 2009 +0000 @@ -62,6 +62,9 @@ #include <gst/farsight/fs-conference-iface.h> FsConference *purple_media_backend_fs2_get_conference( PurpleMediaBackendFs2 *self); +FsSession *purple_media_backend_fs2_get_session( + PurpleMediaBackendFs2 *self, + const gchar *sess_id); /* end tmp */ G_END_DECLS
--- a/libpurple/media/media.c Fri Oct 23 19:59:12 2009 +0000 +++ b/libpurple/media/media.c Fri Oct 23 21:40:38 2009 +0000 @@ -362,17 +362,6 @@ } } - if (priv->sessions) { - GList *sessions = g_hash_table_get_values(priv->sessions); - for (; sessions; sessions = g_list_delete_link(sessions, sessions)) { - PurpleMediaSession *session = sessions->data; - if (session->session) { - g_object_unref(session->session); - session->session = NULL; - } - } - } - if (priv->participants) { GList *participants = g_hash_table_get_values(priv->participants); for (; participants; participants = g_list_delete_link(participants, participants)) @@ -1478,18 +1467,6 @@ stream->connected_cb_id = purple_timeout_add(0, (GSourceFunc)purple_media_connected_cb, stream); } - -static void -purple_media_element_added_cb(FsElementAddedNotifier *self, - GstBin *bin, GstElement *element, gpointer user_data) -{ - /* - * Hack to make H264 work with Gmail video. - */ - if (!strncmp(GST_ELEMENT_NAME(element), "x264", 4)) { - g_object_set(GST_OBJECT(element), "cabac", FALSE, NULL); - } -} #endif /* USE_VV */ gboolean @@ -1539,85 +1516,13 @@ session = purple_media_get_session(media, sess_id); if (!session) { - GError *err = NULL; - GList *codec_conf = NULL, *iter = NULL; - gchar *filename = NULL; PurpleMediaSessionType session_type; GstElement *src = NULL; session = g_new0(PurpleMediaSession, 1); - - session->session = fs_conference_new_session( - media->priv->conference, media_type, &err); - - if (err != NULL) { - purple_media_error(media, _("Error creating session: %s"), err->message); - g_error_free(err); - g_free(session); - return FALSE; - } - - filename = g_build_filename(purple_user_dir(), "fs-codec.conf", NULL); - codec_conf = fs_codec_list_from_keyfile(filename, &err); - g_free(filename); - - if (err != NULL) { - if (err->code == 4) - purple_debug_info("media", "Couldn't read " - "fs-codec.conf: %s\n", - err->message); - else - purple_debug_error("media", "Error reading " - "fs-codec.conf: %s\n", - err->message); - g_error_free(err); - } - - /* - * Add SPEEX if the configuration file doesn't exist or - * there isn't a speex entry. - */ - for (iter = codec_conf; iter; iter = g_list_next(iter)) { - FsCodec *codec = iter->data; - if (!g_ascii_strcasecmp(codec->encoding_name, "speex")) - break; - } - - if (iter == NULL) { - codec_conf = g_list_prepend(codec_conf, - fs_codec_new(FS_CODEC_ID_ANY, - "SPEEX", FS_MEDIA_TYPE_AUDIO, 8000)); - codec_conf = g_list_prepend(codec_conf, - fs_codec_new(FS_CODEC_ID_ANY, - "SPEEX", FS_MEDIA_TYPE_AUDIO, 16000)); - } - - fs_session_set_codec_preferences(session->session, codec_conf, NULL); - - /* - * Removes a 5-7 second delay before - * receiving the src-pad-added signal. - * Only works for non-multicast FsRtpSessions. - */ - if (is_nice || !strcmp(transmitter, "rawudp")) - g_object_set(G_OBJECT(session->session), - "no-rtcp-timeout", 0, NULL); - - /* - * Hack to make x264 work with Gmail video. - */ - if (is_nice && !strcmp(sess_id, "google-video")) { - FsElementAddedNotifier *notifier = - fs_element_added_notifier_new(); - g_signal_connect(G_OBJECT(notifier), "element-added", - G_CALLBACK(purple_media_element_added_cb), - stream); - fs_element_added_notifier_add(notifier, - GST_BIN(media->priv->conference)); - } - - fs_codec_list_destroy(codec_conf); - + session->session = purple_media_backend_fs2_get_session( + PURPLE_MEDIA_BACKEND_FS2(media->priv->backend), + sess_id); session->id = g_strdup(sess_id); session->media = media; session->type = type;