Asterisk - The Open Source Telephony Project GIT-master-7e7a603
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 /* NOTE: The streams API is dependent on the formats being in "preference" order */
275 for (idx = 0; (idx < AST_VECTOR_SIZE(&src->preference_order)) && !res; ++idx) {
276 struct format_cap_framed *framed = AST_VECTOR_GET(&src->preference_order, idx);
277
279 res = ast_format_cap_append(dst, framed->format, framed->framing);
280 }
281 }
282
283 return res;
284}
285
286static int format_cap_replace(struct ast_format_cap *cap, struct ast_format *format, unsigned int framing)
287{
288 struct format_cap_framed *framed;
289 int i;
290
292
293 for (i = 0; i < AST_VECTOR_SIZE(&cap->preference_order); i++) {
294 framed = AST_VECTOR_GET(&cap->preference_order, i);
295
297 ao2_t_replace(framed->format, format, "replacing with new format");
298 framed->framing = framing;
299 return 0;
300 }
301 }
302
303 return -1;
304}
305
307 enum ast_media_type type)
308{
309 int idx;
310
311 for (idx = 0; (idx < AST_VECTOR_SIZE(&src->preference_order)); ++idx) {
312 struct format_cap_framed *framed = AST_VECTOR_GET(&src->preference_order, idx);
313
315 format_cap_replace(dst, framed->format, framed->framing);
316 }
317 }
318}
319
320int ast_format_cap_update_by_allow_disallow(struct ast_format_cap *cap, const char *list, int allowing)
321{
322 int res = 0, all = 0, iter_allowing;
323 char *parse = NULL, *this = NULL, *psize = NULL;
324
325 if (!allowing && ast_strlen_zero(list)) {
326 return 0;
327 }
328
329 parse = ast_strdupa(list);
330
331 /* If the list is being fed to us as a result of ast_format_cap_get_names,
332 * strip off the parenthesis and immediately apply the inverse of the
333 * allowing option
334 */
335 if (parse[0] == '(' && parse[strlen(parse) - 1] == ')') {
336 parse++;
337 parse[strlen(parse) - 1] = '\0';
338
339 if (allowing) {
341 } else {
343 }
344 }
345
346
347 while ((this = ast_strip(strsep(&parse, ",|")))) {
348 int framems = 0;
349 struct ast_format *format = NULL;
350
351 iter_allowing = allowing;
352 if (*this == '!') {
353 this++;
354 iter_allowing = !allowing;
355 }
356 if ((psize = strrchr(this, ':'))) {
357 *psize++ = '\0';
358 ast_debug(1, "Packetization for codec: %s is %s\n", this, psize);
359 if (!sscanf(psize, "%30d", &framems) || (framems < 0)) {
360 framems = 0;
361 res = -1;
362 ast_log(LOG_WARNING, "Bad packetization value for codec %s\n", this);
363 continue;
364 }
365 }
366 all = strcasecmp(this, "all") ? 0 : 1;
367
368 if (!all && !(format = ast_format_cache_get(this))) {
369 ast_log(LOG_WARNING, "Cannot %s unknown format '%s'\n", iter_allowing ? "allow" : "disallow", this);
370 res = -1;
371 continue;
372 }
373
374 if (cap) {
375 if (iter_allowing) {
376 if (all) {
378 } else {
379 ast_format_cap_append(cap, format, framems);
380 }
381 } else {
382 if (all) {
384 } else {
385 ast_format_cap_remove(cap, format);
386 }
387 }
388 }
389
390 ao2_cleanup(format);
391 }
392 return res;
393}
394
395size_t ast_format_cap_count(const struct ast_format_cap *cap)
396{
397 return AST_VECTOR_SIZE(&cap->preference_order);
398}
399
400struct ast_format *ast_format_cap_get_format(const struct ast_format_cap *cap, int position)
401{
402 struct format_cap_framed *framed;
403
405
406 if (position >= AST_VECTOR_SIZE(&cap->preference_order)) {
407 return NULL;
408 }
409
410 framed = AST_VECTOR_GET(&cap->preference_order, position);
411
413 ao2_ref(framed->format, +1);
414 return framed->format;
415}
416
418{
419 int i;
420
422 return ast_format_cap_get_format(cap, 0);
423 }
424
425 for (i = 0; i < AST_VECTOR_SIZE(&cap->preference_order); i++) {
426 struct format_cap_framed *framed = AST_VECTOR_GET(&cap->preference_order, i);
427
428 if (ast_format_get_type(framed->format) == type) {
429 ao2_ref(framed->format, +1);
431 return framed->format;
432 }
433 }
434
435 return NULL;
436}
437
438unsigned int ast_format_cap_get_framing(const struct ast_format_cap *cap)
439{
440 return (cap->framing != UINT_MAX) ? cap->framing : 0;
441}
442
443unsigned int ast_format_cap_get_format_framing(const struct ast_format_cap *cap, const struct ast_format *format)
444{
445 unsigned int framing;
446 struct format_cap_framed_list *list;
447 struct format_cap_framed *framed, *result = NULL;
448
450 return 0;
451 }
452
453 framing = cap->framing != UINT_MAX ? cap->framing : ast_format_get_default_ms(format);
455
456 AST_LIST_TRAVERSE(list, framed, entry) {
457 enum ast_format_cmp_res res = ast_format_cmp(format, framed->format);
458
459 if (res == AST_FORMAT_CMP_NOT_EQUAL) {
460 continue;
461 }
462
463 result = framed;
464
465 if (res == AST_FORMAT_CMP_EQUAL) {
466 break;
467 }
468 }
469
470 if (result && result->framing) {
471 framing = result->framing;
472 }
473
474 return framing;
475}
476
477/*!
478 * \brief format_cap_framed comparator for AST_VECTOR_REMOVE_CMP_ORDERED()
479 *
480 * \param elem Element to compare against
481 * \param value Value to compare with the vector element.
482 *
483 * \retval 0 if element does not match.
484 * \retval Non-zero if element matches.
485 */
486#define FORMAT_CAP_FRAMED_ELEM_CMP(elem, value) ((elem)->format == (value))
487
488/*!
489 * \brief format_cap_framed vector element cleanup.
490 *
491 * \param elem Element to cleanup
492 */
493#define FORMAT_CAP_FRAMED_ELEM_CLEANUP(elem) ao2_cleanup((elem))
494
496{
497 struct format_cap_framed_list *list;
498 struct format_cap_framed *framed;
499
501
503 return -1;
504 }
505
507
508 AST_LIST_TRAVERSE_SAFE_BEGIN(list, framed, entry) {
509 if (!FORMAT_CAP_FRAMED_ELEM_CMP(framed, format)) {
510 continue;
511 }
512
515 break;
516 }
518
521}
522
524{
525 int idx;
526
527 for (idx = 0; idx < AST_VECTOR_SIZE(&cap->formats); ++idx) {
528 struct format_cap_framed_list *list = AST_VECTOR_GET_ADDR(&cap->formats, idx);
529 struct format_cap_framed *framed;
530
531 AST_LIST_TRAVERSE_SAFE_BEGIN(list, framed, entry) {
532 if ((type != AST_MEDIA_TYPE_UNKNOWN) &&
533 ast_format_get_type(framed->format) != type) {
534 continue;
535 }
536
540 ao2_ref(framed, -1);
541 }
543 }
544}
545
546struct ast_format *ast_format_cap_get_compatible_format(const struct ast_format_cap *cap, const struct ast_format *format)
547{
548 struct format_cap_framed_list *list;
549 struct format_cap_framed *framed;
550 struct ast_format *result = NULL;
551
552 ast_assert(format != NULL);
553
554 if (ast_format_get_codec_id(format) >= AST_VECTOR_SIZE(&cap->formats)) {
555 return NULL;
556 }
557
559
560 AST_LIST_TRAVERSE(list, framed, entry) {
561 enum ast_format_cmp_res res = ast_format_cmp(format, framed->format);
562
563 if (res == AST_FORMAT_CMP_NOT_EQUAL) {
564 continue;
565 }
566
567 /* Replace any current result, this one will also be a subset OR an exact match */
569
570 result = ast_format_joint(format, framed->format);
571
572 /* If it's a match we can do no better so return asap */
573 if (res == AST_FORMAT_CMP_EQUAL) {
574 break;
575 }
576 }
577
578 return result;
579}
580
582 const struct ast_format *format)
583{
585 struct format_cap_framed_list *list;
586 struct format_cap_framed *framed;
587
589
592 }
593
595
596 AST_LIST_TRAVERSE(list, framed, entry) {
597 enum ast_format_cmp_res cmp = ast_format_cmp(format, framed->format);
598
599 if (cmp == AST_FORMAT_CMP_NOT_EQUAL) {
600 continue;
601 }
602
603 res = cmp;
604
605 if (res == AST_FORMAT_CMP_EQUAL) {
606 break;
607 }
608 }
609
610 return res;
611}
612
614{
615 int idx;
616
617 for (idx = 0; idx < AST_VECTOR_SIZE(&cap->preference_order); ++idx) {
618 struct format_cap_framed *framed = AST_VECTOR_GET(&cap->preference_order, idx);
619
620 if (ast_format_get_type(framed->format) == type) {
621 return 1;
622 }
623 }
624
625 return 0;
626}
627
628int ast_format_cap_get_compatible(const struct ast_format_cap *cap1, const struct ast_format_cap *cap2,
629 struct ast_format_cap *result)
630{
631 int idx, res = 0;
632
633 for (idx = 0; idx < AST_VECTOR_SIZE(&cap1->preference_order); ++idx) {
634 struct format_cap_framed *framed = AST_VECTOR_GET(&cap1->preference_order, idx);
635 struct ast_format *format;
636
637 format = ast_format_cap_get_compatible_format(cap2, framed->format);
638 if (!format) {
639 continue;
640 }
641
642 res = ast_format_cap_append(result, format, framed->framing);
643 ao2_ref(format, -1);
644
645 if (res) {
646 break;
647 }
648 }
649
650 return res;
651}
652
653int ast_format_cap_iscompatible(const struct ast_format_cap *cap1, const struct ast_format_cap *cap2)
654{
655 int idx;
656
657 for (idx = 0; idx < AST_VECTOR_SIZE(&cap1->preference_order); ++idx) {
658 struct format_cap_framed *framed = AST_VECTOR_GET(&cap1->preference_order, idx);
659
661 return 1;
662 }
663 }
664
665 return 0;
666}
667
668static int internal_format_cap_identical(const struct ast_format_cap *cap1, const struct ast_format_cap *cap2)
669{
670 int idx;
671 struct ast_format *tmp;
672
673 for (idx = 0; idx < AST_VECTOR_SIZE(&cap1->preference_order); ++idx) {
674 tmp = ast_format_cap_get_format(cap1, idx);
675
677 ao2_ref(tmp, -1);
678 return 0;
679 }
680
681 ao2_ref(tmp, -1);
682 }
683
684 return 1;
685}
686
687int ast_format_cap_identical(const struct ast_format_cap *cap1, const struct ast_format_cap *cap2)
688{
690 return 0; /* if they are not the same size, they are not identical */
691 }
692
693 if (!internal_format_cap_identical(cap1, cap2)) {
694 return 0;
695 }
696
697 return internal_format_cap_identical(cap2, cap1);
698}
699
700static const char *__ast_format_cap_get_names(const struct ast_format_cap *cap, struct ast_str **buf, int append)
701{
702 int i;
703
704 if (!buf || !*buf) {
705 return "";
706 }
707
708 if (append) {
709 ast_str_append(buf, 0, "(");
710 } else {
711 ast_str_set(buf, 0, "(");
712 }
713
714 if (!cap || !AST_VECTOR_SIZE(&cap->preference_order)) {
715 ast_str_append(buf, 0, "nothing)");
716 return ast_str_buffer(*buf);
717 }
718
719 for (i = 0; i < AST_VECTOR_SIZE(&cap->preference_order); ++i) {
720 int res;
721 struct format_cap_framed *framed = AST_VECTOR_GET(&cap->preference_order, i);
722
723 res = ast_str_append(buf, 0, "%s%s", ast_format_get_name(framed->format),
724 i < AST_VECTOR_SIZE(&cap->preference_order) - 1 ? "|" : "");
725 if (res < 0) {
726 break;
727 }
728 }
729 ast_str_append(buf, 0, ")");
730
731 return ast_str_buffer(*buf);
732}
733
734const char *ast_format_cap_get_names(const struct ast_format_cap *cap, struct ast_str **buf)
735{
736 return __ast_format_cap_get_names(cap, buf, 0);
737}
738
739const char *ast_format_cap_append_names(const struct ast_format_cap *cap, struct ast_str **buf)
740{
741 return __ast_format_cap_get_names(cap, buf, 1);
742}
743
745{
746 int count = ast_format_cap_count(cap);
747
748 if (count > 1) {
749 return 0;
750 }
751
752 if (count == 0 || AST_VECTOR_GET(&cap->preference_order, 0)->format == ast_format_none) {
753 return 1;
754 }
755
756 return 0;
757}
enum queue_result id
Definition: app_queue.c:1638
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 int tmp()
Definition: bt_open.c:389
static PGresult * result
Definition: cel_pgsql.c:84
static const char type[]
Definition: chan_ooh323.c:109
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.
Definition: format_cache.c:551
#define ast_format_cache_get(name)
Retrieve a named format from the cache.
Definition: format_cache.h:278
struct ast_format * ast_format_none
Built-in "null" format.
Definition: format_cache.c:246
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:744
#define FORMAT_CAP_FRAMED_ELEM_CLEANUP(elem)
format_cap_framed vector element cleanup.
Definition: format_cap.c:493
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:400
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:443
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:320
unsigned int ast_format_cap_get_framing(const struct ast_format_cap *cap)
Get the global framing.
Definition: format_cap.c:438
int ast_format_cap_remove(struct ast_format_cap *cap, struct ast_format *format)
Remove format capability from capability structure.
Definition: format_cap.c:495
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:417
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:628
static const char * __ast_format_cap_get_names(const struct ast_format_cap *cap, struct ast_str **buf, int append)
Definition: format_cap.c:700
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:739
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:523
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:581
static int internal_format_cap_identical(const struct ast_format_cap *cap1, const struct ast_format_cap *cap2)
Definition: format_cap.c:668
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:734
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:306
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:687
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:613
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:653
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:286
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:486
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:395
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:546
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
char * strsep(char **str, const char *delims)
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).
Definition: linkedlists.h:225
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:491
#define AST_LIST_HEAD_NOLOCK_INIT_VALUE
Defines initial values for a declaration of AST_LIST_HEAD_NOLOCK.
Definition: linkedlists.h:252
#define AST_LIST_ENTRY(type)
Declare a forward link structure inside a list entry.
Definition: linkedlists.h:410
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:615
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
Definition: linkedlists.h:711
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:529
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:557
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:833
#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
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:761
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 * 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
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::@356 preference_order
Vector of formats, added in preference order.
struct ast_format_cap::@355 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
Definition: search.h:40
Linked list for formats.
Definition: format_cap.c:64
Structure used for capability formats, adds framing.
Definition: format_cap.c:44
struct format_cap_framed::@354 entry
Linked list information.
struct ast_format * format
A pointer to the format.
Definition: format_cap.c:46
unsigned int framing
The format framing size.
Definition: format_cap.c:48
Utility functions.
#define ast_assert(a)
Definition: utils.h:739
#define MIN(a, b)
Definition: utils.h:231
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:284
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:609
#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:540
#define AST_VECTOR_FREE(vec)
Deallocates this vector.
Definition: vector.h:174
#define AST_VECTOR_INIT(vec, size)
Initialize a vector.
Definition: vector.h:113
#define AST_VECTOR_APPEND(vec, elem)
Append an element to a vector, growing the vector if needed.
Definition: vector.h:256
#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:680
#define AST_VECTOR_GET_ADDR(vec, idx)
Get an address of element in a vector.
Definition: vector.h:668