Asterisk - The Open Source Telephony Project  GIT-master-93d0901
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"
35 #include "asterisk/format_cache.h"
36 #include "asterisk/codec.h"
37 #include "asterisk/astobj2.h"
38 #include "asterisk/strings.h"
39 #include "asterisk/vector.h"
40 #include "asterisk/linkedlists.h"
41 #include "asterisk/utils.h"
42 
43 /*! \brief Structure used for capability formats, adds framing */
45  /*! \brief A pointer to the format */
46  struct ast_format *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 */
70 static 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  }
83  AST_VECTOR_FREE(&cap->formats);
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  */
102 static 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 
136 void 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 */
142 static void format_cap_framed_destroy(void *obj)
143 {
144  struct format_cap_framed *framed = obj;
145 
146  ao2_cleanup(framed->format);
147 }
148 
149 static 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 
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 */
179 static 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 
195 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)
196 {
197  struct format_cap_framed *framed;
198 
199  ast_assert(format != NULL);
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) {
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 
286 static 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 
291  ast_assert(format != NULL);
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 
320 int 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 {
386  }
387  }
388  }
389 
391  }
392  return res;
393 }
394 
395 size_t ast_format_cap_count(const struct ast_format_cap *cap)
396 {
397  return AST_VECTOR_SIZE(&cap->preference_order);
398 }
399 
400 struct ast_format *ast_format_cap_get_format(const struct ast_format_cap *cap, int position)
401 {
402  struct format_cap_framed *framed;
403 
404  ast_assert(position < AST_VECTOR_SIZE(&cap->preference_order));
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 
412  ast_assert(framed->format != ast_format_none);
413  ao2_ref(framed->format, +1);
414  return framed->format;
415 }
416 
418 {
419  int i;
420 
421  if (type == AST_MEDIA_TYPE_UNKNOWN) {
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);
430  ast_assert(framed->format != ast_format_none);
431  return framed->format;
432  }
433  }
434 
435  return NULL;
436 }
437 
438 unsigned int ast_format_cap_get_framing(const struct ast_format_cap *cap)
439 {
440  return (cap->framing != UINT_MAX) ? cap->framing : 0;
441 }
442 
443 unsigned 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 
500  ast_assert(format != NULL);
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 
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 
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 
588  ast_assert(format != NULL);
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 
628 int 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 
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 
653 int 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 
668 static 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 
687 int 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 
700 static 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 
734 const 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 
739 const 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 
744 int ast_format_cap_empty(const struct ast_format_cap *cap)
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:1608
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 snd_pcm_format_t format
Definition: chan_alsa.c:106
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1844
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:337
int ast_codec_get_max(void)
Retrieve the current maximum identifier for codec iteration.
Definition: codec.c:342
static struct ast_codec codec2
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
Media Format API.
const char * ast_format_get_name(const struct ast_format *format)
Get the name associated with a format.
Definition: format.c:334
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_create(struct ast_codec *codec)
Create a new media format.
Definition: format.c:196
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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)
A set of macros to manage forward-linked lists.
#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
Support for logging to various files, console and syslog Configuration in file logger....
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:451
#define LOG_WARNING
Definition: logger.h:275
AST_LIST_HEAD_NOLOCK(contactliststruct, contact)
#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:1115
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:737
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:1089
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::@385 preference_order
Vector of formats, added in preference order.
struct ast_format_cap::@384 formats
Vector of formats, indexed using the codec identifier.
unsigned int framing
Global framing size, applies to all formats if no framing present on format.
Definition: format_cap.c:60
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:602
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 ast_format * format
A pointer to the format.
Definition: format_cap.c:46
struct format_cap_framed::@383 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:734
#define MIN(a, b)
Definition: utils.h:226
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