Merge "stasis_bridges: Remove silly usage of RAII_VAR."
[asterisk/asterisk.git] / main / format_cache.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2014, 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 Format Cache 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/format.h"
34 #include "asterisk/format_cache.h"
35 #include "asterisk/astobj2.h"
36 #include "asterisk/strings.h"
37
38 /*!
39  * \brief Built-in cached signed linear 8kHz format.
40  */
41 struct ast_format *ast_format_slin;
42
43 /*!
44  * \brief Built-in cached signed linear 12kHz format.
45  */
46 struct ast_format *ast_format_slin12;
47
48 /*!
49  * \brief Built-in cached signed linear 16kHz format.
50  */
51 struct ast_format *ast_format_slin16;
52
53 /*!
54  * \brief Built-in cached signed linear 24kHz format.
55  */
56 struct ast_format *ast_format_slin24;
57
58 /*!
59  * \brief Built-in cached signed linear 32kHz format.
60  */
61 struct ast_format *ast_format_slin32;
62
63 /*!
64  * \brief Built-in cached signed linear 44kHz format.
65  */
66 struct ast_format *ast_format_slin44;
67
68 /*!
69  * \brief Built-in cached signed linear 48kHz format.
70  */
71 struct ast_format *ast_format_slin48;
72
73 /*!
74  * \brief Built-in cached signed linear 96kHz format.
75  */
76 struct ast_format *ast_format_slin96;
77
78 /*!
79  * \brief Built-in cached signed linear 192kHz format.
80  */
81 struct ast_format *ast_format_slin192;
82
83 /*!
84  * \brief Built-in cached ulaw format.
85  */
86 struct ast_format *ast_format_ulaw;
87
88 /*!
89  * \brief Built-in cached alaw format.
90  */
91 struct ast_format *ast_format_alaw;
92
93 /*!
94  * \brief Built-in cached testlaw format.
95  */
96 struct ast_format *ast_format_testlaw;
97
98 /*!
99  * \brief Built-in cached gsm format.
100  */
101 struct ast_format *ast_format_gsm;
102
103 /*!
104  * \brief Built-in cached adpcm format.
105  */
106 struct ast_format *ast_format_adpcm;
107
108 /*!
109  * \brief Built-in cached g722 format.
110  */
111 struct ast_format *ast_format_g722;
112
113 /*!
114  * \brief Built-in cached g726 format.
115  */
116 struct ast_format *ast_format_g726;
117
118 /*!
119  * \brief Built-in cached g726-aal2 format.
120  */
121 struct ast_format *ast_format_g726_aal2;
122
123 /*!
124  * \brief Built-in cached ilbc format.
125  */
126 struct ast_format *ast_format_ilbc;
127
128 /*!
129  * \brief Built-in cached ilbc format.
130  */
131 struct ast_format *ast_format_lpc10;
132
133 /*!
134  * \brief Built-in cached speex format.
135  */
136 struct ast_format *ast_format_speex;
137
138 /*!
139  * \brief Built-in cached speex at 16kHz format.
140  */
141 struct ast_format *ast_format_speex16;
142
143 /*!
144  * \brief Built-in cached speex at 32kHz format.
145  */
146 struct ast_format *ast_format_speex32;
147
148 /*!
149  * \brief Built-in cached g723.1 format.
150  */
151 struct ast_format *ast_format_g723;
152
153 /*!
154  * \brief Built-in cached g729 format.
155  */
156 struct ast_format *ast_format_g729;
157
158 /*!
159  * \brief Built-in cached g719 format.
160  */
161 struct ast_format *ast_format_g719;
162
163 /*!
164  * \brief Built-in cached h261 format.
165  */
166 struct ast_format *ast_format_h261;
167
168 /*!
169  * \brief Built-in cached h263 format.
170  */
171 struct ast_format *ast_format_h263;
172
173 /*!
174  * \brief Built-in cached h263 plus format.
175  */
176 struct ast_format *ast_format_h263p;
177
178 /*!
179  * \brief Built-in cached h264 format.
180  */
181 struct ast_format *ast_format_h264;
182
183 /*!
184  * \brief Built-in cached mp4 format.
185  */
186 struct ast_format *ast_format_mp4;
187
188 /*!
189  * \brief Built-in cached vp8 format.
190  */
191 struct ast_format *ast_format_vp8;
192
193 /*!
194  * \brief Built-in cached vp9 format.
195  */
196 struct ast_format *ast_format_vp9;
197
198 /*!
199  * \brief Built-in cached jpeg format.
200  */
201 struct ast_format *ast_format_jpeg;
202
203 /*!
204  * \brief Built-in cached png format.
205  */
206 struct ast_format *ast_format_png;
207
208 /*!
209  * \brief Built-in cached siren14 format.
210  */
211 struct ast_format *ast_format_siren14;
212
213 /*!
214  * \brief Built-in cached siren7 format.
215  */
216 struct ast_format *ast_format_siren7;
217
218 /*!
219  * \brief Built-in cached opus format.
220  */
221 struct ast_format *ast_format_opus;
222
223 /*!
224  * \brief Built-in cached codec2 format.
225  */
226 struct ast_format *ast_format_codec2;
227
228 /*!
229  * \brief Built-in cached t140 format.
230  */
231 struct ast_format *ast_format_t140;
232
233 /*!
234  * \brief Built-in cached t140 red format.
235  */
236 struct ast_format *ast_format_t140_red;
237
238 /*!
239  * \brief Built-in cached T.38 format.
240  */
241 struct ast_format *ast_format_t38;
242
243 /*!
244  * \brief Built-in "null" format.
245  */
246 struct ast_format *ast_format_none;
247
248 /*!
249  * \brief Built-in "silk" format
250  */
251 struct ast_format *ast_format_silk8;
252 struct ast_format *ast_format_silk12;
253 struct ast_format *ast_format_silk16;
254 struct ast_format *ast_format_silk24;
255
256 /*! \brief Number of buckets to use for the media format cache (should be prime for performance reasons) */
257 #define CACHE_BUCKETS 53
258
259 /*! \brief Cached formats */
260 static struct ao2_container *formats;
261
262 static int format_hash_cb(const void *obj, int flags)
263 {
264         const struct ast_format *format;
265         const char *key;
266
267         switch (flags & OBJ_SEARCH_MASK) {
268         case OBJ_SEARCH_KEY:
269                 key = obj;
270                 return ast_str_case_hash(key);
271         case OBJ_SEARCH_OBJECT:
272                 format = obj;
273                 return ast_str_case_hash(ast_format_get_name(format));
274         default:
275                 /* Hash can only work on something with a full key. */
276                 ast_assert(0);
277                 return 0;
278         }
279 }
280
281 static int format_cmp_cb(void *obj, void *arg, int flags)
282 {
283         const struct ast_format *left = obj;
284         const struct ast_format *right = arg;
285         const char *right_key = arg;
286         int cmp;
287
288         switch (flags & OBJ_SEARCH_MASK) {
289         case OBJ_SEARCH_OBJECT:
290                 right_key = ast_format_get_name(right);
291                 /* Fall through */
292         case OBJ_SEARCH_KEY:
293                 cmp = strcasecmp(ast_format_get_name(left), right_key);
294                 break;
295         case OBJ_SEARCH_PARTIAL_KEY:
296                 cmp = strncasecmp(ast_format_get_name(left), right_key, strlen(right_key));
297                 break;
298         default:
299                 ast_assert(0);
300                 cmp = 0;
301                 break;
302         }
303         if (cmp) {
304                 return 0;
305         }
306
307         return CMP_MATCH;
308 }
309
310 /*! \brief Function called when the process is shutting down */
311 static void format_cache_shutdown(void)
312 {
313         ao2_cleanup(formats);
314         formats = NULL;
315
316         ao2_replace(ast_format_g723, NULL);
317         ao2_replace(ast_format_ulaw, NULL);
318         ao2_replace(ast_format_alaw, NULL);
319         ao2_replace(ast_format_gsm, NULL);
320         ao2_replace(ast_format_g726, NULL);
321         ao2_replace(ast_format_g726_aal2, NULL);
322         ao2_replace(ast_format_adpcm, NULL);
323         ao2_replace(ast_format_slin, NULL);
324         ao2_replace(ast_format_slin12, NULL);
325         ao2_replace(ast_format_slin16, NULL);
326         ao2_replace(ast_format_slin24, NULL);
327         ao2_replace(ast_format_slin32, NULL);
328         ao2_replace(ast_format_slin44, NULL);
329         ao2_replace(ast_format_slin48, NULL);
330         ao2_replace(ast_format_slin96, NULL);
331         ao2_replace(ast_format_slin192, NULL);
332         ao2_replace(ast_format_lpc10, NULL);
333         ao2_replace(ast_format_g729, NULL);
334         ao2_replace(ast_format_speex, NULL);
335         ao2_replace(ast_format_speex16, NULL);
336         ao2_replace(ast_format_speex32, NULL);
337         ao2_replace(ast_format_ilbc, NULL);
338         ao2_replace(ast_format_g722, NULL);
339         ao2_replace(ast_format_siren7, NULL);
340         ao2_replace(ast_format_siren14, NULL);
341         ao2_replace(ast_format_testlaw, NULL);
342         ao2_replace(ast_format_g719, NULL);
343         ao2_replace(ast_format_opus, NULL);
344         ao2_replace(ast_format_codec2, NULL);
345         ao2_replace(ast_format_jpeg, NULL);
346         ao2_replace(ast_format_png, NULL);
347         ao2_replace(ast_format_h261, NULL);
348         ao2_replace(ast_format_h263, NULL);
349         ao2_replace(ast_format_h263p, NULL);
350         ao2_replace(ast_format_h264, NULL);
351         ao2_replace(ast_format_mp4, NULL);
352         ao2_replace(ast_format_vp8, NULL);
353         ao2_replace(ast_format_vp9, NULL);
354         ao2_replace(ast_format_t140_red, NULL);
355         ao2_replace(ast_format_t140, NULL);
356         ao2_replace(ast_format_t38, NULL);
357         ao2_replace(ast_format_none, NULL);
358         ao2_replace(ast_format_silk8, NULL);
359         ao2_replace(ast_format_silk12, NULL);
360         ao2_replace(ast_format_silk16, NULL);
361         ao2_replace(ast_format_silk24, NULL);
362 }
363
364 int ast_format_cache_init(void)
365 {
366         formats = ao2_container_alloc_options(AO2_ALLOC_OPT_LOCK_RWLOCK, CACHE_BUCKETS,
367                 format_hash_cb, format_cmp_cb);
368         if (!formats) {
369                 return -1;
370         }
371
372         ast_register_cleanup(format_cache_shutdown);
373
374         return 0;
375 }
376
377 static void set_cached_format(const char *name, struct ast_format *format)
378 {
379         if (!strcmp(name, "codec2")) {
380                 ao2_replace(ast_format_codec2, format);
381         } else if (!strcmp(name, "g723")) {
382                 ao2_replace(ast_format_g723, format);
383         } else if (!strcmp(name, "ulaw")) {
384                 ao2_replace(ast_format_ulaw, format);
385         } else if (!strcmp(name, "alaw")) {
386                 ao2_replace(ast_format_alaw, format);
387         } else if (!strcmp(name, "gsm")) {
388                 ao2_replace(ast_format_gsm, format);
389         } else if (!strcmp(name, "g726")) {
390                 ao2_replace(ast_format_g726, format);
391         } else if (!strcmp(name, "g726aal2")) {
392                 ao2_replace(ast_format_g726_aal2, format);
393         } else if (!strcmp(name, "adpcm")) {
394                 ao2_replace(ast_format_adpcm, format);
395         } else if (!strcmp(name, "slin")) {
396                 ao2_replace(ast_format_slin, format);
397         } else if (!strcmp(name, "slin12")) {
398                 ao2_replace(ast_format_slin12, format);
399         } else if (!strcmp(name, "slin16")) {
400                 ao2_replace(ast_format_slin16, format);
401         } else if (!strcmp(name, "slin24")) {
402                 ao2_replace(ast_format_slin24, format);
403         } else if (!strcmp(name, "slin32")) {
404                 ao2_replace(ast_format_slin32, format);
405         } else if (!strcmp(name, "slin44")) {
406                 ao2_replace(ast_format_slin44, format);
407         } else if (!strcmp(name, "slin48")) {
408                 ao2_replace(ast_format_slin48, format);
409         } else if (!strcmp(name, "slin96")) {
410                 ao2_replace(ast_format_slin96, format);
411         } else if (!strcmp(name, "slin192")) {
412                 ao2_replace(ast_format_slin192, format);
413         } else if (!strcmp(name, "lpc10")) {
414                 ao2_replace(ast_format_lpc10, format);
415         } else if (!strcmp(name, "g729")) {
416                 ao2_replace(ast_format_g729, format);
417         } else if (!strcmp(name, "speex")) {
418                 ao2_replace(ast_format_speex, format);
419         } else if (!strcmp(name, "speex16")) {
420                 ao2_replace(ast_format_speex16, format);
421         } else if (!strcmp(name, "speex32")) {
422                 ao2_replace(ast_format_speex32, format);
423         } else if (!strcmp(name, "ilbc")) {
424                 ao2_replace(ast_format_ilbc, format);
425         } else if (!strcmp(name, "g722")) {
426                 ao2_replace(ast_format_g722, format);
427         } else if (!strcmp(name, "siren7")) {
428                 ao2_replace(ast_format_siren7, format);
429         } else if (!strcmp(name, "siren14")) {
430                 ao2_replace(ast_format_siren14, format);
431         } else if (!strcmp(name, "testlaw")) {
432                 ao2_replace(ast_format_testlaw, format);
433         } else if (!strcmp(name, "g719")) {
434                 ao2_replace(ast_format_g719, format);
435         } else if (!strcmp(name, "opus")) {
436                 ao2_replace(ast_format_opus, format);
437         } else if (!strcmp(name, "jpeg")) {
438                 ao2_replace(ast_format_jpeg, format);
439         } else if (!strcmp(name, "png")) {
440                 ao2_replace(ast_format_png, format);
441         } else if (!strcmp(name, "h261")) {
442                 ao2_replace(ast_format_h261, format);
443         } else if (!strcmp(name, "h263")) {
444                 ao2_replace(ast_format_h263, format);
445         } else if (!strcmp(name, "h263p")) {
446                 ao2_replace(ast_format_h263p, format);
447         } else if (!strcmp(name, "h264")) {
448                 ao2_replace(ast_format_h264, format);
449         } else if (!strcmp(name, "mpeg4")) {
450                 ao2_replace(ast_format_mp4, format);
451         } else if (!strcmp(name, "vp8")) {
452                 ao2_replace(ast_format_vp8, format);
453         } else if (!strcmp(name, "vp9")) {
454                 ao2_replace(ast_format_vp9, format);
455         } else if (!strcmp(name, "red")) {
456                 ao2_replace(ast_format_t140_red, format);
457         } else if (!strcmp(name, "t140")) {
458                 ao2_replace(ast_format_t140, format);
459         } else if (!strcmp(name, "t38")) {
460                 ao2_replace(ast_format_t38, format);
461         } else if (!strcmp(name, "none")) {
462                 ao2_replace(ast_format_none, format);
463         } else if (!strcmp(name, "silk8")) {
464                 ao2_replace(ast_format_silk8, format);
465         } else if (!strcmp(name, "silk12")) {
466                 ao2_replace(ast_format_silk12, format);
467         } else if (!strcmp(name, "silk16")) {
468                 ao2_replace(ast_format_silk16, format);
469         } else if (!strcmp(name, "silk24")) {
470                 ao2_replace(ast_format_silk24, format);
471         }
472 }
473
474 int ast_format_cache_set(struct ast_format *format)
475 {
476         SCOPED_AO2WRLOCK(lock, formats);
477         struct ast_format *old_format;
478
479         ast_assert(format != NULL);
480
481         if (ast_strlen_zero(ast_format_get_name(format))) {
482                 return -1;
483         }
484
485         old_format = ao2_find(formats, ast_format_get_name(format), OBJ_SEARCH_KEY | OBJ_NOLOCK);
486         if (old_format) {
487                 ao2_unlink_flags(formats, old_format, OBJ_NOLOCK);
488         }
489         ao2_link_flags(formats, format, OBJ_NOLOCK);
490
491         set_cached_format(ast_format_get_name(format), format);
492
493         ast_verb(2, "%s cached format with name '%s'\n",
494                 old_format ? "Updated" : "Created",
495                 ast_format_get_name(format));
496
497         ao2_cleanup(old_format);
498
499         return 0;
500 }
501
502 struct ast_format *__ast_format_cache_get(const char *name,
503         const char *tag, const char *file, int line, const char *func)
504 {
505         if (ast_strlen_zero(name)) {
506                 return NULL;
507         }
508
509         return __ao2_find(formats, name, OBJ_SEARCH_KEY, tag, file, line, func);
510 }
511
512 struct ast_format *ast_format_cache_get_slin_by_rate(unsigned int rate)
513 {
514         if (rate >= 192000) {
515                 return ast_format_slin192;
516         } else if (rate >= 96000) {
517                 return ast_format_slin96;
518         } else if (rate >= 48000) {
519                 return ast_format_slin48;
520         } else if (rate >= 44100) {
521                 return ast_format_slin44;
522         } else if (rate >= 32000) {
523                 return ast_format_slin32;
524         } else if (rate >= 24000) {
525                 return ast_format_slin24;
526         } else if (rate >= 16000) {
527                 return ast_format_slin16;
528         } else if (rate >= 12000) {
529                 return ast_format_slin12;
530         }
531         return ast_format_slin;
532 }
533
534 int ast_format_cache_is_slinear(struct ast_format *format)
535 {
536         if ((ast_format_cmp(format, ast_format_slin) == AST_FORMAT_CMP_EQUAL)
537                 || (ast_format_cmp(format, ast_format_slin12) == AST_FORMAT_CMP_EQUAL)
538                 || (ast_format_cmp(format, ast_format_slin16) == AST_FORMAT_CMP_EQUAL)
539                 || (ast_format_cmp(format, ast_format_slin24) == AST_FORMAT_CMP_EQUAL)
540                 || (ast_format_cmp(format, ast_format_slin32) == AST_FORMAT_CMP_EQUAL)
541                 || (ast_format_cmp(format, ast_format_slin44) == AST_FORMAT_CMP_EQUAL)
542                 || (ast_format_cmp(format, ast_format_slin48) == AST_FORMAT_CMP_EQUAL)
543                 || (ast_format_cmp(format, ast_format_slin96) == AST_FORMAT_CMP_EQUAL)
544                 || (ast_format_cmp(format, ast_format_slin192) == AST_FORMAT_CMP_EQUAL)) {
545                 return 1;
546         }
547
548         return 0;
549 }