diff --git a/daemon/call.c b/daemon/call.c index 3382fe0d8..a165975ca 100644 --- a/daemon/call.c +++ b/daemon/call.c @@ -743,6 +743,7 @@ void call_free(void) { void payload_type_free(struct rtp_payload_type *p) { + g_queue_clear(&p->rtcp_fb); g_slice_free1(sizeof(*p), p); } diff --git a/daemon/codec.c b/daemon/codec.c index 7410bd088..444c5b695 100644 --- a/daemon/codec.c +++ b/daemon/codec.c @@ -3131,11 +3131,17 @@ static void __rtp_payload_type_dup(struct call *call, struct rtp_payload_type *p call_str_cpy(call, &pt->encoding_parameters, &pt->encoding_parameters); call_str_cpy(call, &pt->format_parameters, &pt->format_parameters); call_str_cpy(call, &pt->codec_opts, &pt->codec_opts); - call_str_cpy(call, &pt->rtcp_fb, &pt->rtcp_fb); + for (GList *l = pt->rtcp_fb.head; l; l = l->next) { + str *fb = l->data; + call_str_cpy(call, fb, fb); + } } static struct rtp_payload_type *__rtp_payload_type_copy(const struct rtp_payload_type *pt) { struct rtp_payload_type *pt_copy = g_slice_alloc(sizeof(*pt)); *pt_copy = *pt; + g_queue_init(&pt_copy->rtcp_fb); + for (GList *l = pt->rtcp_fb.head; l; l = l->next) + g_queue_push_tail(&pt_copy->rtcp_fb, l->data); return pt_copy; } static void __rtp_payload_type_add_name(GHashTable *ht, struct rtp_payload_type *pt) diff --git a/daemon/sdp.c b/daemon/sdp.c index dd6efe75f..5995bfebf 100644 --- a/daemon/sdp.c +++ b/daemon/sdp.c @@ -1319,13 +1319,14 @@ static int __rtp_payload_types(struct stream_params *sp, struct sdp_media *media g_hash_table_insert(ht_fmtp, &attr->u.fmtp.payload_type, &attr->u.fmtp.format_parms_str); } // do the same for a=rtcp-fb - ht_rtcp_fb = g_hash_table_new(g_int_hash, g_int_equal); + ht_rtcp_fb = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, (GDestroyNotify) g_queue_free); q = attr_list_get_by_id(&media->attributes, ATTR_RTCP_FB); for (ql = q ? q->head : NULL; ql; ql = ql->next) { attr = ql->data; if (attr->u.rtcp_fb.payload_type == -1) continue; - g_hash_table_insert(ht_rtcp_fb, &attr->u.rtcp_fb.payload_type, &attr->u.rtcp_fb.value); + GQueue *rq = g_hash_table_lookup_queue_new(ht_rtcp_fb, GINT_TO_POINTER(attr->u.rtcp_fb.payload_type), NULL); + g_queue_push_tail(rq, &attr->u.rtcp_fb.value); } /* then go through the format list and associate */ @@ -1357,9 +1358,13 @@ static int __rtp_payload_types(struct stream_params *sp, struct sdp_media *media s = g_hash_table_lookup(ht_fmtp, &i); if (s) pt->format_parameters = *s; - s = g_hash_table_lookup(ht_rtcp_fb, &i); - if (s) - pt->rtcp_fb = *s; + GQueue *rq = g_hash_table_lookup(ht_rtcp_fb, GINT_TO_POINTER(i)); + if (rq) { + // steal the list contents and free the list + pt->rtcp_fb = *rq; + g_queue_init(rq); + g_hash_table_remove(ht_rtcp_fb, GINT_TO_POINTER(i)); // frees `rq` + } // fill in ptime if (sp->ptime) @@ -1796,10 +1801,11 @@ static void insert_codec_parameters(struct sdp_chopper *chop, struct call_media pt->payload_type, STR_FMT(&pt->format_parameters)); } - if (pt->rtcp_fb.len) { + for (GList *l = pt->rtcp_fb.head; l; l = l->next) { + str *fb = l->data; chopper_append_printf(chop, "a=rtcp-fb:%u " STR_FORMAT "\r\n", pt->payload_type, - STR_FMT(&pt->rtcp_fb)); + STR_FMT(fb)); } } } diff --git a/lib/rtplib.h b/lib/rtplib.h index 3afbf3dc6..f29b11ce0 100644 --- a/lib/rtplib.h +++ b/lib/rtplib.h @@ -26,7 +26,7 @@ struct rtp_payload_type { int channels; // 2 str format_parameters; // value of a=fmtp str codec_opts; // extra codec-specific options - str rtcp_fb; // a=rtcp-fb:... + GQueue rtcp_fb; // a=rtcp-fb:... int ptime; // default from RFC int bitrate; diff --git a/t/auto-daemon-tests.pl b/t/auto-daemon-tests.pl index 712f72cca..605b08495 100755 --- a/t/auto-daemon-tests.pl +++ b/t/auto-daemon-tests.pl @@ -8046,6 +8046,8 @@ a=msid:qDSKVQw0XQOFzGhek25Kn3RLxyHTM2ooxMUY 7d669de6-65e9-4fbe-829e-e89dc4baf81c a=rtcp-mux a=rtpmap:111 opus/48000/2 a=rtcp-fb:111 transport-cc +a=rtcp-fb:111 testing +a=rtcp-fb:111 foobar a=fmtp:111 minptime=10;useinbandfec=1 a=rtpmap:103 ISAC/16000 a=rtpmap:104 ISAC/32000 @@ -8101,6 +8103,8 @@ a=mid:0 a=rtpmap:111 opus/48000/2 a=fmtp:111 minptime=10;useinbandfec=1 a=rtcp-fb:111 transport-cc +a=rtcp-fb:111 testing +a=rtcp-fb:111 foobar a=rtpmap:103 ISAC/16000 a=rtpmap:104 ISAC/32000 a=rtpmap:9 G722/8000