Mercurial > pidgin
comparison libpurple/media/backend-fs2.c @ 29158:ae81f8baa148
Transfer some GStreamer message handling to the Farsight 2 media backend.
author | maiku@pidgin.im |
---|---|
date | Fri, 23 Oct 2009 19:59:12 +0000 |
parents | 2f8151fed0ae |
children | efeb21092ed2 |
comparison
equal
deleted
inserted
replaced
29157:e85df0170905 | 29158:ae81f8baa148 |
---|---|
24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA | 24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA |
25 */ | 25 */ |
26 | 26 |
27 #include "backend-fs2.h" | 27 #include "backend-fs2.h" |
28 | 28 |
29 #include "internal.h" | |
30 | |
29 #include "backend-iface.h" | 31 #include "backend-iface.h" |
30 #include "debug.h" | 32 #include "debug.h" |
31 #include "media-gst.h" | 33 #include "media-gst.h" |
32 | 34 |
33 #include <gst/farsight/fs-conference-iface.h> | 35 #include <gst/farsight/fs-conference-iface.h> |
255 purple_media_backend_fs2_get_local_candidates; | 257 purple_media_backend_fs2_get_local_candidates; |
256 iface->set_remote_codecs = purple_media_backend_fs2_set_remote_codecs; | 258 iface->set_remote_codecs = purple_media_backend_fs2_set_remote_codecs; |
257 iface->set_send_codec = purple_media_backend_fs2_set_send_codec; | 259 iface->set_send_codec = purple_media_backend_fs2_set_send_codec; |
258 } | 260 } |
259 | 261 |
262 static void | |
263 _gst_handle_message_element(GstBus *bus, GstMessage *msg, | |
264 PurpleMediaBackend *self) | |
265 { | |
266 PurpleMediaBackendFs2Private *priv = | |
267 PURPLE_MEDIA_BACKEND_FS2_GET_PRIVATE(self); | |
268 GstElement *src = GST_ELEMENT(GST_MESSAGE_SRC(msg)); | |
269 | |
270 if (!FS_IS_CONFERENCE(src) || !PURPLE_IS_MEDIA_BACKEND(self) || | |
271 priv->conference != FS_CONFERENCE(src)) | |
272 return; | |
273 | |
274 if (gst_structure_has_name(msg->structure, "farsight-error")) { | |
275 FsError error_no; | |
276 gst_structure_get_enum(msg->structure, "error-no", | |
277 FS_TYPE_ERROR, (gint*)&error_no); | |
278 switch (error_no) { | |
279 case FS_ERROR_NO_CODECS: | |
280 purple_media_error(priv->media, _("No codecs" | |
281 " found. Install some" | |
282 " GStreamer codecs found" | |
283 " in GStreamer plugins" | |
284 " packages.")); | |
285 purple_media_end(priv->media, NULL, NULL); | |
286 break; | |
287 case FS_ERROR_NO_CODECS_LEFT: | |
288 purple_media_error(priv->media, _("No codecs" | |
289 " left. Your codec" | |
290 " preferences in" | |
291 " fs-codecs.conf are too" | |
292 " strict.")); | |
293 purple_media_end(priv->media, NULL, NULL); | |
294 break; | |
295 case FS_ERROR_UNKNOWN_CNAME: | |
296 /* | |
297 * Unknown CName is only a problem for the | |
298 * multicast transmitter which isn't used. | |
299 * It is also deprecated. | |
300 */ | |
301 break; | |
302 default: | |
303 purple_debug_error("backend-fs2", | |
304 "farsight-error: %i: %s\n", | |
305 error_no, | |
306 gst_structure_get_string( | |
307 msg->structure, "error-msg")); | |
308 break; | |
309 } | |
310 | |
311 if (FS_ERROR_IS_FATAL(error_no)) { | |
312 purple_media_error(priv->media, _("A non-recoverable " | |
313 "Farsight2 error has occurred.")); | |
314 purple_media_end(priv->media, NULL, NULL); | |
315 } | |
316 } else if (gst_structure_has_name(msg->structure, | |
317 "farsight-new-local-candidate")) { | |
318 const GValue *value; | |
319 FsStream *stream; | |
320 FsCandidate *local_candidate; | |
321 #if 0 | |
322 PurpleMediaSession *session; | |
323 #endif | |
324 | |
325 value = gst_structure_get_value(msg->structure, "stream"); | |
326 stream = g_value_get_object(value); | |
327 value = gst_structure_get_value(msg->structure, "candidate"); | |
328 local_candidate = g_value_get_boxed(value); | |
329 #if 0 | |
330 session = purple_media_session_from_fs_stream(media, stream); | |
331 _new_local_candidate_cb(stream, local_candidate, session); | |
332 #endif | |
333 } else if (gst_structure_has_name(msg->structure, | |
334 "farsight-local-candidates-prepared")) { | |
335 const GValue *value; | |
336 FsStream *stream; | |
337 #if 0 | |
338 PurpleMediaSession *session; | |
339 #endif | |
340 | |
341 value = gst_structure_get_value(msg->structure, "stream"); | |
342 stream = g_value_get_object(value); | |
343 #if 0 | |
344 session = purple_media_session_from_fs_stream(media, stream); | |
345 _candidates_prepared_cb(stream, session); | |
346 #endif | |
347 } else if (gst_structure_has_name(msg->structure, | |
348 "farsight-new-active-candidate-pair")) { | |
349 const GValue *value; | |
350 FsStream *stream; | |
351 FsCandidate *local_candidate; | |
352 FsCandidate *remote_candidate; | |
353 #if 0 | |
354 PurpleMediaSession *session; | |
355 #endif | |
356 | |
357 value = gst_structure_get_value(msg->structure, "stream"); | |
358 stream = g_value_get_object(value); | |
359 value = gst_structure_get_value(msg->structure, | |
360 "local-candidate"); | |
361 local_candidate = g_value_get_boxed(value); | |
362 value = gst_structure_get_value(msg->structure, | |
363 "remote-candidate"); | |
364 remote_candidate = g_value_get_boxed(value); | |
365 #if 0 | |
366 session = purple_media_session_from_fs_stream(media, stream); | |
367 _candidate_pair_established_cb(stream, local_candidate, | |
368 remote_candidate, session); | |
369 #endif | |
370 } else if (gst_structure_has_name(msg->structure, | |
371 "farsight-recv-codecs-changed")) { | |
372 const GValue *value; | |
373 GList *codecs; | |
374 FsCodec *codec; | |
375 | |
376 value = gst_structure_get_value(msg->structure, "codecs"); | |
377 codecs = g_value_get_boxed(value); | |
378 codec = codecs->data; | |
379 | |
380 purple_debug_info("backend-fs2", | |
381 "farsight-recv-codecs-changed: %s\n", | |
382 codec->encoding_name); | |
383 } else if (gst_structure_has_name(msg->structure, | |
384 "farsight-component-state-changed")) { | |
385 const GValue *value; | |
386 FsStreamState fsstate; | |
387 guint component; | |
388 const gchar *state; | |
389 | |
390 value = gst_structure_get_value(msg->structure, "state"); | |
391 fsstate = g_value_get_enum(value); | |
392 value = gst_structure_get_value(msg->structure, "component"); | |
393 component = g_value_get_uint(value); | |
394 | |
395 switch (fsstate) { | |
396 case FS_STREAM_STATE_FAILED: | |
397 state = "FAILED"; | |
398 break; | |
399 case FS_STREAM_STATE_DISCONNECTED: | |
400 state = "DISCONNECTED"; | |
401 break; | |
402 case FS_STREAM_STATE_GATHERING: | |
403 state = "GATHERING"; | |
404 break; | |
405 case FS_STREAM_STATE_CONNECTING: | |
406 state = "CONNECTING"; | |
407 break; | |
408 case FS_STREAM_STATE_CONNECTED: | |
409 state = "CONNECTED"; | |
410 break; | |
411 case FS_STREAM_STATE_READY: | |
412 state = "READY"; | |
413 break; | |
414 default: | |
415 state = "UNKNOWN"; | |
416 break; | |
417 } | |
418 | |
419 purple_debug_info("backend-fs2", | |
420 "farsight-component-state-changed: " | |
421 "component: %u state: %s\n", | |
422 component, state); | |
423 } else if (gst_structure_has_name(msg->structure, | |
424 "farsight-send-codec-changed")) { | |
425 const GValue *value; | |
426 FsCodec *codec; | |
427 gchar *codec_str; | |
428 | |
429 value = gst_structure_get_value(msg->structure, "codec"); | |
430 codec = g_value_get_boxed(value); | |
431 codec_str = fs_codec_to_string(codec); | |
432 | |
433 purple_debug_info("backend-fs2", | |
434 "farsight-send-codec-changed: codec: %s\n", | |
435 codec_str); | |
436 | |
437 g_free(codec_str); | |
438 } else if (gst_structure_has_name(msg->structure, | |
439 "farsight-codecs-changed")) { | |
440 const GValue *value; | |
441 FsSession *fssession; | |
442 #if 0 | |
443 GList *sessions; | |
444 #endif | |
445 | |
446 value = gst_structure_get_value(msg->structure, "session"); | |
447 fssession = g_value_get_object(value); | |
448 #if 0 | |
449 sessions = g_hash_table_get_values(priv->sessions); | |
450 | |
451 for (; sessions; sessions = | |
452 g_list_delete_link(sessions, sessions)) { | |
453 PurpleMediaBackendFs2Session *session = sessions->data; | |
454 gchar *session_id; | |
455 | |
456 if (session->session != fssession) | |
457 continue; | |
458 | |
459 session_id = g_strdup(session->id); | |
460 g_signal_emit(media, | |
461 purple_media_backend_fs2_signals[ | |
462 CODECS_CHANGED], 0, session_id); | |
463 g_free(session_id); | |
464 g_list_free(sessions); | |
465 break; | |
466 } | |
467 #endif | |
468 } | |
469 } | |
470 | |
471 static void | |
472 _gst_handle_message_error(GstBus *bus, GstMessage *msg, | |
473 PurpleMediaBackend *self) | |
474 { | |
475 PurpleMediaBackendFs2Private *priv = | |
476 PURPLE_MEDIA_BACKEND_FS2_GET_PRIVATE(self); | |
477 GstElement *element = GST_ELEMENT(GST_MESSAGE_SRC(msg)); | |
478 GstElement *lastElement = NULL; | |
479 GList *sessions; | |
480 | |
481 while (!GST_IS_PIPELINE(element)) { | |
482 if (element == priv->confbin) | |
483 break; | |
484 | |
485 lastElement = element; | |
486 element = GST_ELEMENT_PARENT(element); | |
487 } | |
488 | |
489 if (!GST_IS_PIPELINE(element)) | |
490 return; | |
491 | |
492 sessions = purple_media_get_session_ids(priv->media); | |
493 | |
494 for (; sessions; sessions = g_list_delete_link(sessions, sessions)) { | |
495 if (purple_media_get_src(priv->media, sessions->data) | |
496 != lastElement) | |
497 continue; | |
498 | |
499 if (purple_media_get_session_type(priv->media, sessions->data) | |
500 & PURPLE_MEDIA_AUDIO) | |
501 purple_media_error(priv->media, | |
502 _("Error with your microphone")); | |
503 else | |
504 purple_media_error(priv->media, | |
505 _("Error with your webcam")); | |
506 | |
507 break; | |
508 } | |
509 | |
510 g_list_free(sessions); | |
511 | |
512 purple_media_error(priv->media, _("Conference error")); | |
513 purple_media_end(priv->media, NULL, NULL); | |
514 } | |
515 | |
260 static gboolean | 516 static gboolean |
261 _gst_bus_cb(GstBus *bus, GstMessage *msg, PurpleMediaBackend *self) | 517 _gst_bus_cb(GstBus *bus, GstMessage *msg, PurpleMediaBackend *self) |
262 { | 518 { |
519 switch(GST_MESSAGE_TYPE(msg)) { | |
520 case GST_MESSAGE_ELEMENT: | |
521 _gst_handle_message_element(bus, msg, self); | |
522 break; | |
523 case GST_MESSAGE_ERROR: | |
524 _gst_handle_message_error(bus, msg, self); | |
525 break; | |
526 default: | |
527 break; | |
528 } | |
529 | |
263 return TRUE; | 530 return TRUE; |
264 } | 531 } |
265 | 532 |
266 static void | 533 static void |
267 _state_changed_cb(PurpleMedia *media, PurpleMediaState state, | 534 _state_changed_cb(PurpleMedia *media, PurpleMediaState state, |