pidgin: e247c79e: Allow adding or removing media sessions ...
rekkanoryo at pidgin.im
rekkanoryo at pidgin.im
Thu Mar 24 20:12:10 EDT 2011
----------------------------------------------------------------------
Revision: e247c79e5d292103eaa86a95c85fe11aa2a9ab18
Parent: 4ac2c53a02a28d532c23623c06465b14c0ff667b
Author: jakub.adam at ktknet.cz
Date: 03/24/11 19:02:12
Branch: im.pidgin.pidgin
URL: http://d.pidgin.im/viewmtn/revision/info/e247c79e5d292103eaa86a95c85fe11aa2a9ab18
Changelog:
Allow adding or removing media sessions (voice or video) on-the-fly. This
allows, for example, starting a call with only audio and adding video later,
followed by removing the audio component of the call.
Changes against parent 4ac2c53a02a28d532c23623c06465b14c0ff667b
patched libpurple/media/backend-fs2.c
-------------- next part --------------
============================================================
--- libpurple/media/backend-fs2.c 91b00b19579d6d6f26f50a86d6686ad9d76819c2
+++ libpurple/media/backend-fs2.c 9035de5df989f8cf4851bbf1680a753991621408
@@ -86,6 +86,9 @@ static gboolean purple_media_backend_fs2
PurpleMediaBackend *self, const gchar *sess_id,
PurpleMediaCodec *codec);
+static void free_stream(PurpleMediaBackendFs2Stream *stream);
+static void free_session(PurpleMediaBackendFs2Session *session);
+
struct _PurpleMediaBackendFs2Class
{
GObjectClass parent_class;
@@ -110,6 +113,8 @@ struct _PurpleMediaBackendFs2Stream
GstElement *tee;
GstElement *volume;
GstElement *level;
+ GstElement *fakesink;
+ GstElement *queue;
GList *local_candidates;
GList *remote_candidates;
@@ -300,20 +305,7 @@ purple_media_backend_fs2_finalize(GObjec
for (; priv->streams; priv->streams =
g_list_delete_link(priv->streams, priv->streams)) {
PurpleMediaBackendFs2Stream *stream = priv->streams->data;
-
- /* Remove the connected_cb timeout */
- if (stream->connected_cb_id != 0)
- purple_timeout_remove(stream->connected_cb_id);
-
- g_free(stream->participant);
-
- if (stream->local_candidates)
- fs_candidate_list_destroy(stream->local_candidates);
-
- if (stream->remote_candidates)
- fs_candidate_list_destroy(stream->remote_candidates);
-
- g_free(stream);
+ free_stream(stream);
}
if (priv->sessions) {
@@ -323,8 +315,7 @@ purple_media_backend_fs2_finalize(GObjec
g_list_delete_link(sessions, sessions)) {
PurpleMediaBackendFs2Session *session =
sessions->data;
- g_free(session->id);
- g_free(session);
+ free_session(session);
}
g_hash_table_destroy(priv->sessions);
@@ -1138,9 +1129,62 @@ static void
}
static void
+remove_element(GstElement *element)
+{
+ if (element) {
+ 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);
+ }
+}
+
+static void
state_changed_cb(PurpleMedia *media, PurpleMediaState state,
gchar *sid, gchar *name, PurpleMediaBackendFs2 *self)
{
+ if (state == PURPLE_MEDIA_STATE_END) {
+ PurpleMediaBackendFs2Private *priv =
+ PURPLE_MEDIA_BACKEND_FS2_GET_PRIVATE(self);
+
+ if (sid && name) {
+ PurpleMediaBackendFs2Stream *stream = get_stream(self, sid, name);
+ gst_object_unref(stream->stream);
+
+ priv->streams = g_list_remove(priv->streams, stream);
+
+ remove_element(stream->src);
+ remove_element(stream->tee);
+ remove_element(stream->volume);
+ remove_element(stream->level);
+ remove_element(stream->fakesink);
+ remove_element(stream->queue);
+
+ free_stream(stream);
+ } else if (sid && !name) {
+ PurpleMediaBackendFs2Session *session = get_session(self, sid);
+ GstPad *pad;
+
+ g_object_get(session->session, "sink-pad", &pad, NULL);
+ gst_pad_unlink(GST_PAD_PEER(pad), pad);
+ gst_object_unref(pad);
+
+ gst_object_unref(session->session);
+ g_hash_table_remove(priv->sessions, session->id);
+
+ pad = gst_pad_get_peer(session->srcpad);
+ gst_element_remove_pad(GST_ELEMENT_PARENT(pad), pad);
+ gst_object_unref(pad);
+ gst_object_unref(session->srcpad);
+
+ remove_element(session->srcvalve);
+ remove_element(session->tee);
+
+ free_session(session);
+ }
+
+ purple_media_manager_remove_output_windows(
+ purple_media_get_manager(media), media, sid, name);
+ }
}
static void
@@ -1420,6 +1464,7 @@ create_src(PurpleMediaBackendFs2 *self,
? "success" : "failure");
gst_element_set_locked_state(session->src, FALSE);
gst_object_unref(session->src);
+ gst_object_unref(sinkpad);
gst_element_set_state(session->src, GST_STATE_PLAYING);
@@ -1536,6 +1581,13 @@ create_session(PurpleMediaBackendFs2 *se
return TRUE;
}
+static void
+free_session(PurpleMediaBackendFs2Session *session)
+{
+ g_free(session->id);
+ g_free(session);
+}
+
static gboolean
create_participant(PurpleMediaBackendFs2 *self, const gchar *name)
{
@@ -1603,7 +1655,6 @@ src_pad_added_cb(FsStream *fsstream, Gst
GstElement *sink = NULL;
if (codec->media_type == FS_MEDIA_TYPE_AUDIO) {
- GstElement *queue = NULL;
double output_volume = purple_prefs_get_int(
"/purple/media/audio/volume/output")/10.0;
/*
@@ -1611,7 +1662,7 @@ src_pad_added_cb(FsStream *fsstream, Gst
* audioconvert ! audioresample ! liveadder !
* audioresample ! audioconvert ! realsink
*/
- queue = gst_element_factory_make("queue", NULL);
+ stream->queue = gst_element_factory_make("queue", NULL);
stream->volume = gst_element_factory_make(
"volume", NULL);
g_object_set(stream->volume, "volume",
@@ -1625,18 +1676,18 @@ src_pad_added_cb(FsStream *fsstream, Gst
PURPLE_MEDIA_RECV_AUDIO, priv->media,
stream->session->id,
stream->participant);
- gst_bin_add(GST_BIN(priv->confbin), queue);
+ gst_bin_add(GST_BIN(priv->confbin), stream->queue);
gst_bin_add(GST_BIN(priv->confbin), stream->volume);
gst_bin_add(GST_BIN(priv->confbin), stream->level);
gst_bin_add(GST_BIN(priv->confbin), sink);
gst_element_set_state(sink, GST_STATE_PLAYING);
gst_element_set_state(stream->level, GST_STATE_PLAYING);
gst_element_set_state(stream->volume, GST_STATE_PLAYING);
- gst_element_set_state(queue, GST_STATE_PLAYING);
+ gst_element_set_state(stream->queue, GST_STATE_PLAYING);
gst_element_link(stream->level, sink);
gst_element_link(stream->volume, stream->level);
- gst_element_link(queue, stream->volume);
- sink = queue;
+ gst_element_link(stream->queue, stream->volume);
+ sink = stream->queue;
} else if (codec->media_type == FS_MEDIA_TYPE_VIDEO) {
stream->src = gst_element_factory_make(
"fsfunnel", NULL);
@@ -1645,6 +1696,7 @@ src_pad_added_cb(FsStream *fsstream, Gst
g_object_set(G_OBJECT(sink), "async", FALSE, NULL);
gst_bin_add(GST_BIN(priv->confbin), sink);
gst_element_set_state(sink, GST_STATE_PLAYING);
+ stream->fakesink = sink;
}
stream->tee = gst_element_factory_make("tee", NULL);
gst_bin_add_many(GST_BIN(priv->confbin),
@@ -1814,6 +1866,24 @@ create_stream(PurpleMediaBackendFs2 *sel
return TRUE;
}
+static void
+free_stream(PurpleMediaBackendFs2Stream *stream)
+{
+ /* Remove the connected_cb timeout */
+ if (stream->connected_cb_id != 0)
+ purple_timeout_remove(stream->connected_cb_id);
+
+ g_free(stream->participant);
+
+ if (stream->local_candidates)
+ fs_candidate_list_destroy(stream->local_candidates);
+
+ if (stream->remote_candidates)
+ fs_candidate_list_destroy(stream->remote_candidates);
+
+ g_free(stream);
+}
+
static gboolean
purple_media_backend_fs2_add_stream(PurpleMediaBackend *self,
const gchar *sess_id, const gchar *who,
More information about the Commits
mailing list