Sat Apr 26 2014 22:02:50

Asterisk developer's documentation


format_pref.h File Reference

Format Preference API. More...

Include dependency graph for format_pref.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  ast_codec_pref

Defines

#define AST_CODEC_PREF_SIZE   64

Functions

struct ast_formatast_codec_choose (struct ast_codec_pref *pref, struct ast_format_cap *cap, int find_best, struct ast_format *result)
 Select the best audio format according to preference list from supplied options. Best audio format is returned in the result format.
int ast_codec_pref_append (struct ast_codec_pref *pref, struct ast_format *format)
 Append a audio codec to a preference list, removing it first if it was already there.
void ast_codec_pref_convert (struct ast_codec_pref *pref, char *buf, size_t size, int right)
 Shift an audio codec preference list up or down 65 bytes so that it becomes an ASCII string.
struct ast_format_list ast_codec_pref_getsize (struct ast_codec_pref *pref, struct ast_format *format)
 Get packet size for codec.
struct ast_formatast_codec_pref_index (struct ast_codec_pref *pref, int index, struct ast_format *result)
 Codec located at a particular place in the preference index.
void ast_codec_pref_init (struct ast_codec_pref *pref)
 Initialize an audio codec preference to "no preference".
void ast_codec_pref_prepend (struct ast_codec_pref *pref, struct ast_format *format, int only_if_existing)
 Prepend an audio codec to a preference list, removing it first if it was already there.
void ast_codec_pref_remove (struct ast_codec_pref *pref, struct ast_format *format)
 Remove audio a codec from a preference list.
int ast_codec_pref_setsize (struct ast_codec_pref *pref, struct ast_format *format, int framems)
 Set packet size for codec.
int ast_codec_pref_string (struct ast_codec_pref *pref, char *buf, size_t size)
 Dump audio codec preference list into a string.

Detailed Description

Format Preference API.

Definition in file format_pref.h.


Define Documentation


Function Documentation

struct ast_format* ast_codec_choose ( struct ast_codec_pref pref,
struct ast_format_cap cap,
int  find_best,
struct ast_format result 
) [read]

Select the best audio format according to preference list from supplied options. Best audio format is returned in the result format.

Note:
If "find_best" is non-zero then if nothing is found, the "Best" format of the format list is selected and returned in the result structure, otherwise NULL is returned
Return values:
ptrto result struture.
NULL,bestcodec was not found

Definition at line 318 of file format_pref.c.

References ast_best_codec(), ast_debug, ast_format_cap_get_compatible_format(), ast_format_clear(), AST_FORMAT_GET_TYPE, ast_format_list_destroy(), ast_format_list_get(), AST_FORMAT_TYPE_AUDIO, format, ast_format::id, and ast_codec_pref::order.

Referenced by __oh323_new(), gtalk_new(), iax2_codec_choose(), jingle_interpret_content(), jingle_new(), process_sdp(), and sip_new().

{
   int x, slot, found = 0;
   size_t f_len = 0;
   const struct ast_format_list *f_list = ast_format_list_get(&f_len);

   for (x = 0; x < f_len; x++) {
      slot = pref->order[x];

      if (!slot)
         break;
      if (ast_format_cap_get_compatible_format(cap, &f_list[slot-1].format, result)) {
         found = 1; /*format is found and stored in result */
         break;
      }
   }
   ast_format_list_destroy(f_list);
   if (found && (AST_FORMAT_GET_TYPE(result->id) == AST_FORMAT_TYPE_AUDIO)) {
      return result;
   }
   ast_format_clear(result);
   ast_debug(4, "Could not find preferred codec - %s\n", find_best ? "Going for the best codec" : "Returning zero codec");

   return find_best ? ast_best_codec(cap, result) : NULL;
}
int ast_codec_pref_append ( struct ast_codec_pref pref,
struct ast_format format 
)

Append a audio codec to a preference list, removing it first if it was already there.

Definition at line 147 of file format_pref.c.

References ast_codec_pref_remove(), ast_format_cmp(), AST_FORMAT_CMP_EQUAL, ast_format_copy(), ast_format_list_destroy(), ast_format_list_get(), ast_codec_pref::formats, and ast_codec_pref::order.

