codec_pref.c File Reference

Media Format Bitfield Compatibility API. More...

#include "asterisk.h"
#include "asterisk/logger.h"
#include "asterisk/astobj2.h"
#include "asterisk/codec.h"
#include "asterisk/format.h"
#include "asterisk/format_compatibility.h"
#include "asterisk/format_cache.h"
#include "asterisk/format_cap.h"
#include "asterisk/utils.h"
#include "include/codec_pref.h"
#include "include/format_compatibility.h"

Include dependency graph for codec_pref.c:

Go to the source code of this file.

Functions

static void codec_pref_remove (struct iax2_codec_pref *pref, int format_index)
 Remove codec from pref list.
static void codec_pref_remove_index (struct iax2_codec_pref *pref, int codec_pref_index)
void iax2_codec_pref_append (struct iax2_codec_pref *pref, struct ast_format *format, unsigned int framing)
 Append a audio codec to a preference list, removing it first if it was already there.
static void iax2_codec_pref_append_bitfield (struct iax2_codec_pref *pref, uint64_t bitfield, unsigned int framing)
int iax2_codec_pref_best_bitfield2cap (uint64_t bitfield, struct iax2_codec_pref *prefs, struct ast_format_cap *cap)
 Convert a bitfield to a format capabilities structure in the "best" order.
