Sun May 20 06:33:58 2012

Asterisk developer's documentation


res_format_attr_silk.c

Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  *
00004  * Copyright (C) 2011, Digium, Inc.
00005  *
00006  * David Vossel <dvossel@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 /*!
00020  * \file
00021  * \brief SILK format attribute interface
00022  *
00023  * \author David Vossel <dvossel@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: 362307 $")
00033 
00034 #include "asterisk/module.h"
00035 #include "asterisk/format.h"
00036 
00037 /*!
00038  * \brief SILK attribute structure.
00039  *
00040  * \note The only attribute that affects compatibility here is the sample rate.
00041  */
00042 struct silk_attr {
00043    unsigned int samplerate;
00044    unsigned int maxbitrate;
00045    unsigned int dtx;
00046    unsigned int fec;
00047    unsigned int packetloss_percentage;
00048 };
00049 
00050 static enum ast_format_cmp_res silk_cmp(const struct ast_format_attr *fattr1, const struct ast_format_attr *fattr2)
00051 {
00052    struct silk_attr *attr1 = (struct silk_attr *) fattr1;
00053    struct silk_attr *attr2 = (struct silk_attr *) fattr2;
00054 
00055    if (attr1->samplerate == attr2->samplerate) {
00056       return AST_FORMAT_CMP_EQUAL;
00057    }
00058    return AST_FORMAT_CMP_NOT_EQUAL;
00059 }
00060 
00061 static int silk_get_val(const struct ast_format_attr *fattr, int key, void *result)
00062 {
00063    const struct silk_attr *attr = (struct silk_attr *) fattr;
00064    int *val = result;
00065 
00066    switch (key) {
00067    case SILK_ATTR_KEY_SAMP_RATE:
00068       *val = attr->samplerate;
00069       break;
00070    case SILK_ATTR_KEY_MAX_BITRATE:
00071       *val = attr->maxbitrate;
00072       break;
00073    case SILK_ATTR_KEY_DTX:
00074       *val = attr->dtx;
00075       break;
00076    case SILK_ATTR_KEY_FEC:
00077       *val = attr->fec;
00078       break;
00079    case SILK_ATTR_KEY_PACKETLOSS_PERCENTAGE:
00080       *val = attr->packetloss_percentage;
00081       break;
00082    default:
00083       ast_log(LOG_WARNING, "unknown attribute type %d\n", key);
00084       return -1;
00085    }
00086    return 0;
00087 }
00088 
00089 static int silk_isset(const struct ast_format_attr *fattr, va_list ap)
00090 {
00091    enum silk_attr_keys key;
00092    const struct silk_attr *attr = (struct silk_attr *) fattr;
00093 
00094    for (key = va_arg(ap, int);
00095       key != AST_FORMAT_ATTR_END;
00096       key = va_arg(ap, int))
00097    {
00098       switch (key) {
00099       case SILK_ATTR_KEY_SAMP_RATE:
00100          if (attr->samplerate != (va_arg(ap, int))) {
00101             return -1;
00102          }
00103          break;
00104       case SILK_ATTR_KEY_MAX_BITRATE:
00105          if (attr->maxbitrate != (va_arg(ap, int))) {
00106             return -1;
00107          }
00108          break;
00109       case SILK_ATTR_KEY_DTX:
00110          if (attr->dtx != (va_arg(ap, int))) {
00111             return -1;
00112          }
00113          break;
00114       case SILK_ATTR_KEY_FEC:
00115          if (attr->fec != (va_arg(ap, int))) {
00116             return -1;
00117          }
00118          break;
00119       case SILK_ATTR_KEY_PACKETLOSS_PERCENTAGE:
00120          if (attr->packetloss_percentage != (va_arg(ap, int))) {
00121             return -1;
00122          }
00123          break;
00124       default:
00125          ast_log(LOG_WARNING, "unknown attribute type %d\n", key);
00126          return -1;
00127       }
00128    }
00129    return 0;
00130 }
00131 static int silk_getjoint(const struct ast_format_attr *fattr1, const struct ast_format_attr *fattr2, struct ast_format_attr *result)
00132 {
00133    struct silk_attr *attr1 = (struct silk_attr *) fattr1;
00134    struct silk_attr *attr2 = (struct silk_attr *) fattr2;
00135    struct silk_attr *attr_res = (struct silk_attr *) result;
00136    int joint = -1;
00137 
00138    attr_res->samplerate = attr1->samplerate & attr2->samplerate;
00139    /* sample rate is the only attribute that has any bearing on if joint capabilities exist or not */
00140    if (attr_res->samplerate) {
00141       joint = 0;
00142    }
00143    /* Take the lowest max bitrate */
00144    attr_res->maxbitrate = MIN(attr1->maxbitrate, attr2->maxbitrate);
00145 
00146    /* Only do dtx if both sides want it. DTX is a trade off between
00147     * computational complexity and bandwidth. */
00148    attr_res->dtx = attr1->dtx && attr2->dtx ? 1 : 0;
00149 
00150    /* Only do FEC if both sides want it.  If a peer specifically requests not
00151     * to receive with FEC, it may be a waste of bandwidth. */
00152    attr_res->fec = attr1->fec && attr2->fec ? 1 : 0;
00153 
00154    /* Use the maximum packetloss percentage between the two attributes. This affects how
00155     * much redundancy is used in the FEC. */
00156    attr_res->packetloss_percentage = MAX(attr1->packetloss_percentage, attr2->packetloss_percentage);
00157    return joint;
00158 }
00159 
00160 static void silk_set(struct ast_format_attr *fattr, va_list ap)
00161 {
00162    enum silk_attr_keys key;
00163    struct silk_attr *attr = (struct silk_attr *) fattr;
00164 
00165    for (key = va_arg(ap, int);
00166       key != AST_FORMAT_ATTR_END;
00167       key = va_arg(ap, int))
00168    {
00169       switch (key) {
00170       case SILK_ATTR_KEY_SAMP_RATE:
00171          attr->samplerate = (va_arg(ap, int));
00172          break;
00173       case SILK_ATTR_KEY_MAX_BITRATE:
00174          attr->maxbitrate = (va_arg(ap, int));
00175          break;
00176       case SILK_ATTR_KEY_DTX:
00177          attr->dtx = (va_arg(ap, int));
00178          break;
00179       case SILK_ATTR_KEY_FEC:
00180          attr->fec = (va_arg(ap, int));
00181          break;
00182       case SILK_ATTR_KEY_PACKETLOSS_PERCENTAGE:
00183          attr->packetloss_percentage = (va_arg(ap, int));
00184          break;
00185       default:
00186          ast_log(LOG_WARNING, "unknown attribute type %d\n", key);
00187       }
00188    }
00189 }
00190 
00191 static struct ast_format_attr_interface silk_interface = {
00192    .id = AST_FORMAT_SILK,
00193    .format_attr_cmp = silk_cmp,
00194    .format_attr_get_joint = silk_getjoint,
00195    .format_attr_set = silk_set,
00196    .format_attr_isset = silk_isset,
00197    .format_attr_get_val = silk_get_val,
00198 };
00199 
00200 static int load_module(void)
00201 {
00202    if (ast_format_attr_reg_interface(&silk_interface)) {
00203       return AST_MODULE_LOAD_DECLINE;
00204    }
00205 
00206    return AST_MODULE_LOAD_SUCCESS;
00207 }
00208 
00209 static int unload_module(void)
00210 {
00211    ast_format_attr_unreg_interface(&silk_interface);
00212    return 0;
00213 }
00214 
00215 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "SILK Format Attribute Module",
00216    .load = load_module,
00217    .unload = unload_module,
00218    .load_pri = AST_MODPRI_CHANNEL_DEPEND,
00219 );

Generated on Sun May 20 06:33:58 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.5.6