comparison libpurple/media.c @ 26114:730e760ca39f

Move pipeline creation into the media manager.
author Mike Ruprecht <maiku@soc.pidgin.im>
date Fri, 20 Feb 2009 08:36:07 +0000
parents fcfb7571515c
children 9b0761b77218
comparison
equal deleted inserted replaced
26113:9fcff08ce726 26114:730e760ca39f
92 GHashTable *sessions; /* PurpleMediaSession table */ 92 GHashTable *sessions; /* PurpleMediaSession table */
93 GHashTable *participants; /* FsParticipant table */ 93 GHashTable *participants; /* FsParticipant table */
94 94
95 GList *streams; /* PurpleMediaStream table */ 95 GList *streams; /* PurpleMediaStream table */
96 96
97 GstElement *pipeline;
98 GstElement *confbin; 97 GstElement *confbin;
99 }; 98 };
100 99
101 #define PURPLE_MEDIA_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), PURPLE_TYPE_MEDIA, PurpleMediaPrivate)) 100 #define PURPLE_MEDIA_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), PURPLE_TYPE_MEDIA, PurpleMediaPrivate))
102 101
112 static void purple_media_candidates_prepared_cb(FsStream *stream, 111 static void purple_media_candidates_prepared_cb(FsStream *stream,
113 PurpleMediaSession *session); 112 PurpleMediaSession *session);
114 static void purple_media_candidate_pair_established_cb(FsStream *stream, 113 static void purple_media_candidate_pair_established_cb(FsStream *stream,
115 FsCandidate *native_candidate, FsCandidate *remote_candidate, 114 FsCandidate *native_candidate, FsCandidate *remote_candidate,
116 PurpleMediaSession *session); 115 PurpleMediaSession *session);
116 static gboolean media_bus_call(GstBus *bus,
117 GstMessage *msg, PurpleMedia *media);
117 118
118 static GObjectClass *parent_class = NULL; 119 static GObjectClass *parent_class = NULL;
119 120
120 121
121 122
290 purple_media_manager_remove_media(priv->manager, PURPLE_MEDIA(media)); 291 purple_media_manager_remove_media(priv->manager, PURPLE_MEDIA(media));
291 292
292 if (priv->confbin) { 293 if (priv->confbin) {
293 gst_element_set_state(GST_ELEMENT(priv->confbin), 294 gst_element_set_state(GST_ELEMENT(priv->confbin),
294 GST_STATE_NULL); 295 GST_STATE_NULL);
295 gst_bin_remove(GST_BIN(priv->pipeline), priv->confbin); 296 gst_bin_remove(GST_BIN(purple_media_manager_get_pipeline(
297 priv->manager)), priv->confbin);
296 priv->confbin = NULL; 298 priv->confbin = NULL;
297 priv->conference = NULL; 299 priv->conference = NULL;
298 } 300 }
299 301
300 for (iter = priv->streams; iter; iter = g_list_next(iter)) { 302 for (iter = priv->streams; iter; iter = g_list_next(iter)) {
321 for (; participants; participants = g_list_delete_link(participants, participants)) 323 for (; participants; participants = g_list_delete_link(participants, participants))
322 g_object_unref(participants->data); 324 g_object_unref(participants->data);
323 } 325 }
324 326
325 if (priv->manager) { 327 if (priv->manager) {
328 GstElement *pipeline = purple_media_manager_get_pipeline(
329 priv->manager);
330 GstBus *bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline));
331 g_signal_handlers_disconnect_matched(G_OBJECT(bus),
332 G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA,
333 0, 0, 0, media_bus_call, media);
334 gst_object_unref(bus);
335
326 g_object_unref(priv->manager); 336 g_object_unref(priv->manager);
327 priv->manager = NULL; 337 priv->manager = NULL;
328 } 338 }
329 339
330 G_OBJECT_CLASS(parent_class)->finalize(media); 340 G_OBJECT_CLASS(parent_class)->finalize(media);
349 359
350 G_OBJECT_CLASS(parent_class)->finalize(media); 360 G_OBJECT_CLASS(parent_class)->finalize(media);
351 } 361 }
352 362
353 static void 363 static void
364 purple_media_setup_pipeline(PurpleMedia *media)
365 {
366 GstBus *bus;
367 gchar *name;
368 GstElement *pipeline;
369
370 if (media->priv->conference == NULL || media->priv->manager == NULL)
371 return;
372
373 pipeline = purple_media_manager_get_pipeline(media->priv->manager);
374
375 name = g_strdup_printf("conf_%p",
376 media->priv->conference);
377 media->priv->confbin = gst_bin_new(name);
378 g_free(name);
379
380 bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline));
381 g_signal_connect(G_OBJECT(bus), "message",
382 G_CALLBACK(media_bus_call), media);
383 gst_object_unref(bus);
384
385 gst_bin_add(GST_BIN(pipeline),
386 media->priv->confbin);
387 gst_bin_add(GST_BIN(media->priv->confbin),
388 GST_ELEMENT(media->priv->conference));
389 gst_element_set_state(GST_ELEMENT(media->priv->confbin),
390 GST_STATE_PLAYING);
391 }
392
393 static void
354 purple_media_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) 394 purple_media_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
355 { 395 {
356 PurpleMedia *media; 396 PurpleMedia *media;
357 g_return_if_fail(PURPLE_IS_MEDIA(object)); 397 g_return_if_fail(PURPLE_IS_MEDIA(object));
358 398
360 400
361 switch (prop_id) { 401 switch (prop_id) {
362 case PROP_MANAGER: 402 case PROP_MANAGER:
363 media->priv->manager = g_value_get_object(value); 403 media->priv->manager = g_value_get_object(value);
364 g_object_ref(media->priv->manager); 404 g_object_ref(media->priv->manager);
405
406 purple_media_setup_pipeline(media);
365 break; 407 break;
366 case PROP_CONFERENCE: { 408 case PROP_CONFERENCE: {
367 gchar *name;
368
369 if (media->priv->conference) 409 if (media->priv->conference)
370 gst_object_unref(media->priv->conference); 410 gst_object_unref(media->priv->conference);
371 media->priv->conference = g_value_get_object(value); 411 media->priv->conference = g_value_get_object(value);
372 gst_object_ref(media->priv->conference); 412 gst_object_ref(media->priv->conference);
373 413
374 name = g_strdup_printf("conf_%p", 414 purple_media_setup_pipeline(media);
375 media->priv->conference);
376 media->priv->confbin = gst_bin_new(name);
377 g_free(name);
378 gst_bin_add(GST_BIN(purple_media_get_pipeline(media)),
379 media->priv->confbin);
380 gst_bin_add(GST_BIN(media->priv->confbin),
381 GST_ELEMENT(media->priv->conference));
382
383 gst_element_set_state(GST_ELEMENT(
384 media->priv->confbin),
385 GST_STATE_PLAYING);
386 break; 415 break;
387 } 416 }
388 case PROP_INITIATOR: 417 case PROP_INITIATOR:
389 media->priv->initiator = g_value_get_boolean(value); 418 media->priv->initiator = g_value_get_boolean(value);
390 break; 419 break;
1201 0, NULL, NULL); 1230 0, NULL, NULL);
1202 } 1231 }
1203 } 1232 }
1204 1233
1205 static gboolean 1234 static gboolean
1206 media_bus_call(GstBus *bus, GstMessage *msg, PurpleMediaManager *manager) 1235 media_bus_call(GstBus *bus, GstMessage *msg, PurpleMedia *media)
1207 { 1236 {
1208 switch(GST_MESSAGE_TYPE(msg)) { 1237 switch(GST_MESSAGE_TYPE(msg)) {
1209 case GST_MESSAGE_EOS:
1210 purple_debug_info("media", "End of Stream\n");
1211 break;
1212 case GST_MESSAGE_ERROR: {
1213 gchar *debug = NULL;
1214 GError *err = NULL;
1215
1216 gst_message_parse_error(msg, &err, &debug);
1217
1218 purple_debug_error("media", "gst pipeline error: %s\n", err->message);
1219 g_error_free(err);
1220
1221 if (debug) {
1222 purple_debug_error("media", "Debug details: %s\n", debug);
1223 g_free (debug);
1224 }
1225 break;
1226 }
1227 case GST_MESSAGE_ELEMENT: { 1238 case GST_MESSAGE_ELEMENT: {
1228 PurpleMedia *media = NULL; 1239 if (!FS_IS_CONFERENCE(GST_MESSAGE_SRC(msg)) ||
1229 if (FS_IS_CONFERENCE(GST_MESSAGE_SRC(msg))) { 1240 !PURPLE_IS_MEDIA(media) ||
1230 GList *iter = purple_media_manager_get_media( 1241 media->priv->conference !=
1231 manager); 1242 FS_CONFERENCE(GST_MESSAGE_SRC(msg)))
1232 for (; iter; iter = g_list_next(iter)) { 1243 break;
1233 if (PURPLE_MEDIA(iter->data)->priv->conference
1234 == FS_CONFERENCE(GST_MESSAGE_SRC(msg))) {
1235 media = iter->data;
1236 break;
1237 }
1238 }
1239
1240 if (!PURPLE_IS_MEDIA(media))
1241 break;
1242 }
1243 1244
1244 if (gst_structure_has_name(msg->structure, "farsight-error")) { 1245 if (gst_structure_has_name(msg->structure, "farsight-error")) {
1245 FsError error_no; 1246 FsError error_no;
1246 gst_structure_get_enum(msg->structure, "error-no", 1247 gst_structure_get_enum(msg->structure, "error-no",
1247 FS_TYPE_ERROR, (gint*)&error_no); 1248 FS_TYPE_ERROR, (gint*)&error_no);
1345 } 1346 }
1346 1347
1347 GstElement * 1348 GstElement *
1348 purple_media_get_pipeline(PurpleMedia *media) 1349 purple_media_get_pipeline(PurpleMedia *media)
1349 { 1350 {
1350 static GstElement *pipeline = NULL;
1351
1352 g_return_val_if_fail(PURPLE_IS_MEDIA(media), NULL); 1351 g_return_val_if_fail(PURPLE_IS_MEDIA(media), NULL);
1353 1352
1354 if (!pipeline) { 1353 return purple_media_manager_get_pipeline(media->priv->manager);
1355 GstBus *bus;
1356 media->priv->pipeline = pipeline = gst_pipeline_new(NULL);
1357 bus = gst_pipeline_get_bus(GST_PIPELINE(media->priv->pipeline));
1358 gst_bus_add_signal_watch(GST_BUS(bus));
1359 g_signal_connect(G_OBJECT(bus), "message",
1360 G_CALLBACK(media_bus_call),
1361 media->priv->manager);
1362 gst_bus_set_sync_handler(bus, gst_bus_sync_signal_handler, NULL);
1363 gst_object_unref(bus);
1364 gst_element_set_state(pipeline, GST_STATE_PLAYING);
1365 }
1366
1367 media->priv->pipeline = pipeline;
1368 return media->priv->pipeline;
1369 } 1354 }
1370 1355
1371 void 1356 void
1372 purple_media_error(PurpleMedia *media, const gchar *error, ...) 1357 purple_media_error(PurpleMedia *media, const gchar *error, ...)
1373 { 1358 {
2401 data = g_new0(PurpleMediaXOverlayData, 1); 2386 data = g_new0(PurpleMediaXOverlayData, 1);
2402 data->name = name; 2387 data->name = name;
2403 data->window_id = window_id; 2388 data->window_id = window_id;
2404 2389
2405 bus = gst_pipeline_get_bus(GST_PIPELINE( 2390 bus = gst_pipeline_get_bus(GST_PIPELINE(
2406 purple_media_get_pipeline(media))); 2391 purple_media_manager_get_pipeline(
2392 media->priv->manager)));
2407 data->handler_id = g_signal_connect(bus, 2393 data->handler_id = g_signal_connect(bus,
2408 "sync-message::element", 2394 "sync-message::element",
2409 G_CALLBACK(window_id_cb), data); 2395 G_CALLBACK(window_id_cb), data);
2410 gst_object_unref(bus); 2396 gst_object_unref(bus);
2411 2397
2494 data = g_new0(PurpleMediaXOverlayData, 1); 2480 data = g_new0(PurpleMediaXOverlayData, 1);
2495 data->name = name; 2481 data->name = name;
2496 data->window_id = window_id; 2482 data->window_id = window_id;
2497 2483
2498 bus = gst_pipeline_get_bus(GST_PIPELINE( 2484 bus = gst_pipeline_get_bus(GST_PIPELINE(
2499 purple_media_get_pipeline(media))); 2485 purple_media_manager_get_pipeline(
2486 media->priv->manager)));
2500 data->handler_id = g_signal_connect(bus, 2487 data->handler_id = g_signal_connect(bus,
2501 "sync-message::element", 2488 "sync-message::element",
2502 G_CALLBACK(window_id_cb), data); 2489 G_CALLBACK(window_id_cb), data);
2503 gst_object_unref(bus); 2490 gst_object_unref(bus);
2504 2491