Mercurial > pidgin.yaz
comparison libpurple/media.c @ 25728:c48f5c9600c3
Fixed a ton of memory leaks.
author | Mike Ruprecht <maiku@soc.pidgin.im> |
---|---|
date | Mon, 18 Aug 2008 06:25:38 +0000 |
parents | f10e0ac24595 |
children | e4261bc6788d |
comparison
equal
deleted
inserted
replaced
25727:f10e0ac24595 | 25728:c48f5c9600c3 |
---|---|
45 gchar *id; | 45 gchar *id; |
46 PurpleMedia *media; | 46 PurpleMedia *media; |
47 GstElement *src; | 47 GstElement *src; |
48 GstElement *sink; | 48 GstElement *sink; |
49 FsSession *session; | 49 FsSession *session; |
50 GHashTable *streams; /* FsStream list map to participant's name */ | 50 /* FsStream table. Mapped by participant's name */ |
51 GHashTable *streams; | |
51 PurpleMediaSessionType type; | 52 PurpleMediaSessionType type; |
52 GHashTable *local_candidates; /* map to participant's name? */ | 53 /* GList of FsCandidates table. Mapped by participant's name */ |
54 GHashTable *local_candidates; | |
53 | 55 |
54 /* | 56 /* |
55 * These will need to be per stream when sessions with multiple | 57 * These will need to be per stream when sessions with multiple |
56 * streams are supported. | 58 * streams are supported. |
57 */ | 59 */ |
219 | 221 |
220 static void | 222 static void |
221 purple_media_finalize (GObject *media) | 223 purple_media_finalize (GObject *media) |
222 { | 224 { |
223 PurpleMediaPrivate *priv = PURPLE_MEDIA_GET_PRIVATE(media); | 225 PurpleMediaPrivate *priv = PURPLE_MEDIA_GET_PRIVATE(media); |
224 GList *sessions = g_hash_table_get_values(priv->sessions); | |
225 purple_debug_info("media","purple_media_finalize\n"); | 226 purple_debug_info("media","purple_media_finalize\n"); |
226 | 227 |
227 purple_media_manager_remove_media(purple_media_manager_get(), | 228 purple_media_manager_remove_media(purple_media_manager_get(), |
228 PURPLE_MEDIA(media)); | 229 PURPLE_MEDIA(media)); |
229 | 230 |
230 g_free(priv->name); | 231 g_free(priv->name); |
231 | 232 |
232 for (; sessions; sessions = g_list_delete_link(sessions, sessions)) { | 233 if (priv->sessions) { |
233 PurpleMediaSession *session = sessions->data; | 234 GList *sessions = g_hash_table_get_values(priv->sessions); |
234 GList *streams = g_hash_table_get_values(session->streams); | 235 for (; sessions; sessions = g_list_delete_link(sessions, sessions)) { |
235 | 236 PurpleMediaSession *session = sessions->data; |
236 for (; streams; streams = g_list_delete_link(streams, streams)) { | 237 g_free(session->id); |
237 g_object_unref(streams->data); | 238 |
239 if (session->streams) { | |
240 GList *streams = g_hash_table_get_values(session->streams); | |
241 for (; streams; streams = g_list_delete_link(streams, streams)) | |
242 g_object_unref(streams->data); | |
243 g_hash_table_destroy(session->streams); | |
244 } | |
245 | |
246 if (session->local_candidates) { | |
247 GList *candidates = g_hash_table_get_values(session->local_candidates); | |
248 for (; candidates; candidates = | |
249 g_list_delete_link(candidates, candidates)) | |
250 fs_candidate_list_destroy(candidates->data); | |
251 g_hash_table_destroy(session->local_candidates); | |
252 } | |
253 | |
254 if (session->local_candidate) | |
255 fs_candidate_destroy(session->local_candidate); | |
256 if (session->remote_candidate) | |
257 fs_candidate_destroy(session->remote_candidate); | |
258 | |
259 g_free(session); | |
238 } | 260 } |
239 | 261 g_hash_table_destroy(priv->sessions); |
240 g_object_unref(session->session); | 262 } |
263 | |
264 if (priv->participants) { | |
265 GList *participants = g_hash_table_get_values(priv->participants); | |
266 for (; participants; participants = g_list_delete_link(participants, participants)) | |
267 g_object_unref(participants->data); | |
268 g_hash_table_destroy(priv->participants); | |
241 } | 269 } |
242 | 270 |
243 if (priv->pipeline) { | 271 if (priv->pipeline) { |
244 gst_element_set_state(priv->pipeline, GST_STATE_NULL); | 272 gst_element_set_state(priv->pipeline, GST_STATE_NULL); |
245 gst_object_unref(priv->pipeline); | 273 gst_object_unref(priv->pipeline); |
414 | 442 |
415 if (participant) | 443 if (participant) |
416 return participant; | 444 return participant; |
417 | 445 |
418 participant = fs_conference_new_participant(media->priv->conference, | 446 participant = fs_conference_new_participant(media->priv->conference, |
419 g_strdup(name), &err); | 447 (gchar*)name, &err); |
420 | 448 |
421 if (err) { | 449 if (err) { |
422 purple_debug_error("media", "Error creating participant: %s\n", | 450 purple_debug_error("media", "Error creating participant: %s\n", |
423 err->message); | 451 err->message); |
424 g_error_free(err); | 452 g_error_free(err); |
425 return NULL; | 453 return NULL; |
426 } | 454 } |
427 | 455 |
428 if (!media->priv->participants) { | 456 if (!media->priv->participants) { |
429 purple_debug_info("media", "Creating hash table for participants\n"); | 457 purple_debug_info("media", "Creating hash table for participants\n"); |
430 media->priv->participants = g_hash_table_new(g_str_hash, g_str_equal); | 458 media->priv->participants = g_hash_table_new_full(g_str_hash, |
459 g_str_equal, g_free, NULL); | |
431 } | 460 } |
432 | 461 |
433 g_hash_table_insert(media->priv->participants, g_strdup(name), participant); | 462 g_hash_table_insert(media->priv->participants, g_strdup(name), participant); |
434 | 463 |
435 return participant; | 464 return participant; |
438 static void | 467 static void |
439 purple_media_insert_stream(PurpleMediaSession *session, const gchar *name, FsStream *stream) | 468 purple_media_insert_stream(PurpleMediaSession *session, const gchar *name, FsStream *stream) |
440 { | 469 { |
441 if (!session->streams) { | 470 if (!session->streams) { |
442 purple_debug_info("media", "Creating hash table for streams\n"); | 471 purple_debug_info("media", "Creating hash table for streams\n"); |
443 session->streams = g_hash_table_new(g_str_hash, g_str_equal); | 472 session->streams = g_hash_table_new_full(g_str_hash, |
473 g_str_equal, g_free, NULL); | |
444 } | 474 } |
445 | 475 |
446 g_hash_table_insert(session->streams, g_strdup(name), stream); | 476 g_hash_table_insert(session->streams, g_strdup(name), stream); |
447 } | 477 } |
448 | 478 |
454 | 484 |
455 candidates = g_list_append(candidates, candidate); | 485 candidates = g_list_append(candidates, candidate); |
456 | 486 |
457 if (!session->local_candidates) { | 487 if (!session->local_candidates) { |
458 purple_debug_info("media", "Creating hash table for local candidates\n"); | 488 purple_debug_info("media", "Creating hash table for local candidates\n"); |
459 session->local_candidates = g_hash_table_new(g_str_hash, g_str_equal); | 489 session->local_candidates = g_hash_table_new_full(g_str_hash, |
490 g_str_equal, g_free, NULL); | |
460 } | 491 } |
461 | 492 |
462 g_hash_table_insert(session->local_candidates, g_strdup(name), candidates); | 493 g_hash_table_insert(session->local_candidates, g_strdup(name), candidates); |
463 } | 494 } |
464 | 495 |
714 } | 745 } |
715 } | 746 } |
716 | 747 |
717 array = gst_property_probe_probe_and_get_values (probe, pspec); | 748 array = gst_property_probe_probe_and_get_values (probe, pspec); |
718 if (array != NULL) { | 749 if (array != NULL) { |
719 | |
720 for (n = 0 ; n < array->n_values ; n++) { | 750 for (n = 0 ; n < array->n_values ; n++) { |
721 GValue *device = g_value_array_get_nth (array, n); | 751 GValue *device = g_value_array_get_nth (array, n); |
752 GValue *location = g_new0(GValue, 1); | |
722 gst_element_set_state (element, GST_STATE_NULL); | 753 gst_element_set_state (element, GST_STATE_NULL); |
723 | 754 location = g_value_init(location, G_TYPE_STRING); |
724 ret = g_list_append(ret, device); | 755 |
756 g_value_copy(device, location); | |
757 ret = g_list_append(ret, location); | |
725 | 758 |
726 name = purple_media_get_device_name(GST_ELEMENT(element), device); | 759 name = purple_media_get_device_name(GST_ELEMENT(element), device); |
727 purple_debug_info("media", "Found source '%s' (%s) - device '%s' (%s)\n", | 760 purple_debug_info("media", "Found source '%s' (%s) - device '%s' (%s)\n", |
728 longname, GST_PLUGIN_FEATURE (factory)->name, | 761 longname, GST_PLUGIN_FEATURE (factory)->name, |
729 name, g_value_get_string(device)); | 762 name, g_value_get_string(device)); |
730 g_free(name); | 763 g_free(name); |
731 } | 764 } |
765 g_value_array_free(array); | |
732 } | 766 } |
733 } | 767 } |
734 | 768 |
735 return ret; | 769 return ret; |
736 } | 770 } |
914 FsCandidate *local_candidate, | 948 FsCandidate *local_candidate, |
915 PurpleMediaSession *session) | 949 PurpleMediaSession *session) |
916 { | 950 { |
917 gchar *name; | 951 gchar *name; |
918 FsParticipant *participant; | 952 FsParticipant *participant; |
953 FsCandidate *candidate; | |
919 purple_debug_info("media", "got new local candidate: %s\n", local_candidate->candidate_id); | 954 purple_debug_info("media", "got new local candidate: %s\n", local_candidate->candidate_id); |
920 g_object_get(stream, "participant", &participant, NULL); | 955 g_object_get(stream, "participant", &participant, NULL); |
921 g_object_get(participant, "cname", &name, NULL); | 956 g_object_get(participant, "cname", &name, NULL); |
922 g_object_unref(participant); | 957 g_object_unref(participant); |
923 | 958 |
924 purple_media_insert_local_candidate(session, name, fs_candidate_copy(local_candidate)); | 959 purple_media_insert_local_candidate(session, name, fs_candidate_copy(local_candidate)); |
925 | 960 |
961 candidate = fs_candidate_copy(local_candidate); | |
926 g_signal_emit(session->media, purple_media_signals[NEW_CANDIDATE], | 962 g_signal_emit(session->media, purple_media_signals[NEW_CANDIDATE], |
927 0, session->id, name, fs_candidate_copy(local_candidate)); | 963 0, session->id, name, candidate); |
964 fs_candidate_destroy(candidate); | |
928 | 965 |
929 g_free(name); | 966 g_free(name); |
930 } | 967 } |
931 | 968 |
932 static void | 969 static void |
947 purple_media_candidate_pair_established_cb(FsStream *stream, | 984 purple_media_candidate_pair_established_cb(FsStream *stream, |
948 FsCandidate *native_candidate, | 985 FsCandidate *native_candidate, |
949 FsCandidate *remote_candidate, | 986 FsCandidate *remote_candidate, |
950 PurpleMediaSession *session) | 987 PurpleMediaSession *session) |
951 { | 988 { |
989 FsCandidate *local = fs_candidate_copy(native_candidate); | |
990 FsCandidate *remote = fs_candidate_copy(remote_candidate); | |
991 | |
952 session->local_candidate = fs_candidate_copy(native_candidate); | 992 session->local_candidate = fs_candidate_copy(native_candidate); |
953 session->remote_candidate = fs_candidate_copy(remote_candidate); | 993 session->remote_candidate = fs_candidate_copy(remote_candidate); |
954 | 994 |
955 purple_debug_info("media", "candidate pair established\n"); | 995 purple_debug_info("media", "candidate pair established\n"); |
956 g_signal_emit(session->media, purple_media_signals[CANDIDATE_PAIR], 0, | 996 g_signal_emit(session->media, purple_media_signals[CANDIDATE_PAIR], 0, |
957 session->local_candidate, | 997 local, remote); |
958 session->remote_candidate); | 998 |
999 fs_candidate_destroy(local); | |
1000 fs_candidate_destroy(remote); | |
959 } | 1001 } |
960 | 1002 |
961 static void | 1003 static void |
962 purple_media_src_pad_added_cb(FsStream *stream, GstPad *srcpad, | 1004 purple_media_src_pad_added_cb(FsStream *stream, GstPad *srcpad, |
963 FsCodec *codec, PurpleMediaSession *session) | 1005 FsCodec *codec, PurpleMediaSession *session) |
1075 GParameter param[2]; | 1117 GParameter param[2]; |
1076 memset(param, 0, sizeof(GParameter) * 2); | 1118 memset(param, 0, sizeof(GParameter) * 2); |
1077 | 1119 |
1078 param[0].name = "stun-ip"; | 1120 param[0].name = "stun-ip"; |
1079 g_value_init(¶m[0].value, G_TYPE_STRING); | 1121 g_value_init(¶m[0].value, G_TYPE_STRING); |
1080 g_value_set_string(¶m[0].value, stun_ip); | 1122 g_value_take_string(¶m[0].value, stun_ip); |
1081 | |
1082 g_free(stun_ip); | |
1083 | 1123 |
1084 param[1].name = "stun-timeout"; | 1124 param[1].name = "stun-timeout"; |
1085 g_value_init(¶m[1].value, G_TYPE_UINT); | 1125 g_value_init(¶m[1].value, G_TYPE_UINT); |
1086 g_value_set_uint(¶m[1].value, 5); | 1126 g_value_set_uint(¶m[1].value, 5); |
1087 | 1127 |
1088 stream = fs_session_new_stream(session->session, | 1128 stream = fs_session_new_stream(session->session, |
1089 participant, type_direction, | 1129 participant, type_direction, |
1090 transmitter, 2, param, &err); | 1130 transmitter, 2, param, &err); |
1131 g_free(stun_ip); | |
1091 } else { | 1132 } else { |
1092 stream = fs_session_new_stream(session->session, | 1133 stream = fs_session_new_stream(session->session, |
1093 participant, type_direction, | 1134 participant, type_direction, |
1094 transmitter, 0, NULL, &err); | 1135 transmitter, 0, NULL, &err); |
1095 } | 1136 } |
1179 | 1220 |
1180 GList * | 1221 GList * |
1181 purple_media_get_local_candidates(PurpleMedia *media, const gchar *sess_id, const gchar *name) | 1222 purple_media_get_local_candidates(PurpleMedia *media, const gchar *sess_id, const gchar *name) |
1182 { | 1223 { |
1183 PurpleMediaSession *session = purple_media_get_session(media, sess_id); | 1224 PurpleMediaSession *session = purple_media_get_session(media, sess_id); |
1184 return purple_media_session_get_local_candidates(session, name); | 1225 return fs_candidate_list_copy( |
1226 purple_media_session_get_local_candidates(session, name)); | |
1185 } | 1227 } |
1186 | 1228 |
1187 GList * | 1229 GList * |
1188 purple_media_get_negotiated_codecs(PurpleMedia *media, const gchar *sess_id) | 1230 purple_media_get_negotiated_codecs(PurpleMedia *media, const gchar *sess_id) |
1189 { | 1231 { |