|
|
|
@ -36,6 +36,7 @@ struct sdp_attributes { |
|
|
|
GQueue list; |
|
|
|
GHashTable *name_hash; |
|
|
|
GHashTable *lists_hash; |
|
|
|
GHashTable *id_hash; |
|
|
|
}; |
|
|
|
|
|
|
|
struct sdp_session { |
|
|
|
@ -123,6 +124,7 @@ struct sdp_attribute { |
|
|
|
ATTR_RTCP, |
|
|
|
ATTR_CANDIDATE, |
|
|
|
ATTR_ICE, |
|
|
|
ATTR_ICE_UFRAG, |
|
|
|
ATTR_CRYPTO, |
|
|
|
ATTR_SSRC, |
|
|
|
} attr; |
|
|
|
@ -271,6 +273,7 @@ static int parse_media(char *start, char *end, struct sdp_media *output) { |
|
|
|
static void attrs_init(struct sdp_attributes *a) { |
|
|
|
g_queue_init(&a->list); |
|
|
|
a->name_hash = g_hash_table_new(str_hash, str_equal); |
|
|
|
a->id_hash = g_hash_table_new(g_int_hash, g_int_equal); |
|
|
|
a->lists_hash = g_hash_table_new_full(str_hash, str_equal, |
|
|
|
NULL, (GDestroyNotify) g_queue_free); |
|
|
|
} |
|
|
|
@ -494,7 +497,7 @@ static int parse_attribute(struct sdp_attribute *a) { |
|
|
|
if (!str_cmp(&a->name, "candidate")) |
|
|
|
ret = parse_attribute_candidate(a); |
|
|
|
else if (!str_cmp(&a->name, "ice-ufrag")) |
|
|
|
a->attr = ATTR_ICE; |
|
|
|
a->attr = ATTR_ICE_UFRAG; |
|
|
|
break; |
|
|
|
case 11: |
|
|
|
if (!str_cmp(&a->name, "ice-options")) |
|
|
|
@ -610,6 +613,7 @@ int sdp_parse(str *body, GQueue *sessions) { |
|
|
|
attrs = media ? &media->attributes : &session->attributes; |
|
|
|
g_queue_push_tail(&attrs->list, attr); |
|
|
|
g_hash_table_insert(attrs->name_hash, &attr->name, attr); |
|
|
|
g_hash_table_insert(attrs->id_hash, &attr->attr, attr); |
|
|
|
if (attr->key.s) |
|
|
|
g_hash_table_insert(attrs->name_hash, &attr->key, attr); |
|
|
|
|
|
|
|
@ -671,6 +675,7 @@ static void free_attributes(struct sdp_attributes *a) { |
|
|
|
struct sdp_attribute *attr; |
|
|
|
|
|
|
|
g_hash_table_destroy(a->name_hash); |
|
|
|
g_hash_table_destroy(a->id_hash); |
|
|
|
g_hash_table_destroy(a->lists_hash); |
|
|
|
while ((attr = g_queue_pop_head(&a->list))) { |
|
|
|
g_slice_free1(sizeof(*attr), attr); |
|
|
|
@ -734,8 +739,7 @@ int sdp_streams(const GQueue *sessions, GQueue *streams, GHashTable *streamhash, |
|
|
|
struct stream_input *si; |
|
|
|
GList *l, *k; |
|
|
|
const char *errstr; |
|
|
|
int i, num; |
|
|
|
str s; |
|
|
|
int i, num, id; |
|
|
|
struct sdp_attribute *attr; |
|
|
|
enum transport_protocol tp; |
|
|
|
|
|
|
|
@ -770,8 +774,8 @@ int sdp_streams(const GQueue *sessions, GQueue *streams, GHashTable *streamhash, |
|
|
|
|
|
|
|
if (!si || media->port_count != 1) |
|
|
|
continue; |
|
|
|
str_init(&s, "rtcp"); /* XXX use the enum for hash instead? */ |
|
|
|
attr = g_hash_table_lookup(media->attributes.name_hash, &s); |
|
|
|
id = ATTR_RTCP; |
|
|
|
attr = g_hash_table_lookup(media->attributes.id_hash, &id); |
|
|
|
if (!attr || !attr->u.rtcp.port_num) |
|
|
|
continue; |
|
|
|
if (attr->u.rtcp.port_num == si->stream.port + 1) |
|
|
|
@ -1203,20 +1207,20 @@ static int has_ice(GQueue *sessions) { |
|
|
|
GList *l, *m; |
|
|
|
struct sdp_session *session; |
|
|
|
struct sdp_media *media; |
|
|
|
str s; |
|
|
|
int id; |
|
|
|
|
|
|
|
str_init(&s, "ice-ufrag"); |
|
|
|
id = ATTR_ICE_UFRAG; |
|
|
|
|
|
|
|
for (l = sessions->head; l; l = l->next) { |
|
|
|
session = l->data; |
|
|
|
|
|
|
|
if (g_hash_table_lookup(session->attributes.name_hash, &s)) |
|
|
|
if (g_hash_table_lookup(session->attributes.id_hash, &id)) |
|
|
|
return 1; |
|
|
|
|
|
|
|
for (m = session->media_streams.head; m; m = m->next) { |
|
|
|
media = m->data; |
|
|
|
|
|
|
|
if (g_hash_table_lookup(media->attributes.name_hash, &s)) |
|
|
|
if (g_hash_table_lookup(media->attributes.id_hash, &id)) |
|
|
|
return 1; |
|
|
|
} |
|
|
|
} |
|
|
|
|