static void pidgin_media_disconnect_levels(PurpleMedia *media, PidginMedia *gtkmedia) { PurpleMediaManager *manager = purple_media_get_manager(media); GstElement *element = purple_media_manager_get_pipeline(manager); gulong handler_id = g_signal_handler_find(G_OBJECT(gst_pipeline_get_bus(GST_PIPELINE(element))), G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, 0, 0, NULL, G_CALLBACK(level_message_cb), gtkmedia); if (handler_id) g_signal_handler_disconnect(G_OBJECT(gst_pipeline_get_bus(GST_PIPELINE(element))), handler_id); }
struct sipe_backend_media * sipe_backend_media_new(struct sipe_core_public *sipe_public, struct sipe_media_call *call, const gchar *participant, gboolean initiator) { struct sipe_backend_media *media = g_new0(struct sipe_backend_media, 1); struct sipe_backend_private *purple_private = sipe_public->backend_private; PurpleMediaManager *manager = purple_media_manager_get(); GstElement *pipeline; media->m = purple_media_manager_create_media(manager, purple_private->account, "fsrtpconference", participant, initiator); g_signal_connect(G_OBJECT(media->m), "candidates-prepared", G_CALLBACK(on_candidates_prepared_cb), call); g_signal_connect(G_OBJECT(media->m), "codecs-changed", G_CALLBACK(on_codecs_changed_cb), call); g_signal_connect(G_OBJECT(media->m), "stream-info", G_CALLBACK(on_stream_info_cb), call); g_signal_connect(G_OBJECT(media->m), "error", G_CALLBACK(on_error_cb), call); g_signal_connect(G_OBJECT(media->m), "state-changed", G_CALLBACK(on_state_changed_cb), call); /* On error, the pipeline is no longer in PLAYING state and libpurple * will not switch it back to PLAYING, preventing any more calls until * application restart. We switch the state ourselves here to negate * effect of any error in previous call (if any). */ pipeline = purple_media_manager_get_pipeline(manager); gst_element_set_state(pipeline, GST_STATE_PLAYING); return media; }
GstElement * purple_media_manager_get_element(PurpleMediaManager *manager, PurpleMediaSessionType type, PurpleMedia *media, const gchar *session_id, const gchar *participant) { #ifdef USE_VV GstElement *ret = NULL; PurpleMediaElementInfo *info = NULL; PurpleMediaElementType element_type; 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 (info == NULL) return NULL; element_type = purple_media_element_info_get_element_type(info); if (element_type & PURPLE_MEDIA_ELEMENT_UNIQUE && element_type & PURPLE_MEDIA_ELEMENT_SRC) { GstElement *tee; GstPad *pad; GstPad *ghost; gchar *id = purple_media_element_info_get_id(info); ret = gst_bin_get_by_name(GST_BIN( purple_media_manager_get_pipeline( manager)), id); if (ret == NULL) { GstElement *bin, *fakesink; ret = purple_media_element_info_call_create(info, media, session_id, participant); bin = gst_bin_new(id); tee = gst_element_factory_make("tee", "tee"); gst_bin_add_many(GST_BIN(bin), ret, tee, NULL); if (type & PURPLE_MEDIA_SEND_VIDEO) { GstElement *videoscale; GstElement *capsfilter; videoscale = gst_element_factory_make("videoscale", NULL); capsfilter = gst_element_factory_make("capsfilter", "prpl_video_caps"); g_object_set(G_OBJECT(capsfilter), "caps", purple_media_manager_get_video_caps(manager), NULL); gst_bin_add_many(GST_BIN(bin), videoscale, capsfilter, NULL); gst_element_link_many(ret, videoscale, capsfilter, tee, NULL); } else 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_object_ref(ret); gst_bin_add(GST_BIN(purple_media_manager_get_pipeline( manager)), ret); } g_free(id); 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 = purple_media_element_info_call_create(info, media, session_id, participant); } if (ret == NULL) purple_debug_error("media", "Error creating source or sink\n"); return ret; #else return NULL; #endif }
void capture_pipeline(const gchar *label) { PurpleMediaManager *manager = purple_media_manager_get(); GstElement *pipeline = purple_media_manager_get_pipeline(manager); GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS(GST_BIN(pipeline), GST_DEBUG_GRAPH_SHOW_ALL, label); }