Mercurial > pidgin
changeset 31105:0485aed45f5b
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).
committer: John Bailey <rekkanoryo@rekkanoryo.org>
author | jakub.adam@ktknet.cz |
---|---|
date | Sat, 08 Jan 2011 02:13:40 +0000 |
parents | 43ab38a1f55c |
children | a063e2a804ff |
files | libpurple/media/backend-fs2.c libpurple/mediamanager.c |
diffstat | 2 files changed, 24 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/libpurple/media/backend-fs2.c Fri Jan 07 11:42:13 2011 +0000 +++ b/libpurple/media/backend-fs2.c Sat Jan 08 02:13:40 2011 +0000 @@ -126,6 +126,8 @@ GstElement *src; GstElement *tee; + GstPad *srcpad; + PurpleMediaSessionType type; }; @@ -168,6 +170,22 @@ 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 @@ 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 @@ 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 @@ 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) {
--- a/libpurple/mediamanager.c Fri Jan 07 11:42:13 2011 +0000 +++ b/libpurple/mediamanager.c Sat Jan 08 02:13:40 2011 +0000 @@ -400,6 +400,8 @@ 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);