Referenced by ast_parse_allow_disallow().

{
   int x, newindex = 0;
   size_t f_len = 0;
   const struct ast_format_list *f_list = ast_format_list_get(&f_len);

   ast_codec_pref_remove(pref, format);

   for (x = 0; x < f_len; x++) {
      if (ast_format_cmp(&f_list[x].format, format) == AST_FORMAT_CMP_EQUAL) {
         newindex = x + 1;
         break;
      }
   }

   if (newindex) {
      for (x = 0; x < f_len; x++) {
         if (!pref->order[x]) {
            pref->order[x] = newindex;
            ast_format_copy(&pref->formats[x], format);
            break;
         }
      }
   }

   ast_format_list_destroy(f_list);
   return x;
}
void ast_codec_pref_convert ( struct ast_codec_pref pref,
char *  buf,
size_t  size,
int  right 
)

Shift an audio codec preference list up or down 65 bytes so that it becomes an ASCII string.

Note:
Due to a misunderstanding in how codec preferences are stored, this list starts at 'B', not 'A'. For backwards compatibility reasons, this cannot change.
Parameters:
prefA codec preference list structure
bufA string denoting codec preference, appropriate for use in line transmission
sizeSize of buf
rightBoolean: if 0, convert from buf to pref; if 1, convert from pref to buf.

Definition at line 37 of file format_pref.c.

References AST_CODEC_PREF_SIZE, ast_format_copy(), ast_format_list_destroy(), ast_format_list_get(), ast_format_list::format, ast_codec_pref::formats, and ast_codec_pref::order.

Referenced by check_access(), create_addr(), dump_prefs(), and socket_process_helper().

{
   size_t f_len;
   const struct ast_format_list *f_list = ast_format_list_get(&f_len);
   int x, differential = (int) 'A', mem;
   char *from, *to;

   /* TODO re-evaluate this function.  It is using the order of the formats specified
    * in the global format list in a way that may not be safe. */
   if (right) {
      from = pref->order;
      to = buf;
      mem = size;
   } else {
      to = pref->order;
      from = buf;
      mem = AST_CODEC_PREF_SIZE;
   }

   memset(to, 0, mem);
   for (x = 0; x < AST_CODEC_PREF_SIZE; x++) {
      if (!from[x]) {
         break;
      }
      to[x] = right ? (from[x] + differential) : (from[x] - differential);
      if (!right && to[x] && (to[x] < f_len)) {
         ast_format_copy(&pref->formats[x], &f_list[to[x]-1].format);
      }
   }
   ast_format_list_destroy(f_list);
}
struct ast_format_list ast_codec_pref_getsize ( struct ast_codec_pref pref,
struct ast_format format 
) [read]

Get packet size for codec.

Definition at line 271 of file format_pref.c.

References ast_format_cmp(), AST_FORMAT_CMP_EQUAL, ast_format_list_destroy(), ast_format_list_get(), ast_getformatname(), ast_log(), AST_LOG_WARNING, ast_format_list::cur_ms, ast_format_list::def_ms, format, ast_format_list::inc_ms, ast_format_list::max_ms, and ast_format_list::min_ms.

Referenced by add_codec_to_sdp(), ast_rtp_instance_bridge(), ast_rtp_write(), handle_open_receive_channel_ack_message(), skinny_set_rtp_peer(), and transmit_connect().

{
   int x, idx = -1, framems = 0;
   struct ast_format_list fmt = { { 0, }, };
   size_t f_len = 0;
   const struct ast_format_list *f_list = ast_format_list_get(&f_len);

   for (x = 0; x < f_len; x++) {
      if (ast_format_cmp(&f_list[x].format, format) == AST_FORMAT_CMP_EQUAL) {
         fmt = f_list[x];
         idx = x;
         break;
      }
   }

   if (idx < 0) {
      ast_log(AST_LOG_WARNING, "Format %s unknown; unable to get preferred codec packet size\n", ast_getformatname(format));
      ast_format_list_destroy(f_list);
      return fmt;
   }

   for (x = 0; x < f_len; x++) {
      if (pref->order[x] == (idx + 1)) {
         framems = pref->framing[x];
         break;
      }
   }

   /* size validation */
   if (!framems)
      framems = f_list[idx].def_ms;

   if (f_list[idx].inc_ms && framems % f_list[idx].inc_ms) /* avoid division by zero */
      framems -= framems % f_list[idx].inc_ms;

   if (framems < f_list[idx].min_ms)
      framems = f_list[idx].min_ms;

   if (framems > f_list[idx].max_ms)
      framems = f_list[idx].max_ms;

   fmt.cur_ms = framems;
   ast_format_list_destroy(f_list);
   return fmt;
}
struct ast_format* ast_codec_pref_index ( struct ast_codec_pref pref,
int  index,
struct ast_format result 
) [read]

