comparison libpurple/media/backend-fs2.c @ 29566:f600903f7811

Transfer creating Farsight 2 streams to the Fs2 media backend.
author maiku@pidgin.im
date Mon, 26 Oct 2009 21:35:11 +0000
parents 7b0931b3e060
children 983af0970bb2
comparison
equal deleted inserted replaced
29565:eef5ec04a5bf 29566:f600903f7811
28 28
29 #include "internal.h" 29 #include "internal.h"
30 30
31 #include "backend-iface.h" 31 #include "backend-iface.h"
32 #include "debug.h" 32 #include "debug.h"
33 #include "network.h"
33 #include "media-gst.h" 34 #include "media-gst.h"
34 35
35 #include <gst/farsight/fs-conference-iface.h> 36 #include <gst/farsight/fs-conference-iface.h>
36 #include <gst/farsight/fs-element-added-notifier.h> 37 #include <gst/farsight/fs-element-added-notifier.h>
37 38
39 typedef struct _PurpleMediaBackendFs2Class PurpleMediaBackendFs2Class; 40 typedef struct _PurpleMediaBackendFs2Class PurpleMediaBackendFs2Class;
40 /** @copydoc _PurpleMediaBackendFs2Private */ 41 /** @copydoc _PurpleMediaBackendFs2Private */
41 typedef struct _PurpleMediaBackendFs2Private PurpleMediaBackendFs2Private; 42 typedef struct _PurpleMediaBackendFs2Private PurpleMediaBackendFs2Private;
42 /** @copydoc _PurpleMediaBackendFs2Session */ 43 /** @copydoc _PurpleMediaBackendFs2Session */
43 typedef struct _PurpleMediaBackendFs2Session PurpleMediaBackendFs2Session; 44 typedef struct _PurpleMediaBackendFs2Session PurpleMediaBackendFs2Session;
45 /** @copydoc _PurpleMediaBackendFs2Stream */
46 typedef struct _PurpleMediaBackendFs2Stream PurpleMediaBackendFs2Stream;
44 47
45 #define PURPLE_MEDIA_BACKEND_FS2_GET_PRIVATE(obj) \ 48 #define PURPLE_MEDIA_BACKEND_FS2_GET_PRIVATE(obj) \
46 (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ 49 (G_TYPE_INSTANCE_GET_PRIVATE((obj), \
47 PURPLE_TYPE_MEDIA_BACKEND_FS2, PurpleMediaBackendFs2Private)) 50 PURPLE_TYPE_MEDIA_BACKEND_FS2, PurpleMediaBackendFs2Private))
48 51
91 94
92 G_DEFINE_TYPE_WITH_CODE(PurpleMediaBackendFs2, purple_media_backend_fs2, 95 G_DEFINE_TYPE_WITH_CODE(PurpleMediaBackendFs2, purple_media_backend_fs2,
93 G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE( 96 G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE(
94 PURPLE_TYPE_MEDIA_BACKEND, purple_media_backend_iface_init)); 97 PURPLE_TYPE_MEDIA_BACKEND, purple_media_backend_iface_init));
95 98
99 struct _PurpleMediaBackendFs2Stream
100 {
101 PurpleMediaBackendFs2Session *session;
102 gchar *participant;
103 FsStream *stream;
104
105 GList *local_candidates;
106 GList *remote_candidates;
107
108 GList *active_local_candidates;
109 GList *active_remote_candidates;
110
111 guint connected_cb_id;
112
113 gboolean initiator;
114 gboolean accepted;
115 gboolean candidates_prepared;
116 };
117
96 struct _PurpleMediaBackendFs2Session 118 struct _PurpleMediaBackendFs2Session
97 { 119 {
98 PurpleMediaBackendFs2 *backend; 120 PurpleMediaBackendFs2 *backend;
99 gchar *id; 121 gchar *id;
100 gboolean initiator; 122 gboolean initiator;
109 FsConference *conference; 131 FsConference *conference;
110 gchar *conference_type; 132 gchar *conference_type;
111 133
112 GHashTable *sessions; 134 GHashTable *sessions;
113 GHashTable *participants; 135 GHashTable *participants;
136
137 GList *streams;
114 }; 138 };
115 139
116 enum { 140 enum {
117 PROP_0, 141 PROP_0,
118 PROP_CONFERENCE_TYPE, 142 PROP_CONFERENCE_TYPE,
321 return FS_MEDIA_TYPE_VIDEO; 345 return FS_MEDIA_TYPE_VIDEO;
322 else 346 else
323 return 0; 347 return 0;
324 } 348 }
325 349
326 #if 0
327 static FsStreamDirection 350 static FsStreamDirection
328 _session_type_to_fs_stream_direction(PurpleMediaSessionType type) 351 _session_type_to_fs_stream_direction(PurpleMediaSessionType type)
329 { 352 {
330 if ((type & PURPLE_MEDIA_AUDIO) == PURPLE_MEDIA_AUDIO || 353 if ((type & PURPLE_MEDIA_AUDIO) == PURPLE_MEDIA_AUDIO ||
331 (type & PURPLE_MEDIA_VIDEO) == PURPLE_MEDIA_VIDEO) 354 (type & PURPLE_MEDIA_VIDEO) == PURPLE_MEDIA_VIDEO)
338 return FS_DIRECTION_RECV; 361 return FS_DIRECTION_RECV;
339 else 362 else
340 return FS_DIRECTION_NONE; 363 return FS_DIRECTION_NONE;
341 } 364 }
342 365
366 #if 0
343 static PurpleMediaSessionType 367 static PurpleMediaSessionType
344 _session_type_from_fs(FsMediaType type, FsStreamDirection direction) 368 _session_type_from_fs(FsMediaType type, FsStreamDirection direction)
345 { 369 {
346 PurpleMediaSessionType result = PURPLE_MEDIA_NONE; 370 PurpleMediaSessionType result = PURPLE_MEDIA_NONE;
347 if (type == FS_MEDIA_TYPE_AUDIO) { 371 if (type == FS_MEDIA_TYPE_AUDIO) {
459 483
460 if (priv->participants != NULL) 484 if (priv->participants != NULL)
461 participant = g_hash_table_lookup(priv->participants, name); 485 participant = g_hash_table_lookup(priv->participants, name);
462 486
463 return participant; 487 return participant;
488 }
489
490 static PurpleMediaBackendFs2Stream *
491 _get_stream(PurpleMediaBackendFs2 *self,
492 const gchar *sess_id, const gchar *name)
493 {
494 PurpleMediaBackendFs2Private *priv;
495 GList *streams;
496
497 g_return_val_if_fail(PURPLE_IS_MEDIA_BACKEND_FS2(self), NULL);
498
499 priv = PURPLE_MEDIA_BACKEND_FS2_GET_PRIVATE(self);
500 streams = priv->streams;
501
502 for (; streams; streams = g_list_next(streams)) {
503 PurpleMediaBackendFs2Stream *stream = streams->data;
504 if (!strcmp(stream->session->id, sess_id) &&
505 !strcmp(stream->participant, name))
506 return stream;
507 }
508
509 return NULL;
464 } 510 }
465 511
466 static PurpleMediaBackendFs2Session * 512 static PurpleMediaBackendFs2Session *
467 _get_session_from_fs_stream(PurpleMediaBackendFs2 *self, FsStream *stream) 513 _get_session_from_fs_stream(PurpleMediaBackendFs2 *self, FsStream *stream)
468 { 514 {
1021 1067
1022 return TRUE; 1068 return TRUE;
1023 } 1069 }
1024 1070
1025 static gboolean 1071 static gboolean
1072 _create_stream(PurpleMediaBackendFs2 *self,
1073 const gchar *sess_id, const gchar *who,
1074 PurpleMediaSessionType type, gboolean initiator,
1075 const gchar *transmitter,
1076 guint num_params, GParameter *params)
1077 {
1078 PurpleMediaBackendFs2Private *priv =
1079 PURPLE_MEDIA_BACKEND_FS2_GET_PRIVATE(self);
1080 GError *err = NULL;
1081 FsStream *fsstream = NULL;
1082 const gchar *stun_ip = purple_network_get_stun_ip();
1083 const gchar *turn_ip = purple_network_get_turn_ip();
1084 guint _num_params = num_params;
1085 GParameter *_params = g_new0(GParameter, num_params + 2);
1086 FsStreamDirection type_direction =
1087 _session_type_to_fs_stream_direction(type);
1088 PurpleMediaBackendFs2Session *session;
1089 PurpleMediaBackendFs2Stream *stream;
1090 FsParticipant *participant;
1091
1092 memcpy(_params, params, sizeof(GParameter) * num_params);
1093
1094 if (stun_ip) {
1095 purple_debug_info("backend-fs2",
1096 "Setting stun-ip on new stream: %s\n", stun_ip);
1097
1098 _params[_num_params].name = "stun-ip";
1099 g_value_init(&_params[_num_params].value, G_TYPE_STRING);
1100 g_value_set_string(&_params[_num_params].value, stun_ip);
1101 ++_num_params;
1102 }
1103
1104 if (turn_ip && !strcmp("nice", transmitter)) {
1105 GValueArray *relay_info = g_value_array_new(0);
1106 GValue value;
1107 gint turn_port = purple_prefs_get_int(
1108 "/purple/network/turn_port");
1109 const gchar *username = purple_prefs_get_string(
1110 "/purple/network/turn_username");
1111 const gchar *password = purple_prefs_get_string(
1112 "/purple/network/turn_password");
1113 GstStructure *turn_setup = gst_structure_new("relay-info",
1114 "ip", G_TYPE_STRING, turn_ip,
1115 "port", G_TYPE_UINT, turn_port,
1116 "username", G_TYPE_STRING, username,
1117 "password", G_TYPE_STRING, password,
1118 NULL);
1119
1120 if (!turn_setup) {
1121 purple_debug_error("backend-fs2",
1122 "Error creating relay info structure");
1123 return FALSE;
1124 }
1125
1126 memset(&value, 0, sizeof(GValue));
1127 g_value_init(&value, GST_TYPE_STRUCTURE);
1128 gst_value_set_structure(&value, turn_setup);
1129 relay_info = g_value_array_append(relay_info, &value);
1130 gst_structure_free(turn_setup);
1131
1132 purple_debug_info("backend-fs2",
1133 "Setting relay-info on new stream\n");
1134 _params[_num_params].name = "relay-info";
1135 g_value_init(&_params[_num_params].value,
1136 G_TYPE_VALUE_ARRAY);
1137 g_value_set_boxed(&_params[_num_params].value,
1138 relay_info);
1139 g_value_array_free(relay_info);
1140 }
1141
1142 session = _get_session(self, sess_id);
1143
1144 if (session == NULL) {
1145 purple_debug_error("backend-fs2",
1146 "Couldn't find session to create stream.\n");
1147 return FALSE;
1148 }
1149
1150 participant = _get_participant(self, who);
1151
1152 if (participant == NULL) {
1153 purple_debug_error("backend-fs2", "Couldn't find "
1154 "participant to create stream.\n");
1155 return FALSE;
1156 }
1157
1158 fsstream = fs_session_new_stream(session->session, participant,
1159 type_direction & FS_DIRECTION_RECV, transmitter,
1160 _num_params, _params, &err);
1161 g_free(_params);
1162
1163 if (fsstream == NULL) {
1164 if (err) {
1165 purple_debug_error("backend-fs2",
1166 "Error creating stream: %s\n",
1167 err && err->message ?
1168 err->message : "NULL");
1169 g_error_free(err);
1170 } else
1171 purple_debug_error("backend-fs2",
1172 "Error creating stream\n");
1173 return FALSE;
1174 }
1175
1176 stream = g_new0(PurpleMediaBackendFs2Stream, 1);
1177 stream->initiator = initiator;
1178 stream->participant = g_strdup(who);
1179 stream->session = session;
1180 stream->stream = fsstream;
1181
1182 priv->streams = g_list_append(priv->streams, stream);
1183
1184 return TRUE;
1185 }
1186
1187 static gboolean
1026 purple_media_backend_fs2_add_stream(PurpleMediaBackend *self, 1188 purple_media_backend_fs2_add_stream(PurpleMediaBackend *self,
1027 const gchar *sess_id, const gchar *who, 1189 const gchar *sess_id, const gchar *who,
1028 PurpleMediaSessionType type, gboolean initiator, 1190 PurpleMediaSessionType type, gboolean initiator,
1029 const gchar *transmitter, 1191 const gchar *transmitter,
1030 guint num_params, GParameter *params) 1192 guint num_params, GParameter *params)
1052 purple_debug_error("backend-fs2", 1214 purple_debug_error("backend-fs2",
1053 "Error creating the participant.\n"); 1215 "Error creating the participant.\n");
1054 return FALSE; 1216 return FALSE;
1055 } 1217 }
1056 1218
1219 if (_get_stream(backend, sess_id, who) == NULL &&
1220 !_create_stream(backend, sess_id, who, type,
1221 initiator, transmitter, num_params, params)) {
1222 purple_debug_error("backend-fs2",
1223 "Error creating the stream.\n");
1224 return FALSE;
1225 }
1226
1057 return TRUE; 1227 return TRUE;
1058 } 1228 }
1059 1229
1060 static void 1230 static void
1061 purple_media_backend_fs2_add_remote_candidates(PurpleMediaBackend *self, 1231 purple_media_backend_fs2_add_remote_candidates(PurpleMediaBackend *self,
1111 purple_media_backend_fs2_get_participant(PurpleMediaBackendFs2 *self, 1281 purple_media_backend_fs2_get_participant(PurpleMediaBackendFs2 *self,
1112 const gchar *name) 1282 const gchar *name)
1113 { 1283 {
1114 return _get_participant(self, name); 1284 return _get_participant(self, name);
1115 } 1285 }
1286
1287 FsStream *
1288 purple_media_backend_fs2_get_stream(PurpleMediaBackendFs2 *self,
1289 const gchar *sess_id, const gchar *who)
1290 {
1291 PurpleMediaBackendFs2Stream *stream =
1292 _get_stream(self, sess_id, who);
1293 return stream != NULL? stream->stream : NULL;
1294 }