bridge_softmix: Use removed stream spots when renegotiating.
[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         int dest_index = 0;
528
529         for (i = 0; i < ast_stream_topology_get_count(source); ++i) {
530                 struct ast_stream *clone;
531                 int added = 0;
532
533                 clone = ast_stream_clone(ast_stream_topology_get_stream(source, i), NULL);
534                 if (!clone) {
535                         return -1;
536                 }
537
538                 /* If we can reuse an existing removed stream then do so */
539                 while (dest_index < ast_stream_topology_get_count(dest)) {
540                         struct ast_stream *stream = ast_stream_topology_get_stream(dest, dest_index);
541
542                         dest_index++;
543
544                         if (ast_stream_get_state(stream) == AST_STREAM_STATE_REMOVED) {
545                                 ast_stream_topology_set_stream(dest, dest_index - 1, clone);
546                                 added = 1;
547                                 break;
548                         }
549                 }
550
551                 /* If no removed stream exists that we took the place of append the stream */
552                 if (!added && ast_stream_topology_append_stream(dest, clone) < 0) {
553                         ast_stream_free(clone);
554                         return -1;
555                 }
556         }
557
558         return 0;
559 }
560
561 /*!
562  * \brief Issue channel stream topology change requests.
563  *
564  * When in SFU mode, each participant needs to be able to
565  * send video directly to other participants in the bridge.
566  * This means that all participants need to have their topologies
567  * updated. The joiner needs to have destination streams for
568  * all current participants, and the current participants need
569  * to have destinations streams added for the joiner's sources.
570  *
571  * \param joiner The channel that is joining the softmix bridge
572  * \param participants The current participants in the softmix bridge
573  */
574 static void sfu_topologies_on_join(struct ast_bridge_channel *joiner, struct ast_bridge_channels_list *participants)
575 {
576         struct ast_stream_topology *joiner_topology = NULL;
577         struct ast_stream_topology *joiner_video = NULL;
578         struct ast_stream_topology *existing_video = NULL;
579         struct ast_bridge_channel *participant;
580
581         joiner_video = ast_stream_topology_alloc();
582         if (!joiner_video) {
583                 return;
584         }
585
586         if (append_source_streams(joiner_video, ast_channel_name(joiner->chan), ast_channel_get_stream_topology(joiner->chan))) {
587                 goto cleanup;
588         }
589
590         existing_video = ast_stream_topology_alloc();
591         if (!existing_video) {
592                 goto cleanup;
593         }
594
595         AST_LIST_TRAVERSE(participants, participant, entry) {
596                 if (participant == joiner) {
597                         continue;
598                 }
599                 if (append_source_streams(existing_video, ast_channel_name(participant->chan),
600                                 ast_channel_get_stream_topology(participant->chan))) {
601                         goto cleanup;
602                 }
603         }
604
605         joiner_topology = ast_stream_topology_clone(ast_channel_get_stream_topology(joiner->chan));
606         if (!joiner_topology) {
607                 goto cleanup;
608         }
609         if (append_all_streams(joiner_topology, existing_video)) {
610                 goto cleanup;
611         }
612         ast_channel_request_stream_topology_change(joiner->chan, joiner_topology, NULL);
613
614         AST_LIST_TRAVERSE(participants, participant, entry) {
615                 struct ast_stream_topology *participant_topology;
616
617                 if (participant == joiner) {
618                         continue;
619                 }
620                 participant_topology = ast_stream_topology_clone(ast_channel_get_stream_topology(joiner->chan));
621                 if (!participant_topology) {
622                         goto cleanup;
623                 }
624                 if (append_all_streams(participant_topology, joiner_video)) {
625                         ast_stream_topology_free(participant_topology);
626                         goto cleanup;
627                 }
628                 ast_channel_request_stream_topology_change(participant->chan, participant_topology, NULL);
629                 ast_stream_topology_free(participant_topology);
630         }
631
632 cleanup:
633         ast_stream_topology_free(joiner_video);
634         ast_stream_topology_free(existing_video);
635         ast_stream_topology_free(joiner_topology);
636 }
637
638 /*! \brief Function called when a channel is joined into the bridge */
639 static int softmix_bridge_join(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
640 {
641         struct softmix_channel *sc;
642         struct softmix_bridge_data *softmix_data;
643         int set_binaural = 0;
644         /*
645          * If false, the channel will be convolved, but since it is a non stereo channel, output
646          * will be mono.
647          */
648         int skip_binaural_output = 1;
649         int pos_id;
650         int is_announcement = 0;
651         int samplerate_change;
652
653         softmix_data = bridge->tech_pvt;
654         if (!softmix_data) {
655                 return -1;
656         }
657
658         /* Create a new softmix_channel structure and allocate various things on it */
659         if (!(sc = ast_calloc(1, sizeof(*sc)))) {
660                 return -1;
661         }
662
663         samplerate_change = softmix_data->internal_rate;
664         pos_id = -1;
665         if (bridge->softmix.binaural_active) {
666                 if (strncmp(ast_channel_name(bridge_channel->chan), "CBAnn", 5) != 0) {
667                         set_binaural = ast_format_get_channel_count(bridge_channel->write_format) > 1 ? 1 : 0;
668                         if (set_binaural) {
669                                 softmix_data->internal_rate = samplerate_change;
670                         }
671                         skip_binaural_output = 0;
672                 } else {
673                         is_announcement = 1;
674                 }
675                 if (set_binaural) {
676                         softmix_data->convolve.binaural_active = 1;
677                 }
678                 if (!skip_binaural_output)      {
679                         pos_id = set_binaural_data_join(&softmix_data->convolve, softmix_data->default_sample_size);
680                         if (pos_id == -1) {
681                                 ast_log(LOG_ERROR, "Bridge %s: Failed to join channel %s. "
682                                                 "Could not allocate enough memory.\n", bridge->uniqueid,
683                                                 ast_channel_name(bridge_channel->chan));
684                                 return -1;
685                         }
686                 }
687         }
688
689         /* Can't forget the lock */
690         ast_mutex_init(&sc->lock);
691
692         /* Can't forget to record our pvt structure within the bridged channel structure */
693         bridge_channel->tech_pvt = sc;
694
695         set_softmix_bridge_data(softmix_data->internal_rate,
696                 softmix_data->internal_mixing_interval
697                         ? softmix_data->internal_mixing_interval
698                         : DEFAULT_SOFTMIX_INTERVAL,
699                 bridge_channel, 0, set_binaural, pos_id, is_announcement);
700
701         if (bridge->softmix.video_mode.mode == AST_BRIDGE_VIDEO_MODE_SFU) {
702                 sfu_topologies_on_join(bridge_channel, &bridge->channels);
703         }
704
705         softmix_poke_thread(softmix_data);
706         return 0;
707 }
708
709 static int remove_destination_streams(struct ast_stream_topology *dest,
710         const char *channel_name,
711         const struct ast_stream_topology *source)
712 {
713         int i;
714
715         for (i = 0; i < ast_stream_topology_get_count(source); ++i) {
716                 struct ast_stream *stream;
717                 struct ast_stream *stream_clone;
718
719                 stream = ast_stream_topology_get_stream(source, i);
720
721                 if (is_video_dest(stream, channel_name, NULL)) {
722                         continue;
723                 }
724
725                 stream_clone = ast_stream_clone(stream, NULL);
726                 if (!stream_clone) {
727                         continue;
728                 }
729                 if (ast_stream_topology_append_stream(dest, stream_clone) < 0) {
730                         ast_stream_free(stream_clone);
731                 }
732         }
733
734         return 0;
735 }
736
737 static int sfu_topologies_on_leave(struct ast_bridge_channel *leaver, struct ast_bridge_channels_list *participants)
738 {
739         struct ast_stream_topology *leaver_topology;
740         struct ast_bridge_channel *participant;
741
742         leaver_topology = ast_stream_topology_alloc();
743         if (!leaver_topology) {
744                 return -1;
745         }
746
747         AST_LIST_TRAVERSE(participants, participant, entry) {
748                 struct ast_stream_topology *participant_topology;
749
750                 participant_topology = ast_stream_topology_alloc();
751                 if (!participant_topology) {
752                         continue;
753                 }
754
755                 remove_destination_streams(participant_topology, ast_channel_name(leaver->chan), ast_channel_get_stream_topology(participant->chan));
756                 ast_channel_request_stream_topology_change(participant->chan, participant_topology, NULL);
757                 ast_stream_topology_free(participant_topology);
758         }
759
760         remove_destination_streams(leaver_topology, "", ast_channel_get_stream_topology(leaver->chan));
761         ast_channel_request_stream_topology_change(leaver->chan, leaver_topology, NULL);
762         ast_stream_topology_free(leaver_topology);
763
764         return 0;
765 }
766
767 /*! \brief Function called when a channel leaves the bridge */
768 static void softmix_bridge_leave(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
769 {
770         struct softmix_channel *sc;
771         struct softmix_bridge_data *softmix_data;
772         softmix_data = bridge->tech_pvt;
773         sc = bridge_channel->tech_pvt;
774
775         if (bridge->softmix.video_mode.mode == AST_BRIDGE_VIDEO_MODE_SFU) {
776                 sfu_topologies_on_leave(bridge_channel, &bridge->channels);
777         }
778
779         if (!sc) {
780                 return;
781         }
782
783         if (bridge->softmix.binaural_active) {
784                 if (sc->binaural) {
785                         set_binaural_data_leave(&softmix_data->convolve, sc->binaural_pos,
786                                         softmix_data->default_sample_size);
787                 }
788         }
789
790         bridge_channel->tech_pvt = NULL;
791
792         /* Drop mutex lock */
793         ast_mutex_destroy(&sc->lock);
794
795         /* Drop the factory */
796         ast_slinfactory_destroy(&sc->factory);
797
798         /* Drop any formats on the frames */
799         ao2_cleanup(sc->write_frame.subclass.format);
800
801         /* Drop the DSP */
802         ast_dsp_free(sc->dsp);
803
804         /* Eep! drop ourselves */
805         ast_free(sc);
806 }
807
808 static void softmix_pass_video_top_priority(struct ast_bridge *bridge, struct ast_frame *frame)
809 {
810         struct ast_bridge_channel *cur;
811
812         AST_LIST_TRAVERSE(&bridge->channels, cur, entry) {
813                 if (cur->suspended) {
814                         continue;
815                 }
816                 if (ast_bridge_is_video_src(bridge, cur->chan) == 1) {
817                         ast_bridge_channel_queue_frame(cur, frame);
818                         break;
819                 }
820         }
821 }
822
823 /*!
824  * \internal
825  * \brief Determine what to do with a video frame.
826  * \since 12.0.0
827  *
828  * \param bridge Which bridge is getting the frame
829  * \param bridge_channel Which channel is writing the frame.
830  * \param frame What is being written.
831  *
832  * \return Nothing
833  */
834 static void softmix_bridge_write_video(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, struct ast_frame *frame)
835 {
836         struct softmix_channel *sc;
837         int video_src_priority;
838
839         /* Determine if the video frame should be distributed or not */
840         switch (bridge->softmix.video_mode.mode) {
841         case AST_BRIDGE_VIDEO_MODE_NONE:
842                 break;
843         case AST_BRIDGE_VIDEO_MODE_SINGLE_SRC:
844                 video_src_priority = ast_bridge_is_video_src(bridge, bridge_channel->chan);
845                 if (video_src_priority == 1) {
846                         /* Pass to me and everyone else. */
847                         ast_bridge_queue_everyone_else(bridge, NULL, frame);
848                 }
849                 break;
850         case AST_BRIDGE_VIDEO_MODE_TALKER_SRC:
851                 sc = bridge_channel->tech_pvt;
852                 ast_mutex_lock(&sc->lock);
853                 ast_bridge_update_talker_src_video_mode(bridge, bridge_channel->chan,
854                         sc->video_talker.energy_average,
855                         frame->subclass.frame_ending);
856                 ast_mutex_unlock(&sc->lock);
857                 video_src_priority = ast_bridge_is_video_src(bridge, bridge_channel->chan);
858                 if (video_src_priority == 1) {
859                         int num_src = ast_bridge_number_video_src(bridge);
860                         int echo = num_src > 1 ? 0 : 1;
861
862                         ast_bridge_queue_everyone_else(bridge, echo ? NULL : bridge_channel, frame);
863                 } else if (video_src_priority == 2) {
864                         softmix_pass_video_top_priority(bridge, frame);
865                 }
866                 break;
867         case AST_BRIDGE_VIDEO_MODE_SFU:
868                 /* Nothing special to do here, the bridge channel stream map will ensure the
869                  * video goes everywhere it needs to
870                  */
871                 ast_bridge_queue_everyone_else(bridge, bridge_channel, frame);
872                 break;
873         }
874 }
875
876 /*!
877  * \internal
878  * \brief Determine what to do with a voice frame.
879  * \since 12.0.0
880  *
881  * \param bridge Which bridge is getting the frame
882  * \param bridge_channel Which channel is writing the frame.
883  * \param frame What is being written.
884  *
885  * \return Nothing
886  */
887 static void softmix_bridge_write_voice(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, struct ast_frame *frame)
888 {
889         struct softmix_channel *sc = bridge_channel->tech_pvt;
890         struct softmix_bridge_data *softmix_data = bridge->tech_pvt;
891         int totalsilence = 0;
892         int cur_energy = 0;
893         int silence_threshold = bridge_channel->tech_args.silence_threshold ?
894                 bridge_channel->tech_args.silence_threshold :
895                 DEFAULT_SOFTMIX_SILENCE_THRESHOLD;
896         char update_talking = -1;  /* if this is set to 0 or 1, tell the bridge that the channel has started or stopped talking. */
897
898         /* Write the frame into the conference */
899         ast_mutex_lock(&sc->lock);
900
901         if (ast_format_cmp(frame->subclass.format, sc->read_slin_format) != AST_FORMAT_CMP_EQUAL) {
902                 /*
903                  * The incoming frame is not the expected format.  Update
904                  * the channel's translation path to get us slinear from
905                  * the new format for the next frame.
906                  *
907                  * There is the possibility that this frame is an old slinear
908                  * rate frame that was in flight when the softmix bridge
909                  * changed rates.  If so it will self correct on subsequent
910                  * frames.
911                  */
912                 ast_channel_lock(bridge_channel->chan);
913                 ast_debug(1, "Channel %s wrote unexpected format into bridge.  Got %s, expected %s.\n",
914                         ast_channel_name(bridge_channel->chan),
915                         ast_format_get_name(frame->subclass.format),
916                         ast_format_get_name(sc->read_slin_format));
917                 ast_set_read_format_path(bridge_channel->chan, frame->subclass.format,
918                         sc->read_slin_format);
919                 ast_channel_unlock(bridge_channel->chan);
920         }
921
922         /* The channel will be leaving soon if there is no dsp. */
923         if (sc->dsp) {
924                 ast_dsp_silence_with_energy(sc->dsp, frame, &totalsilence, &cur_energy);
925         }
926
927         if (bridge->softmix.video_mode.mode == AST_BRIDGE_VIDEO_MODE_TALKER_SRC) {
928                 int cur_slot = sc->video_talker.energy_history_cur_slot;
929
930                 sc->video_talker.energy_accum -= sc->video_talker.energy_history[cur_slot];
931                 sc->video_talker.energy_accum += cur_energy;
932                 sc->video_talker.energy_history[cur_slot] = cur_energy;
933                 sc->video_talker.energy_average = sc->video_talker.energy_accum / DEFAULT_ENERGY_HISTORY_LEN;
934                 sc->video_talker.energy_history_cur_slot++;
935                 if (sc->video_talker.energy_history_cur_slot == DEFAULT_ENERGY_HISTORY_LEN) {
936                         sc->video_talker.energy_history_cur_slot = 0; /* wrap around */
937                 }
938         }
939
940         if (totalsilence < silence_threshold) {
941                 if (!sc->talking) {
942                         update_talking = 1;
943                 }
944                 sc->talking = 1; /* tell the write process we have audio to be mixed out */
945         } else {
946                 if (sc->talking) {
947                         update_talking = 0;
948                 }
949                 sc->talking = 0;
950         }
951
952         /* Before adding audio in, make sure we haven't fallen behind. If audio has fallen
953          * behind 4 times the amount of samples mixed on every iteration of the mixer, Re-sync
954          * the audio by flushing the buffer before adding new audio in. */
955         if (ast_slinfactory_available(&sc->factory) > (4 * SOFTMIX_SAMPLES(softmix_data->internal_rate, softmix_data->internal_mixing_interval))) {
956                 ast_slinfactory_flush(&sc->factory);
957         }
958
959         /* If a frame was provided add it to the smoother, unless drop silence is enabled and this frame
960          * is not determined to be talking. */
961         if (!(bridge_channel->tech_args.drop_silence && !sc->talking)) {
962                 ast_slinfactory_feed(&sc->factory, frame);
963         }
964
965         /* Alllll done */
966         ast_mutex_unlock(&sc->lock);
967
968         if (update_talking != -1) {
969                 ast_bridge_channel_notify_talking(bridge_channel, update_talking);
970         }
971 }
972
973 /*!
974  * \internal
975  * \brief Determine what to do with a control frame.
976  * \since 12.0.0
977  *
978  * \param bridge Which bridge is getting the frame
979  * \param bridge_channel Which channel is writing the frame.
980  * \param frame What is being written.
981  *
982  * \retval 0 Frame accepted into the bridge.
983  * \retval -1 Frame needs to be deferred.
984  */
985 static int softmix_bridge_write_control(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, struct ast_frame *frame)
986 {
987         /*
988          * XXX Softmix needs to use channel roles to determine what to
989          * do with control frames.
990          */
991
992         switch (frame->subclass.integer) {
993         case AST_CONTROL_VIDUPDATE:
994                 ast_bridge_queue_everyone_else(bridge, NULL, frame);
995                 break;
996         default:
997                 break;
998         }
999
1000         return 0;
1001 }
1002
1003 /*!
1004  * \internal
1005  * \brief Determine what to do with a frame written into the bridge.
1006  * \since 12.0.0
1007  *
1008  * \param bridge Which bridge is getting the frame
1009  * \param bridge_channel Which channel is writing the frame.
1010  * \param frame What is being written.
1011  *
1012  * \retval 0 Frame accepted into the bridge.
1013  * \retval -1 Frame needs to be deferred.
1014  *
1015  * \note On entry, bridge is already locked.
1016  */
1017 static int softmix_bridge_write(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, struct ast_frame *frame)
1018 {
1019         int res = 0;
1020
1021         if (!bridge->tech_pvt || !bridge_channel || !bridge_channel->tech_pvt) {
1022                 /* "Accept" the frame and discard it. */
1023                 return 0;
1024         }
1025
1026         /*
1027          * XXX Softmix needs to use channel roles to determine who gets
1028          * what frame.  Possible roles: announcer, recorder, agent,
1029          * supervisor.
1030          */
1031         switch (frame->frametype) {
1032         case AST_FRAME_NULL:
1033                 /* "Accept" the frame and discard it. */
1034                 break;
1035         case AST_FRAME_DTMF_BEGIN:
1036         case AST_FRAME_DTMF_END:
1037                 res = ast_bridge_queue_everyone_else(bridge, bridge_channel, frame);
1038                 break;
1039         case AST_FRAME_VOICE:
1040                 if (bridge_channel) {
1041                         softmix_bridge_write_voice(bridge, bridge_channel, frame);
1042                 }
1043                 break;
1044         case AST_FRAME_VIDEO:
1045                 if (bridge_channel) {
1046                         softmix_bridge_write_video(bridge, bridge_channel, frame);
1047                 }
1048                 break;
1049         case AST_FRAME_CONTROL:
1050                 res = softmix_bridge_write_control(bridge, bridge_channel, frame);
1051                 break;
1052         case AST_FRAME_BRIDGE_ACTION:
1053                 res = ast_bridge_queue_everyone_else(bridge, bridge_channel, frame);
1054                 break;
1055         case AST_FRAME_BRIDGE_ACTION_SYNC:
1056                 ast_log(LOG_ERROR, "Synchronous bridge action written to a softmix bridge.\n");
1057                 ast_assert(0);
1058         default:
1059                 ast_debug(3, "Frame type %u unsupported\n", frame->frametype);
1060                 /* "Accept" the frame and discard it. */
1061                 break;
1062         }
1063
1064         return res;
1065 }
1066
1067 static void gather_softmix_stats(struct softmix_stats *stats,
1068         const struct softmix_bridge_data *softmix_data,
1069         struct ast_bridge_channel *bridge_channel)
1070 {
1071         int channel_native_rate;
1072
1073         /* Gather stats about channel sample rates. */
1074         ast_channel_lock(bridge_channel->chan);
1075         channel_native_rate = MAX(SOFTMIX_MIN_SAMPLE_RATE,
1076                 ast_format_get_sample_rate(ast_channel_rawreadformat(bridge_channel->chan)));
1077         ast_channel_unlock(bridge_channel->chan);
1078
1079         if (stats->highest_supported_rate < channel_native_rate) {
1080                 stats->highest_supported_rate = channel_native_rate;
1081         }
1082         if (softmix_data->internal_rate < channel_native_rate) {
1083                 int i;
1084
1085                 for (i = 0; i < ARRAY_LEN(stats->sample_rates); i++) {
1086                         if (stats->sample_rates[i] == channel_native_rate) {
1087                                 stats->num_channels[i]++;
1088                                 break;
1089                         } else if (!stats->sample_rates[i]) {
1090                                 stats->sample_rates[i] = channel_native_rate;
1091                                 stats->num_channels[i]++;
1092                                 break;
1093                         }
1094                 }
1095                 stats->num_above_internal_rate++;
1096         } else if (softmix_data->internal_rate == channel_native_rate) {
1097                 stats->num_at_internal_rate++;
1098         }
1099 }
1100
1101 /*!
1102  * \internal
1103  * \brief Analyse mixing statistics and change bridges internal rate
1104  * if necessary.
1105  *
1106  * \retval 0, no changes to internal rate
1107  * \retval 1, internal rate was changed, update all the channels on the next mixing iteration.
1108  */
1109 static unsigned int analyse_softmix_stats(struct softmix_stats *stats,
1110                 struct softmix_bridge_data *softmix_data, int binaural_active)
1111 {
1112         int i;
1113
1114         if (binaural_active) {
1115                 stats->locked_rate = SOFTMIX_BINAURAL_SAMPLE_RATE;
1116         }
1117
1118         /*
1119          * Re-adjust the internal bridge sample rate if
1120          * 1. The bridge's internal sample rate is locked in at a sample
1121          *    rate other than the current sample rate being used.
1122          * 2. two or more channels support a higher sample rate
1123          * 3. no channels support the current sample rate or a higher rate
1124          */
1125         if (stats->locked_rate) {
1126                 /* if the rate is locked by the bridge, only update it if it differs
1127                  * from the current rate we are using. */
1128                 if (softmix_data->internal_rate != stats->locked_rate) {
1129                         ast_debug(1, "Locking at new rate.  Bridge changed from %u to %u.\n",
1130                                 softmix_data->internal_rate, stats->locked_rate);
1131                         softmix_data->internal_rate = stats->locked_rate;
1132                         return 1;
1133                 }
1134         } else if (stats->num_above_internal_rate >= 2) {
1135                 /* the highest rate is just used as a starting point */
1136                 unsigned int best_rate = stats->highest_supported_rate;
1137                 int best_index = -1;
1138
1139                 for (i = 0; i < ARRAY_LEN(stats->num_channels); i++) {
1140                         if (stats->num_channels[i]) {
1141                                 break;
1142                         }
1143                         if (2 <= stats->num_channels[i]) {
1144                                 /* Two or more channels support this rate. */
1145                                 if (best_index == -1
1146                                         || stats->sample_rates[best_index] < stats->sample_rates[i]) {
1147                                         /*
1148                                          * best_rate starts out being the first sample rate
1149                                          * greater than the internal sample rate that two or
1150                                          * more channels support.
1151                                          *
1152                                          * or
1153                                          *
1154                                          * There are multiple rates above the internal rate
1155                                          * and this rate is higher than the previous rate two
1156                                          * or more channels support.
1157                                          */
1158                                         best_rate = stats->sample_rates[i];
1159                                         best_index = i;
1160                                 }
1161                         } else if (best_index == -1) {
1162                                 /*
1163                                  * It is possible that multiple channels exist with native sample
1164                                  * rates above the internal sample rate, but none of those channels
1165                                  * have the same rate in common.  In this case, the lowest sample
1166                                  * rate among those channels is picked. Over time as additional
1167                                  * statistic runs are made the internal sample rate number will
1168                                  * adjust to the most optimal sample rate, but it may take multiple
1169                                  * iterations.
1170                                  */
1171                                 best_rate = MIN(best_rate, stats->sample_rates[i]);
1172                         }
1173                 }
1174
1175                 ast_debug(1, "Multiple above internal rate.  Bridge changed from %u to %u.\n",
1176                         softmix_data->internal_rate, best_rate);
1177                 softmix_data->internal_rate = best_rate;
1178                 return 1;
1179         } else if (!stats->num_at_internal_rate && !stats->num_above_internal_rate) {
1180                 /* In this case, the highest supported rate is actually lower than the internal rate */
1181                 ast_debug(1, "All below internal rate.  Bridge changed from %u to %u.\n",
1182                         softmix_data->internal_rate, stats->highest_supported_rate);
1183                 softmix_data->internal_rate = stats->highest_supported_rate;
1184                 return 1;
1185         }
1186         return 0;
1187 }
1188
1189 static int softmix_mixing_array_init(struct softmix_mixing_array *mixing_array,
1190                 unsigned int starting_num_entries, unsigned int binaural_active)
1191 {
1192         memset(mixing_array, 0, sizeof(*mixing_array));
1193         mixing_array->max_num_entries = starting_num_entries;
1194         if (!(mixing_array->buffers = ast_calloc(mixing_array->max_num_entries, sizeof(int16_t *)))) {
1195                 ast_log(LOG_NOTICE, "Failed to allocate softmix mixing structure.\n");
1196                 return -1;
1197         }
1198         if (binaural_active) {
1199                 if (!(mixing_array->chan_pairs = ast_calloc(mixing_array->max_num_entries,
1200                                 sizeof(struct convolve_channel_pair *)))) {
1201                         ast_log(LOG_NOTICE, "Failed to allocate softmix mixing structure.\n");
1202                         return -1;
1203                 }
1204         }
1205         return 0;
1206 }
1207
1208 static void softmix_mixing_array_destroy(struct softmix_mixing_array *mixing_array,
1209                 unsigned int binaural_active)
1210 {
1211         ast_free(mixing_array->buffers);
1212         if (binaural_active) {
1213                 ast_free(mixing_array->chan_pairs);
1214         }
1215 }
1216
1217 static int softmix_mixing_array_grow(struct softmix_mixing_array *mixing_array,
1218                 unsigned int num_entries, unsigned int binaural_active)
1219 {
1220         int16_t **tmp;
1221
1222         /* give it some room to grow since memory is cheap but allocations can be expensive */
1223         mixing_array->max_num_entries = num_entries;
1224         if (!(tmp = ast_realloc(mixing_array->buffers, (mixing_array->max_num_entries * sizeof(int16_t *))))) {
1225                 ast_log(LOG_NOTICE, "Failed to re-allocate softmix mixing structure.\n");
1226                 return -1;
1227         }
1228         if (binaural_active) {
1229                 struct convolve_channel_pair **tmp2;
1230                 if (!(tmp2 = ast_realloc(mixing_array->chan_pairs,
1231                                 (mixing_array->max_num_entries * sizeof(struct convolve_channel_pair *))))) {
1232                         ast_log(LOG_NOTICE, "Failed to re-allocate softmix mixing structure.\n");
1233                         return -1;
1234                 }
1235                 mixing_array->chan_pairs = tmp2;
1236         }
1237         mixing_array->buffers = tmp;
1238         return 0;
1239 }
1240
1241 /*!
1242  * \brief Mixing loop.
1243  *
1244  * \retval 0 on success
1245  * \retval -1 on failure
1246  */
1247 static int softmix_mixing_loop(struct ast_bridge *bridge)
1248 {
1249         struct softmix_stats stats = { { 0 }, };
1250         struct softmix_mixing_array mixing_array;
1251         struct softmix_bridge_data *softmix_data = bridge->tech_pvt;
1252         struct ast_timer *timer;
1253         struct softmix_translate_helper trans_helper;
1254         int16_t buf[MAX_DATALEN];
1255 #ifdef BINAURAL_RENDERING
1256         int16_t bin_buf[MAX_DATALEN];
1257         int16_t ann_buf[MAX_DATALEN];
1258 #endif
1259         unsigned int stat_iteration_counter = 0; /* counts down, gather stats at zero and reset. */
1260         int timingfd;
1261         int update_all_rates = 0; /* set this when the internal sample rate has changed */
1262         unsigned int idx;
1263         unsigned int x;
1264         int res = -1;
1265
1266         timer = softmix_data->timer;
1267         timingfd = ast_timer_fd(timer);
1268         softmix_translate_helper_init(&trans_helper, softmix_data->internal_rate);
1269         ast_timer_set_rate(timer, (1000 / softmix_data->internal_mixing_interval));
1270
1271         /* Give the mixing array room to grow, memory is cheap but allocations are expensive. */
1272         if (softmix_mixing_array_init(&mixing_array, bridge->num_channels + 10,
1273                         bridge->softmix.binaural_active)) {
1274                 goto softmix_cleanup;
1275         }
1276
1277         /*
1278          * XXX Softmix needs to use channel roles to determine who gets
1279          * what audio mixed.
1280          */
1281         while (!softmix_data->stop && bridge->num_active) {
1282                 struct ast_bridge_channel *bridge_channel;
1283                 int timeout = -1;
1284                 struct ast_format *cur_slin = ast_format_cache_get_slin_by_rate(softmix_data->internal_rate);
1285                 unsigned int softmix_samples = SOFTMIX_SAMPLES(softmix_data->internal_rate, softmix_data->internal_mixing_interval);
1286                 unsigned int softmix_datalen = SOFTMIX_DATALEN(softmix_data->internal_rate, softmix_data->internal_mixing_interval);
1287
1288                 if (softmix_datalen > MAX_DATALEN) {
1289                         /* This should NEVER happen, but if it does we need to know about it. Almost
1290                          * all the memcpys used during this process depend on this assumption.  Rather
1291                          * than checking this over and over again through out the code, this single
1292                          * verification is done on each iteration. */
1293                         ast_log(LOG_WARNING,
1294                                 "Bridge %s: Conference mixing error, requested mixing length greater than mixing buffer.\n",
1295                                 bridge->uniqueid);
1296                         goto softmix_cleanup;
1297                 }
1298
1299                 /* Grow the mixing array buffer as participants are added. */
1300                 if (mixing_array.max_num_entries < bridge->num_channels
1301                         && softmix_mixing_array_grow(&mixing_array, bridge->num_channels + 5,
1302                                         bridge->softmix.binaural_active)) {
1303                         goto softmix_cleanup;
1304                 }
1305
1306                 /* init the number of buffers stored in the mixing array to 0.
1307                  * As buffers are added for mixing, this number is incremented. */
1308                 mixing_array.used_entries = 0;
1309
1310                 /* These variables help determine if a rate change is required */
1311                 if (!stat_iteration_counter) {
1312                         memset(&stats, 0, sizeof(stats));
1313                         stats.locked_rate = bridge->softmix.internal_sample_rate;
1314                 }
1315
1316                 /* If the sample rate has changed, update the translator helper */
1317                 if (update_all_rates) {
1318                         softmix_translate_helper_change_rate(&trans_helper, softmix_data->internal_rate);
1319                 }
1320
1321 #ifdef BINAURAL_RENDERING
1322                 check_binaural_position_change(bridge, softmix_data, bridge_channel);
1323 #endif
1324
1325                 /* Go through pulling audio from each factory that has it available */
1326                 AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
1327                         struct softmix_channel *sc = bridge_channel->tech_pvt;
1328
1329                         if (!sc) {
1330                                 /* This channel failed to join successfully. */
1331                                 continue;
1332                         }
1333
1334                         /* Update the sample rate to match the bridge's native sample rate if necessary. */
1335                         if (update_all_rates) {
1336                                 set_softmix_bridge_data(softmix_data->internal_rate,
1337                                                 softmix_data->internal_mixing_interval, bridge_channel, 1, -1, -1, -1);
1338                         }
1339
1340                         /* If stat_iteration_counter is 0, then collect statistics during this mixing interation */
1341                         if (!stat_iteration_counter) {
1342                                 gather_softmix_stats(&stats, softmix_data, bridge_channel);
1343                         }
1344
1345                         /* if the channel is suspended, don't check for audio, but still gather stats */
1346                         if (bridge_channel->suspended) {
1347                                 continue;
1348                         }
1349
1350                         /* Try to get audio from the factory if available */
1351                         ast_mutex_lock(&sc->lock);
1352                         if ((mixing_array.buffers[mixing_array.used_entries] = softmix_process_read_audio(sc, softmix_samples))) {
1353 #ifdef BINAURAL_RENDERING
1354                                 add_binaural_mixing(bridge, softmix_data, softmix_samples, &mixing_array, sc,
1355                                                 ast_channel_name(bridge_channel->chan));
1356 #endif
1357                                 mixing_array.used_entries++;
1358                         }
1359                         ast_mutex_unlock(&sc->lock);
1360                 }
1361
1362                 /* mix it like crazy (non binaural channels)*/
1363                 memset(buf, 0, softmix_datalen);
1364                 for (idx = 0; idx < mixing_array.used_entries; ++idx) {
1365                         for (x = 0; x < softmix_samples; ++x) {
1366                                 ast_slinear_saturated_add(buf + x, mixing_array.buffers[idx] + x);
1367                         }
1368                 }
1369
1370 #ifdef BINAURAL_RENDERING
1371                 binaural_mixing(bridge, softmix_data, &mixing_array, bin_buf, ann_buf);
1372 #endif
1373
1374                 /* Next step go through removing the channel's own audio and creating a good frame... */
1375                 AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
1376                         struct softmix_channel *sc = bridge_channel->tech_pvt;
1377
1378                         if (!sc || bridge_channel->suspended) {
1379                                 /* This channel failed to join successfully or is suspended. */
1380                                 continue;
1381                         }
1382
1383                         ast_mutex_lock(&sc->lock);
1384
1385                         /* Make SLINEAR write frame from local buffer */
1386                         ao2_t_replace(sc->write_frame.subclass.format, cur_slin,
1387                                 "Replace softmix channel slin format");
1388 #ifdef BINAURAL_RENDERING
1389                         if (bridge->softmix.binaural_active && softmix_data->convolve.binaural_active
1390                                         && sc->binaural) {
1391                                 create_binaural_frame(bridge_channel, sc, bin_buf, ann_buf, softmix_datalen,
1392                                                 softmix_samples, buf);
1393                         } else
1394 #endif
1395                         {
1396                                 sc->write_frame.datalen = softmix_datalen;
1397                                 sc->write_frame.samples = softmix_samples;
1398                                 memcpy(sc->final_buf, buf, softmix_datalen);
1399                         }
1400                         /* process the softmix channel's new write audio */
1401                         softmix_process_write_audio(&trans_helper,
1402                                         ast_channel_rawwriteformat(bridge_channel->chan), sc,
1403                                         softmix_data->default_sample_size);
1404
1405                         ast_mutex_unlock(&sc->lock);
1406
1407                         /* A frame is now ready for the channel. */
1408                         ast_bridge_channel_queue_frame(bridge_channel, &sc->write_frame);
1409                 }
1410
1411                 update_all_rates = 0;
1412                 if (!stat_iteration_counter) {
1413                         update_all_rates = analyse_softmix_stats(&stats, softmix_data,
1414                                         bridge->softmix.binaural_active);
1415                         stat_iteration_counter = SOFTMIX_STAT_INTERVAL;
1416                 }
1417                 stat_iteration_counter--;
1418
1419                 ast_bridge_unlock(bridge);
1420                 /* cleanup any translation frame data from the previous mixing iteration. */
1421                 softmix_translate_helper_cleanup(&trans_helper);
1422                 /* Wait for the timing source to tell us to wake up and get things done */
1423                 ast_waitfor_n_fd(&timingfd, 1, &timeout, NULL);
1424                 if (ast_timer_ack(timer, 1) < 0) {
1425                         ast_log(LOG_ERROR, "Bridge %s: Failed to acknowledge timer in softmix.\n",
1426                                 bridge->uniqueid);
1427                         ast_bridge_lock(bridge);
1428                         goto softmix_cleanup;
1429                 }
1430                 ast_bridge_lock(bridge);
1431
1432                 /* make sure to detect mixing interval changes if they occur. */
1433                 if (bridge->softmix.internal_mixing_interval
1434                         && (bridge->softmix.internal_mixing_interval != softmix_data->internal_mixing_interval)) {
1435                         softmix_data->internal_mixing_interval = bridge->softmix.internal_mixing_interval;
1436                         ast_timer_set_rate(timer, (1000 / softmix_data->internal_mixing_interval));
1437                         update_all_rates = 1; /* if the interval changes, the rates must be adjusted as well just to be notified new interval.*/
1438                 }
1439         }
1440
1441         res = 0;
1442
1443 softmix_cleanup:
1444         softmix_translate_helper_destroy(&trans_helper);
1445         softmix_mixing_array_destroy(&mixing_array, bridge->softmix.binaural_active);
1446         return res;
1447 }
1448
1449 /*!
1450  * \internal
1451  * \brief Mixing thread.
1452  * \since 12.0.0
1453  *
1454  * \note The thread does not have its own reference to the
1455  * bridge.  The lifetime of the thread is tied to the lifetime
1456  * of the mixing technology association with the bridge.
1457  */
1458 static void *softmix_mixing_thread(void *data)
1459 {
1460         struct softmix_bridge_data *softmix_data = data;
1461         struct ast_bridge *bridge = softmix_data->bridge;
1462
1463         ast_bridge_lock(bridge);
1464         if (bridge->callid) {
1465                 ast_callid_threadassoc_add(bridge->callid);
1466         }
1467
1468         ast_debug(1, "Bridge %s: starting mixing thread\n", bridge->uniqueid);
1469
1470         while (!softmix_data->stop) {
1471                 if (!bridge->num_active) {
1472                         /* Wait for something to happen to the bridge. */
1473                         ast_bridge_unlock(bridge);
1474                         ast_mutex_lock(&softmix_data->lock);
1475                         if (!softmix_data->stop) {
1476                                 ast_cond_wait(&softmix_data->cond, &softmix_data->lock);
1477                         }
1478                         ast_mutex_unlock(&softmix_data->lock);
1479                         ast_bridge_lock(bridge);
1480                         continue;
1481                 }
1482
1483                 if (bridge->softmix.binaural_active && !softmix_data->binaural_init) {
1484 #ifndef BINAURAL_RENDERING
1485                         ast_bridge_lock(bridge);
1486                         bridge->softmix.binaural_active = 0;
1487                         ast_bridge_unlock(bridge);
1488                         ast_log(LOG_WARNING, "Bridge: %s: Binaural rendering active by config but not "
1489                                         "compiled.\n", bridge->uniqueid);
1490 #else
1491                         /* Set and init binaural data if binaural is activated in the configuration. */
1492                         softmix_data->internal_rate = SOFTMIX_BINAURAL_SAMPLE_RATE;
1493                         softmix_data->default_sample_size = SOFTMIX_SAMPLES(softmix_data->internal_rate,
1494                                         softmix_data->internal_mixing_interval);
1495                         /* If init for binaural processing fails we will fall back to mono audio processing. */
1496                         if (init_convolve_data(&softmix_data->convolve, softmix_data->default_sample_size)
1497                                         == -1) {
1498                                 ast_bridge_lock(bridge);
1499                                 bridge->softmix.binaural_active = 0;
1500                                 ast_bridge_unlock(bridge);
1501                                 ast_log(LOG_ERROR, "Bridge: %s: Unable to allocate memory for "
1502                                                 "binaural processing,  Will only process mono audio.\n",
1503                                                 bridge->uniqueid);
1504                         }
1505                         softmix_data->binaural_init = 1;
1506 #endif
1507                 }
1508
1509                 if (softmix_mixing_loop(bridge)) {
1510                         /*
1511                          * A mixing error occurred.  Sleep and try again later so we
1512                          * won't flood the logs.
1513                          */
1514                         ast_bridge_unlock(bridge);
1515                         sleep(1);
1516                         ast_bridge_lock(bridge);
1517                 }
1518         }
1519
1520         ast_bridge_unlock(bridge);
1521
1522         ast_debug(1, "Bridge %s: stopping mixing thread\n", bridge->uniqueid);
1523
1524         return NULL;
1525 }
1526
1527 static void softmix_bridge_data_destroy(struct softmix_bridge_data *softmix_data)
1528 {
1529         if (softmix_data->timer) {
1530                 ast_timer_close(softmix_data->timer);
1531                 softmix_data->timer = NULL;
1532         }
1533         ast_mutex_destroy(&softmix_data->lock);
1534         ast_cond_destroy(&softmix_data->cond);
1535         ast_free(softmix_data);
1536 }
1537
1538 /*! \brief Function called when a bridge is created */
1539 static int softmix_bridge_create(struct ast_bridge *bridge)
1540 {
1541         struct softmix_bridge_data *softmix_data;
1542
1543         softmix_data = ast_calloc(1, sizeof(*softmix_data));
1544         if (!softmix_data) {
1545                 return -1;
1546         }
1547         softmix_data->bridge = bridge;
1548         ast_mutex_init(&softmix_data->lock);
1549         ast_cond_init(&softmix_data->cond, NULL);
1550         softmix_data->timer = ast_timer_open();
1551         if (!softmix_data->timer) {
1552                 ast_log(AST_LOG_WARNING, "Failed to open timer for softmix bridge\n");
1553                 softmix_bridge_data_destroy(softmix_data);
1554                 return -1;
1555         }
1556         /* start at minimum rate, let it grow from there */
1557         softmix_data->internal_rate = SOFTMIX_MIN_SAMPLE_RATE;
1558         softmix_data->internal_mixing_interval = DEFAULT_SOFTMIX_INTERVAL;
1559
1560 #ifdef BINAURAL_RENDERING
1561         softmix_data->default_sample_size = SOFTMIX_SAMPLES(softmix_data->internal_rate,
1562                         softmix_data->internal_mixing_interval);
1563 #endif
1564
1565         bridge->tech_pvt = softmix_data;
1566
1567         /* Start the mixing thread. */
1568         if (ast_pthread_create(&softmix_data->thread, NULL, softmix_mixing_thread,
1569                 softmix_data)) {
1570                 softmix_data->thread = AST_PTHREADT_NULL;
1571                 softmix_bridge_data_destroy(softmix_data);
1572                 bridge->tech_pvt = NULL;
1573                 return -1;
1574         }
1575
1576         return 0;
1577 }
1578
1579 /*!
1580  * \internal
1581  * \brief Request the softmix mixing thread stop.
1582  * \since 12.0.0
1583  *
1584  * \param bridge Which bridge is being stopped.
1585  *
1586  * \return Nothing
1587  */
1588 static void softmix_bridge_stop(struct ast_bridge *bridge)
1589 {
1590         struct softmix_bridge_data *softmix_data;
1591
1592         softmix_data = bridge->tech_pvt;
1593         if (!softmix_data) {
1594                 return;
1595         }
1596
1597         ast_mutex_lock(&softmix_data->lock);
1598         softmix_data->stop = 1;
1599         ast_mutex_unlock(&softmix_data->lock);
1600 }
1601
1602 /*! \brief Function called when a bridge is destroyed */
1603 static void softmix_bridge_destroy(struct ast_bridge *bridge)
1604 {
1605         struct softmix_bridge_data *softmix_data;
1606         pthread_t thread;
1607
1608         softmix_data = bridge->tech_pvt;
1609         if (!softmix_data) {
1610                 return;
1611         }
1612
1613         /* Stop the mixing thread. */
1614         ast_mutex_lock(&softmix_data->lock);
1615         softmix_data->stop = 1;
1616         ast_cond_signal(&softmix_data->cond);
1617         thread = softmix_data->thread;
1618         softmix_data->thread = AST_PTHREADT_NULL;
1619         ast_mutex_unlock(&softmix_data->lock);
1620         if (thread != AST_PTHREADT_NULL) {
1621                 ast_debug(1, "Bridge %s: Waiting for mixing thread to die.\n", bridge->uniqueid);
1622                 pthread_join(thread, NULL);
1623         }
1624 #ifdef BINAURAL_RENDERING
1625         free_convolve_data(&softmix_data->convolve);
1626 #endif
1627         softmix_bridge_data_destroy(softmix_data);
1628         bridge->tech_pvt = NULL;
1629 }
1630
1631 /*!
1632  * \brief Map a source stream to all of its destination streams.
1633  *
1634  * \param source_stream_name Name of the source stream
1635  * \param source_channel_name Name of channel where the source stream originates
1636  * \param bridge_stream_position The slot in the bridge where source video will come from
1637  * \param participants The bridge_channels in the bridge
1638  */
1639 static void map_source_to_destinations(const char *source_stream_name, const char *source_channel_name,
1640         size_t bridge_stream_position, struct ast_bridge_channels_list *participants)
1641 {
1642         struct ast_bridge_channel *participant;
1643
1644         AST_LIST_TRAVERSE(participants, participant, entry) {
1645                 int i;
1646                 struct ast_stream_topology *topology;
1647
1648                 if (!strcmp(source_channel_name, ast_channel_name(participant->chan))) {
1649                         continue;
1650                 }
1651
1652                 ast_bridge_channel_lock(participant);
1653                 topology = ast_channel_get_stream_topology(participant->chan);
1654
1655                 for (i = 0; i < ast_stream_topology_get_count(topology); ++i) {
1656                         struct ast_stream *stream;
1657
1658                         stream = ast_stream_topology_get_stream(topology, i);
1659                         if (is_video_dest(stream, source_channel_name, source_stream_name)) {
1660                                 AST_VECTOR_REPLACE(&participant->stream_map.to_channel, bridge_stream_position, i);
1661                                 break;
1662                         }
1663                 }
1664                 ast_bridge_channel_unlock(participant);
1665         }
1666 }
1667
1668 /*\brief stream_topology_changed callback
1669  *
1670  * For most video modes, nothing beyond the ordinary is required.
1671  * For the SFU case, though, we need to completely remap the streams
1672  * in order to ensure video gets directed where it is expected to go.
1673  *
1674  * \param bridge The bridge
1675  * \param bridge_channel Channel whose topology has changed
1676  */
1677 static void softmix_bridge_stream_topology_changed(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
1678 {
1679         struct ast_bridge_channel *participant;
1680         struct ast_vector_int media_types;
1681         int nths[AST_MEDIA_TYPE_END] = {0};
1682
1683         switch (bridge->softmix.video_mode.mode) {
1684         case AST_BRIDGE_VIDEO_MODE_NONE:
1685         case AST_BRIDGE_VIDEO_MODE_SINGLE_SRC:
1686         case AST_BRIDGE_VIDEO_MODE_TALKER_SRC:
1687         default:
1688                 ast_bridge_channel_stream_map(bridge_channel);
1689                 return;
1690         case AST_BRIDGE_VIDEO_MODE_SFU:
1691                 break;
1692         }
1693
1694         AST_VECTOR_INIT(&media_types, AST_MEDIA_TYPE_END);
1695
1696         /* First traversal: re-initialize all of the participants' stream maps */
1697         AST_LIST_TRAVERSE(&bridge->channels, participant, entry) {
1698                 int size;
1699
1700                 ast_bridge_channel_lock(participant);
1701                 size = ast_stream_topology_get_count(ast_channel_get_stream_topology(participant->chan));
1702
1703                 AST_VECTOR_FREE(&participant->stream_map.to_channel);
1704                 AST_VECTOR_FREE(&participant->stream_map.to_bridge);
1705
1706                 AST_VECTOR_INIT(&participant->stream_map.to_channel, size);
1707                 AST_VECTOR_INIT(&participant->stream_map.to_bridge, size);
1708                 ast_bridge_channel_unlock(participant);
1709         }
1710
1711         /* Second traversal: Map specific video channels from their source to their destinations.
1712          *
1713          * This is similar to what is done in ast_stream_topology_map(), except that
1714          * video channels are handled differently. Each video source has it's own
1715          * unique index on the bridge. this way, a particular channel's source video
1716          * can be distributed to the appropriate destination streams on the other
1717          * channels
1718          */
1719         AST_LIST_TRAVERSE(&bridge->channels, participant, entry) {
1720                 int i;
1721                 struct ast_stream_topology *topology;
1722
1723                 topology = ast_channel_get_stream_topology(participant->chan);
1724
1725                 for (i = 0; i < ast_stream_topology_get_count(topology); ++i) {
1726                         struct ast_stream *stream = ast_stream_topology_get_stream(topology, i);
1727                         ast_bridge_channel_lock(participant);
1728                         if (is_video_source(stream)) {
1729                                 AST_VECTOR_APPEND(&media_types, AST_MEDIA_TYPE_VIDEO);
1730                                 AST_VECTOR_REPLACE(&participant->stream_map.to_bridge, i, AST_VECTOR_SIZE(&media_types) - 1);
1731                                 AST_VECTOR_REPLACE(&participant->stream_map.to_channel, AST_VECTOR_SIZE(&media_types) - 1, -1);
1732                                 /* Unlock the participant to prevent potential deadlock
1733                                  * in map_source_to_destinations
1734                                  */
1735                                 ast_bridge_channel_unlock(participant);
1736                                 map_source_to_destinations(ast_stream_get_name(stream), ast_channel_name(participant->chan),
1737                                         AST_VECTOR_SIZE(&media_types) - 1, &bridge->channels);
1738                                 ast_bridge_channel_lock(participant);
1739                         } else if (is_video_dest(stream, NULL, NULL)) {
1740                                 /* We expect to never read media from video destination channels, but just
1741                                  * in case, we should set their to_bridge value to -1.
1742                                  */
1743                                 AST_VECTOR_REPLACE(&participant->stream_map.to_bridge, i, -1);
1744                         } else {
1745                                 /* XXX This is copied from ast_stream_topology_map(). This likely could
1746                                  * be factored out in some way
1747                                  */
1748                                 enum ast_media_type type = ast_stream_get_type(stream);
1749                                 int index = AST_VECTOR_GET_INDEX_NTH(&media_types, ++nths[type],
1750                                         type, AST_VECTOR_ELEM_DEFAULT_CMP);
1751
1752                                 if (index == -1) {
1753                                         AST_VECTOR_APPEND(&media_types, type);
1754                                         index = AST_VECTOR_SIZE(&media_types) - 1;
1755                                 }
1756
1757                                 AST_VECTOR_REPLACE(&participant->stream_map.to_bridge, i, index);
1758                                 AST_VECTOR_REPLACE(&participant->stream_map.to_channel, index, i);
1759                         }
1760                         ast_bridge_channel_unlock(participant);
1761                 }
1762         }
1763 }
1764
1765 static struct ast_bridge_technology softmix_bridge = {
1766         .name = "softmix",
1767         .capabilities = AST_BRIDGE_CAPABILITY_MULTIMIX,
1768         .preference = AST_BRIDGE_PREFERENCE_BASE_MULTIMIX,
1769         .create = softmix_bridge_create,
1770         .stop = softmix_bridge_stop,
1771         .destroy = softmix_bridge_destroy,
1772         .join = softmix_bridge_join,
1773         .leave = softmix_bridge_leave,
1774         .unsuspend = softmix_bridge_unsuspend,
1775         .write = softmix_bridge_write,
1776         .stream_topology_changed = softmix_bridge_stream_topology_changed,
1777 };
1778
1779 #ifdef TEST_FRAMEWORK
1780 struct stream_parameters {
1781         const char *name;
1782         const char *formats;
1783         enum ast_media_type type;
1784 };
1785
1786 static struct ast_stream_topology *build_topology(const struct stream_parameters *params, size_t num_streams)
1787 {
1788         struct ast_stream_topology *topology;
1789         size_t i;
1790
1791         topology = ast_stream_topology_alloc();
1792         if (!topology) {
1793                 return NULL;
1794         }
1795
1796         for (i = 0; i < num_streams; ++i) {
1797                 RAII_VAR(struct ast_format_cap *, caps, NULL, ao2_cleanup);
1798                 struct ast_stream *stream;
1799
1800                 caps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
1801                 if (!caps) {
1802                         goto fail;
1803                 }
1804                 if (ast_format_cap_update_by_allow_disallow(caps, params[i].formats, 1) < 0) {
1805                         goto fail;
1806                 }
1807                 stream = ast_stream_alloc(params[i].name, params[i].type);
1808                 if (!stream) {
1809                         goto fail;
1810                 }
1811                 ast_stream_set_formats(stream, caps);
1812                 if (ast_stream_topology_append_stream(topology, stream) < 0) {
1813                         ast_stream_free(stream);
1814                         goto fail;
1815                 }
1816         }
1817
1818         return topology;
1819
1820 fail:
1821         ast_stream_topology_free(topology);
1822         return NULL;
1823 }
1824
1825 static int validate_stream(struct ast_test *test, struct ast_stream *stream,
1826         const struct stream_parameters *params)
1827 {
1828         struct ast_format_cap *stream_caps;
1829         struct ast_format_cap *params_caps;
1830
1831         if (ast_stream_get_type(stream) != params->type) {
1832                 ast_test_status_update(test, "Expected stream type '%s' but got type '%s'\n",
1833                         ast_codec_media_type2str(params->type),
1834                         ast_codec_media_type2str(ast_stream_get_type(stream)));
1835                 return -1;
1836         }
1837         if (strcmp(ast_stream_get_name(stream), params->name)) {
1838                 ast_test_status_update(test, "Expected stream name '%s' but got type '%s'\n",
1839                         params->name, ast_stream_get_name(stream));
1840                 return -1;
1841         }
1842
1843         stream_caps = ast_stream_get_formats(stream);
1844         params_caps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
1845         if (!params_caps) {
1846                 ast_test_status_update(test, "Allocation error on capabilities\n");
1847                 return -1;
1848         }
1849         ast_format_cap_update_by_allow_disallow(params_caps, params->formats, 1);
1850
1851         if (ast_format_cap_identical(stream_caps, params_caps)) {
1852                 ast_test_status_update(test, "Formats are not as expected on stream '%s'\n",
1853                         ast_stream_get_name(stream));
1854                 ao2_cleanup(params_caps);
1855                 return -1;
1856         }
1857
1858         ao2_cleanup(params_caps);
1859         return 0;
1860 }
1861
1862 static int validate_original_streams(struct ast_test *test, struct ast_stream_topology *topology,
1863         const struct stream_parameters *params, size_t num_streams)
1864 {
1865         int i;
1866
1867         if (ast_stream_topology_get_count(topology) < num_streams) {
1868                 ast_test_status_update(test, "Topology only has %d streams. Needs to have at least %zu\n",
1869                         ast_stream_topology_get_count(topology), num_streams);
1870                 return -1;
1871         }
1872
1873         for (i = 0; i < ARRAY_LEN(params); ++i) {
1874                 if (validate_stream(test, ast_stream_topology_get_stream(topology, i), &params[i])) {
1875                         return -1;
1876                 }
1877         }
1878
1879         return 0;
1880 }
1881
1882 AST_TEST_DEFINE(sfu_append_source_streams)
1883 {
1884         enum ast_test_result_state res = AST_TEST_FAIL;
1885         static const struct stream_parameters bob_streams[] = {
1886                 { "bob_audio", "ulaw,alaw,g722,opus", AST_MEDIA_TYPE_AUDIO, },
1887                 { "bob_video", "h264,vp8", AST_MEDIA_TYPE_VIDEO, },
1888         };
1889         static const struct stream_parameters alice_streams[] = {
1890                 { "alice_audio", "ulaw,opus", AST_MEDIA_TYPE_AUDIO, },
1891                 { "alice_video", "vp8", AST_MEDIA_TYPE_VIDEO, },
1892         };
1893         static const struct stream_parameters alice_dest_stream = {
1894                 "softbridge_dest_PJSIP/Bob-00000001_bob_video", "vp8", AST_MEDIA_TYPE_VIDEO,
1895         };
1896         static const struct stream_parameters bob_dest_stream = {
1897                 "softbridge_dest_PJSIP/Alice-00000000_alice_video", "h264,vp8", AST_MEDIA_TYPE_VIDEO,
1898         };
1899         struct ast_stream_topology *topology_alice = NULL;
1900         struct ast_stream_topology *topology_bob = NULL;
1901
1902         switch (cmd) {
1903         case TEST_INIT:
1904                 info->name = "sfu_append_source_streams";
1905                 info->category = "/bridges/bridge_softmix/";
1906                 info->summary = "Test appending of video streams";
1907                 info->description =
1908                         "This tests does stuff.";
1909                 return AST_TEST_NOT_RUN;
1910         case TEST_EXECUTE:
1911                 break;
1912         }
1913
1914         topology_alice = build_topology(alice_streams, ARRAY_LEN(alice_streams));
1915         if (!topology_alice) {
1916                 goto end;
1917         }
1918
1919         topology_bob = build_topology(bob_streams, ARRAY_LEN(bob_streams));
1920         if (!topology_bob) {
1921                 goto end;
1922         }
1923
1924         if (append_source_streams(topology_alice, "PJSIP/Bob-00000001", topology_bob)) {
1925                 ast_test_status_update(test, "Failed to append Bob's streams to Alice\n");
1926                 goto end;
1927         }
1928
1929         if (ast_stream_topology_get_count(topology_alice) != 3) {
1930                 ast_test_status_update(test, "Alice's topology isn't large enough! It's %d but needs to be %d\n",
1931                         ast_stream_topology_get_count(topology_alice), 3);
1932                 goto end;
1933         }
1934
1935         if (validate_original_streams(test, topology_alice, alice_streams, ARRAY_LEN(alice_streams))) {
1936                 goto end;
1937         }
1938
1939         if (validate_stream(test, ast_stream_topology_get_stream(topology_alice, 2), &alice_dest_stream)) {
1940                 goto end;
1941         }
1942
1943         if (append_source_streams(topology_bob, "PJSIP/Alice-00000000", topology_alice)) {
1944                 ast_test_status_update(test, "Failed to append Alice's streams to Bob\n");
1945                 goto end;
1946         }
1947
1948         if (ast_stream_topology_get_count(topology_bob) != 3) {
1949                 ast_test_status_update(test, "Bob's topology isn't large enough! It's %d but needs to be %d\n",
1950                         ast_stream_topology_get_count(topology_bob), 3);
1951                 goto end;
1952         }
1953
1954         if (validate_original_streams(test, topology_bob, bob_streams, ARRAY_LEN(bob_streams))) {
1955                 goto end;
1956         }
1957
1958         if (validate_stream(test, ast_stream_topology_get_stream(topology_bob, 2), &bob_dest_stream)) {
1959                 goto end;
1960         }
1961
1962         res = AST_TEST_PASS;
1963
1964 end:
1965         ast_stream_topology_free(topology_alice);
1966         ast_stream_topology_free(topology_bob);
1967         return res;
1968 }
1969
1970 AST_TEST_DEFINE(sfu_remove_destination_streams)
1971 {
1972         enum ast_test_result_state res = AST_TEST_FAIL;
1973         static const struct stream_parameters params[] = {
1974                 { "alice_audio", "ulaw,alaw,g722,opus", AST_MEDIA_TYPE_AUDIO, },
1975                 { "alice_video", "h264,vp8", AST_MEDIA_TYPE_VIDEO, },
1976                 { "softbridge_dest_PJSIP/Bob-00000001_video", "vp8", AST_MEDIA_TYPE_VIDEO, },
1977                 { "softbridge_dest_PJSIP/Carol-00000002_video", "h264", AST_MEDIA_TYPE_VIDEO, },
1978         };
1979         static const struct {
1980                 const char *channel_name;
1981                 int num_streams;
1982                 int params_index[4];
1983         } removal_results[] = {
1984                 { "PJSIP/Bob-00000001", 3, { 0, 1, 3, -1 }, },
1985                 { "PJSIP/Edward-00000004", 4, { 0, 1, 2, 3 }, },
1986                 { "", 2, { 0, 1, -1, -1 }, },
1987         };
1988         struct ast_stream_topology *orig = NULL;
1989         struct ast_stream_topology *result = NULL;
1990         int i;
1991
1992         switch (cmd) {
1993         case TEST_INIT:
1994                 info->name = "sfu_remove_destination_streams";
1995                 info->category = "/bridges/bridge_softmix/";
1996                 info->summary = "Test removal of destination video streams";
1997                 info->description =
1998                         "This tests does stuff.";
1999                 return AST_TEST_NOT_RUN;
2000         case TEST_EXECUTE:
2001                 break;
2002         }
2003
2004         orig = build_topology(params, ARRAY_LEN(params));
2005         if (!orig) {
2006                 ast_test_status_update(test, "Unable to build initial stream topology\n");
2007                 goto end;
2008         }
2009
2010         for (i = 0; i < ARRAY_LEN(removal_results); ++i) {
2011                 int j;
2012
2013                 result = ast_stream_topology_alloc();
2014                 if (!result) {
2015                         ast_test_status_update(test, "Unable to allocate result stream topology\n");
2016                         goto end;
2017                 }
2018
2019                 if (remove_destination_streams(result, removal_results[i].channel_name, orig)) {
2020                         ast_test_status_update(test, "Failure while attempting to remove video streams\n");
2021                         goto end;
2022                 }
2023
2024                 if (ast_stream_topology_get_count(result) != removal_results[i].num_streams) {
2025                         ast_test_status_update(test, "Resulting topology has %d streams, when %d are expected\n",
2026                                 ast_stream_topology_get_count(result), removal_results[i].num_streams);
2027                         goto end;
2028                 }
2029
2030                 for (j = 0; j < removal_results[i].num_streams; ++j) {
2031                         struct ast_stream *actual;
2032                         struct ast_stream *expected;
2033                         int orig_index;
2034
2035                         actual = ast_stream_topology_get_stream(result, j);
2036
2037                         orig_index = removal_results[i].params_index[j];
2038                         expected = ast_stream_topology_get_stream(orig, orig_index);
2039
2040                         if (!ast_format_cap_identical(ast_stream_get_formats(actual),
2041                                 ast_stream_get_formats(expected))) {
2042                                 struct ast_str *expected_str;
2043                                 struct ast_str *actual_str;
2044
2045                                 expected_str = ast_str_alloca(64);
2046                                 actual_str = ast_str_alloca(64);
2047
2048                                 ast_test_status_update(test, "Mismatch between expected (%s) and actual (%s) stream formats\n",
2049                                         ast_format_cap_get_names(ast_stream_get_formats(expected), &expected_str),
2050                                         ast_format_cap_get_names(ast_stream_get_formats(actual), &actual_str));
2051                                 goto end;
2052                         }
2053                 }
2054         }
2055
2056         res = AST_TEST_PASS;
2057
2058 end:
2059         ast_stream_topology_free(orig);
2060         ast_stream_topology_free(result);
2061         return res;
2062 }
2063
2064 #endif
2065
2066 static int unload_module(void)
2067 {
2068         ast_bridge_technology_unregister(&softmix_bridge);
2069         AST_TEST_UNREGISTER(sfu_append_source_streams);
2070         AST_TEST_UNREGISTER(sfu_remove_destination_streams);
2071         return 0;
2072 }
2073
2074 static int load_module(void)
2075 {
2076         if (ast_bridge_technology_register(&softmix_bridge)) {
2077                 unload_module();
2078                 return AST_MODULE_LOAD_DECLINE;
2079         }
2080         AST_TEST_REGISTER(sfu_append_source_streams);
2081         AST_TEST_REGISTER(sfu_remove_destination_streams);
2082         return AST_MODULE_LOAD_SUCCESS;
2083 }
2084
2085 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Multi-party software based channel mixing");