summaryrefslogtreecommitdiff
path: root/main/translate.c
diff options
context:
space:
mode:
authorDavid Vossel <dvossel@digium.com>2011-02-22 23:04:49 +0000
committerDavid Vossel <dvossel@digium.com>2011-02-22 23:04:49 +0000
commitd760e81f37b231a99865a40f67838c51079ed4f8 (patch)
treeb061487de973558358757bd1b6e457aaccf41638 /main/translate.c
parent736133f874f270be81810c2c1fb36c47e6a479bf (diff)
Media Project Phase2: SILK 8khz-24khz, SLINEAR 8khz-192khz, SPEEX 32khz, hd audio ConfBridge, and other stuff
-Functional changes 1. Dynamic global format list build by codecs defined in codecs.conf 2. SILK 8khz, 12khz, 16khz, and 24khz with custom attributes defined in codecs.conf 3. Negotiation of SILK attributes in chan_sip. 4. SPEEX 32khz with translation 5. SLINEAR 8khz, 12khz, 24khz, 32khz, 44.1khz, 48khz, 96khz, 192khz with translation using codec_resample.c 6. Various changes to RTP code required to properly handle the dynamic format list and formats with attributes. 7. ConfBridge now dynamically jumps to the best possible sample rate. This allows for conferences to take advantage of HD audio (Which sounds awesome) 8. Audiohooks are no longer limited to 8khz audio, and most effects have been updated to take advantage of this such as Volume, DENOISE, PITCH_SHIFT. 9. codec_resample now uses its own code rather than depending on libresample. -Organizational changes Global format list is moved from frame.c to format.c Various format specific functions moved from frame.c to format.c Review: https://reviewboard.asterisk.org/r/1104/ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@308582 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'main/translate.c')
-rw-r--r--main/translate.c120
1 files changed, 71 insertions, 49 deletions
diff --git a/main/translate.c b/main/translate.c
index 553e70cde..caba2d393 100644
--- a/main/translate.c
+++ b/main/translate.c
@@ -273,7 +273,7 @@ static struct translator_path *matrix_get(unsigned int x, unsigned int y)
* \brief Allocate the descriptor, required outbuf space,
* and possibly desc.
*/
-static void *newpvt(struct ast_translator *t)
+static void *newpvt(struct ast_translator *t, const struct ast_format *explicit_dst)
{
struct ast_trans_pvt *pvt;
int len;
@@ -287,16 +287,23 @@ static void *newpvt(struct ast_translator *t)
if (t->buf_size)
len += AST_FRIENDLY_OFFSET + t->buf_size;
pvt = ast_calloc(1, len);
- if (!pvt)
+ if (!pvt) {
return NULL;
+ }
pvt->t = t;
ofs = (char *)(pvt + 1); /* pointer to data space */
if (t->desc_size) { /* first comes the descriptor */
pvt->pvt = ofs;
ofs += t->desc_size;
}
- if (t->buf_size) /* finally buffer and header */
+ if (t->buf_size) {/* finally buffer and header */
pvt->outbuf.c = ofs + AST_FRIENDLY_OFFSET;
+ }
+ /* if a explicit destination format is provided, set that on the pvt so the
+ * translator will process it. */
+ if (explicit_dst) {
+ ast_format_copy(&pvt->explicit_dst, explicit_dst);
+ }
/* call local init routine, if present */
if (t->newpvt && t->newpvt(pvt)) {
ast_free(pvt);
@@ -424,6 +431,7 @@ struct ast_trans_pvt *ast_translator_build_path(struct ast_format *dst, struct a
while (src_index != dst_index) {
struct ast_trans_pvt *cur;
+ struct ast_format *explicit_dst = NULL;
struct ast_translator *t = matrix_get(src_index, dst_index)->step;
if (!t) {
int src_id = index2format(src_index);
@@ -434,7 +442,10 @@ struct ast_trans_pvt *ast_translator_build_path(struct ast_format *dst, struct a
AST_RWLIST_UNLOCK(&translators);
return NULL;
}
- if (!(cur = newpvt(t))) {
+ if (dst_index == t->dst_fmt_index) {
+ explicit_dst = dst;
+ }
+ if (!(cur = newpvt(t, explicit_dst))) {
int src_id = index2format(src_index);
int dst_id = index2format(dst_index);
ast_log(LOG_WARNING, "Failed to build translator step from %s to %s\n",
@@ -565,12 +576,12 @@ static void generate_computational_cost(struct ast_translator *t, int seconds)
/* If they don't make samples, give them a terrible score */
if (!t->sample) {
- ast_log(LOG_WARNING, "Translator '%s' does not produce sample frames.\n", t->name);
+ ast_debug(3, "Translator '%s' does not produce sample frames.\n", t->name);
t->comp_cost = 999999;
return;
}
- pvt = newpvt(t);
+ pvt = newpvt(t, NULL);
if (!pvt) {
ast_log(LOG_WARNING, "Translator '%s' appears to be broken and will probably fail.\n", t->name);
t->comp_cost = 999999;
@@ -641,13 +652,8 @@ static int generate_table_cost(struct ast_format *src, struct ast_format *dst)
* table cost. */
return 0;
}
- if ((src->id == AST_FORMAT_SLINEAR) || (src->id == AST_FORMAT_SLINEAR16)) {
- src_ll = 1;
- }
- if ((dst->id == AST_FORMAT_SLINEAR) || (dst->id == AST_FORMAT_SLINEAR16)) {
- dst_ll = 1;
- }
-
+ src_ll = ast_format_is_slinear(src);
+ dst_ll = ast_format_is_slinear(dst);
if (src_ll) {
if (dst_ll && (src_rate == dst_rate)) {
return AST_TRANS_COST_LL_LL_ORIGSAMP;
@@ -778,16 +784,17 @@ static void matrix_rebuild(int samples)
const char *ast_translate_path_to_str(struct ast_trans_pvt *p, struct ast_str **str)
{
struct ast_trans_pvt *pn = p;
+ char tmp[256];
if (!p || !p->t) {
return "";
}
- ast_str_set(str, 0, "%s", ast_getformatname(&p->t->src_format));
+ ast_str_set(str, 0, "%s", ast_getformatname_multiple_byid(tmp, sizeof(tmp), p->t->src_format.id));
while ( (p = pn) ) {
pn = p->next;
- ast_str_append(str, 0, "->%s", ast_getformatname(&p->t->dst_format));
+ ast_str_append(str, 0, "->%s", ast_getformatname_multiple_byid(tmp, sizeof(tmp), p->t->dst_format.id));
}
return ast_str_buffer(*str);
@@ -800,10 +807,10 @@ static char *complete_trans_path_choice(const char *line, const char *word, int
int i;
char *ret = NULL;
size_t len = 0;
- const struct ast_format_list *format_list = ast_get_format_list(&len);
+ const struct ast_format_list *format_list = ast_format_list_get(&len);
for (i = 0; i < len; i++) {
- if (AST_FORMAT_GET_TYPE(format_list[i].id) != AST_FORMAT_TYPE_AUDIO) {
+ if (AST_FORMAT_GET_TYPE(format_list[i].format.id) != AST_FORMAT_TYPE_AUDIO) {
continue;
}
if (!strncasecmp(word, format_list[i].name, wordlen) && ++which > state) {
@@ -811,6 +818,7 @@ static char *complete_trans_path_choice(const char *line, const char *word, int
break;
}
}
+ ast_format_list_destroy(format_list);
return ret;
}
@@ -835,46 +843,56 @@ static void handle_cli_recalc(struct ast_cli_args *a)
static char *handle_show_translation_table(struct ast_cli_args *a)
{
- int x, y;
+ int x, y, i, k;
int curlen = 0, longest = 0;
- struct ast_format tmp_fmt;
+ int f_len = 0;
+ const struct ast_format_list *f_list = ast_format_list_get((size_t *) &f_len);
+ struct ast_str *out = ast_str_create(1024);
+
AST_RWLIST_RDLOCK(&translators);
ast_cli(a->fd, " Translation times between formats (in microseconds) for one second of data\n");
ast_cli(a->fd, " Source Format (Rows) Destination Format (Columns)\n\n");
/* Get the length of the longest (usable?) codec name, so we know how wide the left side should be */
- for (x = 0; x < cur_max_index; x++) {
+ for (i = 0; i < f_len; i++) {
/* translation only applies to audio right now. */
- if (AST_FORMAT_GET_TYPE(index2format(x)) != AST_FORMAT_TYPE_AUDIO)
+ if (AST_FORMAT_GET_TYPE(f_list[i].format.id) != AST_FORMAT_TYPE_AUDIO)
continue;
- curlen = strlen(ast_getformatname(ast_format_set(&tmp_fmt, index2format(x), 0)));
+ curlen = strlen(ast_getformatname(&f_list[i].format));
if (curlen > longest) {
longest = curlen;
}
}
- for (x = -1; x < cur_max_index; x++) {
- struct ast_str *out = ast_str_alloca(256);
+ for (i = -1; i < f_len; i++) {
+ x = -1;
+ if ((i >= 0) && ((x = format2index(f_list[i].format.id)) == -1)) {
+ continue;
+ }
/* translation only applies to audio right now. */
- if (x >= 0 && (AST_FORMAT_GET_TYPE(index2format(x)) != AST_FORMAT_TYPE_AUDIO)) {
+ if (i >= 0 && (AST_FORMAT_GET_TYPE(f_list[i].format.id) != AST_FORMAT_TYPE_AUDIO)) {
continue;
}
/*Go ahead and move to next iteration if dealing with an unknown codec*/
- if (x >= 0 && !strcmp(ast_getformatname(ast_format_set(&tmp_fmt, index2format(x), 0)), "unknown")) {
+ if (i >= 0 && !strcmp(ast_getformatname(&f_list[i].format), "unknown")) {
continue;
}
- ast_str_set(&out, -1, " ");
- for (y = -1; y < cur_max_index; y++) {
+ ast_str_set(&out, 0, " ");
+ for (k = -1; k < f_len; k++) {
+ y = -1;
+ if ((k >= 0) && ((y = format2index(f_list[k].format.id)) == -1)) {
+ continue;
+ }
/* translation only applies to audio right now. */
- if (y >= 0 && (AST_FORMAT_GET_TYPE(index2format(y)) != AST_FORMAT_TYPE_AUDIO)) {
+ if (k >= 0 && (AST_FORMAT_GET_TYPE(f_list[k].format.id) != AST_FORMAT_TYPE_AUDIO)) {
continue;
}
/*Go ahead and move to next iteration if dealing with an unknown codec*/
- if (y >= 0 && !strcmp(ast_getformatname(ast_format_set(&tmp_fmt, index2format(y), 0)), "unknown")) {
+ if (k >= 0 && !strcmp(ast_getformatname(&f_list[k].format), "unknown")) {
continue;
}
- if (y >= 0) {
- curlen = strlen(ast_getformatname(ast_format_set(&tmp_fmt, index2format(y), 0)));
+ if (k >= 0) {
+ curlen = strlen(ast_getformatname(&f_list[k].format));
}
if (curlen < 5) {
curlen = 5;
@@ -882,25 +900,27 @@ static char *handle_show_translation_table(struct ast_cli_args *a)
if (x >= 0 && y >= 0 && matrix_get(x, y)->step) {
/* Actual codec output */
- ast_str_append(&out, -1, "%*d", curlen + 1, (matrix_get(x, y)->table_cost/100));
- } else if (x == -1 && y >= 0) {
+ ast_str_append(&out, 0, "%*d", curlen + 1, (matrix_get(x, y)->table_cost/100));
+ } else if (i == -1 && k >= 0) {
/* Top row - use a dynamic size */
- ast_str_append(&out, -1, "%*s", curlen + 1, ast_getformatname(ast_format_set(&tmp_fmt, index2format(y), 0)));
- } else if (y == -1 && x >= 0) {
+ ast_str_append(&out, 0, "%*s", curlen + 1, ast_getformatname(&f_list[k].format));
+ } else if (k == -1 && i >= 0) {
/* Left column - use a static size. */
- ast_str_append(&out, -1, "%*s", longest, ast_getformatname(ast_format_set(&tmp_fmt, index2format(x), 0)));
+ ast_str_append(&out, 0, "%*s", longest, ast_getformatname(&f_list[i].format));
} else if (x >= 0 && y >= 0) {
/* Codec not supported */
- ast_str_append(&out, -1, "%*s", curlen + 1, "-");
+ ast_str_append(&out, 0, "%*s", curlen + 1, "-");
} else {
/* Upper left hand corner */
- ast_str_append(&out, -1, "%*s", longest, "");
+ ast_str_append(&out, 0, "%*s", longest, "");
}
}
- ast_str_append(&out, -1, "\n");
+ ast_str_append(&out, 0, "\n");
ast_cli(a->fd, "%s", ast_str_buffer(out));
}
+ ast_free(out);
AST_RWLIST_UNLOCK(&translators);
+ ast_format_list_destroy(f_list);
return CLI_SUCCESS;
}
@@ -909,23 +929,24 @@ static char *handle_show_translation_path(struct ast_cli_args *a)
struct ast_format input_src_format;
size_t len = 0;
int i;
- const struct ast_format_list *format_list = ast_get_format_list(&len);
- struct ast_str *str = ast_str_alloca(256);
+ const struct ast_format_list *format_list = ast_format_list_get(&len);
+ struct ast_str *str = ast_str_alloca(1024);
struct ast_translator *step;
+ char tmp[256];
ast_format_clear(&input_src_format);
-
for (i = 0; i < len; i++) {
- if (AST_FORMAT_GET_TYPE(format_list[i].id) != AST_FORMAT_TYPE_AUDIO) {
+ if (AST_FORMAT_GET_TYPE(format_list[i].format.id) != AST_FORMAT_TYPE_AUDIO) {
continue;
}
if (!strncasecmp(format_list[i].name, a->argv[4], strlen(format_list[i].name))) {
- ast_format_set(&input_src_format, format_list[i].id, 0);
+ ast_format_copy(&input_src_format, &format_list[i].format);
}
}
if (!input_src_format.id) {
ast_cli(a->fd, "Source codec \"%s\" is not found.\n", a->argv[4]);
+ ast_format_list_destroy(format_list);
return CLI_FAILURE;
}
@@ -934,21 +955,21 @@ static char *handle_show_translation_path(struct ast_cli_args *a)
for (i = 0; i < len; i++) {
int src;
int dst;
- if ((AST_FORMAT_GET_TYPE(format_list[i].id) != AST_FORMAT_TYPE_AUDIO) || (format_list[i].id == input_src_format.id)) {
+ if ((AST_FORMAT_GET_TYPE(format_list[i].format.id) != AST_FORMAT_TYPE_AUDIO) || (format_list[i].format.id == input_src_format.id)) {
continue;
}
- dst = format2index(format_list[i].id);
+ dst = format2index(format_list[i].format.id);
src = format2index(input_src_format.id);
ast_str_reset(str);
if ((len >= cur_max_index) && (src != -1) && (dst != -1) && matrix_get(src, dst)->step) {
- ast_str_append(&str, 0, "%s", ast_getformatname(&matrix_get(src, dst)->step->src_format));
+ ast_str_append(&str, 0, "%s", ast_getformatname_multiple_byid(tmp, sizeof(tmp), matrix_get(src, dst)->step->src_format.id));
while (src != dst) {
step = matrix_get(src, dst)->step;
if (!step) {
ast_str_reset(str);
break;
}
- ast_str_append(&str, 0, "->%s", ast_getformatname(&step->dst_format));
+ ast_str_append(&str, 0, "->%s", ast_getformatname_multiple_byid(tmp, sizeof(tmp), step->dst_format.id));
src = step->dst_fmt_index;
}
}
@@ -960,6 +981,7 @@ static char *handle_show_translation_path(struct ast_cli_args *a)
}
AST_RWLIST_UNLOCK(&translators);
+ ast_format_list_destroy(format_list);
return CLI_SUCCESS;
}