comparison libpurple/media.c @ 26044:b04508e5cc6c

merge of 'd43b253ca7568a3f07aa77bf397fe4351db73a90' and 'dcc53c9783aecbdde6269c4310ec4b0cf511bd9e'
author Marcus Lundblad <ml@update.uu.se>
date Mon, 12 Jan 2009 19:27:55 +0000
parents e5f9cf20c4aa 5275c7ef9edf
children 62b41bb71a60
comparison
equal deleted inserted replaced
26043:e5f9cf20c4aa 26044:b04508e5cc6c
237 G_TYPE_NONE, 0); 237 G_TYPE_NONE, 0);
238 purple_media_signals[NEW_CANDIDATE] = g_signal_new("new-candidate", G_TYPE_FROM_CLASS(klass), 238 purple_media_signals[NEW_CANDIDATE] = g_signal_new("new-candidate", G_TYPE_FROM_CLASS(klass),
239 G_SIGNAL_RUN_LAST, 0, NULL, NULL, 239 G_SIGNAL_RUN_LAST, 0, NULL, NULL,
240 purple_smarshal_VOID__POINTER_POINTER_OBJECT, 240 purple_smarshal_VOID__POINTER_POINTER_OBJECT,
241 G_TYPE_NONE, 3, G_TYPE_POINTER, 241 G_TYPE_NONE, 3, G_TYPE_POINTER,
242 G_TYPE_POINTER, FS_TYPE_CANDIDATE); 242 G_TYPE_POINTER, PURPLE_TYPE_MEDIA_CANDIDATE);
243 purple_media_signals[CANDIDATES_PREPARED] = g_signal_new("candidates-prepared", G_TYPE_FROM_CLASS(klass), 243 purple_media_signals[CANDIDATES_PREPARED] = g_signal_new("candidates-prepared", G_TYPE_FROM_CLASS(klass),
244 G_SIGNAL_RUN_LAST, 0, NULL, NULL, 244 G_SIGNAL_RUN_LAST, 0, NULL, NULL,
245 purple_smarshal_VOID__STRING_STRING, 245 purple_smarshal_VOID__STRING_STRING,
246 G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_STRING); 246 G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_STRING);
247 purple_media_signals[CANDIDATE_PAIR] = g_signal_new("candidate-pair", G_TYPE_FROM_CLASS(klass), 247 purple_media_signals[CANDIDATE_PAIR] = g_signal_new("candidate-pair", G_TYPE_FROM_CLASS(klass),
248 G_SIGNAL_RUN_LAST, 0, NULL, NULL, 248 G_SIGNAL_RUN_LAST, 0, NULL, NULL,
249 purple_smarshal_VOID__BOXED_BOXED, 249 purple_smarshal_VOID__BOXED_BOXED,
250 G_TYPE_NONE, 2, FS_TYPE_CANDIDATE, FS_TYPE_CANDIDATE); 250 G_TYPE_NONE, 2, PURPLE_TYPE_MEDIA_CANDIDATE,
251 PURPLE_TYPE_MEDIA_CANDIDATE);
251 purple_media_signals[CODECS_READY] = g_signal_new("codecs-ready", G_TYPE_FROM_CLASS(klass), 252 purple_media_signals[CODECS_READY] = g_signal_new("codecs-ready", G_TYPE_FROM_CLASS(klass),
252 G_SIGNAL_RUN_LAST, 0, NULL, NULL, 253 G_SIGNAL_RUN_LAST, 0, NULL, NULL,
253 g_cclosure_marshal_VOID__STRING, 254 g_cclosure_marshal_VOID__STRING,
254 G_TYPE_NONE, 1, G_TYPE_STRING); 255 G_TYPE_NONE, 1, G_TYPE_STRING);
255 purple_media_signals[READY_NEW] = g_signal_new("ready-new", G_TYPE_FROM_CLASS(klass), 256 purple_media_signals[READY_NEW] = g_signal_new("ready-new", G_TYPE_FROM_CLASS(klass),
411 break; 412 break;
412 } 413 }
413 414
414 } 415 }
415 416
417 PurpleMediaCandidate *
418 purple_media_candidate_new(const gchar *foundation, guint component_id,
419 PurpleMediaCandidateType type,
420 PurpleMediaNetworkProtocol proto,
421 const gchar *ip, guint port)
422 {
423 PurpleMediaCandidate *candidate = g_new0(PurpleMediaCandidate, 1);
424 candidate->foundation = g_strdup(foundation);
425 candidate->component_id = component_id;
426 candidate->type = type;
427 candidate->proto = proto;
428 candidate->ip = g_strdup(ip);
429 candidate->port = port;
430 return candidate;
431 }
432
433 static PurpleMediaCandidate *
434 purple_media_candidate_copy(PurpleMediaCandidate *candidate)
435 {
436 PurpleMediaCandidate *new_candidate;
437
438 if (candidate == NULL)
439 return NULL;
440
441 new_candidate = g_new0(PurpleMediaCandidate, 1);
442 new_candidate->foundation = g_strdup(candidate->foundation);
443 new_candidate->component_id = candidate->component_id;
444 new_candidate->ip = g_strdup(candidate->ip);
445 new_candidate->port = candidate->port;
446 new_candidate->base_ip = g_strdup(candidate->base_ip);
447 new_candidate->base_port = candidate->base_port;
448 new_candidate->proto = candidate->proto;
449 new_candidate->priority = candidate->priority;
450 new_candidate->type = candidate->type;
451 new_candidate->username = g_strdup(candidate->username);
452 new_candidate->password = g_strdup(candidate->password);
453 new_candidate->ttl = candidate->ttl;
454 return new_candidate;
455 }
456
457 static void
458 purple_media_candidate_free(PurpleMediaCandidate *candidate)
459 {
460 if (candidate == NULL)
461 return;
462
463 g_free((gchar*)candidate->foundation);
464 g_free((gchar*)candidate->ip);
465 g_free((gchar*)candidate->base_ip);
466 g_free((gchar*)candidate->username);
467 g_free((gchar*)candidate->password);
468 g_free(candidate);
469 }
470
471 static FsCandidate *
472 purple_media_candidate_to_fs(PurpleMediaCandidate *candidate)
473 {
474 FsCandidate *fscandidate;
475
476 if (candidate == NULL)
477 return NULL;
478
479 fscandidate = fs_candidate_new(candidate->foundation,
480 candidate->component_id, candidate->type,
481 candidate->proto, candidate->ip, candidate->port);
482
483 fscandidate->base_ip = g_strdup(candidate->base_ip);
484 fscandidate->base_port = candidate->base_port;
485 fscandidate->priority = candidate->priority;
486 fscandidate->username = g_strdup(candidate->username);
487 fscandidate->password = g_strdup(candidate->password);
488 fscandidate->ttl = candidate->ttl;
489 return fscandidate;
490 }
491
492 static PurpleMediaCandidate *
493 purple_media_candidate_from_fs(FsCandidate *fscandidate)
494 {
495 PurpleMediaCandidate *candidate;
496
497 if (fscandidate == NULL)
498 return NULL;
499
500 candidate = purple_media_candidate_new(fscandidate->foundation,
501 fscandidate->component_id, fscandidate->type,
502 fscandidate->proto, fscandidate->ip, fscandidate->port);
503 candidate->base_ip = g_strdup(fscandidate->base_ip);
504 candidate->base_port = fscandidate->base_port;
505 candidate->priority = fscandidate->priority;
506 candidate->username = g_strdup(fscandidate->username);
507 candidate->password = g_strdup(fscandidate->password);
508 candidate->ttl = fscandidate->ttl;
509 return candidate;
510 }
511
512 static GList *
513 purple_media_candidate_list_from_fs(GList *candidates)
514 {
515 GList *new_list = NULL;
516
517 for (; candidates; candidates = g_list_next(candidates)) {
518 new_list = g_list_prepend(new_list,
519 purple_media_candidate_from_fs(
520 candidates->data));
521 }
522
523 new_list = g_list_reverse(new_list);
524 return new_list;
525 }
526
527 static GList *
528 purple_media_candidate_list_to_fs(GList *candidates)
529 {
530 GList *new_list = NULL;
531
532 for (; candidates; candidates = g_list_next(candidates)) {
533 new_list = g_list_prepend(new_list,
534 purple_media_candidate_to_fs(
535 candidates->data));
536 }
537
538 new_list = g_list_reverse(new_list);
539 return new_list;
540 }
541
542 GList *
543 purple_media_candidate_list_copy(GList *candidates)
544 {
545 GList *new_list = NULL;
546
547 for (; candidates; candidates = g_list_next(candidates)) {
548 new_list = g_list_prepend(new_list, g_boxed_copy(
549 PURPLE_TYPE_MEDIA_CANDIDATE,
550 candidates->data));
551 }
552
553 new_list = g_list_reverse(new_list);
554 return new_list;
555 }
556
557 void
558 purple_media_candidate_list_free(GList *candidates)
559 {
560 for (; candidates; candidates =
561 g_list_delete_link(candidates, candidates)) {
562 g_boxed_free(PURPLE_TYPE_MEDIA_CANDIDATE,
563 candidates->data);
564 }
565 }
566
567 GType
568 purple_media_candidate_get_type()
569 {
570 static GType type = 0;
571
572 if (type == 0) {
573 type = g_boxed_type_register_static("PurpleMediaCandidate",
574 (GBoxedCopyFunc)purple_media_candidate_copy,
575 (GBoxedFreeFunc)purple_media_candidate_free);
576 }
577 return type;
578 }
579
416 static FsMediaType 580 static FsMediaType
417 purple_media_to_fs_media_type(PurpleMediaSessionType type) 581 purple_media_to_fs_media_type(PurpleMediaSessionType type)
418 { 582 {
419 if (type & PURPLE_MEDIA_AUDIO) 583 if (type & PURPLE_MEDIA_AUDIO)
420 return FS_MEDIA_TYPE_AUDIO; 584 return FS_MEDIA_TYPE_AUDIO;
455 if (direction & FS_DIRECTION_RECV) 619 if (direction & FS_DIRECTION_RECV)
456 result |= PURPLE_MEDIA_RECV_VIDEO; 620 result |= PURPLE_MEDIA_RECV_VIDEO;
457 } 621 }
458 return result; 622 return result;
459 } 623 }
624
625 void
626 purple_media_codec_add_optional_parameter(PurpleMediaCodec *codec,
627 const gchar *name, const gchar *value)
628 {
629 PurpleMediaCodecParameter *new_param;
630
631 g_return_if_fail(name != NULL && value != NULL);
632
633 new_param = g_new0(PurpleMediaCodecParameter, 1);
634 new_param->name = g_strdup(name);
635 new_param->value = g_strdup(value);
636 codec->optional_params = g_list_append(
637 codec->optional_params, new_param);
638 }
639
640 void
641 purple_media_codec_remove_optional_parameter(PurpleMediaCodec *codec,
642 PurpleMediaCodecParameter *param)
643 {
644 g_free(param->name);
645 g_free(param->value);
646 g_free(param);
647 codec->optional_params =
648 g_list_remove(codec->optional_params, param);
649 }
650
651 PurpleMediaCodecParameter *
652 purple_media_codec_get_optional_parameter(PurpleMediaCodec *codec,
653 const gchar *name, const gchar *value)
654 {
655 GList *iter;
656
657 g_return_val_if_fail(codec != NULL, NULL);
658 g_return_val_if_fail(name != NULL, NULL);
659
660 for (iter = codec->optional_params; iter; iter = g_list_next(iter)) {
661 PurpleMediaCodecParameter *param = iter->data;
662 if (!g_ascii_strcasecmp(param->name, name) &&
663 (value == NULL ||
664 !g_ascii_strcasecmp(param->value, value)))
665 return param;
666 }
667
668 return NULL;
669 }
670
671 PurpleMediaCodec *
672 purple_media_codec_new(int id, const char *encoding_name,
673 PurpleMediaSessionType media_type, guint clock_rate)
674 {
675 PurpleMediaCodec *codec = g_new0(PurpleMediaCodec, 1);
676
677 codec->id = id;
678 codec->encoding_name = g_strdup(encoding_name);
679 codec->media_type = media_type;
680 codec->clock_rate = clock_rate;
681 return codec;
682 }
683
684 static PurpleMediaCodec *
685 purple_media_codec_copy(PurpleMediaCodec *codec)
686 {
687 PurpleMediaCodec *new_codec;
688 GList *iter;
689
690 if (codec == NULL)
691 return NULL;
692
693 new_codec = purple_media_codec_new(codec->id, codec->encoding_name,
694 codec->media_type, codec->clock_rate);
695 new_codec->channels = codec->channels;
696
697 for (iter = codec->optional_params; iter; iter = g_list_next(iter)) {
698 PurpleMediaCodecParameter *param =
699 (PurpleMediaCodecParameter*)iter->data;
700 purple_media_codec_add_optional_parameter(new_codec,
701 param->name, param->value);
702 }
703
704 return new_codec;
705 }
706
707 static void
708 purple_media_codec_free(PurpleMediaCodec *codec)
709 {
710 if (codec == NULL)
711 return;
712
713 g_free(codec->encoding_name);
714
715 for (; codec->optional_params; codec->optional_params =
716 g_list_delete_link(codec->optional_params,
717 codec->optional_params)) {
718 purple_media_codec_remove_optional_parameter(codec,
719 codec->optional_params->data);
720 }
721
722 g_free(codec);
723 }
724
725 static FsCodec *
726 purple_media_codec_to_fs(const PurpleMediaCodec *codec)
727 {
728 FsCodec *new_codec;
729 GList *iter;
730
731 if (codec == NULL)
732 return NULL;
733
734 new_codec = fs_codec_new(codec->id, codec->encoding_name,
735 purple_media_to_fs_media_type(codec->media_type),
736 codec->clock_rate);
737 new_codec->channels = codec->channels;
738
739 for (iter = codec->optional_params; iter; iter = g_list_next(iter)) {
740 PurpleMediaCodecParameter *param =
741 (PurpleMediaCodecParameter*)iter->data;
742 fs_codec_add_optional_parameter(new_codec,
743 param->name, param->value);
744 }
745
746 return new_codec;
747 }
748
749 static PurpleMediaCodec *
750 purple_media_codec_from_fs(const FsCodec *codec)
751 {
752 PurpleMediaCodec *new_codec;
753 GList *iter;
754
755 if (codec == NULL)
756 return NULL;
757
758 new_codec = purple_media_codec_new(codec->id, codec->encoding_name,
759 purple_media_from_fs(codec->media_type,
760 FS_DIRECTION_BOTH), codec->clock_rate);
761 new_codec->channels = codec->channels;
762
763 for (iter = codec->optional_params; iter; iter = g_list_next(iter)) {
764 FsCodecParameter *param = (FsCodecParameter*)iter->data;
765 purple_media_codec_add_optional_parameter(new_codec,
766 param->name, param->value);
767 }
768
769 return new_codec;
770 }
771
772 gchar *
773 purple_media_codec_to_string(const PurpleMediaCodec *codec)
774 {
775 FsCodec *fscodec = purple_media_codec_to_fs(codec);
776 gchar *str = fs_codec_to_string(fscodec);
777 fs_codec_destroy(fscodec);
778 return str;
779 }
780
781 static GList *
782 purple_media_codec_list_from_fs(GList *codecs)
783 {
784 GList *new_list = NULL;
785
786 for (; codecs; codecs = g_list_next(codecs)) {
787 new_list = g_list_prepend(new_list,
788 purple_media_codec_from_fs(
789 codecs->data));
790 }
791
792 new_list = g_list_reverse(new_list);
793 return new_list;
794 }
795
796 static GList *
797 purple_media_codec_list_to_fs(GList *codecs)
798 {
799 GList *new_list = NULL;
800
801 for (; codecs; codecs = g_list_next(codecs)) {
802 new_list = g_list_prepend(new_list,
803 purple_media_codec_to_fs(
804 codecs->data));
805 }
806
807 new_list = g_list_reverse(new_list);
808 return new_list;
809 }
810
811 GList *
812 purple_media_codec_list_copy(GList *codecs)
813 {
814 GList *new_list = NULL;
815
816 for (; codecs; codecs = g_list_next(codecs)) {
817 new_list = g_list_prepend(new_list, g_boxed_copy(
818 PURPLE_TYPE_MEDIA_CODEC,
819 codecs->data));
820 }
821
822 new_list = g_list_reverse(new_list);
823 return new_list;
824 }
825
826 void
827 purple_media_codec_list_free(GList *codecs)
828 {
829 for (; codecs; codecs =
830 g_list_delete_link(codecs, codecs)) {
831 g_boxed_free(PURPLE_TYPE_MEDIA_CODEC,
832 codecs->data);
833 }
834 }
835
836 GType
837 purple_media_codec_get_type()
838 {
839 static GType type = 0;
840
841 if (type == 0) {
842 type = g_boxed_type_register_static("PurpleMediaCodec",
843 (GBoxedCopyFunc)purple_media_codec_copy,
844 (GBoxedFreeFunc)purple_media_codec_free);
845 }
846 return type;
847 }
848
849
460 850
461 PurpleMediaSessionType 851 PurpleMediaSessionType
462 purple_media_get_overall_type(PurpleMedia *media) 852 purple_media_get_overall_type(PurpleMedia *media)
463 { 853 {
464 GList *values = g_hash_table_get_values(media->priv->sessions); 854 GList *values = g_hash_table_get_values(media->priv->sessions);
1067 GstPad *pad; 1457 GstPad *pad;
1068 GstPad *ghost; 1458 GstPad *ghost;
1069 const gchar *audio_device = purple_prefs_get_string("/purple/media/audio/device"); 1459 const gchar *audio_device = purple_prefs_get_string("/purple/media/audio/device");
1070 double input_volume = purple_prefs_get_int("/purple/media/audio/volume/input")/10.0; 1460 double input_volume = purple_prefs_get_int("/purple/media/audio/volume/input")/10.0;
1071 1461
1072 purple_debug_info("media", "purple_media_audio_init_src\n");
1073
1074 *sendbin = gst_bin_new("purplesendaudiobin"); 1462 *sendbin = gst_bin_new("purplesendaudiobin");
1075 src = gst_element_factory_make("alsasrc", "asrc"); 1463 src = gst_element_factory_make("alsasrc", "asrc");
1076 volume = gst_element_factory_make("volume", "purpleaudioinputvolume"); 1464 volume = gst_element_factory_make("volume", "purpleaudioinputvolume");
1077 g_object_set(volume, "volume", input_volume, NULL); 1465 g_object_set(volume, "volume", input_volume, NULL);
1078 *sendlevel = gst_element_factory_make("level", "sendlevel"); 1466 *sendlevel = gst_element_factory_make("level", "sendlevel");
1097 const gchar *video_plugin = purple_prefs_get_string( 1485 const gchar *video_plugin = purple_prefs_get_string(
1098 "/purple/media/video/plugin"); 1486 "/purple/media/video/plugin");
1099 const gchar *video_device = purple_prefs_get_string( 1487 const gchar *video_device = purple_prefs_get_string(
1100 "/purple/media/video/device"); 1488 "/purple/media/video/device");
1101 1489
1102 purple_debug_info("media", "purple_media_video_init_src\n");
1103
1104 *sendbin = gst_bin_new("purplesendvideobin"); 1490 *sendbin = gst_bin_new("purplesendvideobin");
1105 src = gst_element_factory_make(video_plugin, "purplevideosource"); 1491 src = gst_element_factory_make(video_plugin, "purplevideosource");
1106 gst_bin_add(GST_BIN(*sendbin), src); 1492 gst_bin_add(GST_BIN(*sendbin), src);
1107 1493
1108 tee = gst_element_factory_make("tee", "purplevideosrctee"); 1494 tee = gst_element_factory_make("tee", "purplevideosrctee");
1140 { 1526 {
1141 GstElement *sink, *volume; 1527 GstElement *sink, *volume;
1142 GstPad *pad, *ghost; 1528 GstPad *pad, *ghost;
1143 double output_volume = purple_prefs_get_int( 1529 double output_volume = purple_prefs_get_int(
1144 "/purple/media/audio/volume/output")/10.0; 1530 "/purple/media/audio/volume/output")/10.0;
1145
1146 purple_debug_info("media", "purple_media_audio_init_recv\n");
1147 1531
1148 *recvbin = gst_bin_new("pidginrecvaudiobin"); 1532 *recvbin = gst_bin_new("pidginrecvaudiobin");
1149 sink = gst_element_factory_make("alsasink", "asink"); 1533 sink = gst_element_factory_make("alsasink", "asink");
1150 g_object_set(G_OBJECT(sink), "sync", FALSE, NULL); 1534 g_object_set(G_OBJECT(sink), "sync", FALSE, NULL);
1151 volume = gst_element_factory_make("volume", "purpleaudiooutputvolume"); 1535 volume = gst_element_factory_make("volume", "purpleaudiooutputvolume");
1156 gst_element_link(volume, *recvlevel); 1540 gst_element_link(volume, *recvlevel);
1157 pad = gst_element_get_pad(volume, "sink"); 1541 pad = gst_element_get_pad(volume, "sink");
1158 ghost = gst_ghost_pad_new("ghostsink", pad); 1542 ghost = gst_ghost_pad_new("ghostsink", pad);
1159 gst_element_add_pad(*recvbin, ghost); 1543 gst_element_add_pad(*recvbin, ghost);
1160 g_object_set(G_OBJECT(*recvlevel), "message", TRUE, NULL); 1544 g_object_set(G_OBJECT(*recvlevel), "message", TRUE, NULL);
1161
1162 purple_debug_info("media", "purple_media_audio_init_recv end\n");
1163 } 1545 }
1164 1546
1165 void 1547 void
1166 purple_media_video_init_recv(GstElement **recvbin) 1548 purple_media_video_init_recv(GstElement **recvbin)
1167 { 1549 {
1168 GstElement *sink; 1550 GstElement *sink;
1169 GstPad *pad, *ghost; 1551 GstPad *pad, *ghost;
1170
1171 purple_debug_info("media", "purple_media_video_init_recv\n");
1172 1552
1173 *recvbin = gst_bin_new("pidginrecvvideobin"); 1553 *recvbin = gst_bin_new("pidginrecvvideobin");
1174 sink = gst_element_factory_make("autovideosink", "purplevideosink"); 1554 sink = gst_element_factory_make("autovideosink", "purplevideosink");
1175 gst_bin_add(GST_BIN(*recvbin), sink); 1555 gst_bin_add(GST_BIN(*recvbin), sink);
1176 pad = gst_element_get_pad(sink, "sink"); 1556 pad = gst_element_get_pad(sink, "sink");
1177 ghost = gst_ghost_pad_new("ghostsink", pad); 1557 ghost = gst_ghost_pad_new("ghostsink", pad);
1178 gst_element_add_pad(*recvbin, ghost); 1558 gst_element_add_pad(*recvbin, ghost);
1179
1180 purple_debug_info("media", "purple_media_video_init_recv end\n");
1181 } 1559 }
1182 1560
1183 static void 1561 static void
1184 purple_media_new_local_candidate_cb(FsStream *stream, 1562 purple_media_new_local_candidate_cb(FsStream *stream,
1185 FsCandidate *local_candidate, 1563 FsCandidate *local_candidate,
1186 PurpleMediaSession *session) 1564 PurpleMediaSession *session)
1187 { 1565 {
1188 gchar *name; 1566 gchar *name;
1189 FsParticipant *participant; 1567 FsParticipant *participant;
1190 FsCandidate *candidate; 1568 PurpleMediaCandidate *candidate;
1191 purple_debug_info("media", "got new local candidate: %s\n", local_candidate->foundation); 1569 purple_debug_info("media", "got new local candidate: %s\n", local_candidate->foundation);
1192 g_object_get(stream, "participant", &participant, NULL); 1570 g_object_get(stream, "participant", &participant, NULL);
1193 g_object_get(participant, "cname", &name, NULL); 1571 g_object_get(participant, "cname", &name, NULL);
1194 g_object_unref(participant); 1572 g_object_unref(participant);
1195 1573
1196 purple_media_insert_local_candidate(session, name, fs_candidate_copy(local_candidate)); 1574 purple_media_insert_local_candidate(session, name, fs_candidate_copy(local_candidate));
1197 1575
1198 candidate = fs_candidate_copy(local_candidate); 1576 candidate = purple_media_candidate_from_fs(local_candidate);
1199 g_signal_emit(session->media, purple_media_signals[NEW_CANDIDATE], 1577 g_signal_emit(session->media, purple_media_signals[NEW_CANDIDATE],
1200 0, session->id, name, candidate); 1578 0, session->id, name, candidate);
1201 fs_candidate_destroy(candidate); 1579 purple_media_candidate_free(candidate);
1202 1580
1203 g_free(name); 1581 g_free(name);
1204 } 1582 }
1205 1583
1206 static void 1584 static void
1232 FsCandidate *remote_candidate, 1610 FsCandidate *remote_candidate,
1233 PurpleMediaSession *session) 1611 PurpleMediaSession *session)
1234 { 1612 {
1235 gchar *name; 1613 gchar *name;
1236 FsParticipant *participant; 1614 FsParticipant *participant;
1237 FsCandidate *local = fs_candidate_copy(native_candidate); 1615 PurpleMediaCandidate *local =
1238 FsCandidate *remote = fs_candidate_copy(remote_candidate); 1616 purple_media_candidate_from_fs(native_candidate);
1617 PurpleMediaCandidate *remote =
1618 purple_media_candidate_from_fs(remote_candidate);
1239 PurpleMediaStream *stream; 1619 PurpleMediaStream *stream;
1240 1620
1241 g_object_get(fsstream, "participant", &participant, NULL); 1621 g_object_get(fsstream, "participant", &participant, NULL);
1242 g_object_get(participant, "cname", &name, NULL); 1622 g_object_get(participant, "cname", &name, NULL);
1243 g_object_unref(participant); 1623 g_object_unref(participant);
1249 1629
1250 purple_debug_info("media", "candidate pair established\n"); 1630 purple_debug_info("media", "candidate pair established\n");
1251 g_signal_emit(session->media, purple_media_signals[CANDIDATE_PAIR], 0, 1631 g_signal_emit(session->media, purple_media_signals[CANDIDATE_PAIR], 0,
1252 local, remote); 1632 local, remote);
1253 1633
1254 fs_candidate_destroy(local); 1634 purple_media_candidate_free(local);
1255 fs_candidate_destroy(remote); 1635 purple_media_candidate_free(remote);
1636 }
1637
1638 static gboolean
1639 purple_media_connected_cb(PurpleMediaStream *stream)
1640 {
1641 g_signal_emit(stream->session->media,
1642 purple_media_signals[STATE_CHANGED],
1643 0, PURPLE_MEDIA_STATE_CHANGED_CONNECTED,
1644 stream->session->id, stream->participant);
1645 return FALSE;
1256 } 1646 }
1257 1647
1258 static void 1648 static void
1259 purple_media_src_pad_added_cb(FsStream *fsstream, GstPad *srcpad, 1649 purple_media_src_pad_added_cb(FsStream *fsstream, GstPad *srcpad,
1260 FsCodec *codec, PurpleMediaStream *stream) 1650 FsCodec *codec, PurpleMediaStream *stream)
1266 purple_media_manager_get(), type); 1656 purple_media_manager_get(), type);
1267 1657
1268 gst_bin_add(GST_BIN(purple_media_get_pipeline(stream->session->media)), 1658 gst_bin_add(GST_BIN(purple_media_get_pipeline(stream->session->media)),
1269 stream->sink); 1659 stream->sink);
1270 sinkpad = gst_element_get_static_pad(stream->sink, "ghostsink"); 1660 sinkpad = gst_element_get_static_pad(stream->sink, "ghostsink");
1271 purple_debug_info("media", "connecting new src pad: %s\n", 1661 gst_pad_link(srcpad, sinkpad);
1272 gst_pad_link(srcpad, sinkpad) == GST_PAD_LINK_OK ? "success" : "failure");
1273 gst_element_set_state(stream->sink, GST_STATE_PLAYING); 1662 gst_element_set_state(stream->sink, GST_STATE_PLAYING);
1274 1663
1275 g_signal_emit(stream->session->media, purple_media_signals[STATE_CHANGED], 1664 g_timeout_add(0, (GSourceFunc)purple_media_connected_cb, stream);
1276 0, PURPLE_MEDIA_STATE_CHANGED_CONNECTED,
1277 stream->session->id, stream->participant);
1278 } 1665 }
1279 1666
1280 static gchar * 1667 static gchar *
1281 purple_media_get_stun_pref_ip() 1668 purple_media_get_stun_pref_ip()
1282 { 1669 {
1474 } 1861 }
1475 /* XXX: Should wait until codecs-ready is TRUE before using this function */ 1862 /* XXX: Should wait until codecs-ready is TRUE before using this function */
1476 GList * 1863 GList *
1477 purple_media_get_codecs(PurpleMedia *media, const gchar *sess_id) 1864 purple_media_get_codecs(PurpleMedia *media, const gchar *sess_id)
1478 { 1865 {
1866 GList *fscodecs;
1479 GList *codecs; 1867 GList *codecs;
1480 g_object_get(G_OBJECT(purple_media_get_session(media, sess_id)->session), 1868 g_object_get(G_OBJECT(purple_media_get_session(media, sess_id)->session),
1481 "codecs", &codecs, NULL); 1869 "codecs", &fscodecs, NULL);
1870 codecs = purple_media_codec_list_from_fs(fscodecs);
1871 fs_codec_list_destroy(fscodecs);
1482 return codecs; 1872 return codecs;
1483 } 1873 }
1484 1874
1485 GList * 1875 GList *
1486 purple_media_get_local_candidates(PurpleMedia *media, const gchar *sess_id, const gchar *name) 1876 purple_media_get_local_candidates(PurpleMedia *media, const gchar *sess_id, const gchar *name)
1487 { 1877 {
1488 PurpleMediaStream *stream = purple_media_get_stream(media, sess_id, name); 1878 PurpleMediaStream *stream = purple_media_get_stream(media, sess_id, name);
1489 return fs_candidate_list_copy(stream->local_candidates); 1879 return purple_media_candidate_list_from_fs(stream->local_candidates);
1490 } 1880 }
1491 1881
1492 void 1882 void
1493 purple_media_add_remote_candidates(PurpleMedia *media, const gchar *sess_id, 1883 purple_media_add_remote_candidates(PurpleMedia *media, const gchar *sess_id,
1494 const gchar *name, GList *remote_candidates) 1884 const gchar *name, GList *remote_candidates)
1495 { 1885 {
1496 PurpleMediaStream *stream = purple_media_get_stream(media, sess_id, name); 1886 PurpleMediaStream *stream = purple_media_get_stream(media, sess_id, name);
1497 stream->remote_candidates = g_list_concat(stream->remote_candidates, 1887 stream->remote_candidates = g_list_concat(stream->remote_candidates,
1498 fs_candidate_list_copy(remote_candidates)); 1888 purple_media_candidate_list_to_fs(remote_candidates));
1499 1889
1500 if (stream->session->accepted == TRUE) { 1890 if (stream->session->accepted == TRUE) {
1501 purple_media_set_remote_candidates(stream); 1891 purple_media_set_remote_candidates(stream);
1502 } 1892 }
1503 } 1893 }
1504 1894
1505 FsCandidate * 1895 PurpleMediaCandidate *
1506 purple_media_get_local_candidate(PurpleMedia *media, const gchar *sess_id, const gchar *name) 1896 purple_media_get_local_candidate(PurpleMedia *media, const gchar *sess_id, const gchar *name)
1507 { 1897 {
1508 return purple_media_get_stream(media, sess_id, name)->local_candidate; 1898 return purple_media_candidate_from_fs(purple_media_get_stream(
1509 } 1899 media, sess_id, name)->local_candidate);
1510 1900 }
1511 FsCandidate * 1901
1902 PurpleMediaCandidate *
1512 purple_media_get_remote_candidate(PurpleMedia *media, const gchar *sess_id, const gchar *name) 1903 purple_media_get_remote_candidate(PurpleMedia *media, const gchar *sess_id, const gchar *name)
1513 { 1904 {
1514 return purple_media_get_stream(media, sess_id, name)->remote_candidate; 1905 return purple_media_candidate_from_fs(purple_media_get_stream(
1906 media, sess_id, name)->remote_candidate);
1515 } 1907 }
1516 1908
1517 gboolean 1909 gboolean
1518 purple_media_set_remote_codecs(PurpleMedia *media, const gchar *sess_id, const gchar *name, GList *codecs) 1910 purple_media_set_remote_codecs(PurpleMedia *media, const gchar *sess_id, const gchar *name, GList *codecs)
1519 { 1911 {
1520 FsStream *stream = purple_media_get_stream(media, sess_id, name)->stream; 1912 FsStream *stream = purple_media_get_stream(media, sess_id, name)->stream;
1913 GList *fscodecs = purple_media_codec_list_to_fs(codecs);
1521 GError *err = NULL; 1914 GError *err = NULL;
1522 1915
1523 fs_stream_set_remote_codecs(stream, codecs, &err); 1916 fs_stream_set_remote_codecs(stream, fscodecs, &err);
1917 fs_codec_list_destroy(fscodecs);
1524 1918
1525 if (err) { 1919 if (err) {
1526 purple_debug_error("media", "Error setting remote codecs: %s\n", 1920 purple_debug_error("media", "Error setting remote codecs: %s\n",
1527 err->message); 1921 err->message);
1528 g_error_free(err); 1922 g_error_free(err);
1545 1939
1546 return TRUE; 1940 return TRUE;
1547 } 1941 }
1548 1942
1549 gboolean 1943 gboolean
1550 purple_media_set_send_codec(PurpleMedia *media, const gchar *sess_id, FsCodec *codec) 1944 purple_media_set_send_codec(PurpleMedia *media, const gchar *sess_id, PurpleMediaCodec *codec)
1551 { 1945 {
1552 PurpleMediaSession *session = purple_media_get_session(media, sess_id); 1946 PurpleMediaSession *session = purple_media_get_session(media, sess_id);
1947 FsCodec *fscodec = purple_media_codec_to_fs(codec);
1553 GError *err = NULL; 1948 GError *err = NULL;
1554 1949
1555 fs_session_set_send_codec(session->session, codec, &err); 1950 fs_session_set_send_codec(session->session, fscodec, &err);
1951 fs_codec_destroy(fscodec);
1556 1952
1557 if (err) { 1953 if (err) {
1558 purple_debug_error("media", "Error setting send codec\n"); 1954 purple_debug_error("media", "Error setting send codec\n");
1559 g_error_free(err); 1955 g_error_free(err);
1560 return FALSE; 1956 return FALSE;