bridge_softmix / res_rtp_asterisk: Fix packet loss and renegotiation issues.
[asterisk/asterisk.git] / bridges / bridge_softmix.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2011, Digium, Inc.
5  *
6  * Joshua Colp <jcolp@digium.com>
7  * David Vossel <dvossel@digium.com>
8  *
9  * See http://www.asterisk.org for more information about
10  * the Asterisk project. Please do not directly contact
11  * any of the maintainers of this project for assistance;
12  * the project provides a web site, mailing lists and IRC
13  * channels for your use.
14  *
15  * This program is free software, distributed under the terms of
16  * the GNU General Public License Version 2. See the LICENSE file
17  * at the top of the source tree.
18  */
19
20 /*! \file
21  *
22  * \brief Multi-party software based channel mixing
23  *
24  * \author Joshua Colp <jcolp@digium.com>
25  * \author David Vossel <dvossel@digium.com>
26  *
27  * \ingroup bridges
28  */
29
30 /*** MODULEINFO
31         <support_level>core</support_level>
32  ***/
33
34 #include "asterisk.h"
35
36 #include "asterisk/stream.h"
37 #include "asterisk/test.h"
38 #include "asterisk/vector.h"
39 #include "bridge_softmix/include/bridge_softmix_internal.h"
40
41 /*! The minimum sample rate of the bridge. */
42 #define SOFTMIX_MIN_SAMPLE_RATE 8000    /* 8 kHz sample rate */
43
44 /*! \brief Interval at which mixing will take place. Valid options are 10, 20, and 40. */
45 #define DEFAULT_SOFTMIX_INTERVAL 20
46
47 /*! \brief Size of the buffer used for sample manipulation */
48 #define SOFTMIX_DATALEN(rate, interval) ((rate/50) * (interval / 10))
49
50 /*! \brief Number of samples we are dealing with */
51 #define SOFTMIX_SAMPLES(rate, interval) (SOFTMIX_DATALEN(rate, interval) / 2)
52
53 /*! \brief Number of mixing iterations to perform between gathering statistics. */
54 #define SOFTMIX_STAT_INTERVAL 100
55
56 /* This is the threshold in ms at which a channel's own audio will stop getting
57  * mixed out its own write audio stream because it is not talking. */
58 #define DEFAULT_SOFTMIX_SILENCE_THRESHOLD 2500
59 #define DEFAULT_SOFTMIX_TALKING_THRESHOLD 160
60
61 #define SOFTBRIDGE_VIDEO_DEST_PREFIX "softbridge_dest"
62 #define SOFTBRIDGE_VIDEO_DEST_LEN strlen(SOFTBRIDGE_VIDEO_DEST_PREFIX)
63 #define SOFTBRIDGE_VIDEO_DEST_SEPARATOR '_'
64
65 struct softmix_stats {
66         /*! Each index represents a sample rate used above the internal rate. */
67         unsigned int sample_rates[16];
68         /*! Each index represents the number of channels using the same index in the sample_rates array.  */
69         unsigned int num_channels[16];
70         /*! The number of channels above the internal sample rate */
71         unsigned int num_above_internal_rate;
72         /*! The number of channels at the internal sample rate */
73         unsigned int num_at_internal_rate;
74         /*! The absolute highest sample rate preferred by any channel in the bridge */
75         unsigned int highest_supported_rate;
76         /*! Is the sample rate locked by the bridge, if so what is that rate.*/
77         unsigned int locked_rate;
78 };
79
80 struct softmix_translate_helper_entry {
81         int num_times_requested; /*!< Once this entry is no longer requested, free the trans_pvt
82                                       and re-init if it was usable. */
83         struct ast_format *dst_format; /*!< The destination format for this helper */
84         struct ast_trans_pvt *trans_pvt; /*!< the translator for this slot. */
85         struct ast_frame *out_frame; /*!< The output frame from the last translation */
86         AST_LIST_ENTRY(softmix_translate_helper_entry) entry;
87 };
88
89 struct softmix_translate_helper {
90         struct ast_format *slin_src; /*!< the source format expected for all the translators */
91         AST_LIST_HEAD_NOLOCK(, softmix_translate_helper_entry) entries;
92 };
93
94 static struct softmix_translate_helper_entry *softmix_translate_helper_entry_alloc(struct ast_format *dst)
95 {
96         struct softmix_translate_helper_entry *entry;
97         if (!(entry = ast_calloc(1, sizeof(*entry)))) {
98                 return NULL;
99         }
100         entry->dst_format = ao2_bump(dst);
101         /* initialize this to one so that the first time through the cleanup code after
102            allocation it won't be removed from the entry list */
103         entry->num_times_requested = 1;
104         return entry;
105 }
106
107 static void *softmix_translate_helper_free_entry(struct softmix_translate_helper_entry *entry)
108 {
109         ao2_cleanup(entry->dst_format);
110
111         if (entry->trans_pvt) {
112                 ast_translator_free_path(entry->trans_pvt);
113         }
114         if (entry->out_frame) {
115                 ast_frfree(entry->out_frame);
116         }
117         ast_free(entry);
118         return NULL;
119 }
120
121 static void softmix_translate_helper_init(struct softmix_translate_helper *trans_helper, unsigned int sample_rate)
122 {
123         memset(trans_helper, 0, sizeof(*trans_helper));
124         trans_helper->slin_src = ast_format_cache_get_slin_by_rate(sample_rate);
125 }
126
127 static void softmix_translate_helper_destroy(struct softmix_translate_helper *trans_helper)
128 {
129         struct softmix_translate_helper_entry *entry;
130
131         while ((entry = AST_LIST_REMOVE_HEAD(&trans_helper->entries, entry))) {
132                 softmix_translate_helper_free_entry(entry);
133         }
134 }
135
136 static void softmix_translate_helper_change_rate(struct softmix_translate_helper *trans_helper, unsigned int sample_rate)
137 {
138         struct softmix_translate_helper_entry *entry;
139
140         trans_helper->slin_src = ast_format_cache_get_slin_by_rate(sample_rate);
141         AST_LIST_TRAVERSE_SAFE_BEGIN(&trans_helper->entries, entry, entry) {
142                 if (entry->trans_pvt) {
143                         ast_translator_free_path(entry->trans_pvt);
144                         if (!(entry->trans_pvt = ast_translator_build_path(entry->dst_format, trans_helper->slin_src))) {
145                                 AST_LIST_REMOVE_CURRENT(entry);
146                                 entry = softmix_translate_helper_free_entry(entry);
147                         }
148                 }
149         }
150         AST_LIST_TRAVERSE_SAFE_END;
151 }
152
153 /*!
154  * \internal
155  * \brief Get the next available audio on the softmix channel's read stream
156  * and determine if it should be mixed out or not on the write stream.
157  *
158  * \retval pointer to buffer containing the exact number of samples requested on success.
159  * \retval NULL if no samples are present
160  */
161 static int16_t *softmix_process_read_audio(struct softmix_channel *sc, unsigned int num_samples)
162 {
163         if ((ast_slinfactory_available(&sc->factory) >= num_samples) &&
164                 ast_slinfactory_read(&sc->factory, sc->our_buf, num_samples)) {
165                 sc->have_audio = 1;
166                 return sc->our_buf;
167         }
168         sc->have_audio = 0;
169         return NULL;
170 }
171
172 /*!
173  * \internal
174  * \brief Process a softmix channel's write audio
175  *
176  * \details This function will remove the channel's talking from its own audio if present and
177  * possibly even do the channel's write translation for it depending on how many other
178  * channels use the same write format.
179  */
180 static void softmix_process_write_audio(struct softmix_translate_helper *trans_helper,
181         struct ast_format *raw_write_fmt,
182         struct softmix_channel *sc, unsigned int default_sample_size)
183 {
184         struct softmix_translate_helper_entry *entry = NULL;
185         int i;
186
187         /* If we provided audio that was not determined to be silence,
188          * then take it out while in slinear format. */
189         if (sc->have_audio && sc->talking && !sc->binaural) {
190                 for (i = 0; i < sc->write_frame.samples; i++) {
191                         ast_slinear_saturated_subtract(&sc->final_buf[i], &sc->our_buf[i]);
192                 }
193                 /* check to see if any entries exist for the format. if not we'll want
194                    to remove it during cleanup */
195                 AST_LIST_TRAVERSE(&trans_helper->entries, entry, entry) {
196                         if (ast_format_cmp(entry->dst_format, raw_write_fmt) == AST_FORMAT_CMP_EQUAL) {
197                                 ++entry->num_times_requested;
198                                 break;
199                         }
200                 }
201                 /* do not do any special write translate optimization if we had to make
202                  * a special mix for them to remove their own audio. */
203                 return;
204         } else if (sc->have_audio && sc->talking && sc->binaural > 0) {
205                 /*
206                  * Binaural audio requires special saturated substract since we have two
207                  * audio signals per channel now.
208                  */
209                 softmix_process_write_binaural_audio(sc, default_sample_size);
210                 return;
211         }
212
213         /* Attempt to optimize channels using the same translation path/codec. Build a list of entries
214            of translation paths and track the number of references for each type. Each one of the same
215            type should be able to use the same out_frame. Since the optimization is only necessary for
216            multiple channels (>=2) using the same codec make sure resources are allocated only when
217            needed and released when not (see also softmix_translate_helper_cleanup */
218         AST_LIST_TRAVERSE(&trans_helper->entries, entry, entry) {
219                 if (sc->binaural != 0) {
220                         continue;
221                 }
222                 if (ast_format_cmp(entry->dst_format, raw_write_fmt) == AST_FORMAT_CMP_EQUAL) {
223                         entry->num_times_requested++;
224                 } else {
225                         continue;
226                 }
227                 if (!entry->trans_pvt && (entry->num_times_requested > 1)) {
228                         entry->trans_pvt = ast_translator_build_path(entry->dst_format, trans_helper->slin_src);
229                 }
230                 if (entry->trans_pvt && !entry->out_frame) {
231                         entry->out_frame = ast_translate(entry->trans_pvt, &sc->write_frame, 0);
232                 }
233                 if (entry->out_frame && entry->out_frame->frametype == AST_FRAME_VOICE
234                                 && entry->out_frame->datalen < MAX_DATALEN) {
235                         ao2_replace(sc->write_frame.subclass.format, entry->out_frame->subclass.format);
236                         memcpy(sc->final_buf, entry->out_frame->data.ptr, entry->out_frame->datalen);
237                         sc->write_frame.datalen = entry->out_frame->datalen;
238                         sc->write_frame.samples = entry->out_frame->samples;
239                 }
240                 break;
241         }
242
243         /* add new entry into list if this format destination was not matched. */
244         if (!entry && (entry = softmix_translate_helper_entry_alloc(raw_write_fmt))) {
245                 AST_LIST_INSERT_HEAD(&trans_helper->entries, entry, entry);
246         }
247 }
248
249 static void softmix_translate_helper_cleanup(struct softmix_translate_helper *trans_helper)
250 {
251         struct softmix_translate_helper_entry *entry;
252
253         AST_LIST_TRAVERSE_SAFE_BEGIN(&trans_helper->entries, entry, entry) {
254                 /* if it hasn't been requested then remove it */
255                 if (!entry->num_times_requested) {
256                         AST_LIST_REMOVE_CURRENT(entry);
257                         softmix_translate_helper_free_entry(entry);
258                         continue;
259                 }
260
261                 if (entry->out_frame) {
262                         ast_frfree(entry->out_frame);
263                         entry->out_frame = NULL;
264                 }
265
266                 /* nothing is optimized for a single path reference, so there is
267                    no reason to continue to hold onto the codec */
268                 if (entry->num_times_requested == 1 && entry->trans_pvt) {
269                         ast_translator_free_path(entry->trans_pvt);
270                         entry->trans_pvt = NULL;
271                 }
272
273                 /* for each iteration (a mixing run) in the bridge softmix thread the number
274                    of references to a given entry is recalculated, so reset the number of
275                    times requested */
276                 entry->num_times_requested = 0;
277         }
278         AST_LIST_TRAVERSE_SAFE_END;
279 }
280
281 static void set_softmix_bridge_data(int rate, int interval, struct ast_bridge_channel *bridge_channel, int reset, int set_binaural, int binaural_pos_id, int is_announcement)
282 {
283         struct softmix_channel *sc = bridge_channel->tech_pvt;
284         struct ast_format *slin_format;
285         int setup_fail;
286
287 #ifdef BINAURAL_RENDERING
288         if (interval != BINAURAL_MIXING_INTERVAL) {
289                 interval = BINAURAL_MIXING_INTERVAL;
290         }
291 #endif
292
293         /* The callers have already ensured that sc is never NULL. */
294         ast_assert(sc != NULL);
295
296         slin_format = ast_format_cache_get_slin_by_rate(rate);
297
298         ast_mutex_lock(&sc->lock);
299         if (reset) {
300                 ast_slinfactory_destroy(&sc->factory);
301                 ast_dsp_free(sc->dsp);
302         }
303
304         /* Setup write frame parameters */
305         sc->write_frame.frametype = AST_FRAME_VOICE;
306         /*
307          * NOTE: The write_frame format holds a reference because translation
308          * could be needed and the format changed to the translated format
309          * for the channel.  The translated format may not be a
310          * static cached format.
311          */
312         ao2_replace(sc->write_frame.subclass.format, slin_format);
313         sc->write_frame.data.ptr = sc->final_buf;
314         sc->write_frame.datalen = SOFTMIX_DATALEN(rate, interval);
315         sc->write_frame.samples = SOFTMIX_SAMPLES(rate, interval);
316
317         /* We will store the rate here cause we need to set the data again when a channel is unsuspended */
318         sc->rate = rate;
319
320         /* If the channel will contain binaural data we will set a identifier in the channel
321          * if set_binaural == -1 this is just a sample rate update, will ignore it. */
322         if (set_binaural == 1) {
323                 sc->binaural = 1;
324         } else if (set_binaural == 0) {
325                 sc->binaural = 0;
326         }
327
328         /* Setting the binaural position. This doesn't require a change of the overlaying channel infos
329          * and doesn't have to be done if we just updating sample rates. */
330         if (binaural_pos_id != -1) {
331                 sc->binaural_pos = binaural_pos_id;
332         }
333         if (is_announcement != -1) {
334                 sc->is_announcement = is_announcement;
335         }
336
337         /*
338          * NOTE: The read_slin_format does not hold a reference because it
339          * will always be a signed linear format.
340          */
341         sc->read_slin_format = slin_format;
342
343         /* Setup smoother */
344         setup_fail = ast_slinfactory_init_with_format(&sc->factory, slin_format);
345
346         /* set new read and write formats on channel. */
347         ast_channel_lock(bridge_channel->chan);
348         setup_fail |= ast_set_read_format_path(bridge_channel->chan,
349                 ast_channel_rawreadformat(bridge_channel->chan), slin_format);
350         ast_channel_unlock(bridge_channel->chan);
351
352         /* If channel contains binaural data we will set it here for the trans_pvt. */
353         if (set_binaural == 1 || (set_binaural == -1 && sc->binaural == 1)) {
354                 setup_fail |= ast_set_write_format_interleaved_stereo(bridge_channel->chan, slin_format);
355         } else if (set_binaural == 0) {
356                 setup_fail |= ast_set_write_format(bridge_channel->chan, slin_format);
357         }
358
359         /* set up new DSP.  This is on the read side only right before the read frame enters the smoother.  */
360         sc->dsp = ast_dsp_new_with_rate(rate);
361         if (setup_fail || !sc->dsp) {
362                 /* Bad news.  Could not setup the channel for softmix. */
363                 ast_mutex_unlock(&sc->lock);
364                 ast_bridge_channel_leave_bridge(bridge_channel, BRIDGE_CHANNEL_STATE_END, 0);
365                 return;
366         }
367
368         /* we want to aggressively detect silence to avoid feedback */
369         if (bridge_channel->tech_args.talking_threshold) {
370                 ast_dsp_set_threshold(sc->dsp, bridge_channel->tech_args.talking_threshold);
371         } else {
372                 ast_dsp_set_threshold(sc->dsp, DEFAULT_SOFTMIX_TALKING_THRESHOLD);
373         }
374
375         ast_mutex_unlock(&sc->lock);
376 }
377
378 /*!
379  * \internal
380  * \brief Poke the mixing thread in case it is waiting for an active channel.
381  * \since 12.0.0
382  *
383  * \param softmix_data Bridge mixing data.
384  *
385  * \return Nothing
386  */
387 static void softmix_poke_thread(struct softmix_bridge_data *softmix_data)
388 {
389         ast_mutex_lock(&softmix_data->lock);
390         ast_cond_signal(&softmix_data->cond);
391         ast_mutex_unlock(&softmix_data->lock);
392 }
393
394 /*! \brief Function called when a channel is unsuspended from the bridge */
395 static void softmix_bridge_unsuspend(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
396 {
397 #ifdef BINAURAL_RENDERING
398         struct softmix_channel *sc = bridge_channel->tech_pvt;
399         if (sc->binaural) {
400                 /* Restore some usefull data if it was a binaural channel */
401                 struct ast_format *slin_format;
402
403                 slin_format = ast_format_cache_get_slin_by_rate(sc->rate);
404                 ast_set_write_format_interleaved_stereo(bridge_channel->chan, slin_format);
405         }
406 #endif
407         if (bridge->tech_pvt) {
408                 softmix_poke_thread(bridge->tech_pvt);
409         }
410 }
411
412 /*!
413  * \brief Determine if a stream is a video source stream.
414  *
415  * \param stream The stream to test
416  * \retval 1 The stream is a video source
417  * \retval 0 The stream is not a video source
418  */
419 static int is_video_source(const struct ast_stream *stream)
420 {
421         if (ast_stream_get_type(stream) == AST_MEDIA_TYPE_VIDEO &&
422                 strncmp(ast_stream_get_name(stream), SOFTBRIDGE_VIDEO_DEST_PREFIX,
423                         SOFTBRIDGE_VIDEO_DEST_LEN)) {
424                 return 1;
425         }
426
427         return 0;
428 }
429
430 /*!
431  * \brief Determine if a stream is a video destination stream.
432  *
433  * A source channel name can be provided to narrow this to a destination stream
434  * for a particular source channel. Further, a source stream name can be provided
435  * to narrow this to a particular source stream's destination. However, empty strings
436  * can be provided to match any destination video stream, regardless of source channel
437  * or source stream.
438  *
439  * \param stream The stream to test
440  * \param source_channel_name The name of a source video channel to match
441  * \param source_stream_name The name of the source video stream to match
442  * \retval 1 The stream is a video destination stream
443  * \retval 0 The stream is not a video destination stream
444  */
445 static int is_video_dest(const struct ast_stream *stream, const char *source_channel_name,
446         const char *source_stream_name)
447 {
448         char *dest_video_name;
449         size_t dest_video_name_len;
450
451         if (ast_stream_get_type(stream) != AST_MEDIA_TYPE_VIDEO) {
452                 return 0;
453         }
454
455         dest_video_name_len = SOFTBRIDGE_VIDEO_DEST_LEN + 1;
456
457         if (!ast_strlen_zero(source_channel_name)) {
458                 dest_video_name_len += strlen(source_channel_name) + 1;
459                 if (!ast_strlen_zero(source_stream_name)) {
460                         dest_video_name_len += strlen(source_stream_name) + 1;
461                 }
462         }
463         dest_video_name = ast_alloca(dest_video_name_len);
464
465         if (!ast_strlen_zero(source_channel_name)) {
466                 if (!ast_strlen_zero(source_stream_name)) {
467                         snprintf(dest_video_name, dest_video_name_len, "%s%c%s%c%s",
468                                 SOFTBRIDGE_VIDEO_DEST_PREFIX, SOFTBRIDGE_VIDEO_DEST_SEPARATOR,
469                                 source_channel_name, SOFTBRIDGE_VIDEO_DEST_SEPARATOR,
470                                 source_stream_name);
471                         return !strcmp(ast_stream_get_name(stream), dest_video_name);
472                 } else {
473                         snprintf(dest_video_name, dest_video_name_len, "%s%c%s",
474                                 SOFTBRIDGE_VIDEO_DEST_PREFIX, SOFTBRIDGE_VIDEO_DEST_SEPARATOR,
475                                 source_channel_name);
476                         return !strncmp(ast_stream_get_name(stream), dest_video_name, dest_video_name_len - 1);
477                 }
478         } else {
479                 snprintf(dest_video_name, dest_video_name_len, "%s",
480                         SOFTBRIDGE_VIDEO_DEST_PREFIX);
481                 return !strncmp(ast_stream_get_name(stream), dest_video_name, dest_video_name_len - 1);
482         }
483
484         return 0;
485 }
486
487 static int append_source_streams(struct ast_stream_topology *dest,
488         const char *channel_name,
489         const struct ast_stream_topology *source)
490 {
491         int i;
492
493         for (i = 0; i < ast_stream_topology_get_count(source); ++i) {
494                 struct ast_stream *stream;
495                 struct ast_stream *stream_clone;
496                 char *stream_clone_name;
497                 size_t stream_clone_name_len;
498
499                 stream = ast_stream_topology_get_stream(source, i);
500                 if (!is_video_source(stream)) {
501                         continue;
502                 }
503
504                 /* The +3 is for the two underscore separators and null terminator */
505                 stream_clone_name_len = SOFTBRIDGE_VIDEO_DEST_LEN + strlen(channel_name) + strlen(ast_stream_get_name(stream)) + 3;
506                 stream_clone_name = ast_alloca(stream_clone_name_len);
507                 snprintf(stream_clone_name, stream_clone_name_len, "%s_%s_%s", SOFTBRIDGE_VIDEO_DEST_PREFIX,
508                         channel_name, ast_stream_get_name(stream));
509
510                 stream_clone = ast_stream_clone(stream, stream_clone_name);
511                 if (!stream_clone) {
512                         return -1;
513                 }
514                 if (ast_stream_topology_append_stream(dest, stream_clone) < 0) {
515                         ast_stream_free(stream_clone);
516                         return -1;
517                 }
518         }
519
520         return 0;
521 }
522
523 static int append_all_streams(struct ast_stream_topology *dest,
524         const struct ast_stream_topology *source)
525 {
526         int i;
527
528         for (i = 0; i < ast_stream_topology_get_count(source); ++i) {
529                 struct ast_stream *clone;
530
531                 clone = ast_stream_clone(ast_stream_topology_get_stream(source, i), NULL);
532                 if (!clone) {
533                         return -1;
534                 }
535                 if (ast_stream_topology_append_stream(dest, clone) < 0) {
536                         ast_stream_free(clone);
537                         return -1;
538                 }
539         }
540
541         return 0;
542 }
543
544 /*!
545  * \brief Issue channel stream topology change requests.
546  *
547  * When in SFU mode, each participant needs to be able to
548  * send video directly to other participants in the bridge.
549  * This means that all participants need to have their topologies
550  * updated. The joiner needs to have destination streams for
551  * all current participants, and the current participants need
552  * to have destinations streams added for the joiner's sources.
553  *
554  * \param joiner The channel that is joining the softmix bridge
555  * \param participants The current participants in the softmix bridge
556  */
557 static void sfu_topologies_on_join(struct ast_bridge_channel *joiner, struct ast_bridge_channels_list *participants)
558 {
559         struct ast_stream_topology *joiner_topology = NULL;
560         struct ast_stream_topology *joiner_video = NULL;
561         struct ast_stream_topology *existing_video = NULL;
562         struct ast_bridge_channel *participant;
563
564         joiner_video = ast_stream_topology_alloc();
565         if (!joiner_video) {
566                 return;
567         }
568
569         if (append_source_streams(joiner_video, ast_channel_name(joiner->chan), ast_channel_get_stream_topology(joiner->chan))) {
570                 goto cleanup;
571         }
572
573         existing_video = ast_stream_topology_alloc();
574         if (!existing_video) {
575                 goto cleanup;
576         }
577
578         AST_LIST_TRAVERSE(participants, participant, entry) {
579                 if (participant == joiner) {
580                         continue;
581                 }
582                 if (append_source_streams(existing_video, ast_channel_name(participant->chan),
583                                 ast_channel_get_stream_topology(participant->chan))) {
584                         goto cleanup;
585                 }
586         }
587
588         joiner_topology = ast_stream_topology_clone(ast_channel_get_stream_topology(joiner->chan));
589         if (!joiner_topology) {
590                 goto cleanup;
591         }
592         if (append_all_streams(joiner_topology, existing_video)) {
593                 goto cleanup;
594         }
595         ast_channel_request_stream_topology_change(joiner->chan, joiner_topology, NULL);
596
597         AST_LIST_TRAVERSE(participants, participant, entry) {
598                 struct ast_stream_topology *participant_topology;
599
600                 if (participant == joiner) {
601                         continue;
602                 }
603                 participant_topology = ast_stream_topology_clone(ast_channel_get_stream_topology(participant->chan));
604                 if (!participant_topology) {
605                         goto cleanup;
606                 }
607                 if (append_all_streams(participant_topology, joiner_video)) {
608                         ast_stream_topology_free(participant_topology);
609                         goto cleanup;
610                 }
611                 ast_channel_request_stream_topology_change(participant->chan, participant_topology, NULL);
612                 ast_stream_topology_free(participant_topology);
613         }
614
615 cleanup:
616         ast_stream_topology_free(joiner_video);
617         ast_stream_topology_free(existing_video);
618         ast_stream_topology_free(joiner_topology);
619 }
620
621 /*! \brief Function called when a channel is joined into the bridge */
622 static int softmix_bridge_join(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
623 {
624         struct softmix_channel *sc;
625         struct softmix_bridge_data *softmix_data;
626         int set_binaural = 0;
627         /*
628          * If false, the channel will be convolved, but since it is a non stereo channel, output
629          * will be mono.
630          */
631         int skip_binaural_output = 1;
632         int pos_id;
633         int is_announcement = 0;
634         int samplerate_change;
635
636         softmix_data = bridge->tech_pvt;
637         if (!softmix_data) {
638                 return -1;
639         }
640
641         /* Create a new softmix_channel structure and allocate various things on it */
642         if (!(sc = ast_calloc(1, sizeof(*sc)))) {
643                 return -1;
644         }
645
646         samplerate_change = softmix_data->internal_rate;
647         pos_id = -1;
648         if (bridge->softmix.binaural_active) {
649                 if (strncmp(ast_channel_name(bridge_channel->chan), "CBAnn", 5) != 0) {
650                         set_binaural = ast_format_get_channel_count(bridge_channel->write_format) > 1 ? 1 : 0;
651                         if (set_binaural) {
652                                 softmix_data->internal_rate = samplerate_change;
653                         }
654                         skip_binaural_output = 0;
655                 } else {
656                         is_announcement = 1;
657                 }
658                 if (set_binaural) {
659                         softmix_data->convolve.binaural_active = 1;
660                 }
661                 if (!skip_binaural_output)      {
662                         pos_id = set_binaural_data_join(&softmix_data->convolve, softmix_data->default_sample_size);
663                         if (pos_id == -1) {
664                                 ast_log(LOG_ERROR, "Bridge %s: Failed to join channel %s. "
665                                                 "Could not allocate enough memory.\n", bridge->uniqueid,
666                                                 ast_channel_name(bridge_channel->chan));
667                                 return -1;
668                         }
669                 }
670         }
671
672         /* Can't forget the lock */
673         ast_mutex_init(&sc->lock);
674
675         /* Can't forget to record our pvt structure within the bridged channel structure */
676         bridge_channel->tech_pvt = sc;
677
678         set_softmix_bridge_data(softmix_data->internal_rate,
679                 softmix_data->internal_mixing_interval
680                         ? softmix_data->internal_mixing_interval
681                         : DEFAULT_SOFTMIX_INTERVAL,
682                 bridge_channel, 0, set_binaural, pos_id, is_announcement);
683
684         if (bridge->softmix.video_mode.mode == AST_BRIDGE_VIDEO_MODE_SFU) {
685                 sfu_topologies_on_join(bridge_channel, &bridge->channels);
686         }
687
688         softmix_poke_thread(softmix_data);
689         return 0;
690 }
691
692 static int remove_destination_streams(struct ast_stream_topology *dest,
693         const char *channel_name,
694         const struct ast_stream_topology *source)
695 {
696         int i;
697
698         for (i = 0; i < ast_stream_topology_get_count(source); ++i) {
699                 struct ast_stream *stream;
700                 struct ast_stream *stream_clone;
701
702                 stream = ast_stream_topology_get_stream(source, i);
703
704                 stream_clone = ast_stream_clone(stream, NULL);
705                 if (!stream_clone) {
706                         continue;
707                 }
708
709                 if (is_video_dest(stream, channel_name, NULL)) {
710                         ast_stream_set_state(stream_clone, AST_STREAM_STATE_REMOVED);
711                 }
712
713                 if (ast_stream_topology_append_stream(dest, stream_clone) < 0) {
714                         ast_stream_free(stream_clone);
715                 }
716         }
717
718         return 0;
719 }
720
721 static int sfu_topologies_on_leave(struct ast_bridge_channel *leaver, struct ast_bridge_channels_list *participants)
722 {
723         struct ast_stream_topology *leaver_topology;
724         struct ast_bridge_channel *participant;
725
726         leaver_topology = ast_stream_topology_alloc();
727         if (!leaver_topology) {
728                 return -1;
729         }
730
731         AST_LIST_TRAVERSE(participants, participant, entry) {
732                 struct ast_stream_topology *participant_topology;
733
734                 participant_topology = ast_stream_topology_alloc();
735                 if (!participant_topology) {
736                         continue;
737                 }
738
739                 remove_destination_streams(participant_topology, ast_channel_name(leaver->chan), ast_channel_get_stream_topology(participant->chan));
740                 ast_channel_request_stream_topology_change(participant->chan, participant_topology, NULL);
741                 ast_stream_topology_free(participant_topology);
742         }
743
744         remove_destination_streams(leaver_topology, "", ast_channel_get_stream_topology(leaver->chan));
745         ast_channel_request_stream_topology_change(leaver->chan, leaver_topology, NULL);
746         ast_stream_topology_free(leaver_topology);
747
748         return 0;
749 }
750
751 /*! \brief Function called when a channel leaves the bridge */
752 static void softmix_bridge_leave(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
753 {
754         struct softmix_channel *sc;
755         struct softmix_bridge_data *softmix_data;
756         softmix_data = bridge->tech_pvt;
757         sc = bridge_channel->tech_pvt;
758
759         if (bridge->softmix.video_mode.mode == AST_BRIDGE_VIDEO_MODE_SFU) {
760                 sfu_topologies_on_leave(bridge_channel, &bridge->channels);
761         }
762
763         if (!sc) {
764                 return;
765         }
766
767         if (bridge->softmix.binaural_active) {
768                 if (sc->binaural) {
769                         set_binaural_data_leave(&softmix_data->convolve, sc->binaural_pos,
770                                         softmix_data->default_sample_size);
771                 }
772         }
773
774         bridge_channel->tech_pvt = NULL;
775
776         /* Drop mutex lock */
777         ast_mutex_destroy(&sc->lock);
778
779         /* Drop the factory */
780         ast_slinfactory_destroy(&sc->factory);
781
782         /* Drop any formats on the frames */
783         ao2_cleanup(sc->write_frame.subclass.format);
784
785         /* Drop the DSP */
786         ast_dsp_free(sc->dsp);
787
788         /* Eep! drop ourselves */
789         ast_free(sc);
790 }
791
792 static void softmix_pass_video_top_priority(struct ast_bridge *bridge, struct ast_frame *frame)
793 {
794         struct ast_bridge_channel *cur;
795
796         AST_LIST_TRAVERSE(&bridge->channels, cur, entry) {
797                 if (cur->suspended) {
798                         continue;
799                 }
800                 if (ast_bridge_is_video_src(bridge, cur->chan) == 1) {
801                         ast_bridge_channel_queue_frame(cur, frame);
802                         break;
803                 }
804         }
805 }
806
807 /*!
808  * \internal
809  * \brief Determine what to do with a video frame.
810  * \since 12.0.0
811  *
812  * \param bridge Which bridge is getting the frame
813  * \param bridge_channel Which channel is writing the frame.
814  * \param frame What is being written.
815  *
816  * \return Nothing
817  */
818 static void softmix_bridge_write_video(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, struct ast_frame *frame)
819 {
820         struct softmix_channel *sc;
821         int video_src_priority;
822
823         /* Determine if the video frame should be distributed or not */
824         switch (bridge->softmix.video_mode.mode) {
825         case AST_BRIDGE_VIDEO_MODE_NONE:
826                 break;
827         case AST_BRIDGE_VIDEO_MODE_SINGLE_SRC:
828                 video_src_priority = ast_bridge_is_video_src(bridge, bridge_channel->chan);
829                 if (video_src_priority == 1) {
830                         /* Pass to me and everyone else. */
831                         ast_bridge_queue_everyone_else(bridge, NULL, frame);
832                 }
833                 break;
834         case AST_BRIDGE_VIDEO_MODE_TALKER_SRC:
835                 sc = bridge_channel->tech_pvt;
836                 ast_mutex_lock(&sc->lock);
837                 ast_bridge_update_talker_src_video_mode(bridge, bridge_channel->chan,
838                         sc->video_talker.energy_average,
839                         frame->subclass.frame_ending);
840                 ast_mutex_unlock(&sc->lock);
841                 video_src_priority = ast_bridge_is_video_src(bridge, bridge_channel->chan);
842                 if (video_src_priority == 1) {
843                         int num_src = ast_bridge_number_video_src(bridge);
844                         int echo = num_src > 1 ? 0 : 1;
845
846                         ast_bridge_queue_everyone_else(bridge, echo ? NULL : bridge_channel, frame);
847                 } else if (video_src_priority == 2) {
848                         softmix_pass_video_top_priority(bridge, frame);
849                 }
850                 break;
851         case AST_BRIDGE_VIDEO_MODE_SFU:
852                 /* Nothing special to do here, the bridge channel stream map will ensure the
853                  * video goes everywhere it needs to
854                  */
855                 ast_bridge_queue_everyone_else(bridge, bridge_channel, frame);
856                 break;
857         }
858 }
859
860 /*!
861  * \internal
862  * \brief Determine what to do with a voice frame.
863  * \since 12.0.0
864  *
865  * \param bridge Which bridge is getting the frame
866  * \param bridge_channel Which channel is writing the frame.
867  * \param frame What is being written.
868  *
869  * \return Nothing
870  */
871 static void softmix_bridge_write_voice(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, struct ast_frame *frame)
872 {
873         struct softmix_channel *sc = bridge_channel->tech_pvt;
874         struct softmix_bridge_data *softmix_data = bridge->tech_pvt;
875         int totalsilence = 0;
876         int cur_energy = 0;
877         int silence_threshold = bridge_channel->tech_args.silence_threshold ?
878                 bridge_channel->tech_args.silence_threshold :
879                 DEFAULT_SOFTMIX_SILENCE_THRESHOLD;
880         char update_talking = -1;  /* if this is set to 0 or 1, tell the bridge that the channel has started or stopped talking. */
881
882         /* Write the frame into the conference */
883         ast_mutex_lock(&sc->lock);
884
885         if (ast_format_cmp(frame->subclass.format, sc->read_slin_format) != AST_FORMAT_CMP_EQUAL) {
886                 /*
887                  * The incoming frame is not the expected format.  Update
888                  * the channel's translation path to get us slinear from
889                  * the new format for the next frame.
890                  *
891                  * There is the possibility that this frame is an old slinear
892                  * rate frame that was in flight when the softmix bridge
893                  * changed rates.  If so it will self correct on subsequent
894                  * frames.
895                  */
896                 ast_channel_lock(bridge_channel->chan);
897                 ast_debug(1, "Channel %s wrote unexpected format into bridge.  Got %s, expected %s.\n",
898                         ast_channel_name(bridge_channel->chan),
899                         ast_format_get_name(frame->subclass.format),
900                         ast_format_get_name(sc->read_slin_format));
901                 ast_set_read_format_path(bridge_channel->chan, frame->subclass.format,
902                         sc->read_slin_format);
903                 ast_channel_unlock(bridge_channel->chan);
904         }
905
906         /* The channel will be leaving soon if there is no dsp. */
907         if (sc->dsp) {
908                 ast_dsp_silence_with_energy(sc->dsp, frame, &totalsilence, &cur_energy);
909         }
910
911         if (bridge->softmix.video_mode.mode == AST_BRIDGE_VIDEO_MODE_TALKER_SRC) {
912                 int cur_slot = sc->video_talker.energy_history_cur_slot;
913
914                 sc->video_talker.energy_accum -= sc->video_talker.energy_history[cur_slot];
915                 sc->video_talker.energy_accum += cur_energy;
916                 sc->video_talker.energy_history[cur_slot] = cur_energy;
917                 sc->video_talker.energy_average = sc->video_talker.energy_accum / DEFAULT_ENERGY_HISTORY_LEN;
918                 sc->video_talker.energy_history_cur_slot++;
919                 if (sc->video_talker.energy_history_cur_slot == DEFAULT_ENERGY_HISTORY_LEN) {
920                         sc->video_talker.energy_history_cur_slot = 0; /* wrap around */
921                 }
922         }
923
924         if (totalsilence < silence_threshold) {
925                 if (!sc->talking) {
926                         update_talking = 1;
927                 }
928                 sc->talking = 1; /* tell the write process we have audio to be mixed out */
929         } else {
930                 if (sc->talking) {
931                         update_talking = 0;
932                 }
933                 sc->talking = 0;
934         }
935
936         /* Before adding audio in, make sure we haven't fallen behind. If audio has fallen
937          * behind 4 times the amount of samples mixed on every iteration of the mixer, Re-sync
938          * the audio by flushing the buffer before adding new audio in. */
939         if (ast_slinfactory_available(&sc->factory) > (4 * SOFTMIX_SAMPLES(softmix_data->internal_rate, softmix_data->internal_mixing_interval))) {
940                 ast_slinfactory_flush(&sc->factory);
941         }
942
943         /* If a frame was provided add it to the smoother, unless drop silence is enabled and this frame
944          * is not determined to be talking. */
945         if (!(bridge_channel->tech_args.drop_silence && !sc->talking)) {
946                 ast_slinfactory_feed(&sc->factory, frame);
947         }
948
949         /* Alllll done */
950         ast_mutex_unlock(&sc->lock);
951
952         if (update_talking != -1) {
953                 ast_bridge_channel_notify_talking(bridge_channel, update_talking);
954         }
955 }
956
957 /*!
958  * \internal
959  * \brief Determine what to do with a control frame.
960  * \since 12.0.0
961  *
962  * \param bridge Which bridge is getting the frame
963  * \param bridge_channel Which channel is writing the frame.
964  * \param frame What is being written.
965  *
966  * \retval 0 Frame accepted into the bridge.
967  * \retval -1 Frame needs to be deferred.
968  */
969 static int softmix_bridge_write_control(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, struct ast_frame *frame)
970 {
971         struct softmix_bridge_data *softmix_data = bridge->tech_pvt;
972
973         /*
974          * XXX Softmix needs to use channel roles to determine what to
975          * do with control frames.
976          */
977
978         switch (frame->subclass.integer) {
979         case AST_CONTROL_VIDUPDATE:
980                 if (!bridge->softmix.video_mode.video_update_discard ||
981                         ast_tvdiff_ms(ast_tvnow(), softmix_data->last_video_update) > bridge->softmix.video_mode.video_update_discard) {
982                         ast_bridge_queue_everyone_else(bridge, NULL, frame);
983                         softmix_data->last_video_update = ast_tvnow();
984                 }
985                 break;
986         default:
987                 break;
988         }
989
990         return 0;
991 }
992
993 /*!
994  * \internal
995  * \brief Determine what to do with a frame written into the bridge.
996  * \since 12.0.0
997  *
998  * \param bridge Which bridge is getting the frame
999  * \param bridge_channel Which channel is writing the frame.
1000  * \param frame What is being written.
1001  *
1002  * \retval 0 Frame accepted into the bridge.
1003  * \retval -1 Frame needs to be deferred.
1004  *
1005  * \note On entry, bridge is already locked.
1006  */
1007 static int softmix_bridge_write(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, struct ast_frame *frame)
1008 {
1009         int res = 0;
1010
1011         if (!bridge->tech_pvt || !bridge_channel || !bridge_channel->tech_pvt) {
1012                 /* "Accept" the frame and discard it. */
1013                 return 0;
1014         }
1015
1016         /*
1017          * XXX Softmix needs to use channel roles to determine who gets
1018          * what frame.  Possible roles: announcer, recorder, agent,
1019          * supervisor.
1020          */
1021         switch (frame->frametype) {
1022         case AST_FRAME_NULL:
1023                 /* "Accept" the frame and discard it. */
1024                 break;
1025         case AST_FRAME_DTMF_BEGIN:
1026         case AST_FRAME_DTMF_END:
1027                 res = ast_bridge_queue_everyone_else(bridge, bridge_channel, frame);
1028                 break;
1029         case AST_FRAME_VOICE:
1030                 if (bridge_channel) {
1031                         softmix_bridge_write_voice(bridge, bridge_channel, frame);
1032                 }
1033                 break;
1034         case AST_FRAME_VIDEO:
1035                 if (bridge_channel) {
1036                         softmix_bridge_write_video(bridge, bridge_channel, frame);
1037                 }
1038                 break;
1039         case AST_FRAME_CONTROL:
1040                 res = softmix_bridge_write_control(bridge, bridge_channel, frame);
1041                 break;
1042         case AST_FRAME_BRIDGE_ACTION:
1043                 res = ast_bridge_queue_everyone_else(bridge, bridge_channel, frame);
1044                 break;
1045         case AST_FRAME_BRIDGE_ACTION_SYNC:
1046                 ast_log(LOG_ERROR, "Synchronous bridge action written to a softmix bridge.\n");
1047                 ast_assert(0);
1048         default:
1049                 ast_debug(3, "Frame type %u unsupported\n", frame->frametype);
1050                 /* "Accept" the frame and discard it. */
1051                 break;
1052         }
1053
1054         return res;
1055 }
1056
1057 static void gather_softmix_stats(struct softmix_stats *stats,
1058         const struct softmix_bridge_data *softmix_data,
1059         struct ast_bridge_channel *bridge_channel)
1060 {
1061         int channel_native_rate;
1062
1063         /* Gather stats about channel sample rates. */
1064         ast_channel_lock(bridge_channel->chan);
1065         channel_native_rate = MAX(SOFTMIX_MIN_SAMPLE_RATE,
1066                 ast_format_get_sample_rate(ast_channel_rawreadformat(bridge_channel->chan)));
1067         ast_channel_unlock(bridge_channel->chan);
1068
1069         if (stats->highest_supported_rate < channel_native_rate) {
1070                 stats->highest_supported_rate = channel_native_rate;
1071         }
1072         if (softmix_data->internal_rate < channel_native_rate) {
1073                 int i;
1074
1075                 for (i = 0; i < ARRAY_LEN(stats->sample_rates); i++) {
1076                         if (stats->sample_rates[i] == channel_native_rate) {
1077                                 stats->num_channels[i]++;
1078                                 break;
1079                         } else if (!stats->sample_rates[i]) {
1080                                 stats->sample_rates[i] = channel_native_rate;
1081                                 stats->num_channels[i]++;
1082                                 break;
1083                         }
1084                 }
1085                 stats->num_above_internal_rate++;
1086         } else if (softmix_data->internal_rate == channel_native_rate) {
1087                 stats->num_at_internal_rate++;
1088         }
1089 }
1090
1091 /*!
1092  * \internal
1093  * \brief Analyse mixing statistics and change bridges internal rate
1094  * if necessary.
1095  *
1096  * \retval 0, no changes to internal rate
1097  * \retval 1, internal rate was changed, update all the channels on the next mixing iteration.
1098  */
1099 static unsigned int analyse_softmix_stats(struct softmix_stats *stats,
1100                 struct softmix_bridge_data *softmix_data, int binaural_active)
1101 {
1102         int i;
1103
1104         if (binaural_active) {
1105                 stats->locked_rate = SOFTMIX_BINAURAL_SAMPLE_RATE;
1106         }
1107
1108         /*
1109          * Re-adjust the internal bridge sample rate if
1110          * 1. The bridge's internal sample rate is locked in at a sample
1111          *    rate other than the current sample rate being used.
1112          * 2. two or more channels support a higher sample rate
1113          * 3. no channels support the current sample rate or a higher rate
1114          */
1115         if (stats->locked_rate) {
1116                 /* if the rate is locked by the bridge, only update it if it differs
1117                  * from the current rate we are using. */
1118                 if (softmix_data->internal_rate != stats->locked_rate) {
1119                         ast_debug(1, "Locking at new rate.  Bridge changed from %u to %u.\n",
1120                                 softmix_data->internal_rate, stats->locked_rate);
1121                         softmix_data->internal_rate = stats->locked_rate;
1122                         return 1;
1123                 }
1124         } else if (stats->num_above_internal_rate >= 2) {
1125                 /* the highest rate is just used as a starting point */
1126                 unsigned int best_rate = stats->highest_supported_rate;
1127                 int best_index = -1;
1128
1129                 for (i = 0; i < ARRAY_LEN(stats->num_channels); i++) {
1130                         if (stats->num_channels[i]) {
1131                                 break;
1132                         }
1133                         if (2 <= stats->num_channels[i]) {
1134                                 /* Two or more channels support this rate. */
1135                                 if (best_index == -1
1136                                         || stats->sample_rates[best_index] < stats->sample_rates[i]) {
1137                                         /*
1138                                          * best_rate starts out being the first sample rate
1139                                          * greater than the internal sample rate that two or
1140                                          * more channels support.
1141                                          *
1142                                          * or
1143                                          *
1144                                          * There are multiple rates above the internal rate
1145                                          * and this rate is higher than the previous rate two
1146                                          * or more channels support.
1147                                          */
1148                                         best_rate = stats->sample_rates[i];
1149                                         best_index = i;
1150                                 }
1151                         } else if (best_index == -1) {
1152                                 /*
1153                                  * It is possible that multiple channels exist with native sample
1154                                  * rates above the internal sample rate, but none of those channels
1155                                  * have the same rate in common.  In this case, the lowest sample
1156                                  * rate among those channels is picked. Over time as additional
1157                                  * statistic runs are made the internal sample rate number will
1158                                  * adjust to the most optimal sample rate, but it may take multiple
1159                                  * iterations.
1160                                  */
1161                                 best_rate = MIN(best_rate, stats->sample_rates[i]);
1162                         }
1163                 }
1164
1165                 ast_debug(1, "Multiple above internal rate.  Bridge changed from %u to %u.\n",
1166                         softmix_data->internal_rate, best_rate);
1167                 softmix_data->internal_rate = best_rate;
1168                 return 1;
1169         } else if (!stats->num_at_internal_rate && !stats->num_above_internal_rate) {
1170                 /* In this case, the highest supported rate is actually lower than the internal rate */
1171                 ast_debug(1, "All below internal rate.  Bridge changed from %u to %u.\n",
1172                         softmix_data->internal_rate, stats->highest_supported_rate);
1173                 softmix_data->internal_rate = stats->highest_supported_rate;
1174                 return 1;
1175         }
1176         return 0;
1177 }
1178
1179 static int softmix_mixing_array_init(struct softmix_mixing_array *mixing_array,
1180                 unsigned int starting_num_entries, unsigned int binaural_active)
1181 {
1182         memset(mixing_array, 0, sizeof(*mixing_array));
1183         mixing_array->max_num_entries = starting_num_entries;
1184         if (!(mixing_array->buffers = ast_calloc(mixing_array->max_num_entries, sizeof(int16_t *)))) {
1185                 ast_log(LOG_NOTICE, "Failed to allocate softmix mixing structure.\n");
1186                 return -1;
1187         }
1188         if (binaural_active) {
1189                 if (!(mixing_array->chan_pairs = ast_calloc(mixing_array->max_num_entries,
1190                                 sizeof(struct convolve_channel_pair *)))) {
1191                         ast_log(LOG_NOTICE, "Failed to allocate softmix mixing structure.\n");
1192                         return -1;
1193                 }
1194         }
1195         return 0;
1196 }
1197
1198 static void softmix_mixing_array_destroy(struct softmix_mixing_array *mixing_array,
1199                 unsigned int binaural_active)
1200 {
1201         ast_free(mixing_array->buffers);
1202         if (binaural_active) {
1203                 ast_free(mixing_array->chan_pairs);
1204         }
1205 }
1206
1207 static int softmix_mixing_array_grow(struct softmix_mixing_array *mixing_array,
1208                 unsigned int num_entries, unsigned int binaural_active)
1209 {
1210         int16_t **tmp;
1211
1212         /* give it some room to grow since memory is cheap but allocations can be expensive */
1213         mixing_array->max_num_entries = num_entries;
1214         if (!(tmp = ast_realloc(mixing_array->buffers, (mixing_array->max_num_entries * sizeof(int16_t *))))) {
1215                 ast_log(LOG_NOTICE, "Failed to re-allocate softmix mixing structure.\n");
1216                 return -1;
1217         }
1218         if (binaural_active) {
1219                 struct convolve_channel_pair **tmp2;
1220                 if (!(tmp2 = ast_realloc(mixing_array->chan_pairs,
1221                                 (mixing_array->max_num_entries * sizeof(struct convolve_channel_pair *))))) {
1222                         ast_log(LOG_NOTICE, "Failed to re-allocate softmix mixing structure.\n");
1223                         return -1;
1224                 }
1225                 mixing_array->chan_pairs = tmp2;
1226         }
1227         mixing_array->buffers = tmp;
1228         return 0;
1229 }
1230
1231 /*!
1232  * \brief Mixing loop.
1233  *
1234  * \retval 0 on success
1235  * \retval -1 on failure
1236  */
1237 static int softmix_mixing_loop(struct ast_bridge *bridge)
1238 {
1239         struct softmix_stats stats = { { 0 }, };
1240         struct softmix_mixing_array mixing_array;
1241         struct softmix_bridge_data *softmix_data = bridge->tech_pvt;
1242         struct ast_timer *timer;
1243         struct softmix_translate_helper trans_helper;
1244         int16_t buf[MAX_DATALEN];
1245 #ifdef BINAURAL_RENDERING
1246         int16_t bin_buf[MAX_DATALEN];
1247         int16_t ann_buf[MAX_DATALEN];
1248 #endif
1249         unsigned int stat_iteration_counter = 0; /* counts down, gather stats at zero and reset. */
1250         int timingfd;
1251         int update_all_rates = 0; /* set this when the internal sample rate has changed */
1252         unsigned int idx;
1253         unsigned int x;
1254         int res = -1;
1255
1256         timer = softmix_data->timer;
1257         timingfd = ast_timer_fd(timer);
1258         softmix_translate_helper_init(&trans_helper, softmix_data->internal_rate);
1259         ast_timer_set_rate(timer, (1000 / softmix_data->internal_mixing_interval));
1260
1261         /* Give the mixing array room to grow, memory is cheap but allocations are expensive. */
1262         if (softmix_mixing_array_init(&mixing_array, bridge->num_channels + 10,
1263                         bridge->softmix.binaural_active)) {
1264                 goto softmix_cleanup;
1265         }
1266
1267         /*
1268          * XXX Softmix needs to use channel roles to determine who gets
1269          * what audio mixed.
1270          */
1271         while (!softmix_data->stop && bridge->num_active) {
1272                 struct ast_bridge_channel *bridge_channel;
1273                 int timeout = -1;
1274                 struct ast_format *cur_slin = ast_format_cache_get_slin_by_rate(softmix_data->internal_rate);
1275                 unsigned int softmix_samples = SOFTMIX_SAMPLES(softmix_data->internal_rate, softmix_data->internal_mixing_interval);
1276                 unsigned int softmix_datalen = SOFTMIX_DATALEN(softmix_data->internal_rate, softmix_data->internal_mixing_interval);
1277
1278                 if (softmix_datalen > MAX_DATALEN) {
1279                         /* This should NEVER happen, but if it does we need to know about it. Almost
1280                          * all the memcpys used during this process depend on this assumption.  Rather
1281                          * than checking this over and over again through out the code, this single
1282                          * verification is done on each iteration. */
1283                         ast_log(LOG_WARNING,
1284                                 "Bridge %s: Conference mixing error, requested mixing length greater than mixing buffer.\n",
1285                                 bridge->uniqueid);
1286                         goto softmix_cleanup;
1287                 }
1288
1289                 /* Grow the mixing array buffer as participants are added. */
1290                 if (mixing_array.max_num_entries < bridge->num_channels
1291                         && softmix_mixing_array_grow(&mixing_array, bridge->num_channels + 5,
1292                                         bridge->softmix.binaural_active)) {
1293                         goto softmix_cleanup;
1294                 }
1295
1296                 /* init the number of buffers stored in the mixing array to 0.
1297                  * As buffers are added for mixing, this number is incremented. */
1298                 mixing_array.used_entries = 0;
1299
1300                 /* These variables help determine if a rate change is required */
1301                 if (!stat_iteration_counter) {
1302                         memset(&stats, 0, sizeof(stats));
1303                         stats.locked_rate = bridge->softmix.internal_sample_rate;
1304                 }
1305
1306                 /* If the sample rate has changed, update the translator helper */
1307                 if (update_all_rates) {
1308                         softmix_translate_helper_change_rate(&trans_helper, softmix_data->internal_rate);
1309                 }
1310
1311 #ifdef BINAURAL_RENDERING
1312                 check_binaural_position_change(bridge, softmix_data, bridge_channel);
1313 #endif
1314
1315                 /* Go through pulling audio from each factory that has it available */
1316                 AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
1317                         struct softmix_channel *sc = bridge_channel->tech_pvt;
1318
1319                         if (!sc) {
1320                                 /* This channel failed to join successfully. */
1321                                 continue;
1322                         }
1323
1324                         /* Update the sample rate to match the bridge's native sample rate if necessary. */
1325                         if (update_all_rates) {
1326                                 set_softmix_bridge_data(softmix_data->internal_rate,
1327                                                 softmix_data->internal_mixing_interval, bridge_channel, 1, -1, -1, -1);
1328                         }
1329
1330                         /* If stat_iteration_counter is 0, then collect statistics during this mixing interation */
1331                         if (!stat_iteration_counter) {
1332                                 gather_softmix_stats(&stats, softmix_data, bridge_channel);
1333                         }
1334
1335                         /* if the channel is suspended, don't check for audio, but still gather stats */
1336                         if (bridge_channel->suspended) {
1337                                 continue;
1338                         }
1339
1340                         /* Try to get audio from the factory if available */
1341                         ast_mutex_lock(&sc->lock);
1342                         if ((mixing_array.buffers[mixing_array.used_entries] = softmix_process_read_audio(sc, softmix_samples))) {
1343 #ifdef BINAURAL_RENDERING
1344                                 add_binaural_mixing(bridge, softmix_data, softmix_samples, &mixing_array, sc,
1345                                                 ast_channel_name(bridge_channel->chan));
1346 #endif
1347                                 mixing_array.used_entries++;
1348                         }
1349                         ast_mutex_unlock(&sc->lock);
1350                 }
1351
1352                 /* mix it like crazy (non binaural channels)*/
1353                 memset(buf, 0, softmix_datalen);
1354                 for (idx = 0; idx < mixing_array.used_entries; ++idx) {
1355                         for (x = 0; x < softmix_samples; ++x) {
1356                                 ast_slinear_saturated_add(buf + x, mixing_array.buffers[idx] + x);
1357                         }
1358                 }
1359
1360 #ifdef BINAURAL_RENDERING
1361                 binaural_mixing(bridge, softmix_data, &mixing_array, bin_buf, ann_buf);
1362 #endif
1363
1364                 /* Next step go through removing the channel's own audio and creating a good frame... */
1365                 AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
1366                         struct softmix_channel *sc = bridge_channel->tech_pvt;
1367
1368                         if (!sc || bridge_channel->suspended) {
1369                                 /* This channel failed to join successfully or is suspended. */
1370                                 continue;
1371                         }
1372
1373                         ast_mutex_lock(&sc->lock);
1374
1375                         /* Make SLINEAR write frame from local buffer */
1376                         ao2_t_replace(sc->write_frame.subclass.format, cur_slin,
1377                                 "Replace softmix channel slin format");
1378 #ifdef BINAURAL_RENDERING
1379                         if (bridge->softmix.binaural_active && softmix_data->convolve.binaural_active
1380                                         && sc->binaural) {
1381                                 create_binaural_frame(bridge_channel, sc, bin_buf, ann_buf, softmix_datalen,
1382                                                 softmix_samples, buf);
1383                         } else
1384 #endif
1385                         {
1386                                 sc->write_frame.datalen = softmix_datalen;
1387                                 sc->write_frame.samples = softmix_samples;
1388                                 memcpy(sc->final_buf, buf, softmix_datalen);
1389                         }
1390                         /* process the softmix channel's new write audio */
1391                         softmix_process_write_audio(&trans_helper,
1392                                         ast_channel_rawwriteformat(bridge_channel->chan), sc,
1393                                         softmix_data->default_sample_size);
1394
1395                         ast_mutex_unlock(&sc->lock);
1396
1397                         /* A frame is now ready for the channel. */
1398                         ast_bridge_channel_queue_frame(bridge_channel, &sc->write_frame);
1399                 }
1400
1401                 update_all_rates = 0;
1402                 if (!stat_iteration_counter) {
1403                         update_all_rates = analyse_softmix_stats(&stats, softmix_data,
1404                                         bridge->softmix.binaural_active);
1405                         stat_iteration_counter = SOFTMIX_STAT_INTERVAL;
1406                 }
1407                 stat_iteration_counter--;
1408
1409                 ast_bridge_unlock(bridge);
1410                 /* cleanup any translation frame data from the previous mixing iteration. */
1411                 softmix_translate_helper_cleanup(&trans_helper);
1412                 /* Wait for the timing source to tell us to wake up and get things done */
1413                 ast_waitfor_n_fd(&timingfd, 1, &timeout, NULL);
1414                 if (ast_timer_ack(timer, 1) < 0) {
1415                         ast_log(LOG_ERROR, "Bridge %s: Failed to acknowledge timer in softmix.\n",
1416                                 bridge->uniqueid);
1417                         ast_bridge_lock(bridge);
1418                         goto softmix_cleanup;
1419                 }
1420                 ast_bridge_lock(bridge);
1421
1422                 /* make sure to detect mixing interval changes if they occur. */
1423                 if (bridge->softmix.internal_mixing_interval
1424                         && (bridge->softmix.internal_mixing_interval != softmix_data->internal_mixing_interval)) {
1425                         softmix_data->internal_mixing_interval = bridge->softmix.internal_mixing_interval;
1426                         ast_timer_set_rate(timer, (1000 / softmix_data->internal_mixing_interval));
1427                         update_all_rates = 1; /* if the interval changes, the rates must be adjusted as well just to be notified new interval.*/
1428                 }
1429         }
1430
1431         res = 0;
1432
1433 softmix_cleanup:
1434         softmix_translate_helper_destroy(&trans_helper);
1435         softmix_mixing_array_destroy(&mixing_array, bridge->softmix.binaural_active);
1436         return res;
1437 }
1438
1439 /*!
1440  * \internal
1441  * \brief Mixing thread.
1442  * \since 12.0.0
1443  *
1444  * \note The thread does not have its own reference to the
1445  * bridge.  The lifetime of the thread is tied to the lifetime
1446  * of the mixing technology association with the bridge.
1447  */
1448 static void *softmix_mixing_thread(void *data)
1449 {
1450         struct softmix_bridge_data *softmix_data = data;
1451         struct ast_bridge *bridge = softmix_data->bridge;
1452
1453         ast_bridge_lock(bridge);
1454         if (bridge->callid) {
1455                 ast_callid_threadassoc_add(bridge->callid);
1456         }
1457
1458         ast_debug(1, "Bridge %s: starting mixing thread\n", bridge->uniqueid);
1459
1460         while (!softmix_data->stop) {
1461                 if (!bridge->num_active) {
1462                         /* Wait for something to happen to the bridge. */
1463                         ast_bridge_unlock(bridge);
1464                         ast_mutex_lock(&softmix_data->lock);
1465                         if (!softmix_data->stop) {
1466                                 ast_cond_wait(&softmix_data->cond, &softmix_data->lock);
1467                         }
1468                         ast_mutex_unlock(&softmix_data->lock);
1469                         ast_bridge_lock(bridge);
1470                         continue;
1471                 }
1472
1473                 if (bridge->softmix.binaural_active && !softmix_data->binaural_init) {
1474 #ifndef BINAURAL_RENDERING
1475                         ast_bridge_lock(bridge);
1476                         bridge->softmix.binaural_active = 0;
1477                         ast_bridge_unlock(bridge);
1478                         ast_log(LOG_WARNING, "Bridge: %s: Binaural rendering active by config but not "
1479                                         "compiled.\n", bridge->uniqueid);
1480 #else
1481                         /* Set and init binaural data if binaural is activated in the configuration. */
1482                         softmix_data->internal_rate = SOFTMIX_BINAURAL_SAMPLE_RATE;
1483                         softmix_data->default_sample_size = SOFTMIX_SAMPLES(softmix_data->internal_rate,
1484                                         softmix_data->internal_mixing_interval);
1485                         /* If init for binaural processing fails we will fall back to mono audio processing. */
1486                         if (init_convolve_data(&softmix_data->convolve, softmix_data->default_sample_size)
1487                                         == -1) {
1488                                 ast_bridge_lock(bridge);
1489                                 bridge->softmix.binaural_active = 0;
1490                                 ast_bridge_unlock(bridge);
1491                                 ast_log(LOG_ERROR, "Bridge: %s: Unable to allocate memory for "
1492                                                 "binaural processing,  Will only process mono audio.\n",
1493                                                 bridge->uniqueid);
1494                         }
1495                         softmix_data->binaural_init = 1;
1496 #endif
1497                 }
1498
1499                 if (softmix_mixing_loop(bridge)) {
1500                         /*
1501                          * A mixing error occurred.  Sleep and try again later so we
1502                          * won't flood the logs.
1503                          */
1504                         ast_bridge_unlock(bridge);
1505                         sleep(1);
1506                         ast_bridge_lock(bridge);
1507                 }
1508         }
1509
1510         ast_bridge_unlock(bridge);
1511
1512         ast_debug(1, "Bridge %s: stopping mixing thread\n", bridge->uniqueid);
1513
1514         return NULL;
1515 }
1516
1517 static void softmix_bridge_data_destroy(struct softmix_bridge_data *softmix_data)
1518 {
1519         if (softmix_data->timer) {
1520                 ast_timer_close(softmix_data->timer);
1521                 softmix_data->timer = NULL;
1522         }
1523         ast_mutex_destroy(&softmix_data->lock);
1524         ast_cond_destroy(&softmix_data->cond);
1525         ast_free(softmix_data);
1526 }
1527
1528 /*! \brief Function called when a bridge is created */
1529 static int softmix_bridge_create(struct ast_bridge *bridge)
1530 {
1531         struct softmix_bridge_data *softmix_data;
1532
1533         softmix_data = ast_calloc(1, sizeof(*softmix_data));
1534         if (!softmix_data) {
1535                 return -1;
1536         }
1537         softmix_data->bridge = bridge;
1538         ast_mutex_init(&softmix_data->lock);
1539         ast_cond_init(&softmix_data->cond, NULL);
1540         softmix_data->timer = ast_timer_open();
1541         if (!softmix_data->timer) {
1542                 ast_log(AST_LOG_WARNING, "Failed to open timer for softmix bridge\n");
1543                 softmix_bridge_data_destroy(softmix_data);
1544                 return -1;
1545         }
1546         /* start at minimum rate, let it grow from there */
1547         softmix_data->internal_rate = SOFTMIX_MIN_SAMPLE_RATE;
1548         softmix_data->internal_mixing_interval = DEFAULT_SOFTMIX_INTERVAL;
1549
1550 #ifdef BINAURAL_RENDERING
1551         softmix_data->default_sample_size = SOFTMIX_SAMPLES(softmix_data->internal_rate,
1552                         softmix_data->internal_mixing_interval);
1553 #endif
1554
1555         bridge->tech_pvt = softmix_data;
1556
1557         /* Start the mixing thread. */
1558         if (ast_pthread_create(&softmix_data->thread, NULL, softmix_mixing_thread,
1559                 softmix_data)) {
1560                 softmix_data->thread = AST_PTHREADT_NULL;
1561                 softmix_bridge_data_destroy(softmix_data);
1562                 bridge->tech_pvt = NULL;
1563                 return -1;
1564         }
1565
1566         return 0;
1567 }
1568
1569 /*!
1570  * \internal
1571  * \brief Request the softmix mixing thread stop.
1572  * \since 12.0.0
1573  *
1574  * \param bridge Which bridge is being stopped.
1575  *
1576  * \return Nothing
1577  */
1578 static void softmix_bridge_stop(struct ast_bridge *bridge)
1579 {
1580         struct softmix_bridge_data *softmix_data;
1581
1582         softmix_data = bridge->tech_pvt;
1583         if (!softmix_data) {
1584                 return;
1585         }
1586
1587         ast_mutex_lock(&softmix_data->lock);
1588         softmix_data->stop = 1;
1589         ast_mutex_unlock(&softmix_data->lock);
1590 }
1591
1592 /*! \brief Function called when a bridge is destroyed */
1593 static void softmix_bridge_destroy(struct ast_bridge *bridge)
1594 {
1595         struct softmix_bridge_data *softmix_data;
1596         pthread_t thread;
1597
1598         softmix_data = bridge->tech_pvt;
1599         if (!softmix_data) {
1600                 return;
1601         }
1602
1603         /* Stop the mixing thread. */
1604         ast_mutex_lock(&softmix_data->lock);
1605         softmix_data->stop = 1;
1606         ast_cond_signal(&softmix_data->cond);
1607         thread = softmix_data->thread;
1608         softmix_data->thread = AST_PTHREADT_NULL;
1609         ast_mutex_unlock(&softmix_data->lock);
1610         if (thread != AST_PTHREADT_NULL) {
1611                 ast_debug(1, "Bridge %s: Waiting for mixing thread to die.\n", bridge->uniqueid);
1612                 pthread_join(thread, NULL);
1613         }
1614 #ifdef BINAURAL_RENDERING
1615         free_convolve_data(&softmix_data->convolve);
1616 #endif
1617         softmix_bridge_data_destroy(softmix_data);
1618         bridge->tech_pvt = NULL;
1619 }
1620
1621 /*!
1622  * \brief Map a source stream to all of its destination streams.
1623  *
1624  * \param source_stream_name Name of the source stream
1625  * \param source_channel_name Name of channel where the source stream originates
1626  * \param bridge_stream_position The slot in the bridge where source video will come from
1627  * \param participants The bridge_channels in the bridge
1628  */
1629 static void map_source_to_destinations(const char *source_stream_name, const char *source_channel_name,
1630         size_t bridge_stream_position, struct ast_bridge_channels_list *participants)
1631 {
1632         struct ast_bridge_channel *participant;
1633
1634         AST_LIST_TRAVERSE(participants, participant, entry) {
1635                 int i;
1636                 struct ast_stream_topology *topology;
1637
1638                 if (!strcmp(source_channel_name, ast_channel_name(participant->chan))) {
1639                         continue;
1640                 }
1641
1642                 ast_bridge_channel_lock(participant);
1643                 topology = ast_channel_get_stream_topology(participant->chan);
1644
1645                 for (i = 0; i < ast_stream_topology_get_count(topology); ++i) {
1646                         struct ast_stream *stream;
1647
1648                         stream = ast_stream_topology_get_stream(topology, i);
1649                         if (is_video_dest(stream, source_channel_name, source_stream_name)) {
1650                                 AST_VECTOR_REPLACE(&participant->stream_map.to_channel, bridge_stream_position, i);
1651                                 break;
1652                         }
1653                 }
1654                 ast_bridge_channel_unlock(participant);
1655         }
1656 }
1657
1658 /*\brief stream_topology_changed callback
1659  *
1660  * For most video modes, nothing beyond the ordinary is required.
1661  * For the SFU case, though, we need to completely remap the streams
1662  * in order to ensure video gets directed where it is expected to go.
1663  *
1664  * \param bridge The bridge
1665  * \param bridge_channel Channel whose topology has changed
1666  */
1667 static void softmix_bridge_stream_topology_changed(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
1668 {
1669         struct ast_bridge_channel *participant;
1670         struct ast_vector_int media_types;
1671         int nths[AST_MEDIA_TYPE_END] = {0};
1672
1673         switch (bridge->softmix.video_mode.mode) {
1674         case AST_BRIDGE_VIDEO_MODE_NONE:
1675         case AST_BRIDGE_VIDEO_MODE_SINGLE_SRC:
1676         case AST_BRIDGE_VIDEO_MODE_TALKER_SRC:
1677         default:
1678                 ast_bridge_channel_stream_map(bridge_channel);
1679                 return;
1680         case AST_BRIDGE_VIDEO_MODE_SFU:
1681                 break;
1682         }
1683
1684         AST_VECTOR_INIT(&media_types, AST_MEDIA_TYPE_END);
1685
1686         /* First traversal: re-initialize all of the participants' stream maps */
1687         AST_LIST_TRAVERSE(&bridge->channels, participant, entry) {
1688                 int size;
1689
1690                 ast_bridge_channel_lock(participant);
1691                 size = ast_stream_topology_get_count(ast_channel_get_stream_topology(participant->chan));
1692
1693                 AST_VECTOR_FREE(&participant->stream_map.to_channel);
1694                 AST_VECTOR_FREE(&participant->stream_map.to_bridge);
1695
1696                 AST_VECTOR_INIT(&participant->stream_map.to_channel, size);
1697                 AST_VECTOR_INIT(&participant->stream_map.to_bridge, size);
1698                 ast_bridge_channel_unlock(participant);
1699         }
1700
1701         /* Second traversal: Map specific video channels from their source to their destinations.
1702          *
1703          * This is similar to what is done in ast_stream_topology_map(), except that
1704          * video channels are handled differently. Each video source has it's own
1705          * unique index on the bridge. this way, a particular channel's source video
1706          * can be distributed to the appropriate destination streams on the other
1707          * channels
1708          */
1709         AST_LIST_TRAVERSE(&bridge->channels, participant, entry) {
1710                 int i;
1711                 struct ast_stream_topology *topology;
1712
1713                 topology = ast_channel_get_stream_topology(participant->chan);
1714
1715                 for (i = 0; i < ast_stream_topology_get_count(topology); ++i) {
1716                         struct ast_stream *stream = ast_stream_topology_get_stream(topology, i);
1717                         ast_bridge_channel_lock(participant);
1718                         if (is_video_source(stream)) {
1719                                 AST_VECTOR_APPEND(&media_types, AST_MEDIA_TYPE_VIDEO);
1720                                 AST_VECTOR_REPLACE(&participant->stream_map.to_bridge, i, AST_VECTOR_SIZE(&media_types) - 1);
1721                                 AST_VECTOR_REPLACE(&participant->stream_map.to_channel, AST_VECTOR_SIZE(&media_types) - 1, -1);
1722                                 /* Unlock the participant to prevent potential deadlock
1723                                  * in map_source_to_destinations
1724                                  */
1725                                 ast_bridge_channel_unlock(participant);
1726                                 map_source_to_destinations(ast_stream_get_name(stream), ast_channel_name(participant->chan),
1727                                         AST_VECTOR_SIZE(&media_types) - 1, &bridge->channels);
1728                                 ast_bridge_channel_lock(participant);
1729                         } else if (is_video_dest(stream, NULL, NULL)) {
1730                                 /* We expect to never read media from video destination channels, but just
1731                                  * in case, we should set their to_bridge value to -1.
1732                                  */
1733                                 AST_VECTOR_REPLACE(&participant->stream_map.to_bridge, i, -1);
1734                         } else {
1735                                 /* XXX This is copied from ast_stream_topology_map(). This likely could
1736                                  * be factored out in some way
1737                                  */
1738                                 enum ast_media_type type = ast_stream_get_type(stream);
1739                                 int index = AST_VECTOR_GET_INDEX_NTH(&media_types, ++nths[type],
1740                                         type, AST_VECTOR_ELEM_DEFAULT_CMP);
1741
1742                                 if (index == -1) {
1743                                         AST_VECTOR_APPEND(&media_types, type);
1744                                         index = AST_VECTOR_SIZE(&media_types) - 1;
1745                                 }
1746
1747                                 AST_VECTOR_REPLACE(&participant->stream_map.to_bridge, i, index);
1748                                 AST_VECTOR_REPLACE(&participant->stream_map.to_channel, index, i);
1749                         }
1750                         ast_bridge_channel_unlock(participant);
1751                 }
1752         }
1753 }
1754
1755 static struct ast_bridge_technology softmix_bridge = {
1756         .name = "softmix",
1757         .capabilities = AST_BRIDGE_CAPABILITY_MULTIMIX,
1758         .preference = AST_BRIDGE_PREFERENCE_BASE_MULTIMIX,
1759         .create = softmix_bridge_create,
1760         .stop = softmix_bridge_stop,
1761         .destroy = softmix_bridge_destroy,
1762         .join = softmix_bridge_join,
1763         .leave = softmix_bridge_leave,
1764         .unsuspend = softmix_bridge_unsuspend,
1765         .write = softmix_bridge_write,
1766         .stream_topology_changed = softmix_bridge_stream_topology_changed,
1767 };
1768
1769 #ifdef TEST_FRAMEWORK
1770 struct stream_parameters {
1771         const char *name;
1772         const char *formats;
1773         enum ast_media_type type;
1774 };
1775
1776 static struct ast_stream_topology *build_topology(const struct stream_parameters *params, size_t num_streams)
1777 {
1778         struct ast_stream_topology *topology;
1779         size_t i;
1780
1781         topology = ast_stream_topology_alloc();
1782         if (!topology) {
1783                 return NULL;
1784         }
1785
1786         for (i = 0; i < num_streams; ++i) {
1787                 RAII_VAR(struct ast_format_cap *, caps, NULL, ao2_cleanup);
1788                 struct ast_stream *stream;
1789
1790                 caps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
1791                 if (!caps) {
1792                         goto fail;
1793                 }
1794                 if (ast_format_cap_update_by_allow_disallow(caps, params[i].formats, 1) < 0) {
1795                         goto fail;
1796                 }
1797                 stream = ast_stream_alloc(params[i].name, params[i].type);
1798                 if (!stream) {
1799                         goto fail;
1800                 }
1801                 ast_stream_set_formats(stream, caps);
1802                 if (ast_stream_topology_append_stream(topology, stream) < 0) {
1803                         ast_stream_free(stream);
1804                         goto fail;
1805                 }
1806         }
1807
1808         return topology;
1809
1810 fail:
1811         ast_stream_topology_free(topology);
1812         return NULL;
1813 }
1814
1815 static int validate_stream(struct ast_test *test, struct ast_stream *stream,
1816         const struct stream_parameters *params)
1817 {
1818         struct ast_format_cap *stream_caps;
1819         struct ast_format_cap *params_caps;
1820
1821         if (ast_stream_get_type(stream) != params->type) {
1822                 ast_test_status_update(test, "Expected stream type '%s' but got type '%s'\n",
1823                         ast_codec_media_type2str(params->type),
1824                         ast_codec_media_type2str(ast_stream_get_type(stream)));
1825                 return -1;
1826         }
1827         if (strcmp(ast_stream_get_name(stream), params->name)) {
1828                 ast_test_status_update(test, "Expected stream name '%s' but got type '%s'\n",
1829                         params->name, ast_stream_get_name(stream));
1830                 return -1;
1831         }
1832
1833         stream_caps = ast_stream_get_formats(stream);
1834         params_caps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
1835         if (!params_caps) {
1836                 ast_test_status_update(test, "Allocation error on capabilities\n");
1837                 return -1;
1838         }
1839         ast_format_cap_update_by_allow_disallow(params_caps, params->formats, 1);
1840
1841         if (ast_format_cap_identical(stream_caps, params_caps)) {
1842                 ast_test_status_update(test, "Formats are not as expected on stream '%s'\n",
1843                         ast_stream_get_name(stream));
1844                 ao2_cleanup(params_caps);
1845                 return -1;
1846         }
1847
1848         ao2_cleanup(params_caps);
1849         return 0;
1850 }
1851
1852 static int validate_original_streams(struct ast_test *test, struct ast_stream_topology *topology,
1853         const struct stream_parameters *params, size_t num_streams)
1854 {
1855         int i;
1856
1857         if (ast_stream_topology_get_count(topology) < num_streams) {
1858                 ast_test_status_update(test, "Topology only has %d streams. Needs to have at least %zu\n",
1859                         ast_stream_topology_get_count(topology), num_streams);
1860                 return -1;
1861         }
1862
1863         for (i = 0; i < ARRAY_LEN(params); ++i) {
1864                 if (validate_stream(test, ast_stream_topology_get_stream(topology, i), &params[i])) {
1865                         return -1;
1866                 }
1867         }
1868
1869         return 0;
1870 }
1871
1872 AST_TEST_DEFINE(sfu_append_source_streams)
1873 {
1874         enum ast_test_result_state res = AST_TEST_FAIL;
1875         static const struct stream_parameters bob_streams[] = {
1876                 { "bob_audio", "ulaw,alaw,g722,opus", AST_MEDIA_TYPE_AUDIO, },
1877                 { "bob_video", "h264,vp8", AST_MEDIA_TYPE_VIDEO, },
1878         };
1879         static const struct stream_parameters alice_streams[] = {
1880                 { "alice_audio", "ulaw,opus", AST_MEDIA_TYPE_AUDIO, },
1881                 { "alice_video", "vp8", AST_MEDIA_TYPE_VIDEO, },
1882         };
1883         static const struct stream_parameters alice_dest_stream = {
1884                 "softbridge_dest_PJSIP/Bob-00000001_bob_video", "vp8", AST_MEDIA_TYPE_VIDEO,
1885         };
1886         static const struct stream_parameters bob_dest_stream = {
1887                 "softbridge_dest_PJSIP/Alice-00000000_alice_video", "h264,vp8", AST_MEDIA_TYPE_VIDEO,
1888         };
1889         struct ast_stream_topology *topology_alice = NULL;
1890         struct ast_stream_topology *topology_bob = NULL;
1891
1892         switch (cmd) {
1893         case TEST_INIT:
1894                 info->name = "sfu_append_source_streams";
1895                 info->category = "/bridges/bridge_softmix/";
1896                 info->summary = "Test appending of video streams";
1897                 info->description =
1898                         "This tests does stuff.";
1899                 return AST_TEST_NOT_RUN;
1900         case TEST_EXECUTE:
1901                 break;
1902         }
1903
1904         topology_alice = build_topology(alice_streams, ARRAY_LEN(alice_streams));
1905         if (!topology_alice) {
1906                 goto end;
1907         }
1908
1909         topology_bob = build_topology(bob_streams, ARRAY_LEN(bob_streams));
1910         if (!topology_bob) {
1911                 goto end;
1912         }
1913
1914         if (append_source_streams(topology_alice, "PJSIP/Bob-00000001", topology_bob)) {
1915                 ast_test_status_update(test, "Failed to append Bob's streams to Alice\n");
1916                 goto end;
1917         }
1918
1919         if (ast_stream_topology_get_count(topology_alice) != 3) {
1920                 ast_test_status_update(test, "Alice's topology isn't large enough! It's %d but needs to be %d\n",
1921                         ast_stream_topology_get_count(topology_alice), 3);
1922                 goto end;
1923         }
1924
1925         if (validate_original_streams(test, topology_alice, alice_streams, ARRAY_LEN(alice_streams))) {
1926                 goto end;
1927         }
1928
1929         if (validate_stream(test, ast_stream_topology_get_stream(topology_alice, 2), &alice_dest_stream)) {
1930                 goto end;
1931         }
1932
1933         if (append_source_streams(topology_bob, "PJSIP/Alice-00000000", topology_alice)) {
1934                 ast_test_status_update(test, "Failed to append Alice's streams to Bob\n");
1935                 goto end;
1936         }
1937
1938         if (ast_stream_topology_get_count(topology_bob) != 3) {
1939                 ast_test_status_update(test, "Bob's topology isn't large enough! It's %d but needs to be %d\n",
1940                         ast_stream_topology_get_count(topology_bob), 3);
1941                 goto end;
1942         }
1943
1944         if (validate_original_streams(test, topology_bob, bob_streams, ARRAY_LEN(bob_streams))) {
1945                 goto end;
1946         }
1947
1948         if (validate_stream(test, ast_stream_topology_get_stream(topology_bob, 2), &bob_dest_stream)) {
1949                 goto end;
1950         }
1951
1952         res = AST_TEST_PASS;
1953
1954 end:
1955         ast_stream_topology_free(topology_alice);
1956         ast_stream_topology_free(topology_bob);
1957         return res;
1958 }
1959
1960 AST_TEST_DEFINE(sfu_remove_destination_streams)
1961 {
1962         enum ast_test_result_state res = AST_TEST_FAIL;
1963         static const struct stream_parameters params[] = {
1964                 { "alice_audio", "ulaw,alaw,g722,opus", AST_MEDIA_TYPE_AUDIO, },
1965                 { "alice_video", "h264,vp8", AST_MEDIA_TYPE_VIDEO, },
1966                 { "softbridge_dest_PJSIP/Bob-00000001_video", "vp8", AST_MEDIA_TYPE_VIDEO, },
1967                 { "softbridge_dest_PJSIP/Carol-00000002_video", "h264", AST_MEDIA_TYPE_VIDEO, },
1968         };
1969         static const struct {
1970                 const char *channel_name;
1971                 int num_streams;
1972                 int params_index[4];
1973         } removal_results[] = {
1974                 { "PJSIP/Bob-00000001", 4, { 0, 1, 2, 3 }, },
1975                 { "PJSIP/Edward-00000004", 4, { 0, 1, 2, 3 }, },
1976                 { "", 4, { 0, 1, 2, 3 }, },
1977         };
1978         struct ast_stream_topology *orig = NULL;
1979         struct ast_stream_topology *result = NULL;
1980         int i;
1981
1982         switch (cmd) {
1983         case TEST_INIT:
1984                 info->name = "sfu_remove_destination_streams";
1985                 info->category = "/bridges/bridge_softmix/";
1986                 info->summary = "Test removal of destination video streams";
1987                 info->description =
1988                         "This tests does stuff.";
1989                 return AST_TEST_NOT_RUN;
1990         case TEST_EXECUTE:
1991                 break;
1992         }
1993
1994         orig = build_topology(params, ARRAY_LEN(params));
1995         if (!orig) {
1996                 ast_test_status_update(test, "Unable to build initial stream topology\n");
1997                 goto end;
1998         }
1999
2000         for (i = 0; i < ARRAY_LEN(removal_results); ++i) {
2001                 int j;
2002
2003                 result = ast_stream_topology_alloc();
2004                 if (!result) {
2005                         ast_test_status_update(test, "Unable to allocate result stream topology\n");
2006                         goto end;
2007                 }
2008
2009                 if (remove_destination_streams(result, removal_results[i].channel_name, orig)) {
2010                         ast_test_status_update(test, "Failure while attempting to remove video streams\n");
2011                         goto end;
2012                 }
2013
2014                 if (ast_stream_topology_get_count(result) != removal_results[i].num_streams) {
2015                         ast_test_status_update(test, "Resulting topology has %d streams, when %d are expected\n",
2016                                 ast_stream_topology_get_count(result), removal_results[i].num_streams);
2017                         goto end;
2018                 }
2019
2020                 for (j = 0; j < removal_results[i].num_streams; ++j) {
2021                         struct ast_stream *actual;
2022                         struct ast_stream *expected;
2023                         int orig_index;
2024
2025                         actual = ast_stream_topology_get_stream(result, j);
2026
2027                         orig_index = removal_results[i].params_index[j];
2028                         expected = ast_stream_topology_get_stream(orig, orig_index);
2029
2030                         if (!ast_format_cap_identical(ast_stream_get_formats(actual),
2031                                 ast_stream_get_formats(expected))) {
2032                                 struct ast_str *expected_str;
2033                                 struct ast_str *actual_str;
2034
2035                                 expected_str = ast_str_alloca(64);
2036                                 actual_str = ast_str_alloca(64);
2037
2038                                 ast_test_status_update(test, "Mismatch between expected (%s) and actual (%s) stream formats\n",
2039                                         ast_format_cap_get_names(ast_stream_get_formats(expected), &expected_str),
2040                                         ast_format_cap_get_names(ast_stream_get_formats(actual), &actual_str));
2041                                 goto end;
2042                         }
2043
2044                         if (is_video_dest(actual, removal_results[i].channel_name, NULL) &&
2045                                 ast_stream_get_state(actual) != AST_STREAM_STATE_REMOVED) {
2046                                 ast_test_status_update(test, "Removed stream %s does not have a state of removed\n", ast_stream_get_name(actual));
2047                                 goto end;
2048                         }
2049                 }
2050         }
2051
2052         res = AST_TEST_PASS;
2053
2054 end:
2055         ast_stream_topology_free(orig);
2056         ast_stream_topology_free(result);
2057         return res;
2058 }
2059
2060 #endif
2061
2062 static int unload_module(void)
2063 {
2064         ast_bridge_technology_unregister(&softmix_bridge);
2065         AST_TEST_UNREGISTER(sfu_append_source_streams);
2066         AST_TEST_UNREGISTER(sfu_remove_destination_streams);
2067         return 0;
2068 }
2069
2070 static int load_module(void)
2071 {
2072         if (ast_bridge_technology_register(&softmix_bridge)) {
2073                 unload_module();
2074                 return AST_MODULE_LOAD_DECLINE;
2075         }
2076         AST_TEST_REGISTER(sfu_append_source_streams);
2077         AST_TEST_REGISTER(sfu_remove_destination_streams);
2078         return AST_MODULE_LOAD_SUCCESS;
2079 }
2080
2081 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Multi-party software based channel mixing");