Asterisk - The Open Source Telephony Project GIT-master-5467495
Loading...
Searching...
No Matches
format_cap.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 Format Capabilities 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_cap.h"
36#include "asterisk/codec.h"
37#include "asterisk/astobj2.h"
38#include "asterisk/strings.h"
39#include "asterisk/vector.h"
41#include "asterisk/utils.h"
42
43/*! \brief Structure used for capability formats, adds framing */
45 /*! \brief A pointer to the format */
47 /*! \brief The format framing size */
48 unsigned int framing;
49 /*! \brief Linked list information */
51};
52
53/*! \brief Format capabilities structure, holds formats + preference order + etc */
55 /*! \brief Vector of formats, indexed using the codec identifier */
57 /*! \brief Vector of formats, added in preference order */
59 /*! \brief Global framing size, applies to all formats if no framing present on format */
60 unsigned int framing;
61};
62
63/*! \brief Linked list for formats */
65
66/*! \brief Dummy empty list for when we are inserting a new list */
68
69/*! \brief Destructor for format capabilities structure */
70static void format_cap_destroy(void *obj)
71{
72 struct ast_format_cap *cap = obj;
73 int idx;
74
75 for (idx = 0; idx < AST_VECTOR_SIZE(&cap->formats); idx++) {
76 struct format_cap_framed_list *list = AST_VECTOR_GET_ADDR(&cap->formats, idx);
77 struct format_cap_framed *framed;
78
79 while ((framed = AST_LIST_REMOVE_HEAD(list, entry))) {
80 ao2_ref(framed, -1);
81 }
82 }
84
85 for (idx = 0; idx < AST_VECTOR_SIZE(&cap->preference_order); idx++) {
86 struct format_cap_framed *framed = AST_VECTOR_GET(&cap->preference_order, idx);
87
88 /* This will always be non-null, unlike formats */
89 ao2_ref(framed, -1);
90 }
92}
93
94/*!
95 * \brief Initialize values on an ast_format_cap
96 *
97 * \param cap ast_format_cap to initialize
98 * \param flags Unused.
99 * \retval 0 Success
100 * \retval -1 Failure
101 */
102static inline int format_cap_init(struct ast_format_cap *cap, enum ast_format_cap_flags flags)
103{
104 if (AST_VECTOR_INIT(&cap->formats, 0)) {
105 return -1;
106 }
107
108 /* TODO: Look at common usage of this and determine a good starting point */
109 if (AST_VECTOR_INIT(&cap->preference_order, 5)) {
110 return -1;
111 }
112
113 cap->framing = UINT_MAX;
114 return 0;
115}
116
118 const char *tag, const char *file, int line, const char *func)
119{
120 struct ast_format_cap *cap;
121
123 tag, file, line, func);
124 if (!cap) {
125 return NULL;
126 }
127
128 if (format_cap_init(cap, flags)) {
129 ao2_ref(cap, -1);
130 return NULL;
131 }
132
133 return cap;
134}
135
136void ast_format_cap_set_framing(struct ast_format_cap *cap, unsigned int framing)
137{
138 cap->framing = framing;
139}
140
141/*! \brief Destructor for format capabilities framed structure */
142static void format_cap_framed_destroy(void *obj)
143{
144 struct format_cap_framed *framed = obj;
145
146 ao2_cleanup(framed->format);
147}
148
149static inline int format_cap_framed_init(struct format_cap_framed *framed, struct ast_format_cap *cap, struct ast_format *format, unsigned int framing)
150{
151 struct format_cap_framed_list *list;
152
153 framed->framing = framing;
154
155 if (ast_format_get_codec_id(format) >= AST_VECTOR_SIZE(&cap->formats)) {
157 ao2_ref(framed, -1);
158 return -1;
159 }
160 }
162
163 /* This takes the allocation reference */
164 if (AST_VECTOR_APPEND(&cap->preference_order, framed)) {
165 ao2_ref(framed, -1);
166 return -1;
167 }
168
169 /* Order doesn't matter for formats, so insert at the head for performance reasons */
170 ao2_ref(framed, +1);
171 AST_LIST_INSERT_HEAD(list, framed, entry);
172
173 cap->framing = MIN(cap->framing, framing ? framing : ast_format_get_default_ms(format));
174
175 return 0;
176}
177
178/*! \internal \brief Determine if \c format is in \c cap */
179static int format_in_format_cap(struct ast_format_cap *cap, struct ast_format *format)
180{
181 struct format_cap_framed *framed;
182 int i;
183
184 for (i = 0; i < AST_VECTOR_SIZE(&cap->preference_order); i++) {
185 framed = AST_VECTOR_GET(&cap->preference_order, i);
186
188 return 1;
189 }
190 }
191
192 return 0;
193}
194
195int __ast_format_cap_append(struct ast_format_cap *cap, struct ast_format *format, unsigned int framing, const char *tag, const char *file, int line, const char *func)
196{
197 struct format_cap_framed *framed;
198
200
201 if (format_in_format_cap(cap, format)) {
202 return 0;
203 }
204
206 if (!framed) {
207 return -1;
208 }
209
210 __ao2_ref(format, +1, tag, file, line, func);
211 framed->format = format;
212
213 return format_cap_framed_init(framed, cap, format, framing);
214}
215
217{
218 int id;
219
220 for (id = 1; id < ast_codec_get_max(); ++id) {
221 struct ast_codec *codec = ast_codec_get_by_id(id);
222 struct ast_codec *codec2 = NULL;
223 struct ast_format *format;
224 int res;
225
226 if (!codec) {
227 continue;
228 }
229
230 if ((type != AST_MEDIA_TYPE_UNKNOWN) && codec->type != type) {
231 ao2_ref(codec, -1);
232 continue;
233 }
234
236
237 if (format == ast_format_none) {
238 ao2_ref(format, -1);
239 ao2_ref(codec, -1);
240 continue;
241 }
242
243 if (format) {
245 }
246 if (codec != codec2) {
247 ao2_cleanup(format);
248 format = ast_format_create(codec);
249 }
251 ao2_ref(codec, -1);
252
253 if (!format) {
254 return -1;
255 }
256
257 /* Use the global framing or default framing of the codec */
258 res = ast_format_cap_append(cap, format, 0);
259 ao2_ref(format, -1);
260
261 if (res) {
262 return -1;
263 }
264 }
265
266 return 0;
267}
268
270 enum ast_media_type type)
271{
272 int idx, res = 0;
273
274 if (!src) {
275 return 0;
276 }
277
278 /* NOTE: The streams API is dependent on the formats being in "preference" order */
279 for (idx = 0; (idx < AST_VECTOR_SIZE(&src->preference_order)) && !res; ++idx) {
280 struct format_cap_framed *framed = AST_VECTOR_GET(&src->preference_order, idx);
281
283 res = ast_format_cap_append(dst, framed->format, framed->framing);
284 }
285 }
286
287 return res;
288}
289
290static int format_cap_replace(struct ast_format_cap *cap, struct ast_format *format, unsigned int framing)
291{
292 struct format_cap_framed *framed;
293 int i;
294
296
297 for (i = 0; i < AST_VECTOR_SIZE(&cap->preference_order); i++) {
298 framed = AST_VECTOR_GET(&cap->preference_order, i);
299
301 ao2_t_replace(framed->format, format, "replacing with new format");
302 framed->framing = framing;
303 return 0;
304 }
305 }
306
307 return -1;
308}
309
311 enum ast_media_type type)
312{
313 int idx;
314
315 if (!src) {
316 return;
317 }
318
319 for (idx = 0; (idx < AST_VECTOR_SIZE(&src->preference_order)); ++idx) {
320 struct format_cap_framed *framed = AST_VECTOR_GET(&src->preference_order, idx);
321
323 format_cap_replace(dst, framed->format, framed->framing);
324 }
325 }
326}
327
328int ast_format_cap_update_by_allow_disallow(struct ast_format_cap *cap, const char *list, int allowing)
329{
330 int res = 0, all = 0, iter_allowing;
331 char *parse = NULL, *this = NULL, *psize = NULL;
332
333 if (!allowing && ast_strlen_zero(list)) {
334 return 0;
335 }
336
337 parse = ast_strdupa(list);
338
339 /* If the list is being fed to us as a result of ast_format_cap_get_names,
340 * strip off the parenthesis and immediately apply the inverse of the
341 * allowing option
342 */
343 if (parse[0] == '(' && parse[strlen(parse) - 1] == ')') {
344 parse++;
345 parse[strlen(parse) - 1] = '\0';
346
347 if (allowing) {
349 } else {
351 }
352 }
353
354
355 while ((this = ast_strip(strsep(&parse, ",|")))) {
356 int framems = 0;
357 struct ast_format *format = NULL;
358
359 iter_allowing = allowing;
360 if (*this == '!') {
361 this++;
362 iter_allowing = !allowing;
363 }
364 if ((psize = strrchr(this, ':'))) {
365 *psize++ = '\0';
366 ast_debug(1, "Packetization for codec: %s is %s\n", this, psize);
367 if (!sscanf(psize, "%30d", &framems) || (framems < 0)) {
368 framems = 0;
369 res = -1;
370 ast_log(LOG_WARNING, "Bad packetization value for codec %s\n", this);
371 continue;
372 }
373 }
374 all = strcasecmp(this, "all") ? 0 : 1;
375
376 if (!all && !(format = ast_format_cache_get(this))) {
377 ast_log(LOG_WARNING, "Cannot %s unknown format '%s'\n", iter_allowing ? "allow" : "disallow", this);
378 res = -1;
379 continue;
380 }
381
382 if (cap) {
383 if (iter_allowing) {
384 if (all) {
386 } else {
387 ast_format_cap_append(cap, format, framems);
388 }
389 } else {
390 if (all) {
392 } else {
393 ast_format_cap_remove(cap, format);
394 }
395 }
396 }
397
398 ao2_cleanup(format);
399 }
400 return res;
401}
402
403size_t ast_format_cap_count(const struct ast_format_cap *cap)
404{
405 return AST_VECTOR_SIZE(&cap->preference_order);
406}
407
408struct ast_format *ast_format_cap_get_format(const struct ast_format_cap *cap, int position)
409{
410 struct format_cap_framed *framed;
411
413
414 if (position >= AST_VECTOR_SIZE(&cap->preference_order)) {
415 return NULL;
416 }
417
418 framed = AST_VECTOR_GET(&cap->preference_order, position);
419
421 ao2_ref(framed->format, +1);
422 return framed->format;
423}
424
426{
427 int i;
428
430 return ast_format_cap_get_format(cap, 0);
431 }
432
433 for (i = 0; i < AST_VECTOR_SIZE(&cap->preference_order); i++) {
434 struct format_cap_framed *framed = AST_VECTOR_GET(&cap->preference_order, i);
435
436 if (ast_format_get_type(framed->format) == type) {
437 ao2_ref(framed->format, +1);
439 return framed->format;
440 }
441 }
442
443 return NULL;
444}
445
446unsigned int ast_format_cap_get_framing(const struct ast_format_cap *cap)
447{
448 return (cap->framing != UINT_MAX) ? cap->framing : 0;
449}
450
451unsigned int ast_format_cap_get_format_framing(const struct ast_format_cap *cap, const struct ast_format *format)
452{
453 unsigned int framing;
454 struct format_cap_framed_list *list;
455 struct format_cap_framed *framed, *result = NULL;
456
458 return 0;
459 }
460
461 framing = cap->framing != UINT_MAX ? cap->framing : ast_format_get_default_ms(format);
463
464 AST_LIST_TRAVERSE(list, framed, entry) {
465 enum ast_format_cmp_res res = ast_format_cmp(format, framed->format);
466
467 if (res == AST_FORMAT_CMP_NOT_EQUAL) {
468 continue;
469 }
470
471 result = framed;
472
473 if (res == AST_FORMAT_CMP_EQUAL) {
474 break;
475 }
476 }
477
478 if (result && result->framing) {
480 }
481
482 return framing;
483}
484
485/*!
486 * \brief format_cap_framed comparator for AST_VECTOR_REMOVE_CMP_ORDERED()
487 *
488 * \param elem Element to compare against
489 * \param value Value to compare with the vector element.
490 *
491 * \retval 0 if element does not match.
492 * \retval Non-zero if element matches.
493 */
494#define FORMAT_CAP_FRAMED_ELEM_CMP(elem, value) ((elem)->format == (value))
495
496/*!
497 * \brief format_cap_framed vector element cleanup.
498 *
499 * \param elem Element to cleanup
500 */
501#define FORMAT_CAP_FRAMED_ELEM_CLEANUP(elem) ao2_cleanup((elem))
502
504{
505 struct format_cap_framed_list *list;
506 struct format_cap_framed *framed;
507
509
511 return -1;
512 }
513
515
516 AST_LIST_TRAVERSE_SAFE_BEGIN(list, framed, entry) {
517 if (!FORMAT_CAP_FRAMED_ELEM_CMP(framed, format)) {
518 continue;
519 }
520
523 break;
524 }
526
529}
530
532{
533 int idx;
534
535 for (idx = 0; idx < AST_VECTOR_SIZE(&cap->formats); ++idx) {
536 struct format_cap_framed_list *list = AST_VECTOR_GET_ADDR(&cap->formats, idx);
537 struct format_cap_framed *framed;
538
539 AST_LIST_TRAVERSE_SAFE_BEGIN(list, framed, entry) {
540 if ((type != AST_MEDIA_TYPE_UNKNOWN) &&
541 ast_format_get_type(framed->format) != type) {
542 continue;
543 }
544
548 ao2_ref(framed, -1);
549 }
551 }
552}
553
554struct ast_format *ast_format_cap_get_compatible_format(const struct ast_format_cap *cap, const struct ast_format *format)
555{
556 struct format_cap_framed_list *list;
557 struct format_cap_framed *framed;
558 struct ast_format *result = NULL;
559
560 ast_assert(format != NULL);
561
562 if (ast_format_get_codec_id(format) >= AST_VECTOR_SIZE(&cap->formats)) {
563 return NULL;
564 }
565
567
568 AST_LIST_TRAVERSE(list, framed, entry) {
569 enum ast_format_cmp_res res = ast_format_cmp(format, framed->format);
570
571 if (res == AST_FORMAT_CMP_NOT_EQUAL) {
572 continue;
573 }
574
575 /* Replace any current result, this one will also be a subset OR an exact match */
577
578 result = ast_format_joint(format, framed->format);
579
580 /* If it's a match we can do no better so return asap */
581 if (res == AST_FORMAT_CMP_EQUAL) {
582 break;
583 }
584 }
585
586 return result;
587}
588
590 const struct ast_format *format)
591{
593 struct format_cap_framed_list *list;
594 struct format_cap_framed *framed;
595
597
600 }
601
603
604 AST_LIST_TRAVERSE(list, framed, entry) {
605 enum ast_format_cmp_res cmp = ast_format_cmp(format, framed->format);
606
607 if (cmp == AST_FORMAT_CMP_NOT_EQUAL) {
608 continue;
609 }
610
611 res = cmp;
612
613 if (res == AST_FORMAT_CMP_EQUAL) {
614 break;
615 }
616 }
617
618 return res;
619}
620
622{
623 int idx;
624
625 for (idx = 0; idx < AST_VECTOR_SIZE(&cap->preference_order); ++idx) {
626 struct format_cap_framed *framed = AST_VECTOR_GET(&cap->preference_order, idx);
627
628 if (ast_format_get_type(framed->format) == type) {
629 return 1;
630 }
631 }
632
633 return 0;
634}
635
636int ast_format_cap_get_compatible(const struct ast_format_cap *cap1, const struct ast_format_cap *cap2,
637 struct ast_format_cap *result)
638{
639 int idx, res = 0;
640
641 for (idx = 0; idx < AST_VECTOR_SIZE(&cap1->preference_order); ++idx) {
642 struct format_cap_framed *framed = AST_VECTOR_GET(&cap1->preference_order, idx);
643 struct ast_format *format;
644
645 format = ast_format_cap_get_compatible_format(cap2, framed->format);
646 if (!format) {
647 continue;
648 }
649
650 res = ast_format_cap_append(result, format, framed->framing);
651 ao2_ref(format, -1);
652
653 if (res) {
654 break;
655 }
656 }
657
658 return res;
659}
660
661int ast_format_cap_iscompatible(const struct ast_format_cap *cap1, const struct ast_format_cap *cap2)
662{
663 int idx;
664
665 for (idx = 0; idx < AST_VECTOR_SIZE(&cap1->preference_order); ++idx) {
666 struct format_cap_framed *framed = AST_VECTOR_GET(&cap1->preference_order, idx);
667
669 return 1;
670 }
671 }
672
673 return 0;
674}
675
676static int internal_format_cap_identical(const struct ast_format_cap *cap1, const struct ast_format_cap *cap2)
677{
678 int idx;
679 struct ast_format *tmp;
680
681 for (idx = 0; idx < AST_VECTOR_SIZE(&cap1->preference_order); ++idx) {
682 tmp = ast_format_cap_get_format(cap1, idx);
683
685 ao2_ref(tmp, -1);
686 return 0;
687 }
688
689 ao2_ref(tmp, -1);
690 }
691
692 return 1;
693}
694
695int ast_format_cap_identical(const struct ast_format_cap *cap1, const struct ast_format_cap *cap2)
696{
698 return 0; /* if they are not the same size, they are not identical */
699 }
700
701 if (!internal_format_cap_identical(cap1, cap2)) {
702 return 0;
703 }
704
705 return internal_format_cap_identical(cap2, cap1);
706}
707
708static const char *__ast_format_cap_get_names(const struct ast_format_cap *cap, struct ast_str **buf, int append)
709{
710 int i;
711
712 if (!buf || !*buf) {
713 return "";
714 }
715
716 if (append) {
717 ast_str_append(buf, 0, "(");
718 } else {
719 ast_str_set(buf, 0, "(");
720 }
721
722 if (!cap || !AST_VECTOR_SIZE(&cap->preference_order)) {
723 ast_str_append(buf, 0, "nothing)");
724 return ast_str_buffer(*buf);
725 }
726
727 for (i = 0; i < AST_VECTOR_SIZE(&cap->preference_order); ++i) {
728 int res;
729 struct format_cap_framed *framed = AST_VECTOR_GET(&cap->preference_order, i);
730
731 res = ast_str_append(buf, 0, "%s%s", ast_format_get_name(framed->format),
732 i < AST_VECTOR_SIZE(&cap->preference_order) - 1 ? "|" : "");
733 if (res < 0) {
734 break;
735 }
736 }
737 ast_str_append(buf, 0, ")");
738
739 return ast_str_buffer(*buf);
740}
741
742const char *ast_format_cap_get_names(const struct ast_format_cap *cap, struct ast_str **buf)
743{
744 return __ast_format_cap_get_names(cap, buf, 0);
745}
746
747const char *ast_format_cap_append_names(const struct ast_format_cap *cap, struct ast_str **buf)
748{
749 return __ast_format_cap_get_names(cap, buf, 1);
750}
751
753{
754 int count = ast_format_cap_count(cap);
755
756 if (count > 1) {
757 return 0;
758 }
759
760 if (count == 0 || AST_VECTOR_GET(&cap->preference_order, 0)->format == ast_format_none) {
761 return 1;
762 }
763
764 return 0;
765}
enum queue_result id
Definition app_queue.c:1790
char * strsep(char **str, const char *delims)
Asterisk main include file. File version handling, generic pbx functions.
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition astmm.h:298
#define ast_log
Definition astobj2.c:42
@ AO2_ALLOC_OPT_LOCK_NOLOCK
Definition astobj2.h:367
#define ao2_t_replace(dst, src, tag)
Definition astobj2.h:504
#define ao2_cleanup(obj)
Definition astobj2.h:1934
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition astobj2.h:459
#define ao2_alloc_options(data_size, destructor_fn, options)
Definition astobj2.h:404
int __ao2_ref(void *o, int delta, const char *tag, const char *file, int line, const char *func)
Definition astobj2.c:498
void * __ao2_alloc(size_t data_size, ao2_destructor_fn destructor_fn, unsigned int options, const char *tag, const char *file, int line, const char *func) attribute_warn_unused_result
Definition astobj2.c:768
static PGresult * result
Definition cel_pgsql.c:84
static const char type[]
Codec API.
ast_media_type
Types of media.
Definition codec.h:30
@ AST_MEDIA_TYPE_UNKNOWN
Definition codec.h:31
struct ast_codec * ast_codec_get_by_id(int id)
Retrieve a codec given the unique identifier.
Definition codec.c:338
int ast_codec_get_max(void)
Retrieve the current maximum identifier for codec iteration.
Definition codec.c:343
static struct ast_codec codec2
char buf[BUFSIZE]
Definition eagi_proxy.c:66
Media Format API.
enum ast_media_type ast_format_get_type(const struct ast_format *format)
Get the media type of a format.
Definition format.c:354
unsigned int ast_format_get_codec_id(const struct ast_format *format)
Get the codec identifier associated with a format.
Definition format.c:329
struct ast_codec * ast_format_get_codec(const struct ast_format *format)
Get the codec associated with a format.
Definition format.c:324
struct ast_format * ast_format_joint(const struct ast_format *format1, const struct ast_format *format2)
Get a common joint capability between two formats.
Definition format.c:226
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_res
Format comparison results.
Definition format.h:34
@ AST_FORMAT_CMP_EQUAL
Definition format.h:36
@ AST_FORMAT_CMP_NOT_EQUAL
Definition format.h:38
const char * ast_format_get_name(const struct ast_format *format)
Get the name associated with a format.
Definition format.c:334
unsigned int ast_format_get_default_ms(const struct ast_format *format)
Get the default framing size (in milliseconds) for a format.
Definition format.c:359
struct ast_format * ast_format_create(struct ast_codec *codec)
Create a new media format.
Definition format.c:196
Media Format Cache API.
struct ast_format * ast_format_cache_get_by_codec(const struct ast_codec *codec)
Retrieve a format from the cache by its codec.
#define ast_format_cache_get(name)
Retrieve a named format from the cache.
struct ast_format * ast_format_none
Built-in "null" format.
int ast_format_cap_empty(const struct ast_format_cap *cap)
Determine if a format cap has no formats in it.
Definition format_cap.c:752
#define FORMAT_CAP_FRAMED_ELEM_CLEANUP(elem)
format_cap_framed vector element cleanup.
Definition format_cap.c:501
int ast_format_cap_append_by_type(struct ast_format_cap *cap, enum ast_media_type type)
Add all codecs Asterisk knows about for a specific type to the capabilities structure.
Definition format_cap.c:216
struct ast_format * ast_format_cap_get_format(const struct ast_format_cap *cap, int position)
Get the format at a specific index.
Definition format_cap.c:408
unsigned int ast_format_cap_get_format_framing(const struct ast_format_cap *cap, const struct ast_format *format)
Get the framing for a format.
Definition format_cap.c:451
int ast_format_cap_update_by_allow_disallow(struct ast_format_cap *cap, const char *list, int allowing)
Parse an "allow" or "deny" list and modify a format capabilities structure accordingly.
Definition format_cap.c:328
unsigned int ast_format_cap_get_framing(const struct ast_format_cap *cap)
Get the global framing.
Definition format_cap.c:446
int ast_format_cap_remove(struct ast_format_cap *cap, struct ast_format *format)
Remove format capability from capability structure.
Definition format_cap.c:503
struct ast_format * ast_format_cap_get_best_by_type(const struct ast_format_cap *cap, enum ast_media_type type)
Get the most preferred format for a particular media type.
Definition format_cap.c:425
int ast_format_cap_get_compatible(const struct ast_format_cap *cap1, const struct ast_format_cap *cap2, struct ast_format_cap *result)
Find the compatible formats between two capabilities structures.
Definition format_cap.c:636
static const char * __ast_format_cap_get_names(const struct ast_format_cap *cap, struct ast_str **buf, int append)
Definition format_cap.c:708
const char * ast_format_cap_append_names(const struct ast_format_cap *cap, struct ast_str **buf)
Append the names of codecs of a set of formats to an ast_str buffer.
Definition format_cap.c:747
void ast_format_cap_remove_by_type(struct ast_format_cap *cap, enum ast_media_type type)
Remove all formats matching a specific format type.
Definition format_cap.c:531
enum ast_format_cmp_res ast_format_cap_iscompatible_format(const struct ast_format_cap *cap, const struct ast_format *format)
Find if ast_format is within the capabilities of the ast_format_cap object.
Definition format_cap.c:589
static int internal_format_cap_identical(const struct ast_format_cap *cap1, const struct ast_format_cap *cap2)
Definition format_cap.c:676
int ast_format_cap_append_from_cap(struct ast_format_cap *dst, const struct ast_format_cap *src, enum ast_media_type type)
Append the formats of provided type in src to dst.
Definition format_cap.c:269
const char * ast_format_cap_get_names(const struct ast_format_cap *cap, struct ast_str **buf)
Get the names of codecs of a set of formats.
Definition format_cap.c:742
static void format_cap_framed_destroy(void *obj)
Destructor for format capabilities framed structure.
Definition format_cap.c:142
static void format_cap_destroy(void *obj)
Destructor for format capabilities structure.
Definition format_cap.c:70
static int format_in_format_cap(struct ast_format_cap *cap, struct ast_format *format)
Definition format_cap.c:179
static int format_cap_framed_init(struct format_cap_framed *framed, struct ast_format_cap *cap, struct ast_format *format, unsigned int framing)
Definition format_cap.c:149
void ast_format_cap_replace_from_cap(struct ast_format_cap *dst, const struct ast_format_cap *src, enum ast_media_type type)
Replace the formats of provided type in dst with equivalent formats from src.
Definition format_cap.c:310
int ast_format_cap_identical(const struct ast_format_cap *cap1, const struct ast_format_cap *cap2)
Determine if two capabilities structures are identical.
Definition format_cap.c:695
int ast_format_cap_has_type(const struct ast_format_cap *cap, enum ast_media_type type)
Find out if the capabilities structure has any formats of a specific type.
Definition format_cap.c:621
int ast_format_cap_iscompatible(const struct ast_format_cap *cap1, const struct ast_format_cap *cap2)
Determine if any joint capabilities exist between two capabilities structures.
Definition format_cap.c:661
int __ast_format_cap_append(struct ast_format_cap *cap, struct ast_format *format, unsigned int framing, const char *tag, const char *file, int line, const char *func)
Definition format_cap.c:195
static int format_cap_init(struct ast_format_cap *cap, enum ast_format_cap_flags flags)
Initialize values on an ast_format_cap.
Definition format_cap.c:102
static int format_cap_replace(struct ast_format_cap *cap, struct ast_format *format, unsigned int framing)
Definition format_cap.c:290
void ast_format_cap_set_framing(struct ast_format_cap *cap, unsigned int framing)
Set the global framing.
Definition format_cap.c:136
static const struct format_cap_framed_list format_cap_framed_list_empty
Dummy empty list for when we are inserting a new list.
Definition format_cap.c:67
#define FORMAT_CAP_FRAMED_ELEM_CMP(elem, value)
format_cap_framed comparator for AST_VECTOR_REMOVE_CMP_ORDERED()
Definition format_cap.c:494
struct ast_format_cap * __ast_format_cap_alloc(enum ast_format_cap_flags flags, const char *tag, const char *file, int line, const char *func)
Definition format_cap.c:117
size_t ast_format_cap_count(const struct ast_format_cap *cap)
Get the number of formats present within the capabilities structure.
Definition format_cap.c:403
struct ast_format * ast_format_cap_get_compatible_format(const struct ast_format_cap *cap, const struct ast_format *format)
Find if input ast_format is within the capabilities of the ast_format_cap object then return the comp...
Definition format_cap.c:554
Format Capabilities API.
ast_format_cap_flags
Definition format_cap.h:34
#define ast_format_cap_append(cap, format, framing)
Add format capability to capabilities structure.
Definition format_cap.h:99
Support for logging to various files, console and syslog Configuration in file logger....
#define ast_debug(level,...)
Log a DEBUG message.
#define LOG_WARNING
A set of macros to manage forward-linked lists.
#define AST_LIST_HEAD_NOLOCK(name, type)
Defines a structure to be used to hold a list of specified type (with no lock).
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
#define AST_LIST_HEAD_NOLOCK_INIT_VALUE
Defines initial values for a declaration of AST_LIST_HEAD_NOLOCK.
#define AST_LIST_ENTRY(type)
Declare a forward link structure inside a list entry.
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
#define NULL
Definition resample.c:96
String manipulation functions.
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition strings.h:1139
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition strings.h:65
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition strings.h:1113
char *attribute_pure ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition strings.h:761
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
Definition strings.h:223
Represents a media codec within Asterisk.
Definition codec.h:42
enum ast_media_type type
Type of media this codec contains.
Definition codec.h:50
Format capabilities structure, holds formats + preference order + etc.
Definition format_cap.c:54
struct ast_format_cap::@383 preference_order
Vector of formats, added in preference order.
unsigned int framing
Global framing size, applies to all formats if no framing present on format.
Definition format_cap.c:60
struct ast_format_cap::@382 formats
Vector of formats, indexed using the codec identifier.
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
Support for dynamic strings.
Definition strings.h:623
Linked list for formats.
Definition format_cap.c:64
Structure used for capability formats, adds framing.
Definition format_cap.c:44
struct ast_format * format
A pointer to the format.
Definition format_cap.c:46
struct format_cap_framed::@381 entry
Linked list information.
unsigned int framing
The format framing size.
Definition format_cap.c:48
Utility functions.
#define ast_assert(a)
Definition utils.h:779
#define MIN(a, b)
Definition utils.h:252
Vector container support.
#define AST_VECTOR_REPLACE(vec, idx, elem)
Replace an element at a specific position in a vector, growing the vector if needed.
Definition vector.h:295
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition vector.h:637
#define AST_VECTOR_REMOVE_CMP_ORDERED(vec, value, cmp, cleanup)
Remove an element from a vector that matches the given comparison while maintaining order.
Definition vector.h:568
#define AST_VECTOR_FREE(vec)
Deallocates this vector.
Definition vector.h:185
#define AST_VECTOR_INIT(vec, size)
Initialize a vector.
Definition vector.h:124
#define AST_VECTOR_APPEND(vec, elem)
Append an element to a vector, growing the vector if needed.
Definition vector.h:267
#define AST_VECTOR(name, type)
Define a vector structure.
Definition vector.h:44
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition vector.h:708
#define AST_VECTOR_GET_ADDR(vec, idx)
Get an address of element in a vector.
Definition vector.h:696