@@ -4036,7 +4036,9 @@ void media_subscriptions_clear(subscription_q *q) {
40364036 t_queue_clear_full (q , media_subscription_free );
40374037}
40384038
4039- static void __unsubscribe_media_link (struct call_media * which , subscription_list * which_cm_link )
4039+ __attribute__((nonnull (1 , 2 )))
4040+ static inline void __unsubscribe_media_link_store (struct call_media * which , subscription_list * which_cm_link ,
4041+ subscription_store_ht ht )
40404042{
40414043 struct media_subscription * ms = which_cm_link -> data ;
40424044 struct media_subscription * rev_ms = ms -> link -> data ;
@@ -4054,12 +4056,24 @@ static void __unsubscribe_media_link(struct call_media * which, subscription_lis
40544056 t_hash_table_remove (from -> media_subscribers_ht , rev_ms -> media );
40554057
40564058 g_free (ms );
4057- g_free (rev_ms );
4059+
4060+ if (t_hash_table_is_set (ht ))
4061+ t_hash_table_insert (ht , from , rev_ms );
4062+ else
4063+ g_free (rev_ms );
40584064}
4065+
4066+ __attribute__((nonnull (1 , 2 )))
4067+ static void __unsubscribe_media_link (struct call_media * which , subscription_list * which_cm_link )
4068+ {
4069+ __unsubscribe_media_link_store (which , which_cm_link , subscription_store_ht_null ());
4070+ }
4071+
40594072/**
40604073 * Unsubscribe one particular media subscriber from this call media.
40614074 */
4062- bool __unsubscribe_media (struct call_media * which , struct call_media * from )
4075+ __attribute__((nonnull (1 , 2 )))
4076+ bool __unsubscribe_media (struct call_media * which , struct call_media * from )
40634077{
40644078 if (!t_hash_table_is_set (which -> media_subscriptions_ht )
40654079 || !t_hash_table_is_set (from -> media_subscribers_ht ))
@@ -4104,27 +4118,31 @@ static void __unsubscribe_all_offer_answer_medias(struct call_media * cm, medias
41044118 l = next ;
41054119 }
41064120}
4107- static void __unsubscribe_medias_from_all (struct call_monologue * ml ) {
4121+
4122+ __attribute__((nonnull (1 )))
4123+ static inline void __unsubscribe_medias_from_all (struct call_monologue * ml , subscription_store_ht ht )
4124+ {
41084125 for (int i = 0 ; i < ml -> medias -> len ; i ++ )
41094126 {
4110- struct call_media * media = ml -> medias -> pdata [i ];
4127+ struct call_media * media = ml -> medias -> pdata [i ];
41114128 if (!media )
41124129 continue ;
41134130
41144131 for (__auto_type subcription = media -> media_subscriptions .head ; subcription ; )
41154132 {
41164133 __auto_type next = subcription -> next ;
4117- __unsubscribe_media_link (media , subcription );
4134+ __unsubscribe_media_link_store (media , subcription , ht );
41184135 subcription = next ;
41194136 }
41204137 }
41214138}
4139+
41224140/**
41234141 * Check whether this monologue medias are subscribed to a single other monologue medias.
41244142 */
41254143struct call_monologue * ml_medias_subscribed_to_single_ml (struct call_monologue * ml ) {
41264144 /* detect monologues multiplicity */
4127- struct call_monologue * return_ml = NULL ;
4145+ struct call_monologue * return_ml = NULL ;
41284146 for (unsigned int i = 0 ; i < ml -> medias -> len ; i ++ )
41294147 {
41304148 struct call_media * media = ml -> medias -> pdata [i ];
@@ -4141,7 +4159,7 @@ struct call_monologue * ml_medias_subscribed_to_single_ml(struct call_monologue
41414159 }
41424160 return return_ml ;
41434161}
4144- struct media_subscription * __add_media_subscription (struct call_media * which , struct call_media * to ,
4162+ struct media_subscription * __add_media_subscription (struct call_media * which , struct call_media * to ,
41454163 const struct sink_attrs * attrs )
41464164{
41474165 subscription_list * ret ;
@@ -4374,9 +4392,9 @@ int monologue_publish(struct call_monologue *ml, sdp_streams_q *streams, sdp_ng_
43744392}
43754393
43764394/* called with call->master_lock held in W */
4377- __attribute__((nonnull (1 , 2 , 3 , 4 )))
4395+ __attribute__((nonnull (1 , 2 , 3 )))
43784396static int monologue_subscribe_request1 (struct call_monologue * src_ml , struct call_monologue * dst_ml ,
4379- sdp_ng_flags * flags , unsigned int * index )
4397+ sdp_ng_flags * flags , subscription_store_ht ht )
43804398{
43814399 unsigned int idx_diff = 0 , rev_idx_diff = 0 ;
43824400 g_auto (str_ht ) mid_tracker_dst = str_ht_new ();
@@ -4386,8 +4404,15 @@ static int monologue_subscribe_request1(struct call_monologue *src_ml, struct ca
43864404 struct stream_params * sp = l -> data ;
43874405
43884406 struct call_media * src_media = __get_media (src_ml , sp , flags , 0 , mid_tracker_src );
4389- struct call_media * dst_media = call_get_media (dst_ml , & src_media -> type , src_media -> type_id ,
4390- NULL , false, (* index )++ , mid_tracker_dst );
4407+ struct call_media * dst_media = NULL ;
4408+ __auto_type ms = t_hash_table_lookup (ht , src_media );
4409+ if (ms )
4410+ dst_media = ms -> media ;
4411+ if (!dst_media ) {
4412+ // new media needed
4413+ dst_media = call_get_media (dst_ml , & src_media -> type , src_media -> type_id ,
4414+ NULL , false, dst_ml -> medias -> len + 1 , mid_tracker_dst );
4415+ }
43914416
43924417 /* subscribe dst_ml (subscriber) to src_ml, don't forget to carry the egress flag, if required */
43934418 __add_media_subscription (dst_media , src_media , & (struct sink_attrs ) { .egress = !!flags -> egress });
@@ -4464,12 +4489,13 @@ static int monologue_subscribe_request1(struct call_monologue *src_ml, struct ca
44644489
44654490 return 0 ;
44664491}
4492+
44674493/* called with call->master_lock held in W */
44684494__attribute__((nonnull (1 , 2 , 3 )))
44694495int monologue_subscribe_request (const subscription_q * srms , struct call_monologue * dst_ml , sdp_ng_flags * flags ) {
4470- unsigned int index = 1 ; /* running counter for output/dst medias */
4496+ g_auto ( subscription_store_ht ) ht = subscription_store_ht_new ();
44714497
4472- __unsubscribe_medias_from_all (dst_ml );
4498+ __unsubscribe_medias_from_all (dst_ml , ht );
44734499 __call_monologue_init_from_flags (dst_ml , NULL , flags );
44744500
44754501 g_auto (GQueue ) mls = G_QUEUE_INIT ; /* to avoid duplications */
@@ -4481,7 +4507,7 @@ int monologue_subscribe_request(const subscription_q *srms, struct call_monologu
44814507 continue ;
44824508
44834509 if (!g_queue_find (& mls , src_ml )) {
4484- int ret = monologue_subscribe_request1 (src_ml , dst_ml , flags , & index );
4510+ int ret = monologue_subscribe_request1 (src_ml , dst_ml , flags , ht );
44854511 g_queue_push_tail (& mls , src_ml );
44864512 if (ret )
44874513 return -1 ;
0 commit comments