Asterisk - The Open Source Telephony Project GIT-master-7e7a603
format_cache.c
Go to the documentation of this file.
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"
35#include "asterisk/astobj2.h"
36#include "asterisk/strings.h"
37
38/*!
39 * \brief Built-in cached signed linear 8kHz format.
40 */
42
43/*!
44 * \brief Built-in cached signed linear 12kHz format.
45 */
47
48/*!
49 * \brief Built-in cached signed linear 16kHz format.
50 */
52
53/*!
54 * \brief Built-in cached signed linear 24kHz format.
55 */
57
58/*!
59 * \brief Built-in cached signed linear 32kHz format.
60 */
62
63/*!
64 * \brief Built-in cached signed linear 44kHz format.
65 */
67
68/*!
69 * \brief Built-in cached signed linear 48kHz format.
70 */
72
73/*!
74 * \brief Built-in cached signed linear 96kHz format.
75 */
77
78/*!
79 * \brief Built-in cached signed linear 192kHz format.
80 */
82
83/*!
84 * \brief Built-in cached ulaw format.
85 */
87
88/*!
89 * \brief Built-in cached alaw format.
90 */
92
93/*!
94 * \brief Built-in cached gsm format.
95 */
97
98/*!
99 * \brief Built-in cached adpcm format.
100 */
102
103/*!
104 * \brief Built-in cached g722 format.
105 */
107
108/*!
109 * \brief Built-in cached g726 format.
110 */
112
113/*!
114 * \brief Built-in cached g726-aal2 format.
115 */
117
118/*!
119 * \brief Built-in cached ilbc format.
120 */
122
123/*!
124 * \brief Built-in cached ilbc format.
125 */
127
128/*!
129 * \brief Built-in cached speex format.
130 */
132
133/*!
134 * \brief Built-in cached speex at 16kHz format.
135 */
137
138/*!
139 * \brief Built-in cached speex at 32kHz format.
140 */
142
143/*!
144 * \brief Built-in cached g723.1 format.
145 */
147
148/*!
149 * \brief Built-in cached g729 format.
150 */
152
153/*!
154 * \brief Built-in cached g719 format.
155 */
157
158/*!
159 * \brief Built-in cached h261 format.
160 */
162
163/*!
164 * \brief Built-in cached h263 format.
165 */
167
168/*!
169 * \brief Built-in cached h263 plus format.
170 */
172
173/*!
174 * \brief Built-in cached h264 format.
175 */
177
178/*!
179 * \brief Built-in cached h265 format.
180 */
182
183/*!
184 * \brief Built-in cached mp4 format.
185 */
187
188/*!
189 * \brief Built-in cached vp8 format.
190 */
192
193/*!
194 * \brief Built-in cached vp9 format.
195 */
197
198/*!
199 * \brief Built-in cached jpeg format.
200 */
202
203/*!
204 * \brief Built-in cached png format.
205 */
207
208/*!
209 * \brief Built-in cached siren14 format.
210 */
212
213/*!
214 * \brief Built-in cached siren7 format.
215 */
217
218/*!
219 * \brief Built-in cached opus format.
220 */
222
223/*!
224 * \brief Built-in cached codec2 format.
225 */
227
228/*!
229 * \brief Built-in cached t140 format.
230 */
232
233/*!
234 * \brief Built-in cached t140 red format.
235 */
237
238/*!
239 * \brief Built-in cached T.38 format.
240 */
242
243/*!
244 * \brief Built-in "null" format.
245 */
247
248/*!
249 * \brief Built-in "silk" format
250 */
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 */
260static struct ao2_container *formats;
261
262static 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);
272 format = obj;
274 default:
275 /* Hash can only work on something with a full key. */
276 ast_assert(0);
277 return 0;
278 }
279}
280
281static 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) {
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;
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 */
311static void format_cache_shutdown(void)
312{
314 formats = NULL;
315
362}
363
365{
368 if (!formats) {
369 return -1;
370 }
371
373
374 return 0;
375}
376
377static void set_cached_format(const char *name, struct ast_format *format)
378{
379 if (!strcmp(name, "codec2")) {
381 } else if (!strcmp(name, "g723")) {
383 } else if (!strcmp(name, "ulaw")) {
385 } else if (!strcmp(name, "alaw")) {
387 } else if (!strcmp(name, "gsm")) {
389 } else if (!strcmp(name, "g726")) {
391 } else if (!strcmp(name, "g726aal2")) {
393 } else if (!strcmp(name, "adpcm")) {
395 } else if (!strcmp(name, "slin")) {
397 } else if (!strcmp(name, "slin12")) {
399 } else if (!strcmp(name, "slin16")) {
401 } else if (!strcmp(name, "slin24")) {
403 } else if (!strcmp(name, "slin32")) {
405 } else if (!strcmp(name, "slin44")) {
407 } else if (!strcmp(name, "slin48")) {
409 } else if (!strcmp(name, "slin96")) {
411 } else if (!strcmp(name, "slin192")) {
413 } else if (!strcmp(name, "lpc10")) {
415 } else if (!strcmp(name, "g729")) {
417 } else if (!strcmp(name, "speex")) {
419 } else if (!strcmp(name, "speex16")) {
421 } else if (!strcmp(name, "speex32")) {
423 } else if (!strcmp(name, "ilbc")) {
425 } else if (!strcmp(name, "g722")) {
427 } else if (!strcmp(name, "siren7")) {
429 } else if (!strcmp(name, "siren14")) {
431 } else if (!strcmp(name, "g719")) {
433 } else if (!strcmp(name, "opus")) {
435 } else if (!strcmp(name, "jpeg")) {
437 } else if (!strcmp(name, "png")) {
439 } else if (!strcmp(name, "h261")) {
441 } else if (!strcmp(name, "h263")) {
443 } else if (!strcmp(name, "h263p")) {
445 } else if (!strcmp(name, "h264")) {
447 } else if (!strcmp(name, "h265")) {
449 } else if (!strcmp(name, "mpeg4")) {
451 } else if (!strcmp(name, "vp8")) {
453 } else if (!strcmp(name, "vp9")) {
455 } else if (!strcmp(name, "red")) {
457 } else if (!strcmp(name, "t140")) {
459 } else if (!strcmp(name, "t38")) {
461 } else if (!strcmp(name, "none")) {
463 } else if (!strcmp(name, "silk8")) {
465 } else if (!strcmp(name, "silk12")) {
467 } else if (!strcmp(name, "silk16")) {
469 } else if (!strcmp(name, "silk24")) {
471 }
472}
473
475{
477 struct ast_format *old_format;
478
479 ast_assert(format != NULL);
480
482 return -1;
483 }
484
486 if (old_format) {
487 ao2_unlink_flags(formats, old_format, OBJ_NOLOCK);
488 }
490
491 set_cached_format(ast_format_get_name(format), format);
492
493 ast_verb(5, "%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
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
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
535{
545 return 1;
546 }
547
548 return 0;
549}
550
552{
553 struct ast_format *format;
554 struct ao2_iterator it;
555
556 for (it = ao2_iterator_init(formats, 0);
557 (format = ao2_iterator_next(&it));
558 ao2_ref(format, -1)) {
559 struct ast_codec *candidate = ast_format_get_codec(format);
560 if (codec == candidate) {
561 ao2_cleanup(candidate);
563 return format;
564 }
565 ao2_cleanup(candidate);
566 }
567
569 return NULL;
570}
ast_mutex_t lock
Definition: app_sla.c:331
Asterisk main include file. File version handling, generic pbx functions.
int ast_register_cleanup(void(*func)(void))
Register a function to be executed before Asterisk gracefully exits.
Definition: clicompat.c:19
#define ao2_iterator_next(iter)
Definition: astobj2.h:1911
@ CMP_MATCH
Definition: astobj2.h:1027
@ AO2_ALLOC_OPT_LOCK_RWLOCK
Definition: astobj2.h:365
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
#define ao2_unlink_flags(container, obj, flags)
Remove an object from a container.
Definition: astobj2.h:1600
#define ao2_link_flags(container, obj, flags)
Add an object to a container.
Definition: astobj2.h:1554
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1736
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
void * __ao2_find(struct ao2_container *c, const void *arg, enum search_flags flags, const char *tag, const char *file, int line, const char *func)
#define ao2_replace(dst, src)
Replace one object reference with another cleaning up the original.
Definition: astobj2.h:501
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
@ OBJ_SEARCH_PARTIAL_KEY
The arg parameter is a partial search key similar to OBJ_SEARCH_KEY.
Definition: astobj2.h:1116
@ OBJ_SEARCH_OBJECT
The arg parameter is an object of the same type.
Definition: astobj2.h:1087
@ OBJ_NOLOCK
Assume that the ao2_container is already locked.
Definition: astobj2.h:1063
@ OBJ_SEARCH_MASK
Search option field mask.
Definition: astobj2.h:1072
@ OBJ_SEARCH_KEY
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1101
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
Allocate and initialize a hash container with the desired number of buckets.
Definition: astobj2.h:1303
Media Format API.
struct ast_codec * ast_format_get_codec(const struct ast_format *format)
Get the codec associated with a format.
Definition: format.c:324
enum ast_format_cmp_res ast_format_cmp(const struct ast_format *format1, const struct ast_format *format2)
Compare two formats.
Definition: format.c:201
@ AST_FORMAT_CMP_EQUAL
Definition: format.h:36
const char * ast_format_get_name(const struct ast_format *format)
Get the name associated with a format.
Definition: format.c:334
struct ast_format * ast_format_speex16
Built-in cached speex at 16kHz format.
Definition: format_cache.c:136
struct ast_format * ast_format_h264
Built-in cached h264 format.
Definition: format_cache.c:176
struct ast_format * ast_format_slin44
Built-in cached signed linear 44kHz format.
Definition: format_cache.c:66
struct ast_format * ast_format_adpcm
Built-in cached adpcm format.
Definition: format_cache.c:101
struct ast_format * ast_format_slin24
Built-in cached signed linear 24kHz format.
Definition: format_cache.c:56
int ast_format_cache_is_slinear(struct ast_format *format)
Determines if a format is one of the cached slin formats.
Definition: format_cache.c:534
struct ast_format * ast_format_opus
Built-in cached opus format.
Definition: format_cache.c:221
int ast_format_cache_set(struct ast_format *format)
Set a named format cache entry.
Definition: format_cache.c:474
struct ast_format * ast_format_h265
Built-in cached h265 format.
Definition: format_cache.c:181
struct ast_format * ast_format_gsm
Built-in cached gsm format.
Definition: format_cache.c:96
struct ast_format * ast_format_slin32
Built-in cached signed linear 32kHz format.
Definition: format_cache.c:61
struct ast_format * ast_format_siren14
Built-in cached siren14 format.
Definition: format_cache.c:211
struct ast_format * ast_format_speex
Built-in cached speex format.
Definition: format_cache.c:131
struct ast_format * ast_format_h263
Built-in cached h263 format.
Definition: format_cache.c:166
struct ast_format * ast_format_mp4
Built-in cached mp4 format.
Definition: format_cache.c:186
struct ast_format * ast_format_slin192
Built-in cached signed linear 192kHz format.
Definition: format_cache.c:81
struct ast_format * ast_format_ilbc
Built-in cached ilbc format.
Definition: format_cache.c:121
struct ast_format * ast_format_g726
Built-in cached g726 format.
Definition: format_cache.c:111
struct ast_format * ast_format_ulaw
Built-in cached ulaw format.
Definition: format_cache.c:86
struct ast_format * ast_format_lpc10
Built-in cached ilbc format.
Definition: format_cache.c:126
struct ast_format * ast_format_cache_get_by_codec(const struct ast_codec *codec)
Retrieve a format from the cache by its codec.
Definition: format_cache.c:551
struct ast_format * ast_format_slin16
Built-in cached signed linear 16kHz format.
Definition: format_cache.c:51
#define CACHE_BUCKETS
Number of buckets to use for the media format cache (should be prime for performance reasons)
Definition: format_cache.c:257
struct ast_format * ast_format_codec2
Built-in cached codec2 format.
Definition: format_cache.c:226
struct ast_format * ast_format_slin96
Built-in cached signed linear 96kHz format.
Definition: format_cache.c:76
static void set_cached_format(const char *name, struct ast_format *format)
Definition: format_cache.c:377
struct ast_format * ast_format_slin48
Built-in cached signed linear 48kHz format.
Definition: format_cache.c:71
int ast_format_cache_init(void)
Initialize format cache support within the core.
Definition: format_cache.c:364
struct ast_format * ast_format_g723
Built-in cached g723.1 format.
Definition: format_cache.c:146
struct ast_format * ast_format_slin
Built-in cached signed linear 8kHz format.
Definition: format_cache.c:41
struct ast_format * ast_format_none
Built-in "null" format.
Definition: format_cache.c:246
struct ast_format * ast_format_siren7
Built-in cached siren7 format.
Definition: format_cache.c:216
struct ast_format * ast_format_silk12
Definition: format_cache.c:252
static struct ao2_container * formats
Cached formats.
Definition: format_cache.c:260
static int format_cmp_cb(void *obj, void *arg, int flags)
Definition: format_cache.c:281
struct ast_format * ast_format_alaw
Built-in cached alaw format.
Definition: format_cache.c:91
struct ast_format * ast_format_t38
Built-in cached T.38 format.
Definition: format_cache.c:241
struct ast_format * ast_format_speex32
Built-in cached speex at 32kHz format.
Definition: format_cache.c:141
struct ast_format * ast_format_h261
Built-in cached h261 format.
Definition: format_cache.c:161
struct ast_format * ast_format_vp9
Built-in cached vp9 format.
Definition: format_cache.c:196
struct ast_format * ast_format_t140_red
Built-in cached t140 red format.
Definition: format_cache.c:236
struct ast_format * ast_format_slin12
Built-in cached signed linear 12kHz format.
Definition: format_cache.c:46
struct ast_format * __ast_format_cache_get(const char *name, const char *tag, const char *file, int line, const char *func)
Definition: format_cache.c:502
struct ast_format * ast_format_h263p
Built-in cached h263 plus format.
Definition: format_cache.c:171
static void format_cache_shutdown(void)
Function called when the process is shutting down.
Definition: format_cache.c:311
struct ast_format * ast_format_png
Built-in cached png format.
Definition: format_cache.c:206
struct ast_format * ast_format_cache_get_slin_by_rate(unsigned int rate)
Retrieve the best signed linear format given a sample rate.
Definition: format_cache.c:512
struct ast_format * ast_format_g722
Built-in cached g722 format.
Definition: format_cache.c:106
struct ast_format * ast_format_silk16
Definition: format_cache.c:253
struct ast_format * ast_format_g726_aal2
Built-in cached g726-aal2 format.
Definition: format_cache.c:116
struct ast_format * ast_format_t140
Built-in cached t140 format.
Definition: format_cache.c:231
struct ast_format * ast_format_silk24
Definition: format_cache.c:254
static int format_hash_cb(const void *obj, int flags)
Definition: format_cache.c:262
struct ast_format * ast_format_g729
Built-in cached g729 format.
Definition: format_cache.c:151
struct ast_format * ast_format_jpeg
Built-in cached jpeg format.
Definition: format_cache.c:201
struct ast_format * ast_format_vp8
Built-in cached vp8 format.
Definition: format_cache.c:191
struct ast_format * ast_format_g719
Built-in cached g719 format.
Definition: format_cache.c:156
struct ast_format * ast_format_silk8
Built-in "silk" format.
Definition: format_cache.c:251
Media Format Cache API.
static const char name[]
Definition: format_mp3.c:68
Support for logging to various files, console and syslog Configuration in file logger....
#define ast_verb(level,...)
#define SCOPED_AO2WRLOCK(varname, obj)
scoped lock specialization for ao2 write locks.
Definition: lock.h:614
#define NULL
Definition: resample.c:96
String manipulation functions.
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
static force_inline int attribute_pure ast_str_case_hash(const char *str)
Compute a hash value on a case-insensitive string.
Definition: strings.h:1303
Generic container type.
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1821
Represents a media codec within Asterisk.
Definition: codec.h:42
Definition of a media format.
Definition: format.c:43
struct ast_codec * codec
Pointer to the codec in use for this format.
Definition: format.c:47
Definition: file.c:69
#define ast_assert(a)
Definition: utils.h:739