Codec located at a particular place in the preference index.

Parameters:
preferencestructure to get the codec out of
indexto retrieve from
retultast_format structure to store the index value in
Returns:
pointer to input ast_format on success, NULL on failure

Definition at line 105 of file format_pref.c.

References ast_format_clear(), ast_format_copy(), ast_codec_pref::formats, ast_format::id, and ast_codec_pref::order.

Referenced by _sip_show_peer(), _skinny_show_line(), add_sdp(), ast_codec_pref_string(), function_iaxpeer(), function_sippeer(), gtalk_invite(), handle_cli_iax2_show_peer(), jingle_accept_call(), jingle_add_payloads_to_description(), print_codec_to_cli(), and socket_process_helper().

{
   if ((idx >= 0) && (idx < sizeof(pref->order)) && pref->formats[idx].id) {
      ast_format_copy(result, &pref->formats[idx]);
   } else {
      ast_format_clear(result);
      return NULL;
   }

   return result;
}
void ast_codec_pref_init ( struct ast_codec_pref pref)

Initialize an audio codec preference to "no preference".

void ast_codec_pref_prepend ( struct ast_codec_pref pref,
struct ast_format format,
int  only_if_existing 
)

Prepend an audio codec to a preference list, removing it first if it was already there.

Definition at line 177 of file format_pref.c.

References AST_CODEC_PREF_SIZE, ast_format_cmp(), AST_FORMAT_CMP_EQUAL, ast_format_copy(), ast_format_list_destroy(), ast_format_list_get(), ast_codec_pref::formats, ast_codec_pref::framing, and ast_codec_pref::order.

Referenced by create_addr().

{
   int x, newindex = 0;
   size_t f_len = 0;
   const struct ast_format_list *f_list = ast_format_list_get(&f_len);

   /* First step is to get the codecs "index number" */
   for (x = 0; x < f_len; x++) {
      if (ast_format_cmp(&f_list[x].format, format) == AST_FORMAT_CMP_EQUAL) {
         newindex = x + 1;
         break;
      }
   }
   /* Done if its unknown */
   if (!newindex) {
      ast_format_list_destroy(f_list);
      return;
   }

   /* Now find any existing occurrence, or the end */
   for (x = 0; x < AST_CODEC_PREF_SIZE; x++) {
      if (!pref->order[x] || pref->order[x] == newindex)
         break;
   }

   /* If we failed to find any occurrence, set to the end */
   if (x == AST_CODEC_PREF_SIZE) {
      --x;
   }

   if (only_if_existing && !pref->order[x]) {
      ast_format_list_destroy(f_list);
      return;
   }

   /* Move down to make space to insert - either all the way to the end,
      or as far as the existing location (which will be overwritten) */
   for (; x > 0; x--) {
      pref->order[x] = pref->order[x - 1];
      pref->framing[x] = pref->framing[x - 1];
      ast_format_copy(&pref->formats[x], &pref->formats[x - 1]);
   }

   /* And insert the new entry */
   pref->order[0] = newindex;
   pref->framing[0] = 0; /* ? */
   ast_format_copy(&pref->formats[0], format);
   ast_format_list_destroy(f_list);
}
void ast_codec_pref_remove ( struct ast_codec_pref pref,
struct ast_format format 
)

Remove audio a codec from a preference list.

Definition at line 118 of file format_pref.c.

