Sat Apr 26 2014 22:01:40

Asterisk developer's documentation


res_format_attr_celt.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 CELT 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: 370055 $")
00033 
00034 #include "asterisk/module.h"
00035 #include "asterisk/format.h"
00036 
00037 /*!
00038  * \brief CELT attribute structure.
00039  *
00040  * \note The only attribute that affects compatibility here is the sample rate.
00041  */
00042 struct celt_attr {
00043    unsigned int samplerate;
00044    unsigned int maxbitrate;
00045    unsigned int framesize;
00046 };
00047 
00048 static int celt_sdp_parse(struct ast_format_attr *format_attr, const char *attributes)
00049 {
00050    struct celt_attr *attr = (struct celt_attr *) format_attr;
00051    unsigned int val;
00052 
00053    if (sscanf(attributes, "framesize=%30u", &val) == 1) {
00054       attr->framesize = val;
00055    }
00056 
00057    return 0;
00058 }
00059 
00060 static void celt_sdp_generate(const struct ast_format_attr *format_attr, unsigned int payload, struct ast_str **str)
00061 {
00062    struct celt_attr *attr = (struct celt_attr *) format_attr;
00063 
00064    if (!attr->framesize) {
00065       return;
00066    }
00067 
00068    ast_str_append(str, 0, "a=fmtp:%d framesize=%d\r\n", payload, attr->framesize);
00069 }
00070 
00071 static enum ast_format_cmp_res celt_cmp(const struct ast_format_attr *fattr1, const struct ast_format_attr *fattr2)
00072 {
00073    struct celt_attr *attr1 = (struct celt_attr *) fattr1;
00074    struct celt_attr *attr2 = (struct celt_attr *) fattr2;
00075 
00076    if (attr1->samplerate == attr2->samplerate) {
00077       return AST_FORMAT_CMP_EQUAL;
00078    }
00079    return AST_FORMAT_CMP_NOT_EQUAL;
00080 }
00081 
00082 static int celt_get_val(const struct ast_format_attr *fattr, int key, void *result)
00083 {
00084    const struct celt_attr *attr = (struct celt_attr *) fattr;
00085    int *val = result;
00086 
00087    switch (key) {
00088    case CELT_ATTR_KEY_SAMP_RATE:
00089       *val = attr->samplerate;
00090       break;
00091    case CELT_ATTR_KEY_MAX_BITRATE:
00092       *val = attr->maxbitrate;
00093       break;
00094    case CELT_ATTR_KEY_FRAME_SIZE:
00095       *val = attr->framesize;
00096       break;
00097    default:
00098       ast_log(LOG_WARNING, "unknown attribute type %d\n", key);
00099       return -1;
00100    }
00101    return 0;
00102 }
00103 
00104 static int celt_isset(const struct ast_format_attr *fattr, va_list ap)
00105 {
00106    enum celt_attr_keys key;
00107    const struct celt_attr *attr = (struct celt_attr *) fattr;
00108 
00109    for (key = va_arg(ap, int);
00110       key != AST_FORMAT_ATTR_END;
00111       key = va_arg(ap, int))
00112    {
00113       switch (key) {
00114       case CELT_ATTR_KEY_SAMP_RATE:
00115          if (attr->samplerate != (va_arg(ap, int))) {
00116             return -1;
00117          }
00118          break;
00119       case CELT_ATTR_KEY_MAX_BITRATE:
00120          if (attr->maxbitrate != (va_arg(ap, int))) {
00121             return -1;
00122          }
00123          break;
00124       case CELT_ATTR_KEY_FRAME_SIZE:
00125          if (attr->framesize != (va_arg(ap, int))) {
00126             return -1;
00127          }
00128          break;
00129       default:
00130          ast_log(LOG_WARNING, "unknown attribute type %d\n", key);
00131          return -1;
00132       }
00133    }
00134    return 0;
00135 }
00136 static int celt_getjoint(const struct ast_format_attr *fattr1, const struct ast_format_attr *fattr2, struct ast_format_attr *result)
00137 {
00138    struct celt_attr *attr1 = (struct celt_attr *) fattr1;
00139    struct celt_attr *attr2 = (struct celt_attr *) fattr2;
00140    struct celt_attr *attr_res = (struct celt_attr *) result;
00141 
00142    /* sample rate is the only attribute that has any bearing on if joint capabilities exist or not */
00143    if (attr1->samplerate != attr2->samplerate) {
00144       return -1;
00145    }
00146    /* either would work, they are guaranteed the same at this point. */
00147    attr_res->samplerate = attr1->samplerate;
00148    /* Take the lowest max bitrate */
00149    attr_res->maxbitrate = MIN(attr1->maxbitrate, attr2->maxbitrate);
00150 
00151    attr_res->framesize = attr2->framesize; /* TODO figure out what joint framesize means */
00152    return 0;
00153 }
00154 
00155 static void celt_set(struct ast_format_attr *fattr, va_list ap)
00156 {
00157    enum celt_attr_keys key;
00158    struct celt_attr *attr = (struct celt_attr *) fattr;
00159 
00160    for (key = va_arg(ap, int);
00161       key != AST_FORMAT_ATTR_END;
00162       key = va_arg(ap, int))
00163    {
00164       switch (key) {
00165       case CELT_ATTR_KEY_SAMP_RATE:
00166          attr->samplerate = (va_arg(ap, int));
00167          break;
00168       case CELT_ATTR_KEY_MAX_BITRATE:
00169          attr->maxbitrate = (va_arg(ap, int));
00170          break;
00171       case CELT_ATTR_KEY_FRAME_SIZE:
00172          attr->framesize = (va_arg(ap, int));
00173          break;
00174       default:
00175          ast_log(LOG_WARNING, "unknown attribute type %d\n", key);
00176       }
00177    }
00178 }
00179 
00180 static struct ast_format_attr_interface celt_interface = {
00181    .id = AST_FORMAT_CELT,
00182    .format_attr_cmp = celt_cmp,
00183    .format_attr_get_joint = celt_getjoint,
00184    .format_attr_set = celt_set,
00185    .format_attr_isset = celt_isset,
00186    .format_attr_get_val = celt_get_val,
00187    .format_attr_sdp_parse = celt_sdp_parse,
00188    .format_attr_sdp_generate = celt_sdp_generate,
00189 };
00190 
00191 static int load_module(void)
00192 {
00193    if (ast_format_attr_reg_interface(&celt_interface)) {
00194       return AST_MODULE_LOAD_DECLINE;
00195    }
00196 
00197    return AST_MODULE_LOAD_SUCCESS;
00198 }
00199 
00200 static int unload_module(void)
00201 {
00202    ast_format_attr_unreg_interface(&celt_interface);
00203    return 0;
00204 }
00205 
00206 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "CELT Format Attribute Module",
00207    .load = load_module,
00208    .unload = unload_module,
00209    .load_pri = AST_MODPRI_CHANNEL_DEPEND,
00210 );