Ensure that trans_size is correct to prevent uninitialized entries from preventing reload. (closes issue ASTERISK-21401) Reported by: Corey Farrell Tested by: Corey Farrell Patches: codec_resample-unload.patch uploaded by Corey Farrell ........ Merged revisions 385582 from http://svn.asterisk.org/svn/asterisk/branches/11 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@385585 65c4cc65-6c06-0410-ace0-fbb531ad65f3
152 lines
3.6 KiB
C
152 lines
3.6 KiB
C
/*
|
|
* Asterisk -- An open source telephony toolkit.
|
|
*
|
|
* Copyright (C) 2011, Digium, Inc.
|
|
*
|
|
* Russell Bryant <russell@digium.com>
|
|
* David Vossel <dvossel@digium.com>
|
|
*
|
|
* See http://www.asterisk.org for more information about
|
|
* the Asterisk project. Please do not directly contact
|
|
* any of the maintainers of this project for assistance;
|
|
* the project provides a web site, mailing lists and IRC
|
|
* channels for your use.
|
|
*
|
|
* This program is free software, distributed under the terms of
|
|
* the GNU General Public License Version 2. See the LICENSE file
|
|
* at the top of the source tree.
|
|
*/
|
|
|
|
/*!
|
|
* \file
|
|
*
|
|
* \brief Resample slinear audio
|
|
*
|
|
* \ingroup codecs
|
|
*/
|
|
|
|
/*** MODULEINFO
|
|
<support_level>core</support_level>
|
|
***/
|
|
|
|
#include "asterisk.h"
|
|
#include "speex/speex_resampler.h"
|
|
|
|
ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
|
|
|
|
#include "asterisk/module.h"
|
|
#include "asterisk/translate.h"
|
|
#include "asterisk/slin.h"
|
|
|
|
#define OUTBUF_SIZE 8096
|
|
|
|
static struct ast_translator *translators;
|
|
static int trans_size;
|
|
static int id_list[] = {
|
|
AST_FORMAT_SLINEAR,
|
|
AST_FORMAT_SLINEAR12,
|
|
AST_FORMAT_SLINEAR16,
|
|
AST_FORMAT_SLINEAR24,
|
|
AST_FORMAT_SLINEAR32,
|
|
AST_FORMAT_SLINEAR44,
|
|
AST_FORMAT_SLINEAR48,
|
|
AST_FORMAT_SLINEAR96,
|
|
AST_FORMAT_SLINEAR192,
|
|
};
|
|
|
|
static int resamp_new(struct ast_trans_pvt *pvt)
|
|
{
|
|
int err;
|
|
|
|
if (!(pvt->pvt = speex_resampler_init(1, ast_format_rate(&pvt->t->src_format), ast_format_rate(&pvt->t->dst_format), 5, &err))) {
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void resamp_destroy(struct ast_trans_pvt *pvt)
|
|
{
|
|
SpeexResamplerState *resamp_pvt = pvt->pvt;
|
|
speex_resampler_destroy(resamp_pvt);
|
|
}
|
|
|
|
static int resamp_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
|
|
{
|
|
SpeexResamplerState *resamp_pvt = pvt->pvt;
|
|
unsigned int out_samples = (OUTBUF_SIZE / sizeof(int16_t)) - pvt->samples;
|
|
unsigned int in_samples;
|
|
|
|
if (!f->datalen) {
|
|
return -1;
|
|
}
|
|
in_samples = f->datalen / 2;
|
|
|
|
speex_resampler_process_int(resamp_pvt,
|
|
0,
|
|
f->data.ptr,
|
|
&in_samples,
|
|
pvt->outbuf.i16 + pvt->samples,
|
|
&out_samples);
|
|
|
|
pvt->samples += out_samples;
|
|
pvt->datalen += out_samples * 2;
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int unload_module(void)
|
|
{
|
|
int res = 0;
|
|
int idx;
|
|
|
|
for (idx = 0; idx < trans_size; idx++) {
|
|
res |= ast_unregister_translator(&translators[idx]);
|
|
}
|
|
ast_free(translators);
|
|
|
|
return res;
|
|
}
|
|
|
|
static int load_module(void)
|
|
{
|
|
int res = 0;
|
|
int x, y, idx = 0;
|
|
|
|
trans_size = ARRAY_LEN(id_list) * (ARRAY_LEN(id_list) - 1);
|
|
if (!(translators = ast_calloc(1, sizeof(struct ast_translator) * trans_size))) {
|
|
return AST_MODULE_LOAD_FAILURE;
|
|
}
|
|
|
|
for (x = 0; x < ARRAY_LEN(id_list); x++) {
|
|
for (y = 0; y < ARRAY_LEN(id_list); y++) {
|
|
if (x == y) {
|
|
continue;
|
|
}
|
|
translators[idx].newpvt = resamp_new;
|
|
translators[idx].destroy = resamp_destroy;
|
|
translators[idx].framein = resamp_framein;
|
|
translators[idx].desc_size = 0;
|
|
translators[idx].buffer_samples = (OUTBUF_SIZE / sizeof(int16_t));
|
|
translators[idx].buf_size = OUTBUF_SIZE;
|
|
ast_format_set(&translators[idx].src_format, id_list[x], 0);
|
|
ast_format_set(&translators[idx].dst_format, id_list[y], 0);
|
|
snprintf(translators[idx].name, sizeof(translators[idx].name), "slin %dkhz -> %dkhz",
|
|
ast_format_rate(&translators[idx].src_format), ast_format_rate(&translators[idx].dst_format));
|
|
res |= ast_register_translator(&translators[idx]);
|
|
idx++;
|
|
}
|
|
|
|
}
|
|
/* in case ast_register_translator() failed, we call unload_module() and
|
|
ast_unregister_translator won't fail.*/
|
|
if (res) {
|
|
unload_module();
|
|
return AST_MODULE_LOAD_FAILURE;
|
|
}
|
|
|
|
return AST_MODULE_LOAD_SUCCESS;
|
|
}
|
|
|
|
AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "SLIN Resampling Codec");
|