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