|
|
|
@ -67,8 +67,8 @@ enum attr_id { |
|
|
|
ATTR_END_OF_CANDIDATES, |
|
|
|
ATTR_MOH_ATTR_NAME, |
|
|
|
}; |
|
|
|
// make sure g_int_hash can be used |
|
|
|
static_assert(sizeof(gint) == sizeof(enum attr_id), "sizeof enum attr_id wrong"); |
|
|
|
// make sure g_direct_hash can be used |
|
|
|
static_assert(sizeof(void *) >= sizeof(enum attr_id), "sizeof enum attr_id wrong"); |
|
|
|
|
|
|
|
struct sdp_connection { |
|
|
|
str s; |
|
|
|
@ -76,17 +76,9 @@ struct sdp_connection { |
|
|
|
unsigned int parsed:1; |
|
|
|
}; |
|
|
|
|
|
|
|
INLINE unsigned int attr_id_hash(const enum attr_id *e) { |
|
|
|
int i = *e; |
|
|
|
return g_int_hash(&i); |
|
|
|
} |
|
|
|
INLINE gboolean attr_id_eq(const enum attr_id *a, const enum attr_id *b) { |
|
|
|
return *a == *b; |
|
|
|
} |
|
|
|
|
|
|
|
TYPED_GQUEUE(attributes, struct sdp_attribute) |
|
|
|
TYPED_GHASHTABLE(attr_id_ht, enum attr_id, struct sdp_attribute, attr_id_hash, attr_id_eq, NULL, NULL) |
|
|
|
TYPED_GHASHTABLE(attr_list_ht, enum attr_id, attributes_q, attr_id_hash, attr_id_eq, NULL, g_queue_free) |
|
|
|
TYPED_GHASHTABLE(attr_id_ht, void, struct sdp_attribute, g_direct_hash, g_direct_equal, NULL, NULL) |
|
|
|
TYPED_GHASHTABLE(attr_list_ht, void, attributes_q, g_direct_hash, g_direct_equal, NULL, g_queue_free) |
|
|
|
TYPED_GHASHTABLE_LOOKUP_INSERT(attr_list_ht, NULL, attributes_q_new) |
|
|
|
|
|
|
|
struct sdp_attributes { |
|
|
|
@ -431,10 +423,10 @@ INLINE void append_attr_to_gstring(GString *s, const char * name, const str * va |
|
|
|
append_str_attr_to_gstring(s, STR_PTR(name), value, flags, media_type); |
|
|
|
} |
|
|
|
INLINE struct sdp_attribute *attr_get_by_id(struct sdp_attributes *a, enum attr_id id) { |
|
|
|
return t_hash_table_lookup(a->id_hash, &id); |
|
|
|
return t_hash_table_lookup(a->id_hash, GINT_TO_POINTER(id)); |
|
|
|
} |
|
|
|
INLINE attributes_q *attr_list_get_by_id(struct sdp_attributes *a, enum attr_id id) { |
|
|
|
return t_hash_table_lookup(a->id_lists_hash, &id); |
|
|
|
return t_hash_table_lookup(a->id_lists_hash, GINT_TO_POINTER(id)); |
|
|
|
} |
|
|
|
|
|
|
|
static struct sdp_attribute *attr_get_by_id_m_s(struct sdp_media *m, enum attr_id id) { |
|
|
|
@ -576,10 +568,11 @@ static void attrs_init(struct sdp_attributes *a) { |
|
|
|
static void attr_insert(struct sdp_attributes *attrs, struct sdp_attribute *attr) { |
|
|
|
t_queue_push_tail(&attrs->list, attr); |
|
|
|
|
|
|
|
if (!t_hash_table_lookup(attrs->id_hash, &attr->attr)) |
|
|
|
t_hash_table_insert(attrs->id_hash, &attr->attr, attr); |
|
|
|
if (!t_hash_table_lookup(attrs->id_hash, GINT_TO_POINTER(attr->attr))) |
|
|
|
t_hash_table_insert(attrs->id_hash, GINT_TO_POINTER(attr->attr), attr); |
|
|
|
|
|
|
|
attributes_q *attr_queue = attr_list_ht_lookup_insert(attrs->id_lists_hash, &attr->attr); |
|
|
|
attributes_q *attr_queue = attr_list_ht_lookup_insert(attrs->id_lists_hash, |
|
|
|
GINT_TO_POINTER(attr->attr)); |
|
|
|
|
|
|
|
t_queue_push_tail(attr_queue, attr); |
|
|
|
|
|
|
|
@ -1491,20 +1484,21 @@ static bool __rtp_payload_types(struct stream_params *sp, struct sdp_media *medi |
|
|
|
return true; |
|
|
|
|
|
|
|
/* first go through a=rtpmap and build a hash table of attrs */ |
|
|
|
g_autoptr(GHashTable) ht_rtpmap = g_hash_table_new(g_int_hash, g_int_equal); |
|
|
|
g_autoptr(GHashTable) ht_rtpmap = g_hash_table_new(g_direct_hash, g_direct_equal); |
|
|
|
attributes_q *q = attr_list_get_by_id(&media->attributes, ATTR_RTPMAP); |
|
|
|
for (__auto_type ql = q ? q->head : NULL; ql; ql = ql->next) { |
|
|
|
rtp_payload_type *pt; |
|
|
|
attr = ql->data; |
|
|
|
pt = &attr->rtpmap.rtp_pt; |
|
|
|
g_hash_table_insert(ht_rtpmap, &pt->payload_type, pt); |
|
|
|
g_hash_table_insert(ht_rtpmap, GINT_TO_POINTER(pt->payload_type), pt); |
|
|
|
} |
|
|
|
// do the same for a=fmtp |
|
|
|
g_autoptr(GHashTable) ht_fmtp = g_hash_table_new(g_int_hash, g_int_equal); |
|
|
|
g_autoptr(GHashTable) ht_fmtp = g_hash_table_new(g_direct_hash, g_direct_equal); |
|
|
|
q = attr_list_get_by_id(&media->attributes, ATTR_FMTP); |
|
|
|
for (__auto_type ql = q ? q->head : NULL; ql; ql = ql->next) { |
|
|
|
attr = ql->data; |
|
|
|
g_hash_table_insert(ht_fmtp, &attr->fmtp.payload_type, &attr->fmtp.format_parms_str); |
|
|
|
g_hash_table_insert(ht_fmtp, GINT_TO_POINTER(attr->fmtp.payload_type), |
|
|
|
&attr->fmtp.format_parms_str); |
|
|
|
} |
|
|
|
// do the same for a=rtcp-fb |
|
|
|
g_autoptr(GHashTable) ht_rtcp_fb = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, (GDestroyNotify) g_queue_free); |
|
|
|
@ -1536,7 +1530,7 @@ static bool __rtp_payload_types(struct stream_params *sp, struct sdp_media *medi |
|
|
|
/* first look in rtpmap for a match, then check RFC types, |
|
|
|
* else fall back to an "unknown" type */ |
|
|
|
ptrfc = rtp_get_rfc_payload_type(i); |
|
|
|
ptl = g_hash_table_lookup(ht_rtpmap, &i); |
|
|
|
ptl = g_hash_table_lookup(ht_rtpmap, GINT_TO_POINTER(i)); |
|
|
|
|
|
|
|
pt = memory_arena_alloc0(rtp_payload_type); |
|
|
|
if (ptl) |
|
|
|
@ -1546,7 +1540,7 @@ static bool __rtp_payload_types(struct stream_params *sp, struct sdp_media *medi |
|
|
|
else |
|
|
|
pt->payload_type = i; |
|
|
|
|
|
|
|
s = g_hash_table_lookup(ht_fmtp, &i); |
|
|
|
s = g_hash_table_lookup(ht_fmtp, GINT_TO_POINTER(i)); |
|
|
|
if (s) |
|
|
|
pt->format_parameters = *s; |
|
|
|
else |
|
|
|
|