Mercurial > pidgin
comparison libpurple/media/backend-fs2.c @ 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 | a8cc50c2279f |
children | 66fe4bda9a85 |
comparison
equal
deleted
inserted
replaced
31104:43ab38a1f55c | 31105:0485aed45f5b |
---|---|
124 FsSession *session; | 124 FsSession *session; |
125 | 125 |
126 GstElement *src; | 126 GstElement *src; |
127 GstElement *tee; | 127 GstElement *tee; |
128 | 128 |
129 GstPad *srcpad; | |
130 | |
129 PurpleMediaSessionType type; | 131 PurpleMediaSessionType type; |
130 }; | 132 }; |
131 | 133 |
132 struct _PurpleMediaBackendFs2Private | 134 struct _PurpleMediaBackendFs2Private |
133 { | 135 { |
165 if (priv->confbin) { | 167 if (priv->confbin) { |
166 GstElement *pipeline; | 168 GstElement *pipeline; |
167 | 169 |
168 pipeline = purple_media_manager_get_pipeline( | 170 pipeline = purple_media_manager_get_pipeline( |
169 purple_media_get_manager(priv->media)); | 171 purple_media_get_manager(priv->media)); |
172 | |
173 /* All connections to media sources should be blocked before confbin is | |
174 * removed, to prevent freezing of any other simultaneously running | |
175 * media calls. */ | |
176 if (priv->sessions) { | |
177 GList *sessions = g_hash_table_get_values(priv->sessions); | |
178 for (; sessions; sessions = | |
179 g_list_delete_link(sessions, sessions)) { | |
180 PurpleMediaBackendFs2Session *session = sessions->data; | |
181 if (session->srcpad) { | |
182 gst_pad_set_blocked(session->srcpad, TRUE); | |
183 gst_object_unref(session->srcpad); | |
184 session->srcpad = NULL; | |
185 } | |
186 } | |
187 } | |
170 | 188 |
171 gst_element_set_locked_state(priv->confbin, TRUE); | 189 gst_element_set_locked_state(priv->confbin, TRUE); |
172 gst_element_set_state(GST_ELEMENT(priv->confbin), | 190 gst_element_set_state(GST_ELEMENT(priv->confbin), |
173 GST_STATE_NULL); | 191 GST_STATE_NULL); |
174 | 192 |
1256 FsMediaType media_type = session_type_to_fs_media_type(type); | 1274 FsMediaType media_type = session_type_to_fs_media_type(type); |
1257 FsStreamDirection type_direction = | 1275 FsStreamDirection type_direction = |
1258 session_type_to_fs_stream_direction(type); | 1276 session_type_to_fs_stream_direction(type); |
1259 GstElement *src; | 1277 GstElement *src; |
1260 GstPad *sinkpad, *srcpad; | 1278 GstPad *sinkpad, *srcpad; |
1279 GstPad *ghost = NULL; | |
1261 | 1280 |
1262 if ((type_direction & FS_DIRECTION_SEND) == 0) | 1281 if ((type_direction & FS_DIRECTION_SEND) == 0) |
1263 return TRUE; | 1282 return TRUE; |
1264 | 1283 |
1265 session_type = session_type_from_fs( | 1284 session_type = session_type_from_fs( |
1295 | 1314 |
1296 /* This supposedly isn't necessary, but it silences some warnings */ | 1315 /* This supposedly isn't necessary, but it silences some warnings */ |
1297 if (GST_ELEMENT_PARENT(priv->confbin) | 1316 if (GST_ELEMENT_PARENT(priv->confbin) |
1298 == GST_ELEMENT_PARENT(session->src)) { | 1317 == GST_ELEMENT_PARENT(session->src)) { |
1299 GstPad *pad = gst_element_get_static_pad(session->tee, "sink"); | 1318 GstPad *pad = gst_element_get_static_pad(session->tee, "sink"); |
1300 GstPad *ghost = gst_ghost_pad_new(NULL, pad); | 1319 ghost = gst_ghost_pad_new(NULL, pad); |
1301 gst_object_unref(pad); | 1320 gst_object_unref(pad); |
1302 gst_pad_set_active(ghost, TRUE); | 1321 gst_pad_set_active(ghost, TRUE); |
1303 gst_element_add_pad(priv->confbin, ghost); | 1322 gst_element_add_pad(priv->confbin, ghost); |
1304 } | 1323 } |
1305 | 1324 |
1306 gst_element_set_state(session->tee, GST_STATE_PLAYING); | 1325 gst_element_set_state(session->tee, GST_STATE_PLAYING); |
1307 gst_element_link(session->src, priv->confbin); | 1326 gst_element_link(session->src, priv->confbin); |
1327 if (ghost) | |
1328 session->srcpad = gst_pad_get_peer(ghost); | |
1308 | 1329 |
1309 g_object_get(session->session, "sink-pad", &sinkpad, NULL); | 1330 g_object_get(session->session, "sink-pad", &sinkpad, NULL); |
1310 if (session->type & PURPLE_MEDIA_SEND_AUDIO) { | 1331 if (session->type & PURPLE_MEDIA_SEND_AUDIO) { |
1311 gchar *name = g_strdup_printf("volume_%s", session->id); | 1332 gchar *name = g_strdup_printf("volume_%s", session->id); |
1312 GstElement *level; | 1333 GstElement *level; |