From d532b325b8f5c381426d604422247fe52db5b1b5 Mon Sep 17 00:00:00 2001 From: Jakub Adam Date: Sat, 11 Jun 2011 19:21:46 +0200 Subject: [PATCH] media: removed patches released in pidgin 2.8.0 and updated README Now it should be possible to compile voice&video enabled SIPE without patching any of required libraries. I'm leaving media-patches directory in place because I'm preparing support for ICE-TCP in libnice and will put there new patches before they are integrated upstream. --- contrib/media-patches/README.txt | 37 +- .../media-patches/pidgin_media_dynamic_av.patch | 514 --------------------- ...gin_media_reject_only_unaccepted_sessions.patch | 35 -- contrib/media-patches/purple_SDES.patch | 269 ----------- .../media-patches/purple_media_fs2_dispose.patch | 88 ---- .../purple_media_get_active_candidates.patch | 48 -- 6 files changed, 8 insertions(+), 983 deletions(-) delete mode 100644 contrib/media-patches/pidgin_media_dynamic_av.patch delete mode 100644 contrib/media-patches/pidgin_media_reject_only_unaccepted_sessions.patch delete mode 100644 contrib/media-patches/purple_SDES.patch delete mode 100644 contrib/media-patches/purple_media_fs2_dispose.patch delete mode 100644 contrib/media-patches/purple_media_get_active_candidates.patch diff --git a/contrib/media-patches/README.txt b/contrib/media-patches/README.txt index 67fc4f99..14c2e6e4 100644 --- a/contrib/media-patches/README.txt +++ b/contrib/media-patches/README.txt @@ -1,13 +1,7 @@ -To enable experimental voice support in SIPE (only on platforms where libpurple -supports voice & video): +To enable voice support in SIPE (only on platforms where libpurple supports +voice & video): -- libnice >= 0.1.0 and farsight2 >= 0.0.26 are required -- source tree of Pidgin 2.7.10 or higher is required and following patches must - be applied: - - purple_media_get_active_candidates.patch - - purple_SDES.patch - - pidgin_media_dynamic_av.patch - - pidgin_media_reject_only_unaccepted_sessions.patch +- pidgin >= 2.8.0, libnice >= 0.1.0 and farsight2 >= 0.0.26 are required - compile SIPE source, check that voice support is enabled in configure output - If you get errors on incompatible encryption levels when making a call, change to peer's registry is needed to allow unencrypted media transfer; use the @@ -15,27 +9,12 @@ supports voice & video): on your domain policy configuration, in this case registry change is not needed. - now you can try to make a voice call -STATUS OF PATCHES IN UPSTREAM -============================= - -purple_media_get_active_candidates.patch - - reported as http://developer.pidgin.im/ticket/11830 - - commited for future 2.8.0 release - -purple_SDES.patch - - reported as http://developer.pidgin.im/ticket/12981 - - accepted for future 2.8.0 release - -pidgin_media_dynamic_av.patch - - reported as http://developer.pidgin.im/ticket/13535 - - accepted for future 2.7.12 release - -pidgin_media_reject_only_unaccepted_sessions.patch - - reported as http://developer.pidgin.im/ticket/13537 - - accepted for future 2.7.12 release - Biggest show stopper now is a lack of SRTP (encrypted transfer) in Farsight library, requiring Office Communicator users to change their registry settings as a workaround is unacceptable. According to FS website, someone is working on -this, but no results are available so far. UPDATE: in some environments unencrypted +this, but no results are available so far. In some environments unencrypted calls can be allowed by domain policy, so not all users are affected. + +Also media transport over TCP will not work, proof of concept implementation for +libnice exists, it is now in state of code cleanup and integration into upstream +libraries. Contact jakub (dot) adam (at) ktknet (dot) cz for details diff --git a/contrib/media-patches/pidgin_media_dynamic_av.patch b/contrib/media-patches/pidgin_media_dynamic_av.patch deleted file mode 100644 index 1d062687..00000000 --- a/contrib/media-patches/pidgin_media_dynamic_av.patch +++ /dev/null @@ -1,514 +0,0 @@ -From 3e3b71d8431017cce260b46caa1b87406f0b8eff Mon Sep 17 00:00:00 2001 -From: Jakub Adam -Date: Wed, 2 Mar 2011 23:40:24 +0100 -Subject: [PATCH] Allow dynamic adding and removal of audio and video streams during call - ---- - libpurple/media/backend-fs2.c | 114 +++++++++++++++++++++----- - pidgin/gtkmedia.c | 176 +++++++++++++++++++++++++++++++++++------ - 2 files changed, 243 insertions(+), 47 deletions(-) - -diff --git a/libpurple/media/backend-fs2.c b/libpurple/media/backend-fs2.c -index 9fb0bdf..e0527ac 100644 ---- a/libpurple/media/backend-fs2.c -+++ b/libpurple/media/backend-fs2.c -@@ -89,6 +89,9 @@ static void purple_media_backend_fs2_set_params(PurpleMediaBackend *self, - guint num_params, GParameter *params); - static const gchar **purple_media_backend_fs2_get_available_params(void); - -+static void free_stream(PurpleMediaBackendFs2Stream *stream); -+static void free_session(PurpleMediaBackendFs2Session *session); -+ - struct _PurpleMediaBackendFs2Class - { - GObjectClass parent_class; -@@ -113,6 +116,8 @@ struct _PurpleMediaBackendFs2Stream - GstElement *tee; - GstElement *volume; - GstElement *level; -+ GstElement *fakesink; -+ GstElement *queue; - - GList *local_candidates; - GList *remote_candidates; -@@ -301,20 +306,7 @@ purple_media_backend_fs2_finalize(GObject *obj) - for (; priv->streams; priv->streams = - g_list_delete_link(priv->streams, priv->streams)) { - PurpleMediaBackendFs2Stream *stream = priv->streams->data; -- -- /* Remove the connected_cb timeout */ -- if (stream->connected_cb_id != 0) -- purple_timeout_remove(stream->connected_cb_id); -- -- g_free(stream->participant); -- -- if (stream->local_candidates) -- fs_candidate_list_destroy(stream->local_candidates); -- -- if (stream->remote_candidates) -- fs_candidate_list_destroy(stream->remote_candidates); -- -- g_free(stream); -+ free_stream(stream); - } - - if (priv->sessions) { -@@ -324,8 +316,7 @@ purple_media_backend_fs2_finalize(GObject *obj) - g_list_delete_link(sessions, sessions)) { - PurpleMediaBackendFs2Session *session = - sessions->data; -- g_free(session->id); -- g_free(session); -+ free_session(session); - } - - g_hash_table_destroy(priv->sessions); -@@ -1127,9 +1118,62 @@ gst_bus_cb(GstBus *bus, GstMessage *msg, PurpleMediaBackendFs2 *self) - } - - static void -+remove_element(GstElement *element) -+{ -+ if (element) { -+ gst_element_set_locked_state(element, TRUE); -+ gst_element_set_state(element, GST_STATE_NULL); -+ gst_bin_remove(GST_BIN(GST_ELEMENT_PARENT(element)), element); -+ } -+} -+ -+static void - state_changed_cb(PurpleMedia *media, PurpleMediaState state, - gchar *sid, gchar *name, PurpleMediaBackendFs2 *self) - { -+ if (state == PURPLE_MEDIA_STATE_END) { -+ PurpleMediaBackendFs2Private *priv = -+ PURPLE_MEDIA_BACKEND_FS2_GET_PRIVATE(self); -+ -+ if (sid && name) { -+ PurpleMediaBackendFs2Stream *stream = get_stream(self, sid, name); -+ gst_object_unref(stream->stream); -+ -+ priv->streams = g_list_remove(priv->streams, stream); -+ -+ remove_element(stream->src); -+ remove_element(stream->tee); -+ remove_element(stream->volume); -+ remove_element(stream->level); -+ remove_element(stream->fakesink); -+ remove_element(stream->queue); -+ -+ free_stream(stream); -+ } else if (sid && !name) { -+ PurpleMediaBackendFs2Session *session = get_session(self, sid); -+ GstPad *pad; -+ -+ g_object_get(session->session, "sink-pad", &pad, NULL); -+ gst_pad_unlink(GST_PAD_PEER(pad), pad); -+ gst_object_unref(pad); -+ -+ gst_object_unref(session->session); -+ g_hash_table_remove(priv->sessions, session->id); -+ -+ pad = gst_pad_get_peer(session->srcpad); -+ gst_element_remove_pad(GST_ELEMENT_PARENT(pad), pad); -+ gst_object_unref(pad); -+ gst_object_unref(session->srcpad); -+ -+ remove_element(session->srcvalve); -+ remove_element(session->tee); -+ -+ free_session(session); -+ } -+ -+ purple_media_manager_remove_output_windows( -+ purple_media_get_manager(media), media, sid, name); -+ } - } - - static void -@@ -1398,6 +1442,7 @@ create_src(PurpleMediaBackendFs2 *self, const gchar *sess_id, - ? "success" : "failure"); - gst_element_set_locked_state(session->src, FALSE); - gst_object_unref(session->src); -+ gst_object_unref(sinkpad); - - gst_element_set_state(session->src, GST_STATE_PLAYING); - -@@ -1514,6 +1559,13 @@ create_session(PurpleMediaBackendFs2 *self, const gchar *sess_id, - return TRUE; - } - -+static void -+free_session(PurpleMediaBackendFs2Session *session) -+{ -+ g_free(session->id); -+ g_free(session); -+} -+ - static gboolean - create_participant(PurpleMediaBackendFs2 *self, const gchar *name) - { -@@ -1581,7 +1633,6 @@ src_pad_added_cb(FsStream *fsstream, GstPad *srcpad, - GstElement *sink = NULL; - - if (codec->media_type == FS_MEDIA_TYPE_AUDIO) { -- GstElement *queue = NULL; - double output_volume = purple_prefs_get_int( - "/purple/media/audio/volume/output")/10.0; - /* -@@ -1589,7 +1640,7 @@ src_pad_added_cb(FsStream *fsstream, GstPad *srcpad, - * audioconvert ! audioresample ! liveadder ! - * audioresample ! audioconvert ! realsink - */ -- queue = gst_element_factory_make("queue", NULL); -+ stream->queue = gst_element_factory_make("queue", NULL); - stream->volume = gst_element_factory_make( - "volume", NULL); - g_object_set(stream->volume, "volume", -@@ -1603,18 +1654,18 @@ src_pad_added_cb(FsStream *fsstream, GstPad *srcpad, - PURPLE_MEDIA_RECV_AUDIO, priv->media, - stream->session->id, - stream->participant); -- gst_bin_add(GST_BIN(priv->confbin), queue); -+ gst_bin_add(GST_BIN(priv->confbin), stream->queue); - gst_bin_add(GST_BIN(priv->confbin), stream->volume); - gst_bin_add(GST_BIN(priv->confbin), stream->level); - gst_bin_add(GST_BIN(priv->confbin), sink); - gst_element_set_state(sink, GST_STATE_PLAYING); - gst_element_set_state(stream->level, GST_STATE_PLAYING); - gst_element_set_state(stream->volume, GST_STATE_PLAYING); -- gst_element_set_state(queue, GST_STATE_PLAYING); -+ gst_element_set_state(stream->queue, GST_STATE_PLAYING); - gst_element_link(stream->level, sink); - gst_element_link(stream->volume, stream->level); -- gst_element_link(queue, stream->volume); -- sink = queue; -+ gst_element_link(stream->queue, stream->volume); -+ sink = stream->queue; - } else if (codec->media_type == FS_MEDIA_TYPE_VIDEO) { - stream->src = gst_element_factory_make( - "fsfunnel", NULL); -@@ -1623,6 +1674,7 @@ src_pad_added_cb(FsStream *fsstream, GstPad *srcpad, - g_object_set(G_OBJECT(sink), "async", FALSE, NULL); - gst_bin_add(GST_BIN(priv->confbin), sink); - gst_element_set_state(sink, GST_STATE_PLAYING); -+ stream->fakesink = sink; - } - stream->tee = gst_element_factory_make("tee", NULL); - gst_bin_add_many(GST_BIN(priv->confbin), -@@ -1792,6 +1844,24 @@ create_stream(PurpleMediaBackendFs2 *self, - return TRUE; - } - -+static void -+free_stream(PurpleMediaBackendFs2Stream *stream) -+{ -+ /* Remove the connected_cb timeout */ -+ if (stream->connected_cb_id != 0) -+ purple_timeout_remove(stream->connected_cb_id); -+ -+ g_free(stream->participant); -+ -+ if (stream->local_candidates) -+ fs_candidate_list_destroy(stream->local_candidates); -+ -+ if (stream->remote_candidates) -+ fs_candidate_list_destroy(stream->remote_candidates); -+ -+ g_free(stream); -+} -+ - static gboolean - purple_media_backend_fs2_add_stream(PurpleMediaBackend *self, - const gchar *sess_id, const gchar *who, -diff --git a/pidgin/gtkmedia.c b/pidgin/gtkmedia.c -index e3b4933..06beb7b 100644 ---- a/pidgin/gtkmedia.c -+++ b/pidgin/gtkmedia.c -@@ -93,7 +93,7 @@ struct _PidginMediaPrivate - GtkWidget *pause; - - GtkWidget *send_progress; -- GtkWidget *recv_progress; -+ GHashTable *recv_progressbars; - - PidginMediaState state; - -@@ -102,7 +102,7 @@ struct _PidginMediaPrivate - GtkWidget *recv_widget; - GtkWidget *button_widget; - GtkWidget *local_video; -- GtkWidget *remote_video; -+ GHashTable *remote_videos; - - guint timeout_id; - PurpleMediaSessionType request_type; -@@ -352,18 +352,110 @@ pidgin_media_init (PidginMedia *media) - - g_signal_connect(G_OBJECT(media), "delete-event", - G_CALLBACK(pidgin_media_delete_event_cb), media); -+ -+ media->priv->recv_progressbars = -+ g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); -+ media->priv->remote_videos = -+ g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); -+} -+ -+static gchar * -+create_key(const gchar *session_id, const gchar *participant) -+{ -+ return g_strdup_printf("%s_%s", session_id, participant); -+} -+ -+static void -+pidgin_media_insert_widget(PidginMedia *gtkmedia, GtkWidget *widget, -+ const gchar *session_id, const gchar *participant) -+{ -+ gchar *key = create_key(session_id, participant); -+ PurpleMediaSessionType type = -+ purple_media_get_session_type(gtkmedia->priv->media, session_id); -+ -+ if (type & PURPLE_MEDIA_AUDIO) -+ g_hash_table_insert(gtkmedia->priv->recv_progressbars, key, widget); -+ else if (type & PURPLE_MEDIA_VIDEO) -+ g_hash_table_insert(gtkmedia->priv->remote_videos, key, widget); -+} -+ -+static GtkWidget * -+pidgin_media_get_widget(PidginMedia *gtkmedia, -+ const gchar *session_id, const gchar *participant) -+{ -+ GtkWidget *widget = NULL; -+ gchar *key = create_key(session_id, participant); -+ PurpleMediaSessionType type = -+ purple_media_get_session_type(gtkmedia->priv->media, session_id); -+ -+ if (type & PURPLE_MEDIA_AUDIO) -+ widget = g_hash_table_lookup(gtkmedia->priv->recv_progressbars, key); -+ else if (type & PURPLE_MEDIA_VIDEO) -+ widget = g_hash_table_lookup(gtkmedia->priv->remote_videos, key); -+ -+ g_free(key); -+ return widget; -+} -+ -+static void -+pidgin_media_remove_widget(PidginMedia *gtkmedia, -+ const gchar *session_id, const gchar *participant) -+{ -+ GtkWidget *widget = pidgin_media_get_widget(gtkmedia, session_id, participant); -+ -+ if (widget) { -+ PurpleMediaSessionType type = -+ purple_media_get_session_type(gtkmedia->priv->media, session_id); -+ gchar *key = create_key(session_id, participant); -+ GtkRequisition req; -+ -+ if (type & PURPLE_MEDIA_AUDIO) { -+ g_hash_table_remove(gtkmedia->priv->recv_progressbars, key); -+ -+ if (g_hash_table_size(gtkmedia->priv->recv_progressbars) == 0 && -+ gtkmedia->priv->send_progress) { -+ -+ gtk_widget_destroy(gtkmedia->priv->send_progress); -+ gtkmedia->priv->send_progress = NULL; -+ -+ gtk_widget_destroy(gtkmedia->priv->mute); -+ gtkmedia->priv->mute = NULL; -+ } -+ } else if (type & PURPLE_MEDIA_VIDEO) { -+ g_hash_table_remove(gtkmedia->priv->remote_videos, key); -+ -+ if (g_hash_table_size(gtkmedia->priv->remote_videos) == 0 && -+ gtkmedia->priv->local_video) { -+ -+ gtk_widget_destroy(gtkmedia->priv->local_video); -+ gtkmedia->priv->local_video = NULL; -+ -+ gtk_widget_destroy(gtkmedia->priv->pause); -+ gtkmedia->priv->pause = NULL; -+ } -+ } -+ -+ g_free(key); -+ -+ gtk_widget_destroy(widget); -+ -+ gtk_widget_size_request(GTK_WIDGET(gtkmedia), &req); -+ gtk_window_resize(GTK_WINDOW(gtkmedia), req.width, req.height); -+ } - } - - static void - level_message_cb(PurpleMedia *media, gchar *session_id, gchar *participant, - double level, PidginMedia *gtkmedia) - { -- GtkWidget *progress; -+ GtkWidget *progress = NULL; - if (participant == NULL) - progress = gtkmedia->priv->send_progress; - else -- progress = gtkmedia->priv->recv_progress; -- gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progress), level); -+ progress = pidgin_media_get_widget(gtkmedia, session_id, participant); -+ -+ if (progress) -+ gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progress), level); - } - - -@@ -402,6 +494,13 @@ pidgin_media_dispose(GObject *media) - if (gtkmedia->priv->timeout_id != 0) - g_source_remove(gtkmedia->priv->timeout_id); - -+ if (gtkmedia->priv->recv_progressbars) { -+ g_hash_table_destroy(gtkmedia->priv->recv_progressbars); -+ g_hash_table_destroy(gtkmedia->priv->remote_videos); -+ gtkmedia->priv->recv_progressbars = NULL; -+ gtkmedia->priv->remote_videos = NULL; -+ } -+ - G_OBJECT_CLASS(parent_class)->dispose(media); - } - -@@ -436,24 +535,30 @@ static gboolean - realize_cb_cb(PidginMediaRealizeData *data) - { - PidginMediaPrivate *priv = data->gtkmedia->priv; -- gulong window_id; -+ GdkWindow *window = NULL; - --#ifdef _WIN32 - if (data->participant == NULL) -- window_id = GDK_WINDOW_HWND(priv->local_video->window); -- else -- window_id = GDK_WINDOW_HWND(priv->remote_video->window); -+ window = gtk_widget_get_window(priv->local_video); -+ else { -+ GtkWidget *widget = pidgin_media_get_widget(data->gtkmedia, -+ data->session_id, data->participant); -+ if (widget) -+ window = gtk_widget_get_window(widget); -+ } -+ -+ if (window) { -+ gulong window_id; -+#ifdef _WIN32 -+ window_id = GDK_WINDOW_HWND(window); - #elif defined(HAVE_X11) -- if (data->participant == NULL) -- window_id = GDK_WINDOW_XWINDOW(priv->local_video->window); -- else -- window_id = GDK_WINDOW_XWINDOW(priv->remote_video->window); -+ window_id = GDK_WINDOW_XWINDOW(window); - #else --# error "Unsupported windowing system" -+# error "Unsupported windowing system" - #endif - -- purple_media_set_output_window(priv->media, data->session_id, -- data->participant, window_id); -+ purple_media_set_output_window(priv->media, data->session_id, -+ data->participant, window_id); -+ } - - g_free(data->session_id); - g_free(data->participant); -@@ -563,9 +668,17 @@ pidgin_media_output_volume_changed(GtkRange *range, PurpleMedia *media) - purple_media_set_output_volume(media, NULL, NULL, val); - } - -+static void -+destroy_parent_widget_cb(GtkWidget *widget, GtkWidget *parent) -+{ -+ g_return_if_fail(GTK_IS_WIDGET(parent)); -+ -+ gtk_widget_destroy(parent); -+} -+ - static GtkWidget * - pidgin_media_add_audio_widget(PidginMedia *gtkmedia, -- PurpleMediaSessionType type) -+ PurpleMediaSessionType type, const gchar *sid) - { - GtkWidget *volume_widget, *progress_parent, *volume, *progress; - double value; -@@ -619,9 +732,14 @@ pidgin_media_add_audio_widget(PidginMedia *gtkmedia, - g_signal_connect (G_OBJECT(volume), "value-changed", - G_CALLBACK(pidgin_media_output_volume_changed), - gtkmedia->priv->media); -- gtkmedia->priv->recv_progress = progress; -+ -+ pidgin_media_insert_widget(gtkmedia, progress, sid, gtkmedia->priv->screenname); - } - -+ g_signal_connect(G_OBJECT(progress), "destroy", -+ G_CALLBACK(destroy_parent_widget_cb), -+ volume_widget); -+ - gtk_widget_show_all(volume_widget); - - return volume_widget; -@@ -691,13 +809,17 @@ pidgin_media_ready_cb(PurpleMedia *media, PidginMedia *gtkmedia, const gchar *si - G_CALLBACK(realize_cb), data); - gtk_container_add(GTK_CONTAINER(aspect), remote_video); - gtk_widget_set_size_request (GTK_WIDGET(remote_video), 320, 240); -+ g_signal_connect(G_OBJECT(remote_video), "destroy", -+ G_CALLBACK(destroy_parent_widget_cb), aspect); -+ - gtk_widget_show(remote_video); - gtk_widget_show(aspect); - -- gtkmedia->priv->remote_video = remote_video; -+ pidgin_media_insert_widget(gtkmedia, remote_video, -+ data->session_id, data->participant); - } - -- if (type & PURPLE_MEDIA_SEND_VIDEO) { -+ if (type & PURPLE_MEDIA_SEND_VIDEO && !gtkmedia->priv->local_video) { - PidginMediaRealizeData *data; - GtkWidget *aspect; - GtkWidget *local_video; -@@ -718,6 +840,8 @@ pidgin_media_ready_cb(PurpleMedia *media, PidginMedia *gtkmedia, const gchar *si - G_CALLBACK(realize_cb), data); - gtk_container_add(GTK_CONTAINER(aspect), local_video); - gtk_widget_set_size_request (GTK_WIDGET(local_video), 80, 60); -+ g_signal_connect(G_OBJECT(local_video), "destroy", -+ G_CALLBACK(destroy_parent_widget_cb), aspect); - - gtk_widget_show(local_video); - gtk_widget_show(aspect); -@@ -736,7 +860,7 @@ pidgin_media_ready_cb(PurpleMedia *media, PidginMedia *gtkmedia, const gchar *si - if (type & PURPLE_MEDIA_RECV_AUDIO) { - gtk_box_pack_end(GTK_BOX(recv_widget), - pidgin_media_add_audio_widget(gtkmedia, -- PURPLE_MEDIA_RECV_AUDIO), FALSE, FALSE, 0); -+ PURPLE_MEDIA_RECV_AUDIO, sid), FALSE, FALSE, 0); - } - - if (type & PURPLE_MEDIA_SEND_AUDIO) { -@@ -751,7 +875,7 @@ pidgin_media_ready_cb(PurpleMedia *media, PidginMedia *gtkmedia, const gchar *si - - gtk_box_pack_end(GTK_BOX(recv_widget), - pidgin_media_add_audio_widget(gtkmedia, -- PURPLE_MEDIA_SEND_AUDIO), FALSE, FALSE, 0); -+ PURPLE_MEDIA_SEND_AUDIO, NULL), FALSE, FALSE, 0); - } - - if (type & PURPLE_MEDIA_AUDIO && -@@ -804,8 +928,10 @@ pidgin_media_state_changed_cb(PurpleMedia *media, PurpleMediaState state, - { - purple_debug_info("gtkmedia", "state: %d sid: %s name: %s\n", - state, sid ? sid : "(null)", name ? name : "(null)"); -- if (sid == NULL && name == NULL) { -- if (state == PURPLE_MEDIA_STATE_END) { -+ if (state == PURPLE_MEDIA_STATE_END) { -+ if (sid != NULL && name != NULL) { -+ pidgin_media_remove_widget(gtkmedia, sid, name); -+ } else if (sid == NULL && name == NULL) { - pidgin_media_emit_message(gtkmedia, - _("The call has been terminated.")); - gtk_widget_destroy(GTK_WIDGET(gtkmedia)); --- -1.7.4.1 - diff --git a/contrib/media-patches/pidgin_media_reject_only_unaccepted_sessions.patch b/contrib/media-patches/pidgin_media_reject_only_unaccepted_sessions.patch deleted file mode 100644 index 2427347b..00000000 --- a/contrib/media-patches/pidgin_media_reject_only_unaccepted_sessions.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 929b115ec4fb5d7f3eda6ab8b3659faee3e56182 Mon Sep 17 00:00:00 2001 -From: Jakub Adam -Date: Tue, 15 Mar 2011 22:26:02 +0100 -Subject: [PATCH] When user rejects call, reject only sessions that were not previously - accepted - -For example when buddy adds video to running call, allow rejecting -it without dropping voice. ---- - pidgin/gtkmedia.c | 9 +++++++-- - 1 files changed, 7 insertions(+), 2 deletions(-) - -diff --git a/pidgin/gtkmedia.c b/pidgin/gtkmedia.c -index ca4e10c..d45eaef 100644 ---- a/pidgin/gtkmedia.c -+++ b/pidgin/gtkmedia.c -@@ -595,8 +595,13 @@ pidgin_media_accept_cb(PurpleMedia *media, int index) - static void - pidgin_media_reject_cb(PurpleMedia *media, int index) - { -- purple_media_stream_info(media, PURPLE_MEDIA_INFO_REJECT, -- NULL, NULL, TRUE); -+ GList *iter = purple_media_get_session_ids(media); -+ for (; iter; iter = g_list_delete_link(iter, iter)) { -+ const gchar *sessionid = iter->data; -+ if (!purple_media_accepted(media, sessionid, NULL)) -+ purple_media_stream_info(media, PURPLE_MEDIA_INFO_REJECT, -+ sessionid, NULL, TRUE); -+ } - } - - static gboolean --- -1.7.2.3 - diff --git a/contrib/media-patches/purple_SDES.patch b/contrib/media-patches/purple_SDES.patch deleted file mode 100644 index 39157368..00000000 --- a/contrib/media-patches/purple_SDES.patch +++ /dev/null @@ -1,269 +0,0 @@ -From 2e1f0022e9f2a411f6fa5079bb10877d89f1dcfb Mon Sep 17 00:00:00 2001 -From: Jakub Adam -Date: Wed, 24 Nov 2010 22:19:54 +0100 -Subject: [PATCH] Allow to set SDES properties of FsRtpConference - ---- - libpurple/media.c | 41 +++++++++++++++++++++++++++++++++ - libpurple/media.h | 46 +++++++++++++++++++++++++++++++++++++ - libpurple/media/backend-fs2.c | 48 +++++++++++++++++++++++++++++++++++++++ - libpurple/media/backend-iface.c | 17 +++++++++++++ - libpurple/media/backend-iface.h | 28 ++++++++++++++++++++++ - 5 files changed, 180 insertions(+), 0 deletions(-) - -diff --git a/libpurple/media.c b/libpurple/media.c -index ca79eed..c789089 100644 ---- a/libpurple/media.c -+++ b/libpurple/media.c -@@ -916,6 +916,47 @@ purple_media_stream_info(PurpleMedia *media, PurpleMediaInfoType type, - #endif - } - -+void -+purple_media_set_params(PurpleMedia *media, -+ guint num_params, GParameter *params) -+{ -+#ifdef USE_VV -+ g_return_if_fail(PURPLE_IS_MEDIA(media)); -+ -+ purple_media_backend_set_params(media->priv->backend, num_params, params); -+#endif -+} -+ -+const gchar ** -+purple_media_get_available_params(PurpleMedia *media) -+{ -+ static const gchar *NULL_ARRAY[] = { NULL }; -+#ifdef USE_VV -+ g_return_val_if_fail(PURPLE_IS_MEDIA(media), NULL_ARRAY); -+ -+ return purple_media_backend_get_available_params(media->priv->backend); -+#else -+ return NULL_ARRAY; -+#endif -+} -+ -+gboolean -+purple_media_param_is_supported(PurpleMedia *media, const gchar *param) -+{ -+#ifdef USE_VV -+ const gchar **params; -+ -+ g_return_val_if_fail(PURPLE_IS_MEDIA(media), FALSE); -+ g_return_val_if_fail(param != NULL, FALSE); -+ -+ params = purple_media_backend_get_available_params(media->priv->backend); -+ for (; *params != NULL; ++params) -+ if (!strcmp(*params, param)) -+ return TRUE; -+#endif -+ return FALSE; -+} -+ - #ifdef USE_VV - static void - purple_media_new_local_candidate_cb(PurpleMediaBackend *backend, -diff --git a/libpurple/media.h b/libpurple/media.h -index dc84f2d..926765a 100644 ---- a/libpurple/media.h -+++ b/libpurple/media.h -@@ -144,6 +144,52 @@ void purple_media_stream_info(PurpleMedia *media, PurpleMediaInfoType type, - gboolean local); - - /** -+ * Sets various optional parameters of the media call. -+ * -+ * Currently supported are: -+ * - "sdes-cname" : The CNAME for the RTP sessions -+ * - "sdes-name" : Real name used to describe the source in SDES messages -+ * - "sdes-tool" : The TOOL to put in SDES messages -+ * - "sdes-email" : Email address to put in SDES messages -+ * - "sdes-location" : The LOCATION to put in SDES messages -+ * - "sdes-note" : The NOTE to put in SDES messages -+ * - "sdes-phone" : The PHONE to put in SDES messages -+ * -+ * @param media The media object to set the parameters on. -+ * @param num_params The number of parameters to pass -+ * @param params Array of @c GParameter to pass -+ * -+ * @since 2.8.0 -+ */ -+void purple_media_set_params(PurpleMedia *media, -+ guint num_params, GParameter *params); -+ -+/** -+ * Gets the list of optional parameters supported by the media backend. -+ * -+ * The list is owned by the @c PurpleMedia internals and should NOT be freed. -+ * -+ * @param media The media object -+ * -+ * @return NULL-terminated array of names of supported parameters. -+ * -+ * @since 2.8.0 -+ */ -+const gchar **purple_media_get_available_params(PurpleMedia *media); -+ -+/** -+ * Checks if given optional parameter is supported by the media backend. -+ * -+ * @param media The media object -+ * @param param name of parameter -+ * -+ * @return @c TRUE if backend recognizes the parameter, @c FALSE otherwise. -+ * -+ * @since 2.8.0 -+ */ -+gboolean purple_media_param_is_supported(PurpleMedia *media, const gchar *param); -+ -+/** - * Adds a stream to a session. - * - * It only adds a stream to one audio session or video session as -diff --git a/libpurple/media/backend-fs2.c b/libpurple/media/backend-fs2.c -index fd9de82..b2c84db 100644 ---- a/libpurple/media/backend-fs2.c -+++ b/libpurple/media/backend-fs2.c -@@ -85,6 +85,9 @@ static gboolean purple_media_backend_fs2_set_remote_codecs( - static gboolean purple_media_backend_fs2_set_send_codec( - PurpleMediaBackend *self, const gchar *sess_id, - PurpleMediaCodec *codec); -+static void purple_media_backend_fs2_set_params(PurpleMediaBackend *self, -+ guint num_params, GParameter *params); -+static const gchar **purple_media_backend_fs2_get_available_params(void); - - struct _PurpleMediaBackendFs2Class - { -@@ -367,6 +370,8 @@ purple_media_backend_iface_init(PurpleMediaBackendIface *iface) - purple_media_backend_fs2_get_local_candidates; - iface->set_remote_codecs = purple_media_backend_fs2_set_remote_codecs; - iface->set_send_codec = purple_media_backend_fs2_set_send_codec; -+ iface->set_params = purple_media_backend_fs2_set_params; -+ iface->get_available_params = purple_media_backend_fs2_get_available_params; - } - - static FsMediaType -@@ -1958,6 +1963,49 @@ purple_media_backend_fs2_set_send_codec(PurpleMediaBackend *self, - - return TRUE; - } -+ -+static void -+purple_media_backend_fs2_set_params(PurpleMediaBackend *self, -+ guint num_params, GParameter *params) -+{ -+ PurpleMediaBackendFs2Private *priv; -+ const gchar **supported = purple_media_backend_fs2_get_available_params(); -+ const gchar **p; -+ guint i; -+ -+ g_return_if_fail(PURPLE_IS_MEDIA_BACKEND_FS2(self)); -+ -+ priv = PURPLE_MEDIA_BACKEND_FS2_GET_PRIVATE(self); -+ -+ if (priv->conference == NULL && -+ !init_conference(PURPLE_MEDIA_BACKEND_FS2(self))) { -+ purple_debug_error("backend-fs2", -+ "Error initializing the conference.\n"); -+ return; -+ } -+ -+ for (i = 0; i != num_params; ++i) { -+ for (p = supported; *p != NULL; ++p) { -+ if (!strcmp(params[i].name, *p)) { -+ g_object_set(priv->conference, -+ params[i].name, g_value_get_string(¶ms[i].value), -+ NULL); -+ break; -+ } -+ } -+ } -+} -+ -+static const gchar ** -+purple_media_backend_fs2_get_available_params(void) -+{ -+ static const gchar *supported_params[] = { -+ "sdes-cname", "sdes-email", "sdes-location", "sdes-name", "sdes-note", -+ "sdes-phone", "sdes-tool", NULL -+ }; -+ -+ return supported_params; -+} - #else - GType - purple_media_backend_fs2_get_type(void) -diff --git a/libpurple/media/backend-iface.c b/libpurple/media/backend-iface.c -index 9c06934..fd53898 100644 ---- a/libpurple/media/backend-iface.c -+++ b/libpurple/media/backend-iface.c -@@ -192,3 +192,20 @@ purple_media_backend_set_send_codec(PurpleMediaBackend *self, - return PURPLE_MEDIA_BACKEND_GET_INTERFACE(self)->set_send_codec(self, - sess_id, codec); - } -+ -+void -+purple_media_backend_set_params(PurpleMediaBackend *self, -+ guint num_params, GParameter *params) -+{ -+ g_return_if_fail(PURPLE_IS_MEDIA_BACKEND(self)); -+ PURPLE_MEDIA_BACKEND_GET_INTERFACE(self)->set_params(self, num_params, params); -+} -+ -+const gchar ** -+purple_media_backend_get_available_params(PurpleMediaBackend *self) -+{ -+ static const gchar *NULL_ARRAY[] = { NULL }; -+ -+ g_return_val_if_fail(PURPLE_IS_MEDIA_BACKEND(self), NULL_ARRAY); -+ return PURPLE_MEDIA_BACKEND_GET_INTERFACE(self)->get_available_params(); -+} -diff --git a/libpurple/media/backend-iface.h b/libpurple/media/backend-iface.h -index 258db85..471eb02 100644 ---- a/libpurple/media/backend-iface.h -+++ b/libpurple/media/backend-iface.h -@@ -68,6 +68,9 @@ struct _PurpleMediaBackendIface - GList *codecs); - gboolean (*set_send_codec) (PurpleMediaBackend *self, - const gchar *sess_id, PurpleMediaCodec *codec); -+ void (*set_params) (PurpleMediaBackend *self, -+ guint num_params, GParameter *params); -+ const gchar **(*get_available_params) (void); - }; - - /** -@@ -191,6 +194,31 @@ gboolean purple_media_backend_set_remote_codecs(PurpleMediaBackend *self, - gboolean purple_media_backend_set_send_codec(PurpleMediaBackend *self, - const gchar *sess_id, PurpleMediaCodec *codec); - -+/** -+ * Sets various optional parameters of the media backend. -+ * -+ * @param self The media backend to set the parameters on. -+ * @param num_params The number of parameters to pass to backend -+ * @param params Array of @c GParameter to pass to backend -+ * -+ * @since 2.8.0 -+ */ -+void purple_media_backend_set_params(PurpleMediaBackend *self, -+ guint num_params, GParameter *params); -+ -+/** -+ * Gets the list of optional parameters supported by the media backend. -+ * -+ * The list should NOT be freed. -+ * -+ * @param self The media backend -+ * -+ * @return NULL-terminated array of names of supported parameters. -+ * -+ * @since 2.8.0 -+ */ -+const gchar **purple_media_backend_get_available_params(PurpleMediaBackend *self); -+ - G_END_DECLS - - #endif /* _MEDIA_BACKEND_IFACE_H_ */ --- -1.7.2.3 - diff --git a/contrib/media-patches/purple_media_fs2_dispose.patch b/contrib/media-patches/purple_media_fs2_dispose.patch deleted file mode 100644 index b12312c6..00000000 --- a/contrib/media-patches/purple_media_fs2_dispose.patch +++ /dev/null @@ -1,88 +0,0 @@ -From 528aec37edb45e33ac1dd1ee7f28238ca0fdd65a Mon Sep 17 00:00:00 2001 -From: Jakub Adam -Date: Sat, 18 Dec 2010 21:52:49 +0100 -Subject: [PATCH] Hanging up a video call freezes other running calls - ---- - libpurple/media/backend-fs2.c | 23 ++++++++++++++++++++++- - libpurple/mediamanager.c | 2 ++ - 2 files changed, 24 insertions(+), 1 deletions(-) - -diff --git a/libpurple/media/backend-fs2.c b/libpurple/media/backend-fs2.c -index 54c4d5b..08eea5f 100644 ---- a/libpurple/media/backend-fs2.c -+++ b/libpurple/media/backend-fs2.c -@@ -129,6 +129,8 @@ struct _PurpleMediaBackendFs2Session - GstElement *src; - GstElement *tee; - -+ GstPad *srcpad; -+ - PurpleMediaSessionType type; - }; - -@@ -171,6 +173,22 @@ purple_media_backend_fs2_dispose(GObject *obj) - pipeline = purple_media_manager_get_pipeline( - purple_media_get_manager(priv->media)); - -+ /* All connections to media sources should be blocked before confbin is -+ * removed, to prevent freezing of any other simultaneously running -+ * media calls. */ -+ 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->srcpad) { -+ gst_pad_set_blocked(session->srcpad, TRUE); -+ gst_object_unref(session->srcpad); -+ session->srcpad = NULL; -+ } -+ } -+ } -+ - gst_element_set_locked_state(priv->confbin, TRUE); - gst_element_set_state(GST_ELEMENT(priv->confbin), - GST_STATE_NULL); -@@ -1263,6 +1281,7 @@ create_src(PurpleMediaBackendFs2 *self, const gchar *sess_id, - session_type_to_fs_stream_direction(type); - GstElement *src; - GstPad *sinkpad, *srcpad; -+ GstPad *ghost = NULL; - - if ((type_direction & FS_DIRECTION_SEND) == 0) - return TRUE; -@@ -1302,7 +1321,7 @@ create_src(PurpleMediaBackendFs2 *self, const gchar *sess_id, - if (GST_ELEMENT_PARENT(priv->confbin) - == GST_ELEMENT_PARENT(session->src)) { - GstPad *pad = gst_element_get_static_pad(session->tee, "sink"); -- GstPad *ghost = gst_ghost_pad_new(NULL, pad); -+ ghost = gst_ghost_pad_new(NULL, pad); - gst_object_unref(pad); - gst_pad_set_active(ghost, TRUE); - gst_element_add_pad(priv->confbin, ghost); -@@ -1310,6 +1329,8 @@ create_src(PurpleMediaBackendFs2 *self, const gchar *sess_id, - - gst_element_set_state(session->tee, GST_STATE_PLAYING); - gst_element_link(session->src, priv->confbin); -+ if (ghost) -+ session->srcpad = gst_pad_get_peer(ghost); - - g_object_get(session->session, "sink-pad", &sinkpad, NULL); - if (session->type & PURPLE_MEDIA_SEND_AUDIO) { -diff --git a/libpurple/mediamanager.c b/libpurple/mediamanager.c -index e6f8a46..584eb34 100644 ---- a/libpurple/mediamanager.c -+++ b/libpurple/mediamanager.c -@@ -400,6 +400,8 @@ request_pad_unlinked_cb(GstPad *pad, GstPad *peer, gpointer user_data) - GstIteratorResult result; - - gst_element_release_request_pad(GST_ELEMENT_PARENT(pad), pad); -+ gst_pad_set_blocked(pad, FALSE); -+ - iter = gst_element_iterate_src_pads(parent); - - result = gst_iterator_next(iter, (gpointer)&remaining_pad); --- -1.7.2.3 - diff --git a/contrib/media-patches/purple_media_get_active_candidates.patch b/contrib/media-patches/purple_media_get_active_candidates.patch deleted file mode 100644 index e507c919..00000000 --- a/contrib/media-patches/purple_media_get_active_candidates.patch +++ /dev/null @@ -1,48 +0,0 @@ -diff -ru pidgin-2.6.5/libpurple/media.c pidgin-2.6.5-patched/libpurple/media.c ---- pidgin-2.6.5/libpurple/media.c 2010-05-13 21:56:23.151991938 +0200 -+++ pidgin-2.6.5-patched/libpurple/media.c 2010-05-13 22:06:00.455752108 +0200 -@@ -2966,12 +2966,6 @@ - #endif - } - --#if 0 --/* -- * These two functions aren't being used and I'd rather not lock in the API -- * until they are needed. If they ever are. -- */ -- - GList * - purple_media_get_active_local_candidates(PurpleMedia *media, - const gchar *sess_id, const gchar *participant) -@@ -3001,7 +2995,6 @@ - return NULL; - #endif - } --#endif - - gboolean - purple_media_set_remote_codecs(PurpleMedia *media, const gchar *sess_id, -diff -ru pidgin-2.6.5/libpurple/media.h pidgin-2.6.5-patched/libpurple/media.h ---- pidgin-2.6.5/libpurple/media.h 2010-05-13 21:56:23.151991938 +0200 -+++ pidgin-2.6.5-patched/libpurple/media.h 2010-05-13 22:03:20.495755295 +0200 -@@ -520,12 +520,6 @@ - const gchar *sess_id, - const gchar *participant); - --#if 0 --/* -- * These two functions aren't being used and I'd rather not lock in the API -- * until they are needed. If they ever are. -- */ -- - /** - * Gets the active local candidates for the stream. - * -@@ -551,7 +545,6 @@ - */ - GList *purple_media_get_active_remote_candidates(PurpleMedia *media, - const gchar *sess_id, const gchar *participant); --#endif - - /** - * Sets remote candidates from the stream. -- 2.11.4.GIT