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,