codec_pref.c

Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  *
00004  * Copyright (C) 2014, Digium, Inc.
00005  *
00006  * Joshua Colp <jcolp@digium.com>
00007  *
00008  * See http://www.asterisk.org for more information about
00009  * the Asterisk project. Please do not directly contact
00010  * any of the maintainers of this project for assistance;
00011  * the project provides a web site, mailing lists and IRC
00012  * channels for your use.
00013  *
00014  * This program is free software, distributed under the terms of
00015  * the GNU General Public License Version 2. See the LICENSE file
00016  * at the top of the source tree.
00017  */
00018 
00019 /*! \file
00020  *
00021  * \brief Media Format Bitfield Compatibility API
00022  *
00023  * \author Joshua Colp <jcolp@digium.com>
00024  */
00025 
00026 /*** MODULEINFO
00027    <support_level>core</support_level>
00028  ***/
00029 
00030 #include "asterisk.h"
00031 
00032 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 420364 $")
00033 
00034 #include "asterisk/logger.h"
00035 #include "asterisk/astobj2.h"
00036 #include "asterisk/codec.h"
00037 #include "asterisk/format.h"
00038 #include "asterisk/format_compatibility.h"
00039 #include "asterisk/format_cache.h"
00040 #include "asterisk/format_cap.h"
00041 #include "asterisk/utils.h"
00042 
00043 #include "include/codec_pref.h"
00044 #include "include/format_compatibility.h"
00045 
00046 void iax2_codec_pref_convert(struct iax2_codec_pref *pref, char *buf, size_t size, int right)
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 }
00078 
00079 struct ast_format *iax2_codec_pref_index(struct iax2_codec_pref *pref, int idx, struct ast_format **result)
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 }
00092 
00093 int iax2_codec_pref_to_cap(struct iax2_codec_pref *pref, struct ast_format_cap *cap)
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 }
00113 
00114 int iax2_codec_pref_best_bitfield2cap(uint64_t bitfield, struct iax2_codec_pref *prefs, struct ast_format_cap *cap)
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 }
00179 
00180 int iax2_codec_pref_string(struct iax2_codec_pref *pref, char *buf, size_t size)
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 }
00247 
00248 static void codec_pref_remove_index(struct iax2_codec_pref *pref, int codec_pref_index)
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 }
00268 
00269 /*! \brief Remove codec from pref list */
00270 static void codec_pref_remove(struct iax2_codec_pref *pref, int format_index)
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 }
00289 
00290 void iax2_codec_pref_remove_missing(struct iax2_codec_pref *pref, uint64_t bitfield)
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 }
00316 
00317 /*!
00318  * \brief Formats supported by IAX2.
00319  *
00320  * \note All AST_FORMAT_xxx compatibility bit defines must be
00321  *  represented here.
00322  *
00323  * \note The order is important because the array index+1 values
00324  * go out over the wire.
00325  */
00326 static const uint64_t iax2_supported_formats[] = {
00327    AST_FORMAT_G723,
00328    AST_FORMAT_GSM,
00329    AST_FORMAT_ULAW,
00330    AST_FORMAT_ALAW,
00331    AST_FORMAT_G726,
00332    AST_FORMAT_ADPCM,
00333    AST_FORMAT_SLIN,
00334    AST_FORMAT_LPC10,
00335    AST_FORMAT_G729,
00336    AST_FORMAT_SPEEX,
00337    AST_FORMAT_SPEEX16,
00338    AST_FORMAT_ILBC,
00339    AST_FORMAT_G726_AAL2,
00340    AST_FORMAT_G722,
00341    AST_FORMAT_SLIN16,
00342    AST_FORMAT_JPEG,
00343    AST_FORMAT_PNG,
00344    AST_FORMAT_H261,
00345    AST_FORMAT_H263,
00346    AST_FORMAT_H263P,
00347    AST_FORMAT_H264,
00348    AST_FORMAT_MP4,
00349    AST_FORMAT_T140_RED,
00350    AST_FORMAT_T140,
00351    AST_FORMAT_SIREN7,
00352    AST_FORMAT_SIREN14,
00353    AST_FORMAT_TESTLAW,
00354    AST_FORMAT_G719,
00355    0, /* Place holder */
00356    0, /* Place holder */
00357    0, /* Place holder */
00358    0, /* Place holder */
00359    0, /* Place holder */
00360    0, /* Place holder */
00361    0, /* Place holder */
00362    0, /* Place holder */
00363    AST_FORMAT_OPUS,
00364    AST_FORMAT_VP8,
00365    /* ONLY ADD TO THE END OF THIS LIST */
00366    /* XXX Use up the place holder slots first. */
00367 };
00368 
00369 uint64_t iax2_codec_pref_order_value_to_format_bitfield(int order_value)
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 }
00377 
00378 int iax2_codec_pref_format_bitfield_to_order_value(uint64_t bitfield)
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 }
00391 
00392 /*!
00393  * \internal
00394  * \brief Append the bitfield format to the codec preference list.
00395  * \since 13.0.0
00396  *
00397  * \param pref Codec preference list to append the given bitfield.
00398  * \param bitfield Format bitfield to append.
00399  * \param framing Framing size of the codec.
00400  *
00401  * \return Nothing
00402  */
00403 static void iax2_codec_pref_append_bitfield(struct iax2_codec_pref *pref, uint64_t bitfield, unsigned int framing)
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 }
00423 
00424 void iax2_codec_pref_append(struct iax2_codec_pref *pref, struct ast_format *format, unsigned int framing)
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 }
00435 
00436 void iax2_codec_pref_prepend(struct iax2_codec_pref *pref, struct ast_format *format, unsigned int framing,
00437    int only_if_existing)
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 }
00484 
00485 uint64_t iax2_codec_pref_from_bitfield(struct iax2_codec_pref *pref, uint64_t bitfield)
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 }

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