pidgin: a0565ad3: This patch fixes #12758.

rekkanoryo at pidgin.im rekkanoryo at pidgin.im
Fri Jan 7 22:05:50 EST 2011


----------------------------------------------------------------------
Revision: a0565ad3f3685a23a6b4e17e0197799f61d8f74e
Parent:   69a7107525200e51498ac5e48baaf043c4cd7b09
Author:   jakub.adam at ktknet.cz
Date:     01/07/11 21:13:40
Branch:   im.pidgin.pidgin
URL: http://d.pidgin.im/viewmtn/revision/info/a0565ad3f3685a23a6b4e17e0197799f61d8f74e

Changelog: 

This patch fixes #12758.

If the user starts two parallel video calls, then ends one of them some time
later, the user can still see and hear the participant from the non-ended call,
but the other participant no longer receives the user's video or audio.  The
problem lies in purple_media_backend_fs2_dispose(), which calls
gst_element_set_state() in such a way that the media sources stop sending data.

Additional reference information is mentioned on #12758, comment 6
(http://developer.pidgin.im/ticket/12758#comment:6).

Changes against parent 69a7107525200e51498ac5e48baaf043c4cd7b09

  patched  libpurple/media/backend-fs2.c
  patched  libpurple/mediamanager.c

-------------- next part --------------
============================================================
--- libpurple/mediamanager.c	e0222ef60f84976df8aeb38f7bcab68c7d89dd58
+++ libpurple/mediamanager.c	9819df92ea6ecba80a2bab6ed0c2061097073c10
@@ -400,6 +400,8 @@ request_pad_unlinked_cb(GstPad *pad, Gst
 	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);
============================================================
--- libpurple/media/backend-fs2.c	f7d2d8ff1b6e94fa251abf3bc6d78bf5c15fcfa7
+++ libpurple/media/backend-fs2.c	4e2b97e73f8d94fb94f6eda21941ef4ef3fdb366
@@ -126,6 +126,8 @@ struct _PurpleMediaBackendFs2Session
 	GstElement *src;
 	GstElement *tee;
 
+	GstPad *srcpad;
+
 	PurpleMediaSessionType type;
 };
 
@@ -168,6 +170,22 @@ purple_media_backend_fs2_dispose(GObject
 		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);
@@ -1258,6 +1276,7 @@ create_src(PurpleMediaBackendFs2 *self, 
 			session_type_to_fs_stream_direction(type);
 	GstElement *src;
 	GstPad *sinkpad, *srcpad;
+	GstPad *ghost = NULL;
 
 	if ((type_direction & FS_DIRECTION_SEND) == 0)
 		return TRUE;
@@ -1297,7 +1316,7 @@ create_src(PurpleMediaBackendFs2 *self, 
 	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);
@@ -1305,6 +1324,8 @@ create_src(PurpleMediaBackendFs2 *self, 
 
 	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) {


More information about the Commits mailing list