pidgin.vv: 8d9e0cb3: Make sharing sources between media sessi...
maiku at soc.pidgin.im
maiku at soc.pidgin.im
Mon Mar 30 18:07:15 EDT 2009
-----------------------------------------------------------------
Revision: 8d9e0cb37a09a393a8d0a05be8c2df7a38568961
Ancestor: c95a65b7b24deeab5f3c217a7f4ed0f8b422c3d3
Author: maiku at soc.pidgin.im
Date: 2009-03-30T22:00:35
Branch: im.pidgin.pidgin.vv
URL: http://d.pidgin.im/viewmtn/revision/info/8d9e0cb37a09a393a8d0a05be8c2df7a38568961
Modified files:
libpurple/media.c libpurple/mediamanager.c
ChangeLog:
Make sharing sources between media sessions work.
-------------- next part --------------
============================================================
--- libpurple/media.c e2991907b994729191cd32076089086cb50afecc
+++ libpurple/media.c b586b86e33379d00cc842076ec7ad27ba3ddda4c
@@ -1151,12 +1151,21 @@ purple_media_set_src(PurpleMedia *media,
gst_object_unref(session->src);
session->src = src;
gst_element_set_locked_state(session->src, TRUE);
- gst_bin_add(GST_BIN(session->media->priv->confbin),
- session->src);
session->tee = gst_element_factory_make("tee", NULL);
gst_bin_add(GST_BIN(session->media->priv->confbin), session->tee);
- gst_element_link(session->src, session->tee);
+
+ /* This supposedly isn't necessary, but it silences some warnings */
+ if (GST_ELEMENT_PARENT(session->media->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);
+ gst_object_unref(pad);
+ gst_pad_set_active(ghost, TRUE);
+ gst_element_add_pad(session->media->priv->confbin, ghost);
+ }
+
+ gst_element_link(session->src, session->media->priv->confbin);
gst_element_set_state(session->tee, GST_STATE_PLAYING);
g_object_get(session->session, "sink-pad", &sinkpad, NULL);
@@ -1165,6 +1174,7 @@ purple_media_set_src(PurpleMedia *media,
gst_pad_link(srcpad, sinkpad) == GST_PAD_LINK_OK
? "success" : "failure");
gst_element_set_locked_state(session->src, FALSE);
+ gst_object_unref(session->src);
}
#endif
============================================================
--- libpurple/mediamanager.c 09bdedc4750b6440f17c0accabf67ba26c7efc4a
+++ libpurple/mediamanager.c d41dccf3403ce64d5b40dc0263e83be2e605ef2f
@@ -328,29 +328,95 @@ purple_media_manager_remove_media(Purple
#endif
}
+#ifdef USE_VV
+static void
+request_pad_unlinked_cb(GstPad *pad, GstPad *peer, gpointer user_data)
+{
+ GstElement *parent = GST_ELEMENT_PARENT(pad);
+ GstIterator *iter;
+ GstPad *remaining_pad;
+
+ gst_element_release_request_pad(GST_ELEMENT_PARENT(pad), pad);
+ iter = gst_element_iterate_pads(parent);
+
+ if (gst_iterator_next(iter, (gpointer)&remaining_pad)
+ == GST_ITERATOR_DONE) {
+ gst_element_set_locked_state(parent, TRUE);
+ gst_element_set_state(parent, GST_STATE_NULL);
+ gst_bin_remove(GST_BIN(GST_ELEMENT_PARENT(parent)), parent);
+ }
+
+ gst_iterator_free(iter);
+}
+#endif
+
GstElement *
purple_media_manager_get_element(PurpleMediaManager *manager,
PurpleMediaSessionType type)
{
#ifdef USE_VV
GstElement *ret = NULL;
+ PurpleMediaElementInfo *info = NULL;
- /* TODO: If src, retrieve current src */
- /* TODO: Send a signal here to allow for overriding the source/sink */
+ if (type & PURPLE_MEDIA_SEND_AUDIO)
+ info = manager->priv->audio_src;
+ else if (type & PURPLE_MEDIA_RECV_AUDIO)
+ info = manager->priv->audio_sink;
+ else if (type & PURPLE_MEDIA_SEND_VIDEO)
+ info = manager->priv->video_src;
+ else if (type & PURPLE_MEDIA_RECV_VIDEO)
+ info = manager->priv->video_sink;
- if (type & PURPLE_MEDIA_SEND_AUDIO
- && manager->priv->audio_src != NULL)
- ret = manager->priv->audio_src->create();
- else if (type & PURPLE_MEDIA_RECV_AUDIO
- && manager->priv->audio_sink != NULL)
- ret = manager->priv->audio_sink->create();
- else if (type & PURPLE_MEDIA_SEND_VIDEO
- && manager->priv->video_src != NULL)
- ret = manager->priv->video_src->create();
- else if (type & PURPLE_MEDIA_RECV_VIDEO
- && manager->priv->video_sink != NULL)
- ret = manager->priv->video_sink->create();
+ if (info == NULL)
+ return NULL;
+ if (info->type & PURPLE_MEDIA_ELEMENT_UNIQUE &&
+ info->type & PURPLE_MEDIA_ELEMENT_SRC) {
+ GstElement *tee;
+ GstPad *pad;
+ GstPad *ghost;
+
+ ret = gst_bin_get_by_name(GST_BIN(
+ purple_media_manager_get_pipeline(
+ manager)), info->id);
+
+ if (ret == NULL) {
+ GstElement *bin, *fakesink;
+ ret = info->create();
+ bin = gst_bin_new(info->id);
+ tee = gst_element_factory_make("tee", "tee");
+ gst_bin_add_many(GST_BIN(bin), ret, tee, NULL);
+ gst_element_link(ret, tee);
+
+ /*
+ * This shouldn't be necessary, but it stops it from
+ * giving a not-linked error upon destruction
+ */
+ fakesink = gst_element_factory_make("fakesink", NULL);
+ g_object_set(fakesink, "sync", FALSE, NULL);
+ gst_bin_add(GST_BIN(bin), fakesink);
+ gst_element_link(tee, fakesink);
+
+ ret = bin;
+ gst_element_set_locked_state(ret, TRUE);
+ gst_object_ref(ret);
+ gst_bin_add(GST_BIN(purple_media_manager_get_pipeline(
+ manager)), ret);
+ }
+
+ tee = gst_bin_get_by_name(GST_BIN(ret), "tee");
+ pad = gst_element_get_request_pad(tee, "src%d");
+ gst_object_unref(tee);
+ ghost = gst_ghost_pad_new(NULL, pad);
+ gst_object_unref(pad);
+ g_signal_connect(GST_PAD(ghost), "unlinked",
+ G_CALLBACK(request_pad_unlinked_cb), NULL);
+ gst_pad_set_active(ghost, TRUE);
+ gst_element_add_pad(ret, ghost);
+ } else {
+ ret = info->create();
+ }
+
if (ret == NULL)
purple_debug_error("media", "Error creating source or sink\n");
More information about the Commits
mailing list