comparison libpurple/media.c @ 26152:7be8c88d630c

Have all media sessions use a single pipeline. This temporarily breaks the audio levels.
author Mike Ruprecht <maiku@soc.pidgin.im>
date Sat, 31 Jan 2009 05:19:16 +0000
parents 4f013819e4e3
children 4cbf594b2f17
comparison
equal deleted inserted replaced
26151:e6d548856fcd 26152:7be8c88d630c
90 GHashTable *participants; /* FsParticipant table */ 90 GHashTable *participants; /* FsParticipant table */
91 91
92 GList *streams; /* PurpleMediaStream table */ 92 GList *streams; /* PurpleMediaStream table */
93 93
94 GstElement *pipeline; 94 GstElement *pipeline;
95 95 GstElement *confbin;
96 }; 96 };
97 97
98 #define PURPLE_MEDIA_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), PURPLE_TYPE_MEDIA, PurpleMediaPrivate)) 98 #define PURPLE_MEDIA_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), PURPLE_TYPE_MEDIA, PurpleMediaPrivate))
99 99
100 static void purple_media_class_init (PurpleMediaClass *klass); 100 static void purple_media_class_init (PurpleMediaClass *klass);
268 purple_debug_info("media","purple_media_dispose\n"); 268 purple_debug_info("media","purple_media_dispose\n");
269 269
270 purple_media_manager_remove_media(purple_media_manager_get(), 270 purple_media_manager_remove_media(purple_media_manager_get(),
271 PURPLE_MEDIA(media)); 271 PURPLE_MEDIA(media));
272 272
273 if (priv->pipeline) { 273 if (priv->confbin) {
274 GstBus *bus = gst_pipeline_get_bus(GST_PIPELINE(priv->pipeline)); 274 gst_element_set_state(GST_ELEMENT(priv->confbin),
275 gst_bus_remove_signal_watch(bus); 275 GST_STATE_NULL);
276 gst_object_unref(bus); 276 gst_bin_remove(GST_BIN(priv->pipeline), priv->confbin);
277 gst_element_set_state(priv->pipeline, GST_STATE_NULL); 277 priv->confbin = NULL;
278 gst_object_unref(priv->pipeline); 278 priv->conference = NULL;
279 priv->pipeline = NULL;
280 } 279 }
281 280
282 for (iter = priv->streams; iter; iter = g_list_next(iter)) { 281 for (iter = priv->streams; iter; iter = g_list_next(iter)) {
283 PurpleMediaStream *stream = iter->data; 282 PurpleMediaStream *stream = iter->data;
284 if (stream->stream) { 283 if (stream->stream) {
322 purple_media_session_free(sessions->data); 321 purple_media_session_free(sessions->data);
323 } 322 }
324 g_hash_table_destroy(priv->sessions); 323 g_hash_table_destroy(priv->sessions);
325 } 324 }
326 325
327 gst_object_unref(priv->conference);
328
329 G_OBJECT_CLASS(parent_class)->finalize(media); 326 G_OBJECT_CLASS(parent_class)->finalize(media);
330 } 327 }
331 328
332 static void 329 static void
333 purple_media_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) 330 purple_media_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
336 g_return_if_fail(PURPLE_IS_MEDIA(object)); 333 g_return_if_fail(PURPLE_IS_MEDIA(object));
337 334
338 media = PURPLE_MEDIA(object); 335 media = PURPLE_MEDIA(object);
339 336
340 switch (prop_id) { 337 switch (prop_id) {
341 case PROP_CONFERENCE: 338 case PROP_CONFERENCE: {
339 gchar *name;
340
342 if (media->priv->conference) 341 if (media->priv->conference)
343 g_object_unref(media->priv->conference); 342 gst_object_unref(media->priv->conference);
344 media->priv->conference = g_value_get_object(value); 343 media->priv->conference = g_value_get_object(value);
345 g_object_ref(media->priv->conference); 344 gst_object_ref(media->priv->conference);
345
346 name = g_strdup_printf("conf_%p",
347 media->priv->conference);
348 media->priv->confbin = gst_bin_new(name);
349 g_free(name);
350 gst_bin_add(GST_BIN(purple_media_get_pipeline(media)),
351 media->priv->confbin);
352 gst_bin_add(GST_BIN(media->priv->confbin),
353 GST_ELEMENT(media->priv->conference));
354
355 gst_element_set_state(GST_ELEMENT(
356 media->priv->confbin),
357 GST_STATE_PLAYING);
346 break; 358 break;
359 }
347 case PROP_INITIATOR: 360 case PROP_INITIATOR:
348 media->priv->initiator = g_value_get_boolean(value); 361 media->priv->initiator = g_value_get_boolean(value);
349 break; 362 break;
350 default: 363 default:
351 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); 364 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
979 GstPad *srcpad; 992 GstPad *srcpad;
980 993
981 if (session->src) 994 if (session->src)
982 gst_object_unref(session->src); 995 gst_object_unref(session->src);
983 session->src = src; 996 session->src = src;
984 gst_bin_add(GST_BIN(purple_media_get_pipeline(media)), 997 gst_bin_add(GST_BIN(session->media->priv->confbin),
985 session->src); 998 session->src);
986 999
987 g_object_get(session->session, "sink-pad", &sinkpad, NULL); 1000 g_object_get(session->session, "sink-pad", &sinkpad, NULL);
988 srcpad = gst_element_get_static_pad(src, "ghostsrc"); 1001 srcpad = gst_element_get_static_pad(src, "ghostsrc");
989 purple_debug_info("media", "connecting pad: %s\n", 1002 purple_debug_info("media", "connecting pad: %s\n",
999 purple_media_get_stream(media, sess_id, participant); 1012 purple_media_get_stream(media, sess_id, participant);
1000 1013
1001 if (stream->sink) 1014 if (stream->sink)
1002 gst_object_unref(stream->sink); 1015 gst_object_unref(stream->sink);
1003 stream->sink = sink; 1016 stream->sink = sink;
1004 gst_bin_add(GST_BIN(purple_media_get_pipeline(media)), 1017 gst_bin_add(GST_BIN(stream->session->media->priv->confbin),
1005 stream->sink); 1018 stream->sink);
1006 } 1019 }
1007 1020
1008 GstElement * 1021 GstElement *
1009 purple_media_get_src(PurpleMedia *media, const gchar *sess_id) 1022 purple_media_get_src(PurpleMedia *media, const gchar *sess_id)
1088 0, NULL, NULL); 1101 0, NULL, NULL);
1089 } 1102 }
1090 } 1103 }
1091 1104
1092 static gboolean 1105 static gboolean
1093 media_bus_call(GstBus *bus, GstMessage *msg, gpointer media) 1106 media_bus_call(GstBus *bus, GstMessage *msg, gpointer dummy)
1094 { 1107 {
1095 switch(GST_MESSAGE_TYPE(msg)) { 1108 switch(GST_MESSAGE_TYPE(msg)) {
1096 case GST_MESSAGE_EOS: 1109 case GST_MESSAGE_EOS:
1097 purple_debug_info("media", "End of Stream\n"); 1110 purple_debug_info("media", "End of Stream\n");
1098 break; 1111 break;
1110 g_free (debug); 1123 g_free (debug);
1111 } 1124 }
1112 break; 1125 break;
1113 } 1126 }
1114 case GST_MESSAGE_ELEMENT: { 1127 case GST_MESSAGE_ELEMENT: {
1128 PurpleMedia *media = NULL;
1129 if (FS_IS_CONFERENCE(GST_MESSAGE_SRC(msg))) {
1130 GList *iter = purple_media_manager_get_media(
1131 purple_media_manager_get());
1132 for (; iter; iter = g_list_next(iter)) {
1133 if (PURPLE_MEDIA(iter->data)->priv->conference
1134 == FS_CONFERENCE(GST_MESSAGE_SRC(msg))) {
1135 media = iter->data;
1136 break;
1137 }
1138 }
1139 }
1140
1115 if (gst_structure_has_name(msg->structure, "farsight-error")) { 1141 if (gst_structure_has_name(msg->structure, "farsight-error")) {
1116 FsError error_no; 1142 FsError error_no;
1117 gst_structure_get_enum(msg->structure, "error-no", 1143 gst_structure_get_enum(msg->structure, "error-no",
1118 FS_TYPE_ERROR, (gint*)&error_no); 1144 FS_TYPE_ERROR, (gint*)&error_no);
1119 /* 1145 /*
1187 } 1213 }
1188 1214
1189 GstElement * 1215 GstElement *
1190 purple_media_get_pipeline(PurpleMedia *media) 1216 purple_media_get_pipeline(PurpleMedia *media)
1191 { 1217 {
1192 if (!media->priv->pipeline) { 1218 static GstElement *pipeline = NULL;
1219
1220 if (!pipeline) {
1193 GstBus *bus; 1221 GstBus *bus;
1194 media->priv->pipeline = gst_pipeline_new(NULL); 1222 media->priv->pipeline = pipeline = gst_pipeline_new(NULL);
1195 bus = gst_pipeline_get_bus(GST_PIPELINE(media->priv->pipeline)); 1223 bus = gst_pipeline_get_bus(GST_PIPELINE(media->priv->pipeline));
1196 gst_bus_add_signal_watch(GST_BUS(bus)); 1224 gst_bus_add_signal_watch(GST_BUS(bus));
1197 g_signal_connect(G_OBJECT(bus), "message", 1225 g_signal_connect(G_OBJECT(bus), "message",
1198 G_CALLBACK(media_bus_call), media); 1226 G_CALLBACK(media_bus_call), NULL);
1199 gst_bus_set_sync_handler(bus, gst_bus_sync_signal_handler, NULL); 1227 gst_bus_set_sync_handler(bus, gst_bus_sync_signal_handler, NULL);
1200 gst_object_unref(bus); 1228 gst_object_unref(bus);
1201 1229 gst_element_set_state(pipeline, GST_STATE_PLAYING);
1202 gst_bin_add(GST_BIN(media->priv->pipeline), GST_ELEMENT(media->priv->conference)); 1230 }
1203 } 1231
1204 1232 media->priv->pipeline = pipeline;
1205 return media->priv->pipeline; 1233 return media->priv->pipeline;
1206 } 1234 }
1207 1235
1208 void 1236 void
1209 purple_media_error(PurpleMedia *media, const gchar *error, ...) 1237 purple_media_error(PurpleMedia *media, const gchar *error, ...)
1543 1571
1544 if (stream->sink == NULL) 1572 if (stream->sink == NULL)
1545 stream->sink = purple_media_manager_get_element( 1573 stream->sink = purple_media_manager_get_element(
1546 purple_media_manager_get(), type); 1574 purple_media_manager_get(), type);
1547 1575
1548 gst_bin_add(GST_BIN(purple_media_get_pipeline(stream->session->media)), 1576 gst_bin_add(GST_BIN(stream->session->media->priv->confbin),
1549 stream->sink); 1577 stream->sink);
1550 sinkpad = gst_element_get_static_pad(stream->sink, "ghostsink"); 1578 sinkpad = gst_element_get_static_pad(stream->sink, "ghostsink");
1551 gst_pad_link(srcpad, sinkpad); 1579 gst_pad_link(srcpad, sinkpad);
1552 gst_element_set_state(stream->sink, GST_STATE_PLAYING); 1580 gst_element_set_state(stream->sink, GST_STATE_PLAYING);
1553 1581