00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
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
00039
00040
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 int silk_sdp_parse(struct ast_format_attr *format_attr, const char *attributes)
00051 {
00052 struct silk_attr *attr = (struct silk_attr *) format_attr;
00053 unsigned int val;
00054
00055 if (sscanf(attributes, "maxaveragebitrate=%30u", &val) == 1) {
00056 attr->maxbitrate = val;
00057 }
00058 if (sscanf(attributes, "usedtx=%30u", &val) == 1) {
00059 attr->dtx = val;
00060 }
00061 if (sscanf(attributes, "useinbandfec=%30u", &val) == 1) {
00062 attr->fec = val;
00063 }
00064
00065 return 0;
00066 }
00067
00068 static void silk_sdp_generate(const struct ast_format_attr *format_attr, unsigned int payload, struct ast_str **str)
00069 {
00070 struct silk_attr *attr = (struct silk_attr *) format_attr;
00071
00072 if ((attr->maxbitrate > 5000) && (attr->maxbitrate < 40000)) {
00073 ast_str_append(str, 0, "a=fmtp:%d maxaveragebitrate=%d\r\n", payload, attr->maxbitrate);
00074 }
00075
00076 ast_str_append(str, 0, "a=fmtp:%d usedtx=%d\r\n", payload, attr->dtx);
00077 ast_str_append(str, 0, "a=fmtp:%d useinbandfec=%d\r\n", payload, attr->fec);
00078 }
00079
00080 static enum ast_format_cmp_res silk_cmp(const struct ast_format_attr *fattr1, const struct ast_format_attr *fattr2)
00081 {
00082 struct silk_attr *attr1 = (struct silk_attr *) fattr1;
00083 struct silk_attr *attr2 = (struct silk_attr *) fattr2;
00084
00085 if (attr1->samplerate == attr2->samplerate) {
00086 return AST_FORMAT_CMP_EQUAL;
00087 }
00088 return AST_FORMAT_CMP_NOT_EQUAL;
00089 }
00090
00091 static int silk_get_val(const struct ast_format_attr *fattr, int key, void *result)
00092 {
00093 const struct silk_attr *attr = (struct silk_attr *) fattr;
00094 int *val = result;
00095
00096 switch (key) {
00097 case SILK_ATTR_KEY_SAMP_RATE:
00098 *val = attr->samplerate;
00099 break;
00100 case SILK_ATTR_KEY_MAX_BITRATE:
00101 *val = attr->maxbitrate;
00102 break;
00103 case SILK_ATTR_KEY_DTX:
00104 *val = attr->dtx;
00105 break;
00106 case SILK_ATTR_KEY_FEC:
00107 *val = attr->fec;
00108 break;
00109 case SILK_ATTR_KEY_PACKETLOSS_PERCENTAGE:
00110 *val = attr->packetloss_percentage;
00111 break;
00112 default:
00113 ast_log(LOG_WARNING, "unknown attribute type %d\n", key);
00114 return -1;
00115 }
00116 return 0;
00117 }
00118
00119 static int silk_isset(const struct ast_format_attr *fattr, va_list ap)
00120 {
00121 enum silk_attr_keys key;
00122 const struct silk_attr *attr = (struct silk_attr *) fattr;
00123
00124 for (key = va_arg(ap, int);
00125 key != AST_FORMAT_ATTR_END;
00126 key = va_arg(ap, int))
00127 {
00128 switch (key) {
00129 case SILK_ATTR_KEY_SAMP_RATE:
00130 if (attr->samplerate != (va_arg(ap, int))) {
00131 return -1;
00132 }
00133 break;
00134 case SILK_ATTR_KEY_MAX_BITRATE:
00135 if (attr->maxbitrate != (va_arg(ap, int))) {
00136 return -1;
00137 }
00138 break;
00139 case SILK_ATTR_KEY_DTX:
00140 if (attr->dtx != (va_arg(ap, int))) {
00141 return -1;
00142 }
00143 break;
00144 case SILK_ATTR_KEY_FEC:
00145 if (attr->fec != (va_arg(ap, int))) {
00146 return -1;
00147 }
00148 break;
00149 case SILK_ATTR_KEY_PACKETLOSS_PERCENTAGE:
00150 if (attr->packetloss_percentage != (va_arg(ap, int))) {
00151 return -1;
00152 }
00153 break;
00154 default:
00155 ast_log(LOG_WARNING, "unknown attribute type %d\n", key);
00156 return -1;
00157 }
00158 }
00159 return 0;
00160 }
00161 static int silk_getjoint(const struct ast_format_attr *fattr1, const struct ast_format_attr *fattr2, struct ast_format_attr *result)
00162 {
00163 struct silk_attr *attr1 = (struct silk_attr *) fattr1;
00164 struct silk_attr *attr2 = (struct silk_attr *) fattr2;
00165 struct silk_attr *attr_res = (struct silk_attr *) result;
00166 int joint = -1;
00167
00168 attr_res->samplerate = attr1->samplerate & attr2->samplerate;
00169
00170 if (attr_res->samplerate) {
00171 joint = 0;
00172 }
00173
00174 attr_res->maxbitrate = MIN(attr1->maxbitrate, attr2->maxbitrate);
00175
00176
00177
00178 attr_res->dtx = attr1->dtx && attr2->dtx ? 1 : 0;
00179
00180
00181
00182 attr_res->fec = attr1->fec && attr2->fec ? 1 : 0;
00183
00184
00185
00186 attr_res->packetloss_percentage = MAX(attr1->packetloss_percentage, attr2->packetloss_percentage);
00187 return joint;
00188 }
00189
00190 static void silk_set(struct ast_format_attr *fattr, va_list ap)
00191 {
00192 enum silk_attr_keys key;
00193 struct silk_attr *attr = (struct silk_attr *) fattr;
00194
00195 for (key = va_arg(ap, int);
00196 key != AST_FORMAT_ATTR_END;
00197 key = va_arg(ap, int))
00198 {
00199 switch (key) {
00200 case SILK_ATTR_KEY_SAMP_RATE:
00201 attr->samplerate = (va_arg(ap, int));
00202 break;
00203 case SILK_ATTR_KEY_MAX_BITRATE:
00204 attr->maxbitrate = (va_arg(ap, int));
00205 break;
00206 case SILK_ATTR_KEY_DTX:
00207 attr->dtx = (va_arg(ap, int));
00208 break;
00209 case SILK_ATTR_KEY_FEC:
00210 attr->fec = (va_arg(ap, int));
00211 break;
00212 case SILK_ATTR_KEY_PACKETLOSS_PERCENTAGE:
00213 attr->packetloss_percentage = (va_arg(ap, int));
00214 break;
00215 default:
00216 ast_log(LOG_WARNING, "unknown attribute type %d\n", key);
00217 }
00218 }
00219 }
00220
00221 static struct ast_format_attr_interface silk_interface = {
00222 .id = AST_FORMAT_SILK,
00223 .format_attr_cmp = silk_cmp,
00224 .format_attr_get_joint = silk_getjoint,
00225 .format_attr_set = silk_set,
00226 .format_attr_isset = silk_isset,
00227 .format_attr_get_val = silk_get_val,
00228 .format_attr_sdp_parse = silk_sdp_parse,
00229 .format_attr_sdp_generate = silk_sdp_generate,
00230 };
00231
00232 static int load_module(void)
00233 {
00234 if (ast_format_attr_reg_interface(&silk_interface)) {
00235 return AST_MODULE_LOAD_DECLINE;
00236 }
00237
00238 return AST_MODULE_LOAD_SUCCESS;
00239 }
00240
00241 static int unload_module(void)
00242 {
00243 ast_format_attr_unreg_interface(&silk_interface);
00244 return 0;
00245 }
00246
00247 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "SILK Format Attribute Module",
00248 .load = load_module,
00249 .unload = unload_module,
00250 .load_pri = AST_MODPRI_CHANNEL_DEPEND,
00251 );