void iax2_codec_pref_convert (struct iax2_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.
int iax2_codec_pref_format_bitfield_to_order_value (uint64_t bitfield)
 Convert a format bitfield into an iax2_codec_pref order value.
uint64_t iax2_codec_pref_from_bitfield (struct iax2_codec_pref *pref, uint64_t bitfield)
 Create codec preference list from the given bitfield formats.
struct ast_formatiax2_codec_pref_index (struct iax2_codec_pref *pref, int idx, struct ast_format **result)
 Codec located at a particular place in the preference index.
uint64_t iax2_codec_pref_order_value_to_format_bitfield (int order_value)
 Convert an iax2_codec_pref order value into a format bitfield.
void iax2_codec_pref_prepend (struct iax2_codec_pref *pref, struct ast_format *format, unsigned int framing, int only_if_existing)
 Prepend an audio codec to a preference list, removing it first if it was already there.
void iax2_codec_pref_remove_missing (struct iax2_codec_pref *pref, uint64_t bitfield)
 Removes format from the pref list that aren't in the bitfield.
int iax2_codec_pref_string (struct iax2_codec_pref *pref, char *buf, size_t size)
 Dump audio codec preference list into a string.
int iax2_codec_pref_to_cap (struct iax2_codec_pref *pref, struct ast_format_cap *cap)
 Convert a preference structure to a capabilities structure.

Variables

static const uint64_t iax2_supported_formats []
 Formats supported by IAX2.


Detailed Description

Media Format Bitfield Compatibility API.

Author:
Joshua Colp <jcolp@digium.com>

Definition in file codec_pref.c.


Function Documentation

static void codec_pref_remove ( struct iax2_codec_pref pref,
int  format_index 
) [static]

Remove codec from pref list.

Definition at line 270 of file codec_pref.c.

References ARRAY_LEN, codec_pref_remove_index(), and iax2_codec_pref::order.

Referenced by iax2_codec_pref_append_bitfield().

00271 {
00272    int x;
00273 
00274    if (!pref->order[0]) {
00275       return;
00276    }
00277 
00278    for (x = 0; x < ARRAY_LEN(pref->order); ++x) {
00279       if (!pref->order[x]) {
00280          break;
00281       }
00282 
00283       if (pref->order[x] == format_index) {
00284          codec_pref_remove_index(pref, x);
00285          break;
00286       }
00287    }
00288 }

static void codec_pref_remove_index ( struct iax2_codec_pref pref,
int  codec_pref_index 
) [static]

Definition at line 248 of file codec_pref.c.

References ARRAY_LEN, iax2_codec_pref::framing, and iax2_codec_pref::order.

Referenced by codec_pref_remove(), and iax2_codec_pref_remove_missing().

00249 {
00250    int idx;
00251 
00252    idx = codec_pref_index;
00253    if (idx == ARRAY_LEN(pref->order) - 1) {
00254       /* Remove from last array entry. */
00255       pref->order[idx] = 0;
00256       pref->framing[idx] = 0;
00257       return;
00258    }
00259 
00260    for (; idx < ARRAY_LEN(pref->order); ++idx) {
00261       pref->order[idx] = pref->order[idx + 1];
00262       pref->framing[idx] = pref->framing[idx + 1];
00263       if (!pref->order[idx]) {
00264          return;
00265       }
00266    }
00267 }

void iax2_codec_pref_append ( struct iax2_codec_pref pref,
struct ast_format format,
unsigned int  framing 
)

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

Definition at line 424 of file codec_pref.c.

References ast_format_compatibility_format2bitfield(), and iax2_codec_pref_append_bitfield().

Referenced by iax2_parse_allow_disallow().

00425 {
00426    uint64_t bitfield;
00427 
00428    bitfield = ast_format_compatibility_format2bitfield(format);
00429    if (!bitfield) {
00430       return;
00431    }
00432 
00433    iax2_codec_pref_append_bitfield(pref, bitfield, framing);
00434 }

static void iax2_codec_pref_append_bitfield ( struct iax2_codec_pref pref,
uint64_t  bitfield,
unsigned int  framing 
) [static]

Definition at line 403 of file codec_pref.c.

References ARRAY_LEN, codec_pref_remove(), iax2_codec_pref::framing, iax2_codec_pref_format_bitfield_to_order_value(), and iax2_codec_pref::order.

Referenced by iax2_codec_pref_append(), and iax2_codec_pref_from_bitfield().

00404 {
00405    int format_index;
00406    int x;
00407 
00408    format_index = iax2_codec_pref_format_bitfield_to_order_value(bitfield);
00409    if (!format_index) {
00410       return;
00411    }
00412 
00413    codec_pref_remove(pref, format_index);
00414 
00415    for (x = 0; x < ARRAY_LEN(pref->order); ++x) {
00416       if (!pref->order[x]) {
00417          pref->order[x] = format_index;
00418          pref->framing[x] = framing;
00419          break;
00420       }
00421    }
00422 }

int iax2_codec_pref_best_bitfield2cap ( uint64_t  bitfield,
struct iax2_codec_pref prefs,
struct ast_format_cap cap 
)

Convert a bitfield to a format capabilities structure in the "best" order.

Parameters:
bitfield The bitfield for the media formats
prefs Format preference order to use as a guide. (May be NULL)
cap Capabilities structure to place formats into
Return values:
0 on success.
-1 on error.
Note:
If failure occurs the capabilities structure may contain a partial set of formats

Definition at line 114 of file codec_pref.c.

References ARRAY_LEN, ast_assert, ast_format_cap_append, ast_format_compatibility_bitfield2format(), format, iax2_codec_pref::framing, iax2_codec_pref_order_value_to_format_bitfield(), iax2_format_compatibility_best(), NULL, and iax2_codec_pref::order.

Referenced by ast_iax2_new(), and socket_process_helper().

00115 {
00116    uint64_t best_bitfield;
00117    struct ast_format *format;
00118 
00119    /* Add any user preferred codecs first. */
00120    if (prefs) {
00121       int idx;
00122 
00123       for (idx = 0; bitfield && idx < ARRAY_LEN(prefs->order); ++idx) {
00124          best_bitfield = iax2_codec_pref_order_value_to_format_bitfield(prefs->order[idx]);
00125          if (!best_bitfield) {
00126             break;
00127          }
00128 
00129          if (best_bitfield & bitfield) {
00130             format = ast_format_compatibility_bitfield2format(best_bitfield);
00131             if (format && ast_format_cap_append(cap, format, prefs->framing[idx])) {
00132                return -1;
00133             }
00134 
00135             /* Remove just added codec. */
00136             bitfield &= ~best_bitfield;
00137          }
00138       }
00139    }
00140 
00141    /* Add the hard coded "best" codecs. */
00142    while (bitfield) {
00143       best_bitfield = iax2_format_compatibility_best(bitfield);
00144       if (!best_bitfield) {
00145          /* No more codecs considered best. */
00146          break;
00147       }
00148 
00149       format = ast_format_compatibility_bitfield2format(best_bitfield);
00150       /* The best_bitfield should always be convertible to a format. */
00151       ast_assert(format != NULL);
00152 
00153       if (ast_format_cap_append(cap, format, 0)) {
00154          return -1;
00155       }
00156 
00157       /* Remove just added "best" codec to find the next "best". */
00158       bitfield &= ~best_bitfield;
00159    }
00160 
00161    /* Add any remaining codecs. */
00162    if (bitfield) {
00163       int bit;
00164 
00165       for (bit = 0; bit < 64; ++bit) {
00166          uint64_t mask = (1ULL << bit);
00167 
00168          if (mask & bitfield) {
00169             format = ast_format_compatibility_bitfield2format(mask);
00170             if (format && ast_format_cap_append(cap, format, 0)) {
00171                return -1;
00172             }
00173          }
00174       }
00175    }
00176 
00177    return 0;
00178 }

void iax2_codec_pref_convert ( struct iax2_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:
pref A codec preference list structure
buf A string denoting codec preference, appropriate for use in line transmission
size Size of buf
right Boolean: if 0, convert from buf to pref; if 1, convert from pref to buf.

Definition at line 46 of file codec_pref.c.

References ARRAY_LEN, iax2_codec_pref::framing, and iax2_codec_pref::order.

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

00047 {
00048    static int differential = (int) 'A';
00049    int x;
00050 
00051    if (right) {
00052       --size;/* Save room for the nul string terminator. */
00053       for (x = 0; x < ARRAY_LEN(pref->order) && x < size; ++x) {
00054          if (!pref->order[x]) {
00055             break;
00056          }
00057 
00058          buf[x] = pref->order[x] + differential;
00059       }
00060 
00061       buf[x] = '\0';
00062    } else {
00063       for (x = 0; x < ARRAY_LEN(pref->order) && x < size; ++x) {
00064          if (buf[x] == '\0') {
00065             break;
00066          }
00067 
00068          pref->order[x] = buf[x] - differential;
00069          pref->framing[x] = 0;
00070       }
00071 
00072       if (x < ARRAY_LEN(pref->order)) {
00073          pref->order[x] = 0;
00074          pref->framing[x] = 0;
00075       }
00076    }
00077 }

int iax2_codec_pref_format_bitfield_to_order_value ( uint64_t  bitfield  ) 

Convert a format bitfield into an iax2_codec_pref order value.

Parameters:
bitfield value being converted
Returns:
the iax2_codec_pref order value of the most significant format in the bitfield.
Note:
This is really meant to be used on single format bitfields. It will work with multiformat bitfields, but it can only return the index of the most significant one if that is the case.

Definition at line 378 of file codec_pref.c.

References ARRAY_LEN.

Referenced by iax2_codec_pref_append_bitfield(), and iax2_codec_pref_prepend().

00379 {
00380    int idx;
00381 
00382    if (bitfield) {
00383       for (idx = 0; idx < ARRAY_LEN(iax2_supported_formats); ++idx) {
00384          if (iax2_supported_formats[idx] == bitfield) {
00385             return idx + 1;
00386          }
00387       }
00388    }
00389    return 0;
00390 }

uint64_t iax2_codec_pref_from_bitfield ( struct iax2_codec_pref pref,
uint64_t  bitfield 
)

Create codec preference list from the given bitfield formats.

Since:
13.0.0
Parameters:
pref Codec preference list to setup from the given bitfield.
bitfield Format bitfield to guide preference list creation.
Returns:
Updated bitfield with any bits not mapped to a format cleared.

Definition at line 485 of file codec_pref.c.

References ast_assert, ast_format_compatibility_bitfield2format(), format, iax2_codec_pref_append_bitfield(), iax2_format_compatibility_best(), and NULL.

Referenced by set_config().

00486 {
00487    int bit;
00488    uint64_t working_bitfield;
00489    uint64_t best_bitfield;
00490    struct ast_format *format;
00491 
00492    /* Init the preference list. */
00493    memset(pref, 0, sizeof(*pref));
00494 
00495    working_bitfield = bitfield;
00496 
00497    /* Add the "best" codecs first. */
00498    while (working_bitfield) {
00499       best_bitfield = iax2_format_compatibility_best(working_bitfield);
00500       if (!best_bitfield) {
00501          /* No more codecs considered best. */
00502          break;
00503       }
00504 
00505       /* Remove current "best" codec to find the next "best". */
00506       working_bitfield &= ~best_bitfield;
00507 
00508       format = ast_format_compatibility_bitfield2format(best_bitfield);
00509       /* The best_bitfield should always be convertible to a format. */
00510       ast_assert(format != NULL);
00511 
00512       iax2_codec_pref_append_bitfield(pref, best_bitfield, 0);
00513    }
00514 
00515    /* Add any remaining codecs. */
00516    if (working_bitfield) {
00517       for (bit = 0; bit < 64; ++bit) {
00518          uint64_t mask = (1ULL << bit);
00519 
00520          if (mask & working_bitfield) {
00521             format = ast_format_compatibility_bitfield2format(mask);
00522             if (!format) {
00523                /* The bit is not associated with any format. */
00524                bitfield &= ~mask;
00525                continue;
00526             }
00527 
00528             iax2_codec_pref_append_bitfield(pref, mask, 0);
00529          }
00530       }
00531    }
00532 
00533    return bitfield;
00534 }

struct ast_format* iax2_codec_pref_index ( struct iax2_codec_pref pref,
int  index,
struct ast_format **  result 
) [read]

Codec located at a particular place in the preference index.

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

Definition at line 79 of file codec_pref.c.

References ARRAY_LEN, ast_format_compatibility_bitfield2format(), iax2_codec_pref_order_value_to_format_bitfield(), NULL, and iax2_codec_pref::order.

Referenced by function_iaxpeer(), and socket_process_helper().

00080 {
00081    if (0 <= idx && idx < ARRAY_LEN(pref->order) && pref->order[idx]) {
00082       uint64_t pref_bitfield;
00083 
00084       pref_bitfield = iax2_codec_pref_order_value_to_format_bitfield(pref->order[idx]);
00085       *result = ast_format_compatibility_bitfield2format(pref_bitfield);
00086    } else {
00087       *result = NULL;
00088    }
00089 
00090    return *result;
00091 }

uint64_t iax2_codec_pref_order_value_to_format_bitfield ( int  order_value  ) 

Convert an iax2_codec_pref order value into a format bitfield.

Parameters:
order_value value being converted
Returns:
the bitfield value of the order_value format

Definition at line 369 of file codec_pref.c.

References ARRAY_LEN.

Referenced by codec_choose_from_prefs(), iax2_codec_pref_best_bitfield2cap(), iax2_codec_pref_index(), iax2_codec_pref_remove_missing(), and iax2_codec_pref_to_cap().

00370 {
00371    if (order_value < 1 || ARRAY_LEN(iax2_supported_formats) < order_value) {
00372       return 0;
00373    }
00374 
00375    return iax2_supported_formats[order_value - 1];
00376 }

void iax2_codec_pref_prepend ( struct iax2_codec_pref pref,
struct ast_format format,
unsigned int  framing,
int  only_if_existing 
)

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

Definition at line 436 of file codec_pref.c.

References ARRAY_LEN, ast_assert, ast_format_compatibility_format2bitfield(), iax2_codec_pref::framing, iax2_codec_pref_format_bitfield_to_order_value(), and iax2_codec_pref::order.

Referenced by create_addr().

00438 {
00439    uint64_t bitfield;
00440    int format_index;
00441    int x;
00442 
00443    bitfield = ast_format_compatibility_format2bitfield(format);
00444    if (!bitfield) {
00445       return;
00446    }
00447    format_index = iax2_codec_pref_format_bitfield_to_order_value(bitfield);
00448    if (!format_index) {
00449       return;
00450    }
00451 
00452    /* Now find any existing occurrence, or the end */
00453    for (x = 0; x < ARRAY_LEN(pref->order); ++x) {
00454       if (!pref->order[x] || pref->order[x] == format_index)
00455          break;
00456    }
00457 
00458    /*
00459     * The array can never be full without format_index
00460     * also being in the array.
00461     */
00462    ast_assert(x < ARRAY_LEN(pref->order));
00463 
00464    /* If we failed to find any occurrence, set to the end for safety. */
00465    if (ARRAY_LEN(pref->order) <= x) {
00466       x = ARRAY_LEN(pref->order) - 1;
00467    }
00468 
00469    if (only_if_existing && !pref->order[x]) {
00470       return;
00471    }
00472 
00473    /* Move down to make space to insert - either all the way to the end,
00474       or as far as the existing location (which will be overwritten) */
00475    for (; x > 0; --x) {
00476       pref->order[x] = pref->order[x - 1];
00477       pref->framing[x] = pref->framing[x - 1];
00478    }
00479 
00480    /* And insert the new entry */
00481    pref->order[0] = format_index;
00482    pref->framing[0] = framing;
00483 }

void iax2_codec_pref_remove_missing ( struct iax2_codec_pref pref,
uint64_t  bitfield 
)

Removes format from the pref list that aren't in the bitfield.

Definition at line 290 of file codec_pref.c.

References ARRAY_LEN, codec_pref_remove_index(), iax2_codec_pref_order_value_to_format_bitfield(), and iax2_codec_pref::order.

Referenced by iax2_parse_allow_disallow().

00291 {
00292    int idx;
00293 
00294    if (!pref->order[0]) {
00295       return;
00296    }
00297 
00298    /*
00299     * Work from the end of the list so we always deal with
00300     * unmodified entries in case we have to remove a pref.
00301     */
00302    for (idx = ARRAY_LEN(pref->order); idx--;) {
00303       uint64_t pref_bitfield;
00304 
00305       pref_bitfield = iax2_codec_pref_order_value_to_format_bitfield(pref->order[idx]);
00306       if (!pref_bitfield) {
00307          continue;
00308       }
00309 
00310       /* If this format isn't in the bitfield, remove it from the prefs. */
00311       if (!(pref_bitfield & bitfield)) {
00312          codec_pref_remove_index(pref, idx);
00313       }
00314    }
00315 }

int iax2_codec_pref_string ( struct iax2_codec_pref pref,
char *  buf,
size_t  size 
)

Dump audio codec preference list into a string.

Parameters:
pref preference structure to dump string representation of order for
buf character buffer to put string into
size size of the character buffer
Returns:
-1 on error. Otherwise returns the remaining spaaaaaace in the buffer.
Note:
Format is (codec1|codec2|codec3|...) -- if the list is too long for the size of the buffer, codecs will be written until they exceed the length remaining in which case the list will be closed with '...)' after the last writable codec.

Definition at line 180 of file codec_pref.c.

References ao2_cleanup, ao2_ref, ast_format_cap_alloc, ast_format_cap_count(), AST_FORMAT_CAP_FLAG_DEFAULT, ast_format_cap_get_format(), ast_format_get_name(), iax2_codec_pref_to_cap(), and name.

Referenced by dump_prefs(), handle_cli_iax2_show_peer(), and socket_process_helper().

00181 {
00182    int x;
00183    struct ast_format_cap *cap;
00184    size_t total_len;
00185    char *cur;
00186 
00187    /* This function is useless if you have less than a 6 character buffer.
00188     * '(...)' is six characters. */
00189    if (size < 6) {
00190       return -1;
00191    }
00192 
00193    /* Convert the preferences into a format cap so that we can read the format names */
00194    cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
00195    if (!cap || iax2_codec_pref_to_cap(pref, cap)) {
00196       strcpy(buf, "(...)"); /* Safe */
00197       ao2_cleanup(cap);
00198       return -1;
00199    }
00200 
00201    /* We know that at a minimum, 3 characters are used - (, ), and \0 */
00202    total_len = size - 3;
00203 
00204    /* This character has already been accounted for total_len purposes */
00205    buf[0] = '(';
00206    cur = buf + 1;
00207 
00208    /* Loop through the formats and write as many into the buffer as we can */
00209    for (x = 0; x < ast_format_cap_count(cap); x++) {
00210       size_t name_len;
00211       struct ast_format *fmt = ast_format_cap_get_format(cap, x);
00212       const char *name = ast_format_get_name(fmt);
00213 
00214       name_len = strlen(name);
00215 
00216       /* all entries after the first need a delimiter character */
00217       if (x) {
00218          name_len++;
00219       }
00220 
00221       /* Terminate the list early if we don't have room for the entry.
00222        * If it's not the last entry in the list, save enough room to write '...'.
00223        */
00224       if (((x == ast_format_cap_count(cap) - 1) && (total_len < name_len)) ||
00225             ((x < ast_format_cap_count(cap) - 1) && (total_len < name_len + 3))) {
00226          strcpy(cur, "...");
00227          cur += 3;
00228          total_len -= 3;
00229          ao2_ref(fmt, -1);
00230          break;
00231       }
00232 
00233       sprintf(cur, "%s%s", x ? "|" : "", name);
00234       cur += name_len;
00235       total_len -= name_len;
00236 
00237       ao2_ref(fmt, -1);
00238    }
00239    ao2_ref(cap, -1);
00240 
00241    /* These two characters have already been accounted for total_len purposes */
00242    cur[0] = ')';
00243    cur[1] = '\0';
00244 
00245    return size - total_len;
00246 }

int iax2_codec_pref_to_cap ( struct iax2_codec_pref pref,
struct ast_format_cap cap 
)

Convert a preference structure to a capabilities structure.

Parameters:
pref Formats in preference order to build the capabilities.
cap Capabilities structure to place formats into
Return values:
0 on success.
-1 on error.
Note:
If failure occurs the capabilities structure may contain a partial set of formats

Definition at line 93 of file codec_pref.c.

References ARRAY_LEN, ast_format_cap_append, ast_format_compatibility_bitfield2format(), iax2_codec_pref::framing, iax2_codec_pref_order_value_to_format_bitfield(), and iax2_codec_pref::order.

Referenced by iax2_codec_pref_string(), and iax2_parse_allow_disallow().

00094 {
00095    int idx;
00096 
00097    for (idx = 0; idx < ARRAY_LEN(pref->order); ++idx) {
00098       uint64_t pref_bitfield;
00099       struct ast_format *pref_format;
00100 
00101       pref_bitfield = iax2_codec_pref_order_value_to_format_bitfield(pref->order[idx]);
00102       if (!pref_bitfield) {
00103          break;
00104       }
00105 
00106       pref_format = ast_format_compatibility_bitfield2format(pref_bitfield);
00107       if (pref_format && ast_format_cap_append(cap, pref_format, pref->framing[idx])) {
00108          return -1;
00109       }
00110    }
00111    return 0;
00112 }


Variable Documentation

const uint64_t iax2_supported_formats[] [static]

Formats supported by IAX2.

Note:
All AST_FORMAT_xxx compatibility bit defines must be represented here.

The order is important because the array index+1 values go out over the wire.

Definition at line 326 of file codec_pref.c.


Generated on Thu Apr 16 06:30:16 2015 for Asterisk - The Open Source Telephony Project by  doxygen 1.5.6