From 62f50766900bc9bd0a36e305f02584534cbb136f Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Fri, 13 Feb 2026 09:54:10 -0400 Subject: [PATCH] MT#55283 save per-media stream_params instead of the full list of stream params per monologue Change-Id: I5fbee96bbd14525ea93b059a15f2199108b30bf1 --- daemon/call.c | 22 +++++++++++++++++++--- daemon/call_interfaces.c | 9 --------- daemon/janus.c | 1 - daemon/sdp.c | 13 ++++++++++++- include/call.h | 2 +- include/call_interfaces.h | 1 - include/sdp.h | 3 +++ 7 files changed, 35 insertions(+), 16 deletions(-) diff --git a/daemon/call.c b/daemon/call.c index 7c095b256..f6f246a87 100644 --- a/daemon/call.c +++ b/daemon/call.c @@ -3991,6 +3991,8 @@ int monologue_offer_answer(struct call_monologue *monologues[2], sdp_streams_q * media_update_transcoding_flag(receiver_media); media_update_transcoding_flag(sender_media); + + sdp_sp_move(&sender_media->sp, sp); } monologue_bundle_accept(sender_ml, flags); @@ -4342,6 +4344,8 @@ int monologue_publish(struct call_monologue *ml, sdp_streams_q *streams, sdp_ng_ return -1; __ice_init(media); ice_update(media->ice_agent, sp, false); + + sdp_sp_move(&media->sp, sp); } monologue_open_ports(ml); @@ -4359,8 +4363,20 @@ static int monologue_subscribe_request1(struct call_monologue *src_ml, struct ca g_auto(str_ht) mid_tracker_dst = str_ht_new(); g_auto(str_ht) mid_tracker_src = str_ht_new(); - for (__auto_type l = src_ml->last_in_sdp_streams.head; l; l = l->next) { - struct stream_params *sp = l->data; + unsigned int src_media_iter_idx = 0; + + while (true) { + struct stream_params *sp = NULL; + + while (!sp && src_media_iter_idx < src_ml->medias->len) { + struct call_media *src_media_iter = src_ml->medias->pdata[src_media_iter_idx++]; + if (!src_media_iter) + continue; + sp = &src_media_iter->sp; + } + + if (!sp) + break; struct call_media *dst_media = __get_media(dst_ml, sp, flags, (*index)++, mid_tracker_dst); struct call_media *src_media = __get_media(src_ml, sp, flags, 0, mid_tracker_src); @@ -4752,6 +4768,7 @@ static void __call_cleanup(call_t *c) { t38_gateway_put(&md->t38_gateway); audio_player_free(md); mutex_destroy(&md->dtmf_lock); + sdp_sp_clear(&md->sp); } for (__auto_type l = c->monologues.head; l; l = l->next) { @@ -5057,7 +5074,6 @@ void __monologue_free(struct call_monologue *m) { t_queue_clear_full(&m->generic_attributes, sdp_attr_free); t_queue_clear_full(&m->all_attributes, sdp_attr_free); t_queue_clear(&m->tag_aliases); - sdp_streams_clear(&m->last_in_sdp_streams); t_queue_clear(&m->groups_other); g_free(m); } diff --git a/daemon/call_interfaces.c b/daemon/call_interfaces.c index 1de45a01f..774cb11f0 100644 --- a/daemon/call_interfaces.c +++ b/daemon/call_interfaces.c @@ -2546,13 +2546,6 @@ static enum load_limit_reasons call_offer_session_limit(void) { } -void save_last_sdp(struct call_monologue *ml, str *sdp, sdp_sessions_q *parsed, sdp_streams_q *streams) { - sdp_streams_clear(&ml->last_in_sdp_streams); - ml->last_in_sdp_streams = *streams; - t_queue_init(streams); -} - - static enum basic_errors call_ng_basic_checks(sdp_ng_flags *flags) { if (!flags->sdp.s) @@ -2710,7 +2703,6 @@ static const char *call_offer_answer_ng(ng_command_ctx_t *ctx, const char* addr) /* if all fine, prepare an outer sdp and save it */ if (sdp_create(&sdp_out, to_ml, &flags)) { /* TODO: should we save sdp_out? */ - save_last_sdp(from_ml, &sdp, &parsed, &streams); ret = 0; } else @@ -4143,7 +4135,6 @@ const char *call_publish_ng(ng_command_ctx_t *ctx, const char *addr) { if (!ok) return "Failed to create SDP"; - save_last_sdp(ml, &sdp_in, &parsed, &streams); ctx->ngbuf->sdp_out = sdp_out.s; parser->dict_add_str(ctx->resp, "sdp", &sdp_out); diff --git a/daemon/janus.c b/daemon/janus.c index f277d8e36..9f30d1a0e 100644 --- a/daemon/janus.c +++ b/daemon/janus.c @@ -880,7 +880,6 @@ static const char *janus_videoroom_configure(struct websocket_message *wm, struc if (!ml->janus_session) ml->janus_session = obj_get(session); - save_last_sdp(ml, &sdp_in, &parsed, &streams); *jsep_sdp_out = sdp_out; sdp_out = STR_NULL; // ownership passed to output diff --git a/daemon/sdp.c b/daemon/sdp.c index f61db7900..d9da1c0d9 100644 --- a/daemon/sdp.c +++ b/daemon/sdp.c @@ -1788,16 +1788,27 @@ static void __sdp_t38(struct stream_params *sp, struct sdp_media *media) { } -static void sp_free(struct stream_params *s) { +void sdp_sp_clear(struct stream_params *s) { codec_store_cleanup(&s->codecs); ice_candidates_free(&s->ice_candidates); crypto_params_sdes_queue_clear(&s->sdes_params); t_queue_clear_full(&s->generic_attributes, sdp_attr_free); t_queue_clear_full(&s->all_attributes, sdp_attr_free); t_queue_clear_full(&s->extmap, rtp_extension_free); +} + +static void sp_free(struct stream_params *s) { + sdp_sp_clear(s); g_free(s); } +void sdp_sp_move(struct stream_params *dst, struct stream_params *src) { + sdp_sp_clear(dst); + *dst = *src; + *src = (struct stream_params) {}; + src->media_id = dst->media_id; // used by the `tracker` hash table in call_get_media() +} + // Check the list for a legacy non-RFC OSRTP offer: // Given m= lines must be alternating between one RTP and one SRTP m= line, with matching diff --git a/include/call.h b/include/call.h index ab8688aa7..930e7a139 100644 --- a/include/call.h +++ b/include/call.h @@ -504,6 +504,7 @@ struct call_media { unsigned int index; /* RO */ unsigned int unique_id; /* RO */ + struct stream_params sp; str type; enum media_type type_id; str protocol_str; @@ -624,7 +625,6 @@ struct call_monologue { struct media_player *player; struct media_player *rec_player; struct session_bandwidth sdp_session_bandwidth; - sdp_streams_q last_in_sdp_streams; /* last parsed `stream_params` */ GString *last_out_sdp; sdp_origin * session_sdp_orig; /* actual origin belonging to this monologue */ diff --git a/include/call_interfaces.h b/include/call_interfaces.h index b295e4420..ce661d1ff 100644 --- a/include/call_interfaces.h +++ b/include/call_interfaces.h @@ -352,7 +352,6 @@ const char *call_transform_ng(ng_command_ctx_t *); void add_media_to_sub_list(subscription_q *q, struct call_media *media, struct call_monologue *ml); -void save_last_sdp(struct call_monologue *ml, str *sdp, sdp_sessions_q *parsed, sdp_streams_q *streams); void call_ng_flags_init(sdp_ng_flags *out, enum ng_opmode opmode); void call_ng_free_flags(sdp_ng_flags *flags); void call_unlock_release(call_t *c); diff --git a/include/sdp.h b/include/sdp.h index b2850b8db..61c6a516b 100644 --- a/include/sdp.h +++ b/include/sdp.h @@ -57,6 +57,9 @@ int sdp_parse_candidate(struct ice_candidate *cand, const str *s); // returns -1 G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(sdp_streams_q, sdp_streams_clear) G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(sdp_sessions_q, sdp_sessions_clear) +void sdp_sp_clear(struct stream_params *s); +void sdp_sp_move(struct stream_params *dst, struct stream_params *src); + INLINE int is_trickle_ice_address(const struct endpoint *ep) { if (is_addr_unspecified(&ep->address) && ep->port == 9)