Add primitive SFU support to bridge_softmix.
[asterisk/asterisk.git] / main / stream.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2017, Digium, Inc.
5  *
6  * Joshua Colp <jcolp@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18
19 /*! \file
20  *
21  * \brief Media Stream API
22  *
23  * \author Joshua Colp <jcolp@digium.com>
24  */
25
26 /*** MODULEINFO
27         <support_level>core</support_level>
28  ***/
29
30 #include "asterisk.h"
31
32 #include "asterisk/logger.h"
33 #include "asterisk/stream.h"
34 #include "asterisk/strings.h"
35 #include "asterisk/format.h"
36 #include "asterisk/format_cap.h"
37
38 struct ast_stream {
39         /*!
40          * \brief The type of media the stream is handling
41          */
42         enum ast_media_type type;
43
44         /*!
45          * \brief The position of the stream in the topology
46          */
47         unsigned int position;
48
49         /*!
50          * \brief Current formats negotiated on the stream
51          */
52         struct ast_format_cap *formats;
53
54         /*!
55          * \brief The current state of the stream
56          */
57         enum ast_stream_state state;
58
59         /*!
60          * \brief Opaque stream data
61          */
62         void *data[AST_STREAM_DATA_SLOT_MAX];
63
64         /*!
65          * \brief What to do with data when the stream is freed
66          */
67         ast_stream_data_free_fn data_free_fn[AST_STREAM_DATA_SLOT_MAX];
68
69         /*!
70          * \brief Name for the stream within the context of the channel it is on
71          */
72         char name[0];
73 };
74
75 struct ast_stream_topology {
76         /*!
77          * \brief A vector of all the streams in this topology
78          */
79         AST_VECTOR(, struct ast_stream *) streams;
80 };
81
82 struct ast_stream *ast_stream_alloc(const char *name, enum ast_media_type type)
83 {
84         struct ast_stream *stream;
85
86         stream = ast_calloc(1, sizeof(*stream) + strlen(S_OR(name, "")) + 1);
87         if (!stream) {
88                 return NULL;
89         }
90
91         stream->type = type;
92         stream->state = AST_STREAM_STATE_INACTIVE;
93         strcpy(stream->name, S_OR(name, "")); /* Safe */
94
95         return stream;
96 }
97
98 struct ast_stream *ast_stream_clone(const struct ast_stream *stream, const char *name)
99 {
100         struct ast_stream *new_stream;
101         size_t stream_size;
102         int idx;
103         const char *stream_name;
104
105         if (!stream) {
106                 return NULL;
107         }
108
109         stream_name = name ?: stream->name;
110         stream_size = sizeof(*stream) + strlen(stream_name) + 1;
111         new_stream = ast_calloc(1, stream_size);
112         if (!new_stream) {
113                 return NULL;
114         }
115
116         memcpy(new_stream, stream, sizeof(*new_stream));
117         strcpy(new_stream->name, stream_name); /* Safe */
118         if (new_stream->formats) {
119                 ao2_ref(new_stream->formats, +1);
120         }
121
122         /* We cannot clone the opaque data because we don't know how. */
123         for (idx = 0; idx < AST_STREAM_DATA_SLOT_MAX; ++idx) {
124                 new_stream->data[idx] = NULL;
125                 new_stream->data_free_fn[idx] = NULL;
126         }
127
128         return new_stream;
129 }
130
131 void ast_stream_free(struct ast_stream *stream)
132 {
133         int i;
134
135         if (!stream) {
136                 return;
137         }
138
139         for (i = 0; i < AST_STREAM_DATA_SLOT_MAX; i++) {
140                 if (stream->data_free_fn[i]) {
141                         stream->data_free_fn[i](stream->data[i]);
142                 }
143         }
144
145         ao2_cleanup(stream->formats);
146         ast_free(stream);
147 }
148
149 const char *ast_stream_get_name(const struct ast_stream *stream)
150 {
151         ast_assert(stream != NULL);
152
153         return stream->name;
154 }
155
156 enum ast_media_type ast_stream_get_type(const struct ast_stream *stream)
157 {
158         ast_assert(stream != NULL);
159
160         return stream->type;
161 }
162
163 void ast_stream_set_type(struct ast_stream *stream, enum ast_media_type type)
164 {
165         ast_assert(stream != NULL);
166
167         stream->type = type;
168 }
169
170 struct ast_format_cap *ast_stream_get_formats(const struct ast_stream *stream)
171 {
172         ast_assert(stream != NULL);
173
174         return stream->formats;
175 }
176
177 void ast_stream_set_formats(struct ast_stream *stream, struct ast_format_cap *caps)
178 {
179         ast_assert(stream != NULL);
180
181         ao2_cleanup(stream->formats);
182         stream->formats = ao2_bump(caps);
183 }
184
185 enum ast_stream_state ast_stream_get_state(const struct ast_stream *stream)
186 {
187         ast_assert(stream != NULL);
188
189         return stream->state;
190 }
191
192 void ast_stream_set_state(struct ast_stream *stream, enum ast_stream_state state)
193 {
194         ast_assert(stream != NULL);
195
196         stream->state = state;
197 }
198
199 const char *ast_stream_state2str(enum ast_stream_state state)
200 {
201         switch (state) {
202         case AST_STREAM_STATE_REMOVED:
203                 return "removed";
204         case AST_STREAM_STATE_SENDRECV:
205                 return "sendrecv";
206         case AST_STREAM_STATE_SENDONLY:
207                 return "sendonly";
208         case AST_STREAM_STATE_RECVONLY:
209                 return "recvonly";
210         case AST_STREAM_STATE_INACTIVE:
211                 return "inactive";
212         default:
213                 return "<unknown>";
214         }
215 }
216
217 void *ast_stream_get_data(struct ast_stream *stream, enum ast_stream_data_slot slot)
218 {
219         ast_assert(stream != NULL);
220
221         return stream->data[slot];
222 }
223
224 void *ast_stream_set_data(struct ast_stream *stream, enum ast_stream_data_slot slot,
225         void *data, ast_stream_data_free_fn data_free_fn)
226 {
227         ast_assert(stream != NULL);
228
229         stream->data[slot] = data;
230         stream->data_free_fn[slot] = data_free_fn;
231
232         return data;
233 }
234
235 int ast_stream_get_position(const struct ast_stream *stream)
236 {
237         ast_assert(stream != NULL);
238
239         return stream->position;
240 }
241
242 #define TOPOLOGY_INITIAL_STREAM_COUNT 2
243 struct ast_stream_topology *ast_stream_topology_alloc(void)
244 {
245         struct ast_stream_topology *topology;
246
247         topology = ast_calloc(1, sizeof(*topology));
248         if (!topology) {
249                 return NULL;
250         }
251
252         if (AST_VECTOR_INIT(&topology->streams, TOPOLOGY_INITIAL_STREAM_COUNT)) {
253                 ast_free(topology);
254                 topology = NULL;
255         }
256
257         return topology;
258 }
259
260 struct ast_stream_topology *ast_stream_topology_clone(
261         const struct ast_stream_topology *topology)
262 {
263         struct ast_stream_topology *new_topology;
264         int i;
265
266         ast_assert(topology != NULL);
267
268         new_topology = ast_stream_topology_alloc();
269         if (!new_topology) {
270                 return NULL;
271         }
272
273         for (i = 0; i < AST_VECTOR_SIZE(&topology->streams); i++) {
274                 struct ast_stream *stream =
275                         ast_stream_clone(AST_VECTOR_GET(&topology->streams, i), NULL);
276
277                 if (!stream || AST_VECTOR_APPEND(&new_topology->streams, stream)) {
278                         ast_stream_free(stream);
279                         ast_stream_topology_free(new_topology);
280                         return NULL;
281                 }
282         }
283
284         return new_topology;
285 }
286
287 void ast_stream_topology_free(struct ast_stream_topology *topology)
288 {
289         if (!topology) {
290                 return;
291         }
292
293         AST_VECTOR_CALLBACK_VOID(&topology->streams, ast_stream_free);
294         AST_VECTOR_FREE(&topology->streams);
295         ast_free(topology);
296 }
297
298 int ast_stream_topology_append_stream(struct ast_stream_topology *topology, struct ast_stream *stream)
299 {
300         ast_assert(topology && stream);
301
302         if (AST_VECTOR_APPEND(&topology->streams, stream)) {
303                 return -1;
304         }
305
306         stream->position = AST_VECTOR_SIZE(&topology->streams) - 1;
307
308         return AST_VECTOR_SIZE(&topology->streams) - 1;
309 }
310
311 int ast_stream_topology_get_count(const struct ast_stream_topology *topology)
312 {
313         ast_assert(topology != NULL);
314
315         return AST_VECTOR_SIZE(&topology->streams);
316 }
317
318 struct ast_stream *ast_stream_topology_get_stream(
319         const struct ast_stream_topology *topology, unsigned int stream_num)
320 {
321         ast_assert(topology != NULL);
322
323         return AST_VECTOR_GET(&topology->streams, stream_num);
324 }
325
326 int ast_stream_topology_set_stream(struct ast_stream_topology *topology,
327         unsigned int position, struct ast_stream *stream)
328 {
329         struct ast_stream *existing_stream;
330
331         ast_assert(topology && stream);
332
333         if (position > AST_VECTOR_SIZE(&topology->streams)) {
334                 return -1;
335         }
336
337         if (position < AST_VECTOR_SIZE(&topology->streams)) {
338                 existing_stream = AST_VECTOR_GET(&topology->streams, position);
339                 ast_stream_free(existing_stream);
340         }
341
342         stream->position = position;
343
344         if (position == AST_VECTOR_SIZE(&topology->streams)) {
345                 AST_VECTOR_APPEND(&topology->streams, stream);
346                 return 0;
347         }
348
349         return AST_VECTOR_REPLACE(&topology->streams, position, stream);
350 }
351
352 struct ast_stream_topology *ast_stream_topology_create_from_format_cap(
353         struct ast_format_cap *cap)
354 {
355         struct ast_stream_topology *topology;
356         enum ast_media_type type;
357
358         topology = ast_stream_topology_alloc();
359         if (!topology || !cap || !ast_format_cap_count(cap)) {
360                 return topology;
361         }
362
363         for (type = AST_MEDIA_TYPE_UNKNOWN + 1; type < AST_MEDIA_TYPE_END; type++) {
364                 struct ast_format_cap *new_cap;
365                 struct ast_stream *stream;
366
367                 if (!ast_format_cap_has_type(cap, type)) {
368                         continue;
369                 }
370
371                 new_cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
372                 if (!new_cap) {
373                         ast_stream_topology_free(topology);
374                         return NULL;
375                 }
376
377                 ast_format_cap_set_framing(new_cap, ast_format_cap_get_framing(cap));
378                 if (ast_format_cap_append_from_cap(new_cap, cap, type)) {
379                         ao2_cleanup(new_cap);
380                         ast_stream_topology_free(topology);
381                         return NULL;
382                 }
383
384                 stream = ast_stream_alloc(ast_codec_media_type2str(type), type);
385                 if (!stream) {
386                         ao2_cleanup(new_cap);
387                         ast_stream_topology_free(topology);
388                         return NULL;
389                 }
390                 /* We're transferring the initial ref so no bump needed */
391                 stream->formats = new_cap;
392                 stream->state = AST_STREAM_STATE_SENDRECV;
393                 if (ast_stream_topology_append_stream(topology, stream) == -1) {
394                         ast_stream_free(stream);
395                         ast_stream_topology_free(topology);
396                         return NULL;
397                 }
398         }
399
400         return topology;
401 }
402
403 struct ast_format_cap *ast_format_cap_from_stream_topology(
404     struct ast_stream_topology *topology)
405 {
406         struct ast_format_cap *caps;
407         int i;
408
409         ast_assert(topology != NULL);
410
411         caps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
412         if (!caps) {
413                 return NULL;
414         }
415
416         for (i = 0; i < AST_VECTOR_SIZE(&topology->streams); i++) {
417                 struct ast_stream *stream = AST_VECTOR_GET(&topology->streams, i);
418
419                 if (!stream->formats) {
420                         continue;
421                 }
422
423                 ast_format_cap_append_from_cap(caps, stream->formats, AST_MEDIA_TYPE_UNKNOWN);
424         }
425
426         return caps;
427 }
428
429 struct ast_stream *ast_stream_topology_get_first_stream_by_type(
430         const struct ast_stream_topology *topology,
431         enum ast_media_type type)
432 {
433         int i;
434
435         ast_assert(topology != NULL);
436
437         for (i = 0; i < AST_VECTOR_SIZE(&topology->streams); i++) {
438                 struct ast_stream *stream = AST_VECTOR_GET(&topology->streams, i);
439
440                 if (stream->type == type) {
441                         return stream;
442                 }
443         }
444
445         return NULL;
446 }
447
448 void ast_stream_topology_map(const struct ast_stream_topology *topology,
449         struct ast_vector_int *types, struct ast_vector_int *v0, struct ast_vector_int *v1)
450 {
451         int i;
452         int nths[AST_MEDIA_TYPE_END] = {0};
453         int size = ast_stream_topology_get_count(topology);
454
455         /*
456          * Clear out any old mappings and initialize the new ones
457          */
458         AST_VECTOR_FREE(v0);
459         AST_VECTOR_FREE(v1);
460
461         /*
462          * Both vectors are sized to the topology. The media types vector is always
463          * guaranteed to be the size of the given topology or greater.
464          */
465         AST_VECTOR_INIT(v0, size);
466         AST_VECTOR_INIT(v1, size);
467
468         for (i = 0; i < size; ++i) {
469                 struct ast_stream *stream = ast_stream_topology_get_stream(topology, i);
470                 enum ast_media_type type = ast_stream_get_type(stream);
471                 int index = AST_VECTOR_GET_INDEX_NTH(types, ++nths[type],
472                         type, AST_VECTOR_ELEM_DEFAULT_CMP);
473
474                 if (index == -1) {
475                         /*
476                          * If a given type is not found for an index level then update the
477                          * media types vector with that type. This keeps the media types
478                          * vector always at the max topology size.
479                          */
480                         AST_VECTOR_APPEND(types, type);
481                         index = AST_VECTOR_SIZE(types) - 1;
482                 }
483
484                 /*
485                  * The mapping is reflexive in the sense that if it maps in one direction
486                  * then the reverse direction maps back to the other's index.
487                  */
488                 AST_VECTOR_REPLACE(v0, i, index);
489                 AST_VECTOR_REPLACE(v1, index, i);
490         }
491 }