Thu, 16 Jun 2016 11:05:15 -0500
Merged in xhaakon/pidgin/release-2.x.y (pull request #52)
Backport of media patches from 3.0
| ChangeLog | file | annotate | diff | comparison | revisions |
--- a/ChangeLog Thu Jun 16 02:40:40 2016 -0300 +++ b/ChangeLog Thu Jun 16 11:05:15 2016 -0500 @@ -1,6 +1,12 @@ Pidgin and Finch: The Pimpin' Penguin IM Clients That're Good for the Soul version 2.10.13 (MM/DD/YY): + libpurple: + * media: fix an issue with ximagesink displaying only a corner cut-out of + a larger webcam video (Jakub Adam) + * mediamanager: update output window destruction so that it reflects recent + changes in the media pipeline structure (Jakub Adam) + Pidgin: * Fixed #14962 * Fixed alignment of incoming right-to-left messages in protocols that
--- a/libpurple/mediamanager.c Thu Jun 16 02:40:40 2016 -0300 +++ b/libpurple/mediamanager.c Thu Jun 16 11:05:15 2016 -0500 @@ -1449,7 +1449,7 @@ (participant == ow->participant)) && !strcmp(session_id, ow->session_id)) { GstBus *bus; - GstElement *queue, *convert; + GstElement *queue, *convert, *scale; GstElement *tee = purple_media_get_tee(media, session_id, participant); @@ -1462,6 +1462,7 @@ #else convert = gst_element_factory_make("ffmpegcolorspace", NULL); #endif + scale = gst_element_factory_make("videoscale", NULL); ow->sink = purple_media_manager_get_element( manager, PURPLE_MEDIA_RECV_VIDEO, ow->media, ow->session_id, @@ -1482,7 +1483,7 @@ } gst_bin_add_many(GST_BIN(GST_ELEMENT_PARENT(tee)), - queue, convert, ow->sink, NULL); + queue, convert, scale, ow->sink, NULL); bus = gst_pipeline_get_bus(GST_PIPELINE( manager->priv->pipeline)); @@ -1491,9 +1492,11 @@ gst_object_unref(bus); gst_element_set_state(ow->sink, GST_STATE_PLAYING); + gst_element_set_state(scale, GST_STATE_PLAYING); gst_element_set_state(convert, GST_STATE_PLAYING); gst_element_set_state(queue, GST_STATE_PLAYING); - gst_element_link(convert, ow->sink); + gst_element_link(scale, ow->sink); + gst_element_link(convert, scale); gst_element_link(queue, convert); gst_element_link(tee, queue); } @@ -1560,32 +1563,53 @@ return FALSE; if (output_window->sink != NULL) { - GstPad *pad = gst_element_get_static_pad( - output_window->sink, "sink"); - GstPad *peer = gst_pad_get_peer(pad); - GstElement *colorspace = GST_ELEMENT_PARENT(peer), *queue; - gst_object_unref(pad); - gst_object_unref(peer); - pad = gst_element_get_static_pad(colorspace, "sink"); - peer = gst_pad_get_peer(pad); - queue = GST_ELEMENT_PARENT(peer); - gst_object_unref(pad); - gst_object_unref(peer); - pad = gst_element_get_static_pad(queue, "sink"); - peer = gst_pad_get_peer(pad); - gst_object_unref(pad); - if (peer != NULL) - gst_element_release_request_pad(GST_ELEMENT_PARENT(peer), peer); - gst_element_set_locked_state(queue, TRUE); - gst_element_set_state(queue, GST_STATE_NULL); - gst_bin_remove(GST_BIN(GST_ELEMENT_PARENT(queue)), queue); - gst_element_set_locked_state(colorspace, TRUE); - gst_element_set_state(colorspace, GST_STATE_NULL); - gst_bin_remove(GST_BIN(GST_ELEMENT_PARENT(colorspace)), colorspace); - gst_element_set_locked_state(output_window->sink, TRUE); - gst_element_set_state(output_window->sink, GST_STATE_NULL); - gst_bin_remove(GST_BIN(GST_ELEMENT_PARENT(output_window->sink)), - output_window->sink); + GstElement *element = output_window->sink; + GstPad *teepad = NULL; + GSList *to_remove = NULL; + + /* Find the tee element this output is connected to. */ + while (!teepad) { + GstPad *pad; + GstPad *peer; + GstElementFactory *factory; + const gchar *factory_name; + + to_remove = g_slist_append(to_remove, element); + + pad = gst_element_get_static_pad(element, "sink"); + peer = gst_pad_get_peer(pad); + if (!peer) { + /* Output is disconnected from the pipeline. */ + gst_object_unref(pad); + break; + } + + factory = gst_element_get_factory(GST_PAD_PARENT(peer)); + factory_name = gst_plugin_feature_get_name(factory); + if (purple_strequal(factory_name, "tee")) { + teepad = peer; + } + + element = GST_PAD_PARENT(peer); + + gst_object_unref(pad); + gst_object_unref(peer); + } + + if (teepad) { + gst_element_release_request_pad(GST_PAD_PARENT(teepad), + teepad); + } + + while (to_remove) { + GstElement *element = to_remove->data; + + 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); + to_remove = g_slist_delete_link(to_remove, to_remove); + } } g_free(output_window->session_id);