diff --git a/daemon/call.c b/daemon/call.c index bfd95e7e0..0d3e667ad 100644 --- a/daemon/call.c +++ b/daemon/call.c @@ -2646,7 +2646,6 @@ static void __call_monologue_init_from_flags(struct call_monologue *ml, sdp_ng_f flags->session_sdp_orig.username.len); if (!ml->sdp_session_id && flags->session_sdp_orig.session_id.len) ml->sdp_session_id = str_to_ui(&flags->session_sdp_orig.session_id, 0); - ml->sdp_version = flags->session_sdp_orig.version_num; if (ml->sdp_version == ULLONG_MAX) ml->sdp_version = (unsigned int)ssl_random(); @@ -2658,6 +2657,12 @@ static void __call_monologue_init_from_flags(struct call_monologue *ml, sdp_ng_f ml->sdp_session_name = call_strdup_len(call, flags->session_sdp_name.s, flags->session_sdp_name.len); } + /* sdp bandwidth per session level + * 0 value is supported (e.g. b=RR:0 and b=RS:0), to be able to disable rtcp */ + if (flags->session_rr >= 0) + ml->sdp_session_rr = flags->session_rr; + if (flags->session_rs >= 0) + ml->sdp_session_rs = flags->session_rs; } // reset offer ipv4/ipv6/mixed media stats @@ -4196,6 +4201,8 @@ struct call_monologue *__monologue_create(call_t *call) { ret->media_ids = g_hash_table_new((GHashFunc) str_hash, (GEqualFunc) str_equal); ret->ssrc_hash = create_ssrc_hash_call(); ret->sdp_attr_print = sdp_insert_monologue_attributes; + /* explicitely set b=RR/b=RS to -1 so it's not considered as 0 inadvertently */ + ret->sdp_session_rr = ret->sdp_session_rs = -1; gettimeofday(&ret->started, NULL); diff --git a/daemon/sdp.c b/daemon/sdp.c index d93b678cb..321c82442 100644 --- a/daemon/sdp.c +++ b/daemon/sdp.c @@ -1806,6 +1806,8 @@ int sdp_streams(const sdp_sessions_q *sessions, sdp_streams_q *streams, sdp_ng_f sdp_attr_append_other(&flags->session_attributes, &session->attributes); flags->session_sdp_orig = session->origin; flags->session_sdp_name = session->session_name; + flags->session_rr = session->rr; + flags->session_rs = session->rs; for (__auto_type k = session->media_streams.head; k; k = k->next) { media = k->data; @@ -3443,6 +3445,21 @@ static void sdp_out_add_session_name(GString *out, struct call_monologue *monolo g_string_append_printf(out, "s=%s\r\n", sdp_session_name); } +static void sdp_out_add_bandwidth(GString *out, struct call_monologue *monologue) +{ + struct call_monologue *ml = monologue; + struct media_subscription *ms = call_get_top_media_subscription(monologue); + if (ms && ms->monologue) + ml = ms->monologue; + + /* sdp bandwidth per session level + * 0 value is supported (e.g. b=RR:0 and b=RS:0), to be able to disable rtcp */ + if (ml->sdp_session_rr >= 0) + g_string_append_printf(out, "b=RR:%d\r\n", ml->sdp_session_rr); + if (ml->sdp_session_rs >= 0) + g_string_append_printf(out, "b=RS:%d\r\n", ml->sdp_session_rs); +} + static void sdp_out_add_media_connection(GString *out, struct call_media *media, struct packet_stream *rtp_ps, struct stream_params *sp, sdp_ng_flags *flags) @@ -3507,6 +3524,9 @@ int sdp_create(str *out, struct call_monologue *monologue, /* don't set connection on the session level * but instead per media, below */ + /* add bandwidth control per session level */ + sdp_out_add_bandwidth(s, monologue); + /* set timing to always be: 0 0 */ g_string_append(s, "t=0 0\r\n"); diff --git a/include/call.h b/include/call.h index 66effcf0b..96c1e0070 100644 --- a/include/call.h +++ b/include/call.h @@ -602,6 +602,7 @@ struct call_monologue { struct media_player *rec_player; unsigned long long sdp_session_id; unsigned long long sdp_version; + int sdp_session_rr, sdp_session_rs; str last_in_sdp; sdp_sessions_q last_in_sdp_parsed; /* last parsed `sdp_session` */ sdp_streams_q last_in_sdp_streams; /* last parsed `stream_params` */ diff --git a/include/call_interfaces.h b/include/call_interfaces.h index e2afb53bb..f5e9107af 100644 --- a/include/call_interfaces.h +++ b/include/call_interfaces.h @@ -73,6 +73,7 @@ struct sdp_ng_flags { sdp_attr_q session_attributes; // top-level (not part of an m= section) SDP session attributes struct sdp_origin session_sdp_orig; str session_sdp_name; + int session_rr, session_rs; /* b= bandwidth per session level */ /* commands to manipulate attr lines in SDP */ struct sdp_manipulations * sdp_manipulations[__MT_MAX];