References ast_format_cmp(), AST_FORMAT_CMP_NOT_EQUAL, ast_format_copy(), ast_format_list_destroy(), ast_format_list_get(), ast_format_list::format, ast_codec_pref::formats, ast_codec_pref::framing, and ast_codec_pref::order.

Referenced by ast_codec_pref_append(), and ast_parse_allow_disallow().

{
   struct ast_codec_pref oldorder;
   int x, y = 0;
   size_t f_len = 0;
   const struct ast_format_list *f_list;

   if (!pref->order[0]) {
      return;
   }

   f_list = ast_format_list_get(&f_len);
   memcpy(&oldorder, pref, sizeof(oldorder));
   memset(pref, 0, sizeof(*pref));

   for (x = 0; x < f_len; x++) {
      if (!oldorder.order[x]) {
         break;
      }
      if (ast_format_cmp(&f_list[oldorder.order[x]-1].format, format) == AST_FORMAT_CMP_NOT_EQUAL) {
         pref->order[y] = oldorder.order[x];
         ast_format_copy(&pref->formats[y], &oldorder.formats[x]);
         pref->framing[y++] = oldorder.framing[x];
      }
   }
   ast_format_list_destroy(f_list);
}
int ast_codec_pref_setsize ( struct ast_codec_pref pref,
struct ast_format format,
int  framems 
)

Set packet size for codec.

Definition at line 228 of file format_pref.c.

References ast_format_cmp(), AST_FORMAT_CMP_EQUAL, ast_format_list_destroy(), ast_format_list_get(), ast_format_list::def_ms, ast_codec_pref::framing, ast_format_list::inc_ms, ast_format_list::max_ms, ast_format_list::min_ms, and ast_codec_pref::order.

Referenced by ast_parse_allow_disallow(), and process_sdp_a_audio().

{
   int x, idx = -1;
   size_t f_len = 0;
   const struct ast_format_list *f_list = ast_format_list_get(&f_len);

   for (x = 0; x < f_len; x++) {
      if (ast_format_cmp(&f_list[x].format, format) == AST_FORMAT_CMP_EQUAL) {
         idx = x;
         break;
      }
   }

   if (idx < 0) {
      ast_format_list_destroy(f_list);
      return -1;
   }

   /* size validation */
   if (!framems)
      framems = f_list[idx].def_ms;

   if (f_list[idx].inc_ms && framems % f_list[idx].inc_ms) /* avoid division by zero */
      framems -= framems % f_list[idx].inc_ms;

   if (framems < f_list[idx].min_ms)
      framems = f_list[idx].min_ms;

   if (framems > f_list[idx].max_ms)
      framems = f_list[idx].max_ms;

   for (x = 0; x < f_len; x++) {
      if (pref->order[x] == (idx + 1)) {
         pref->framing[x] = framems;
         break;
      }
   }

   ast_format_list_destroy(f_list);
   return x;
}
int ast_codec_pref_string ( struct ast_codec_pref pref,
char *  buf,
size_t  size 
)

Dump audio codec preference list into a string.

Definition at line 69 of file format_pref.c.

References ast_codec_pref_index(), AST_CODEC_PREF_SIZE, and ast_getformatname().

Referenced by dump_prefs(), and socket_process_helper().

{
   int x;
   struct ast_format format;
   size_t total_len, slen;
   const char *formatname;

   memset(buf, 0, size);
   total_len = size;
   buf[0] = '(';
   total_len--;
   for (x = 0; x < AST_CODEC_PREF_SIZE; x++) {
      if (total_len <= 0)
         break;
      if (!(ast_codec_pref_index(pref, x, &format)))
         break;
      if ((formatname = ast_getformatname(&format))) {
         slen = strlen(formatname);
         if (slen > total_len)
            break;
         strncat(buf, formatname, total_len - 1); /* safe */
         total_len -= slen;
      }
      if (total_len && x < AST_CODEC_PREF_SIZE - 1 && ast_codec_pref_index(pref, x + 1, &format)) {
         strncat(buf, "|", total_len - 1); /* safe */
         total_len--;
      }
   }
   if (total_len) {
      strncat(buf, ")", total_len - 1); /* safe */
      total_len--;
   }

   return size - total_len;
}