Asterisk - The Open Source Telephony Project  18.5.0
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 <[email protected]>
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 <[email protected]>
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 */
58  AST_VECTOR(, struct format_cap_framed *) 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  }
91  AST_VECTOR_FREE(&cap->preference_order);
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 
155  if (ast_format_get_codec_id(format) >= AST_VECTOR_SIZE(&cap->formats)) {
156  if (AST_VECTOR_REPLACE(&cap->formats, ast_format_get_codec_id(format), format_cap_framed_list_empty)) {
157  ao2_ref(framed, -1);
158  return -1;
159  }
160  }
161  list = AST_VECTOR_GET_ADDR(&cap->formats, ast_format_get_codec_id(format));
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 
187  if (ast_format_get_codec_id(format) == ast_format_get_codec_id(framed->format)) {
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 
235  format = ast_format_cache_get_by_codec(codec);
236 
237  if (format == ast_format_none) {
238  ao2_ref(format, -1);
239  ao2_ref(codec, -1);
240  continue;
241  }
242 
243  if (format) {
244  codec2 = ast_format_get_codec(format);
245  }
246  if (codec != codec2) {
247  ao2_cleanup(format);
248  format = ast_format_create(codec);
249  }
250  ao2_cleanup(codec2);
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 
278  if (type == AST_MEDIA_TYPE_UNKNOWN || ast_format_get_type(framed->format) == type) {
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 
296  if (ast_format_get_codec_id(format) == ast_format_get_codec_id(framed->format)) {
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 
314  if (type == AST_MEDIA_TYPE_UNKNOWN || ast_format_get_type(framed->format) == type) {
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 {
385  ast_format_cap_remove(cap, format);
386  }
387  }
388  }
389 
390  ao2_cleanup(format);
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 
449  if (ast_format_get_codec_id(format) >= AST_VECTOR_SIZE(&cap->formats)) {
450  return 0;
451  }
452 
453  framing = cap->framing != UINT_MAX ? cap->framing : ast_format_get_default_ms(format);
454  list = AST_VECTOR_GET_ADDR(&cap->formats, ast_format_get_codec_id(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  * \return 0 if element does not match.
484  * \return 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  * \return Nothing
494  */
495 #define FORMAT_CAP_FRAMED_ELEM_CLEANUP(elem) ao2_cleanup((elem))
496 
498 {
499  struct format_cap_framed_list *list;
500  struct format_cap_framed *framed;
501 
502  ast_assert(format != NULL);
503 
504  if (ast_format_get_codec_id(format) >= AST_VECTOR_SIZE(&cap->formats)) {
505  return -1;
506  }
507 
508  list = AST_VECTOR_GET_ADDR(&cap->formats, ast_format_get_codec_id(format));
509 
510  AST_LIST_TRAVERSE_SAFE_BEGIN(list, framed, entry) {
511  if (!FORMAT_CAP_FRAMED_ELEM_CMP(framed, format)) {
512  continue;
513  }
514 
517  break;
518  }
520 
521  return AST_VECTOR_REMOVE_CMP_ORDERED(&cap->preference_order, format,
523 }
524 
526 {
527  int idx;
528 
529  for (idx = 0; idx < AST_VECTOR_SIZE(&cap->formats); ++idx) {
530  struct format_cap_framed_list *list = AST_VECTOR_GET_ADDR(&cap->formats, idx);
531  struct format_cap_framed *framed;
532 
533  AST_LIST_TRAVERSE_SAFE_BEGIN(list, framed, entry) {
534  if ((type != AST_MEDIA_TYPE_UNKNOWN) &&
535  ast_format_get_type(framed->format) != type) {
536  continue;
537  }
538 
540  AST_VECTOR_REMOVE_CMP_ORDERED(&cap->preference_order, framed->format,
542  ao2_ref(framed, -1);
543  }
545  }
546 }
547 
549 {
550  struct format_cap_framed_list *list;
551  struct format_cap_framed *framed;
552  struct ast_format *result = NULL;
553 
554  ast_assert(format != NULL);
555 
556  if (ast_format_get_codec_id(format) >= AST_VECTOR_SIZE(&cap->formats)) {
557  return NULL;
558  }
559 
560  list = AST_VECTOR_GET_ADDR(&cap->formats, ast_format_get_codec_id(format));
561 
562  AST_LIST_TRAVERSE(list, framed, entry) {
563  enum ast_format_cmp_res res = ast_format_cmp(format, framed->format);
564 
565  if (res == AST_FORMAT_CMP_NOT_EQUAL) {
566  continue;
567  }
568 
569  /* Replace any current result, this one will also be a subset OR an exact match */
570  ao2_cleanup(result);
571 
572  result = ast_format_joint(format, framed->format);
573 
574  /* If it's a match we can do no better so return asap */
575  if (res == AST_FORMAT_CMP_EQUAL) {
576  break;
577  }
578  }
579 
580  return result;
581 }
582 
584  const struct ast_format *format)
585 {
587  struct format_cap_framed_list *list;
588  struct format_cap_framed *framed;
589 
590  ast_assert(format != NULL);
591 
592  if (ast_format_get_codec_id(format) >= AST_VECTOR_SIZE(&cap->formats)) {
594  }
595 
596  list = AST_VECTOR_GET_ADDR(&cap->formats, ast_format_get_codec_id(format));
597 
598  AST_LIST_TRAVERSE(list, framed, entry) {
599  enum ast_format_cmp_res cmp = ast_format_cmp(format, framed->format);
600 
601  if (cmp == AST_FORMAT_CMP_NOT_EQUAL) {
602  continue;
603  }
604 
605  res = cmp;
606 
607  if (res == AST_FORMAT_CMP_EQUAL) {
608  break;
609  }
610  }
611 
612  return res;
613 }
614 
616 {
617  int idx;
618 
619  for (idx = 0; idx < AST_VECTOR_SIZE(&cap->preference_order); ++idx) {
620  struct format_cap_framed *framed = AST_VECTOR_GET(&cap->preference_order, idx);
621 
622  if (ast_format_get_type(framed->format) == type) {
623  return 1;
624  }
625  }
626 
627  return 0;
628 }
629 
630 int ast_format_cap_get_compatible(const struct ast_format_cap *cap1, const struct ast_format_cap *cap2,
631  struct ast_format_cap *result)
632 {
633  int idx, res = 0;
634 
635  for (idx = 0; idx < AST_VECTOR_SIZE(&cap1->preference_order); ++idx) {
636  struct format_cap_framed *framed = AST_VECTOR_GET(&cap1->preference_order, idx);
637  struct ast_format *format;
638 
639  format = ast_format_cap_get_compatible_format(cap2, framed->format);
640  if (!format) {
641  continue;
642  }
643 
644  res = ast_format_cap_append(result, format, framed->framing);
645  ao2_ref(format, -1);
646 
647  if (res) {
648  break;
649  }
650  }
651 
652  return res;
653 }
654 
655 int ast_format_cap_iscompatible(const struct ast_format_cap *cap1, const struct ast_format_cap *cap2)
656 {
657  int idx;
658 
659  for (idx = 0; idx < AST_VECTOR_SIZE(&cap1->preference_order); ++idx) {
660  struct format_cap_framed *framed = AST_VECTOR_GET(&cap1->preference_order, idx);
661 
663  return 1;
664  }
665  }
666 
667  return 0;
668 }
669 
670 static int internal_format_cap_identical(const struct ast_format_cap *cap1, const struct ast_format_cap *cap2)
671 {
672  int idx;
673  struct ast_format *tmp;
674 
675  for (idx = 0; idx < AST_VECTOR_SIZE(&cap1->preference_order); ++idx) {
676  tmp = ast_format_cap_get_format(cap1, idx);
677 
679  ao2_ref(tmp, -1);
680  return 0;
681  }
682 
683  ao2_ref(tmp, -1);
684  }
685 
686  return 1;
687 }
688 
689 int ast_format_cap_identical(const struct ast_format_cap *cap1, const struct ast_format_cap *cap2)
690 {
691  if (AST_VECTOR_SIZE(&cap1->preference_order) != AST_VECTOR_SIZE(&cap2->preference_order)) {
692  return 0; /* if they are not the same size, they are not identical */
693  }
694 
695  if (!internal_format_cap_identical(cap1, cap2)) {
696  return 0;
697  }
698 
699  return internal_format_cap_identical(cap2, cap1);
700 }
701 
702 static const char *__ast_format_cap_get_names(const struct ast_format_cap *cap, struct ast_str **buf, int append)
703 {
704  int i;
705 
706  if (!buf || !*buf) {
707  return "";
708  }
709 
710  if (append) {
711  ast_str_append(buf, 0, "(");
712  } else {
713  ast_str_set(buf, 0, "(");
714  }
715 
716  if (!cap || !AST_VECTOR_SIZE(&cap->preference_order)) {
717  ast_str_append(buf, 0, "nothing)");
718  return ast_str_buffer(*buf);
719  }
720 
721  for (i = 0; i < AST_VECTOR_SIZE(&cap->preference_order); ++i) {
722  int res;
723  struct format_cap_framed *framed = AST_VECTOR_GET(&cap->preference_order, i);
724 
725  res = ast_str_append(buf, 0, "%s%s", ast_format_get_name(framed->format),
726  i < AST_VECTOR_SIZE(&cap->preference_order) - 1 ? "|" : "");
727  if (res < 0) {
728  break;
729  }
730  }
731  ast_str_append(buf, 0, ")");
732 
733  return ast_str_buffer(*buf);
734 }
735 
736 const char *ast_format_cap_get_names(const struct ast_format_cap *cap, struct ast_str **buf)
737 {
738  return __ast_format_cap_get_names(cap, buf, 0);
739 }
740 
741 const char *ast_format_cap_append_names(const struct ast_format_cap *cap, struct ast_str **buf)
742 {
743  return __ast_format_cap_get_names(cap, buf, 1);
744 }
745 
746 int ast_format_cap_empty(const struct ast_format_cap *cap)
747 {
748  int count = ast_format_cap_count(cap);
749 
750  if (count > 1) {
751  return 0;
752  }
753 
754  if (count == 0 || AST_VECTOR_GET(&cap->preference_order, 0)->format == ast_format_none) {
755  return 1;
756  }
757 
758  return 0;
759 }
static int format_in_format_cap(struct ast_format_cap *cap, struct ast_format *format)
Definition: format_cap.c:179
#define AST_VECTOR_FREE(vec)
Deallocates this vector.
Definition: vector.h:174
static const char type[]
Definition: chan_ooh323.c:109
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
enum ast_media_type ast_format_get_type(const struct ast_format *format)
Get the media type of a format.
Definition: format.c:354
Asterisk main include file. File version handling, generic pbx functions.
struct ast_codec * ast_format_get_codec(const struct ast_format *format)
Get the codec associated with a format.
Definition: format.c:324
String manipulation functions.
#define FORMAT_CAP_FRAMED_ELEM_CLEANUP(elem)
format_cap_framed vector element cleanup.
Definition: format_cap.c:495
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:559
static struct formats formats
static const char * __ast_format_cap_get_names(const struct ast_format_cap *cap, struct ast_str **buf, int append)
Definition: format_cap.c:702
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
struct ast_format * ast_format_create(struct ast_codec *codec)
Create a new media format.
Definition: format.c:196
struct ast_codec * ast_codec_get_by_id(int id)
Retrieve a codec given the unique identifier.
Definition: codec.c:337
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:630
#define LOG_WARNING
Definition: logger.h:274
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
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:615
static int tmp()
Definition: bt_open.c:389
#define AST_VECTOR_APPEND(vec, elem)
Append an element to a vector, growing the vector if needed.
Definition: vector.h:256
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:765
#define ao2_t_replace(dst, src, tag)
Replace one object reference with another cleaning up the original.
Definition: astobj2.h:503
Codec API.
Definition of a media format.
Definition: format.c:43
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:1091
#define ao2_alloc_options(data_size, destructor_fn, options)
Definition: astobj2.h:406
#define ast_assert(a)
Definition: utils.h:695
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)
Add format capability to capabilities structure.
Definition: format_cap.c:195
const char * ast_format_get_name(const struct ast_format *format)
Get the name associated with a format.
Definition: format.c:334
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:689
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
struct format_cap_framed::@392 entry
Linked list information.
#define NULL
Definition: resample.c:96
struct ast_format * format
A pointer to the format.
Definition: format_cap.c:46
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:525
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:614
static void format_cap_framed_destroy(void *obj)
Destructor for format capabilities framed structure.
Definition: format_cap.c:142
struct ast_format * ast_format_none
Built-in "null" format.
Definition: format_cache.c:251
#define ast_format_cache_get(name)
Definition: format_cache.h:286
int ast_codec_get_max(void)
Retrieve the current maximum identifier for codec iteration.
Definition: codec.c:342
Utility functions.
Media Format API.
#define ast_strlen_zero(foo)
Definition: strings.h:52
unsigned int framing
The format framing size.
Definition: format_cap.c:48
static struct ast_codec codec2
#define MIN(a, b)
Definition: utils.h:226
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:1065
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
int __ao2_ref(void *o, int delta, const char *tag, const char *file, int line, const char *func)
Definition: astobj2.c:498
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
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
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
#define AST_VECTOR_INIT(vec, size)
Initialize a vector.
Definition: vector.h:113
#define AST_VECTOR_GET_ADDR(vec, idx)
Get an address of element in a vector.
Definition: vector.h:670
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
Definition: strings.h:219
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:556
#define ao2_ref(o, delta)
Definition: astobj2.h:464
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
ast_format_cmp_res
Format comparison results.
Definition: format.h:34
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
#define ast_format_cap_append(cap, format, framing)
Definition: format_cap.h:103
A set of macros to manage forward-linked lists.
#define AST_VECTOR(name, type)
Define a vector structure.
Definition: vector.h:44
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
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:832
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
AST_LIST_HEAD_NOLOCK(contactliststruct, contact)
Format Capabilities API.
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:655
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
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
Linked list for formats.
Definition: format_cap.c:64
ast_format_cap_flags
Definition: format_cap.h:34
int ast_format_cap_remove(struct ast_format_cap *cap, struct ast_format *format)
Remove format capability from capability structure.
Definition: format_cap.c:497
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:746
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
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 AST_LIST_ENTRY(type)
Declare a forward link structure inside a list entry.
Definition: linkedlists.h:409
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
Definition: linkedlists.h:710
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1872
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
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
#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 * 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:548
Vector container support.
#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_LIST_HEAD_NOLOCK_INIT_VALUE
Defines initial values for a declaration of AST_LIST_HEAD_NOLOCK.
Definition: linkedlists.h:251
Support for logging to various files, console and syslog Configuration in file logger.conf.
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:741
static int format_cap_replace(struct ast_format_cap *cap, struct ast_format *format, unsigned int framing)
Definition: format_cap.c:286
static int internal_format_cap_identical(const struct ast_format_cap *cap1, const struct ast_format_cap *cap2)
Definition: format_cap.c:670
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:682
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:583
char * strsep(char **str, const char *delims)
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
static PGresult * result
Definition: cel_pgsql.c:88
#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
unsigned int ast_format_cap_get_framing(const struct ast_format_cap *cap)
Get the global framing.
Definition: format_cap.c:438
static int format_cap_init(struct ast_format_cap *cap, enum ast_format_cap_flags flags)
Definition: format_cap.c:102
enum ast_media_type type
Type of media this codec contains.
Definition: codec.h:50
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
Definition: search.h:40
enum queue_result id
Definition: app_queue.c:1507
ast_media_type
Types of media.
Definition: codec.h:30
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:528
static void format_cap_destroy(void *obj)
Destructor for format capabilities structure.
Definition: format_cap.c:70
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:736
void ast_format_cap_set_framing(struct ast_format_cap *cap, unsigned int framing)
Set the global framing.
Definition: format_cap.c:136
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)
Allocate a new ast_format_cap structure.
Definition: format_cap.c:117
unsigned int ast_format_get_codec_id(const struct ast_format *format)
Get the codec identifier associated with a format.
Definition: format.c:329
Represents a media codec within Asterisk.
Definition: codec.h:42
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:611
Media Format Cache API.
Structure used for capability formats, adds framing.
Definition: format_cap.c:44