diff --git a/daemon/call.c b/daemon/call.c index a9da7d5c5..a548fbc06 100644 --- a/daemon/call.c +++ b/daemon/call.c @@ -1441,6 +1441,7 @@ static void __rtp_payload_types(struct call_media *media, GQueue *types, GHashTa call_str_cpy(call, &pt->encoding_with_params, &pt->encoding_with_params); call_str_cpy(call, &pt->encoding, &pt->encoding); call_str_cpy(call, &pt->encoding_parameters, &pt->encoding_parameters); + call_str_cpy(call, &pt->format_parameters, &pt->format_parameters); g_hash_table_replace(media->rtp_payload_types, &pt->payload_type, pt); g_queue_push_tail(&media->rtp_payload_types_prefs, pt); } diff --git a/daemon/redis.c b/daemon/redis.c index 8e2dd14bb..379bee9e4 100644 --- a/daemon/redis.c +++ b/daemon/redis.c @@ -1133,7 +1133,7 @@ static int redis_tags(struct call *c, struct redis_list *tags) { static int rbl_cb_plts(str *s, GQueue *q, struct redis_list *list, void *ptr) { struct rtp_payload_type *pt; - str ptype, enc, clock, parms; + str ptype, enc, clock, enc_parms, fmt_parms; struct call_media *med = ptr; struct call *call = med->call; @@ -1143,7 +1143,12 @@ static int rbl_cb_plts(str *s, GQueue *q, struct redis_list *list, void *ptr) { return -1; if (str_token(&clock, s, '/')) return -1; - parms = *s; + if (str_token(&enc_parms, s, '/')) { + enc_parms = *s; + fmt_parms = STR_EMPTY; + } + else + fmt_parms = *s; // from call.c // XXX remove all the duplicate code @@ -1151,7 +1156,8 @@ static int rbl_cb_plts(str *s, GQueue *q, struct redis_list *list, void *ptr) { pt->payload_type = str_to_ui(&ptype, 0); call_str_cpy(call, &pt->encoding, &enc); pt->clock_rate = str_to_ui(&clock, 0); - call_str_cpy(call, &pt->encoding_parameters, &parms); + call_str_cpy(call, &pt->encoding_parameters, &enc_parms); + call_str_cpy(call, &pt->format_parameters, &fmt_parms); g_hash_table_replace(med->rtp_payload_types, &pt->payload_type, pt); return 0; } @@ -1939,9 +1945,10 @@ char* redis_encode_json(struct call *c) { json_builder_begin_array (builder); for (m = k; m; m = m->next) { pt = m->data; - JSON_ADD_STRING("%u/" STR_FORMAT "/%u/" STR_FORMAT, + JSON_ADD_STRING("%u/" STR_FORMAT "/%u/" STR_FORMAT "/" STR_FORMAT, pt->payload_type, STR_FMT(&pt->encoding), - pt->clock_rate, STR_FMT(&pt->encoding_parameters)); + pt->clock_rate, STR_FMT(&pt->encoding_parameters), + STR_FMT(&pt->format_parameters)); } json_builder_end_array (builder); diff --git a/daemon/sdp.c b/daemon/sdp.c index b0315e2c4..3487ca521 100644 --- a/daemon/sdp.c +++ b/daemon/sdp.c @@ -1104,7 +1104,7 @@ static int fill_endpoint(struct endpoint *ep, const struct sdp_media *media, str static int __rtp_payload_types(struct stream_params *sp, struct sdp_media *media) { - GHashTable *ht; + GHashTable *ht_rtpmap, *ht_fmtp; GQueue *q; GList *ql; struct sdp_attribute *attr; @@ -1114,15 +1114,21 @@ static int __rtp_payload_types(struct stream_params *sp, struct sdp_media *media return 0; /* first go through a=rtpmap and build a hash table of attrs */ - ht = g_hash_table_new(g_int_hash, g_int_equal); + ht_rtpmap = g_hash_table_new(g_int_hash, g_int_equal); q = attr_list_get_by_id(&media->attributes, ATTR_RTPMAP); for (ql = q ? q->head : NULL; ql; ql = ql->next) { struct rtp_payload_type *pt; attr = ql->data; pt = &attr->u.rtpmap.rtp_pt; - g_hash_table_insert(ht, &pt->payload_type, pt); + g_hash_table_insert(ht_rtpmap, &pt->payload_type, pt); + } + // do the same for a=fmtp + ht_fmtp = g_hash_table_new(g_int_hash, g_int_equal); + q = attr_list_get_by_id(&media->attributes, ATTR_FMTP); + for (ql = q ? q->head : NULL; ql; ql = ql->next) { + attr = ql->data; + g_hash_table_insert(ht_fmtp, &attr->u.fmtp.payload_type, &attr->u.fmtp.format_parms_str); } - /* a=fmtp processing would go here */ /* then go through the format list and associate */ for (ql = media->format_list.head; ql; ql = ql->next) { @@ -1139,13 +1145,18 @@ static int __rtp_payload_types(struct stream_params *sp, struct sdp_media *media /* first look in rtpmap for a match, then check RFC types, * else fall back to an "unknown" type */ - ptl = rtp_payload_type(i, ht); + ptl = rtp_payload_type(i, ht_rtpmap); pt = g_slice_alloc0(sizeof(*pt)); if (ptl) *pt = *ptl; else pt->payload_type = i; + + s = g_hash_table_lookup(ht_fmtp, &i); + if (s) + pt->format_parameters = *s; + g_queue_push_tail(&sp->rtp_payload_types, pt); } @@ -1155,7 +1166,8 @@ error: ret = -1; goto out; out: - g_hash_table_destroy(ht); + g_hash_table_destroy(ht_rtpmap); + g_hash_table_destroy(ht_fmtp); return ret; } diff --git a/lib/rtplib.h b/lib/rtplib.h index 3ef82c753..6e525b90e 100644 --- a/lib/rtplib.h +++ b/lib/rtplib.h @@ -21,6 +21,7 @@ struct rtp_payload_type { str encoding; unsigned int clock_rate; str encoding_parameters; + str format_parameters; };