mirror of
https://github.com/asterisk/asterisk.git
synced 2025-10-13 16:21:01 +00:00
Merged revisions 11062,11089 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.2 ........ r11062 | kpfleming | 2006-02-24 22:59:50 -0600 (Fri, 24 Feb 2006) | 3 lines reformat code to fit guidelines remember which translation paths are multi-step paths ........ r11089 | kpfleming | 2006-02-24 23:08:46 -0600 (Fri, 24 Feb 2006) | 2 lines factor the number of translation steps required into translation path decisions, so that equal cost paths that require fewer translations are preferred ........ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@11090 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
110
translate.c
110
translate.c
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Asterisk -- An open source telephony toolkit.
|
* Asterisk -- An open source telephony toolkit.
|
||||||
*
|
*
|
||||||
* Copyright (C) 1999 - 2005, Digium, Inc.
|
* Copyright (C) 1999 - 2006, Digium, Inc.
|
||||||
*
|
*
|
||||||
* Mark Spencer <markster@digium.com>
|
* Mark Spencer <markster@digium.com>
|
||||||
*
|
*
|
||||||
@@ -55,7 +55,8 @@ static AST_LIST_HEAD_STATIC(translators, ast_translator);
|
|||||||
|
|
||||||
struct ast_translator_dir {
|
struct ast_translator_dir {
|
||||||
struct ast_translator *step; /*!< Next step translator */
|
struct ast_translator *step; /*!< Next step translator */
|
||||||
int cost; /*!< Complete cost to destination */
|
unsigned int cost; /*!< Complete cost to destination */
|
||||||
|
unsigned int multistep; /*!< Multiple conversions required for this translation */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ast_frame_delivery {
|
struct ast_frame_delivery {
|
||||||
@@ -275,55 +276,63 @@ static void rebuild_matrix(int samples)
|
|||||||
{
|
{
|
||||||
struct ast_translator *t;
|
struct ast_translator *t;
|
||||||
int changed;
|
int changed;
|
||||||
int x,y,z;
|
int x, y, z;
|
||||||
|
|
||||||
if (option_debug)
|
if (option_debug)
|
||||||
ast_log(LOG_DEBUG, "Resetting translation matrix\n");
|
ast_log(LOG_DEBUG, "Resetting translation matrix\n");
|
||||||
|
|
||||||
bzero(tr_matrix, sizeof(tr_matrix));
|
bzero(tr_matrix, sizeof(tr_matrix));
|
||||||
|
|
||||||
AST_LIST_TRAVERSE(&translators, t, list) {
|
AST_LIST_TRAVERSE(&translators, t, list) {
|
||||||
if(samples)
|
if (samples)
|
||||||
calc_cost(t, samples);
|
calc_cost(t, samples);
|
||||||
|
|
||||||
if (!tr_matrix[t->srcfmt][t->dstfmt].step ||
|
if (!tr_matrix[t->srcfmt][t->dstfmt].step ||
|
||||||
tr_matrix[t->srcfmt][t->dstfmt].cost > t->cost) {
|
tr_matrix[t->srcfmt][t->dstfmt].cost > t->cost) {
|
||||||
tr_matrix[t->srcfmt][t->dstfmt].step = t;
|
tr_matrix[t->srcfmt][t->dstfmt].step = t;
|
||||||
tr_matrix[t->srcfmt][t->dstfmt].cost = t->cost;
|
tr_matrix[t->srcfmt][t->dstfmt].cost = t->cost;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
changed = 0;
|
changed = 0;
|
||||||
|
|
||||||
/* Don't you just love O(N^3) operations? */
|
/* Don't you just love O(N^3) operations? */
|
||||||
for (x=0; x< MAX_FORMAT; x++) /* For each source format */
|
for (x = 0; x< MAX_FORMAT; x++) { /* For each source format */
|
||||||
for (y=0; y < MAX_FORMAT; y++) /* And each destination format */
|
for (y = 0; y < MAX_FORMAT; y++) { /* And each destination format */
|
||||||
if (x != y) /* Except ourselves, of course */
|
if (x == y) /* Except ourselves, of course */
|
||||||
for (z=0; z < MAX_FORMAT; z++) /* And each format it might convert to */
|
continue;
|
||||||
if ((x!=z) && (y!=z)) /* Don't ever convert back to us */
|
|
||||||
if (tr_matrix[x][y].step && /* We can convert from x to y */
|
for (z=0; z < MAX_FORMAT; z++) { /* And each format it might convert to */
|
||||||
tr_matrix[y][z].step && /* And from y to z and... */
|
if ((x == z) || (y == z)) /* Don't ever convert back to us */
|
||||||
(!tr_matrix[x][z].step || /* Either there isn't an x->z conversion */
|
continue;
|
||||||
(tr_matrix[x][y].cost +
|
|
||||||
tr_matrix[y][z].cost < /* Or we're cheaper than the existing */
|
if (tr_matrix[x][y].step && /* We can convert from x to y */
|
||||||
tr_matrix[x][z].cost) /* solution */
|
tr_matrix[y][z].step && /* And from y to z and... */
|
||||||
)) {
|
(!tr_matrix[x][z].step || /* Either there isn't an x->z conversion */
|
||||||
/* We can get from x to z via y with a cost that
|
(tr_matrix[x][y].cost +
|
||||||
is the sum of the transition from x to y and
|
tr_matrix[y][z].cost < /* Or we're cheaper than the existing */
|
||||||
from y to z */
|
tr_matrix[x][z].cost) /* solution */
|
||||||
|
)) {
|
||||||
tr_matrix[x][z].step = tr_matrix[x][y].step;
|
/* We can get from x to z via y with a cost that
|
||||||
tr_matrix[x][z].cost = tr_matrix[x][y].cost +
|
is the sum of the transition from x to y and
|
||||||
tr_matrix[y][z].cost;
|
from y to z */
|
||||||
if (option_debug)
|
|
||||||
ast_log(LOG_DEBUG, "Discovered %d cost path from %s to %s, via %d\n", tr_matrix[x][z].cost, ast_getformatname(x), ast_getformatname(z), y);
|
tr_matrix[x][z].step = tr_matrix[x][y].step;
|
||||||
changed++;
|
tr_matrix[x][z].cost = tr_matrix[x][y].cost +
|
||||||
}
|
tr_matrix[y][z].cost;
|
||||||
|
tr_matrix[x][z].multistep = 1;
|
||||||
|
if (option_debug)
|
||||||
|
ast_log(LOG_DEBUG, "Discovered %d cost path from %s to %s, via %d\n", tr_matrix[x][z].cost, ast_getformatname(x), ast_getformatname(z), y);
|
||||||
|
changed++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} while (changed);
|
} while (changed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*! \brief CLI "show translation" command handler */
|
/*! \brief CLI "show translation" command handler */
|
||||||
static int show_translation(int fd, int argc, char *argv[])
|
static int show_translation(int fd, int argc, char *argv[])
|
||||||
{
|
{
|
||||||
@@ -444,14 +453,14 @@ int ast_translator_best_choice(int *dst, int *srcs)
|
|||||||
int bestdst = 0;
|
int bestdst = 0;
|
||||||
int cur = 1;
|
int cur = 1;
|
||||||
int besttime = INT_MAX;
|
int besttime = INT_MAX;
|
||||||
|
int beststeps = INT_MAX;
|
||||||
int common;
|
int common;
|
||||||
|
|
||||||
if ((common = (*dst) & (*srcs))) {
|
if ((common = (*dst) & (*srcs))) {
|
||||||
/* We have a format in common */
|
/* We have a format in common */
|
||||||
for (y=0; y < MAX_FORMAT; y++) {
|
for (y = 0; y < MAX_FORMAT; y++) {
|
||||||
if (cur & common) {
|
if (cur & common) {
|
||||||
/* This is a common format to both. Pick it if we don't have one already */
|
/* This is a common format to both. Pick it if we don't have one already */
|
||||||
besttime = 0;
|
|
||||||
bestdst = cur;
|
bestdst = cur;
|
||||||
best = cur;
|
best = cur;
|
||||||
}
|
}
|
||||||
@@ -460,25 +469,38 @@ int ast_translator_best_choice(int *dst, int *srcs)
|
|||||||
} else {
|
} else {
|
||||||
/* We will need to translate */
|
/* We will need to translate */
|
||||||
AST_LIST_LOCK(&translators);
|
AST_LIST_LOCK(&translators);
|
||||||
for (y=0; y < MAX_FORMAT; y++) {
|
for (y = 0; y < MAX_FORMAT; y++) {
|
||||||
if (cur & *dst)
|
if (!(cur & *dst))
|
||||||
for (x=0; x < MAX_FORMAT; x++) {
|
continue;
|
||||||
if ((*srcs & (1 << x)) && /* x is a valid source format */
|
|
||||||
tr_matrix[x][y].step && /* There's a step */
|
for (x = 0; x < MAX_FORMAT; x++) {
|
||||||
(tr_matrix[x][y].cost < besttime)) { /* It's better than what we have so far */
|
if ((*srcs & (1 << x)) && /* x is a valid source format */
|
||||||
best = 1 << x;
|
tr_matrix[x][y].step) { /* There's a step */
|
||||||
bestdst = cur;
|
if (tr_matrix[x][y].cost > besttime)
|
||||||
besttime = tr_matrix[x][y].cost;
|
continue; /* It's more expensive, skip it */
|
||||||
}
|
|
||||||
|
if (tr_matrix[x][y].cost == besttime &&
|
||||||
|
tr_matrix[x][y].multistep >= beststeps)
|
||||||
|
continue; /* It requires the same (or more) steps,
|
||||||
|
skip it */
|
||||||
|
|
||||||
|
/* It's better than what we have so far */
|
||||||
|
best = 1 << x;
|
||||||
|
bestdst = cur;
|
||||||
|
besttime = tr_matrix[x][y].cost;
|
||||||
|
beststeps = tr_matrix[x][y].multistep;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
cur = cur << 1;
|
cur = cur << 1;
|
||||||
}
|
}
|
||||||
AST_LIST_UNLOCK(&translators);
|
AST_LIST_UNLOCK(&translators);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (best > -1) {
|
if (best > -1) {
|
||||||
*srcs = best;
|
*srcs = best;
|
||||||
*dst = bestdst;
|
*dst = bestdst;
|
||||||
best = 0;
|
best = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return best;
|
return best;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user