Mercurial > pidgin.yaz
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 |