Skip to content
Snippets Groups Projects
Commit a80bce7e authored by Mark Spencer's avatar Mark Spencer
Browse files

Allow translation table to be recalculated, including with higher resolution

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@2996 65c4cc65-6c06-0410-ace0-fbb531ad65f3
parent 4b56cf02
No related merge requests found
......@@ -29,6 +29,8 @@
#include <string.h>
#include <stdio.h>
#define MAX_RECALC 200 /* max sample recalc */
/* This could all be done more efficiently *IF* we chained packets together
by default, but it would also complicate virtually every application. */
......@@ -219,7 +221,55 @@ struct ast_frame *ast_translate(struct ast_trans_pvt *path, struct ast_frame *f,
return NULL;
}
static void rebuild_matrix(void)
static void calc_cost(struct ast_translator *t,int samples)
{
int sofar=0;
struct ast_translator_pvt *pvt;
struct ast_frame *f, *out;
struct timeval start, finish;
int cost;
if(!samples)
samples = 1;
/* 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);
t->cost = 99999;
return;
}
pvt = t->new();
if (!pvt) {
ast_log(LOG_WARNING, "Translator '%s' appears to be broken and will probably fail.\n", t->name);
t->cost = 99999;
return;
}
gettimeofday(&start, NULL);
/* Call the encoder until we've processed one second of time */
while(sofar < samples * 8000) {
f = t->sample();
if (!f) {
ast_log(LOG_WARNING, "Translator '%s' failed to produce a sample frame.\n", t->name);
t->destroy(pvt);
t->cost = 99999;
return;
}
t->framein(pvt, f);
ast_frfree(f);
while((out = t->frameout(pvt))) {
sofar += out->samples;
ast_frfree(out);
}
}
gettimeofday(&finish, NULL);
t->destroy(pvt);
cost = (finish.tv_sec - start.tv_sec) * 1000 + (finish.tv_usec - start.tv_usec) / 1000;
t->cost = cost / samples;
if (!t->cost)
t->cost = 1;
}
static void rebuild_matrix(int samples)
{
struct ast_translator *t;
int changed;
......@@ -230,6 +280,9 @@ static void rebuild_matrix(void)
bzero(tr_matrix, sizeof(tr_matrix));
t = list;
while(t) {
if(samples)
calc_cost(t,samples);
if (!tr_matrix[t->srcfmt][t->dstfmt].step ||
tr_matrix[t->srcfmt][t->dstfmt].cost > t->cost) {
tr_matrix[t->srcfmt][t->dstfmt].step = t;
......@@ -267,57 +320,35 @@ static void rebuild_matrix(void)
} while (changed);
}
static void calc_cost(struct ast_translator *t)
{
int sofar=0;
struct ast_translator_pvt *pvt;
struct ast_frame *f, *out;
struct timeval start, finish;
int cost;
/* 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);
t->cost = 99999;
return;
}
pvt = t->new();
if (!pvt) {
ast_log(LOG_WARNING, "Translator '%s' appears to be broken and will probably fail.\n", t->name);
t->cost = 99999;
return;
}
gettimeofday(&start, NULL);
/* Call the encoder until we've processed one second of time */
while(sofar < 8000) {
f = t->sample();
if (!f) {
ast_log(LOG_WARNING, "Translator '%s' failed to produce a sample frame.\n", t->name);
t->destroy(pvt);
t->cost = 99999;
return;
}
t->framein(pvt, f);
ast_frfree(f);
while((out = t->frameout(pvt))) {
sofar += out->samples;
ast_frfree(out);
}
}
gettimeofday(&finish, NULL);
t->destroy(pvt);
cost = (finish.tv_sec - start.tv_sec) * 1000 + (finish.tv_usec - start.tv_usec) / 1000;
t->cost = cost;
if (!t->cost)
t->cost = 1;
}
static int show_translation(int fd, int argc, char *argv[])
{
#define SHOW_TRANS 11
int x,y;
int x,y,z;
char line[80];
if (argc != 2)
if (argc > 4)
return RESULT_SHOWUSAGE;
if(argv[2] && !strcasecmp(argv[2],"recalc")) {
z = argv[3] ? atoi(argv[3]) : 1;
if(z <= 0) {
ast_cli(fd," C'mon let's be serious here... defaulting to 1.\n");
z = 1;
}
if(z > MAX_RECALC) {
ast_cli(fd," Maximum limit of recalc exceeded by %d, truncating value to %d\n",z-MAX_RECALC,MAX_RECALC);
z = MAX_RECALC;
}
ast_cli(fd," Recalculating Codec Translation (number of sample seconds: %d)\n\n",z);
rebuild_matrix(z);
}
ast_cli(fd, " Translation times between formats (in milliseconds)\n");
ast_cli(fd, " Source Format (Rows) Destination Format(Columns)\n\n");
ast_mutex_lock(&list_lock);
......@@ -346,9 +377,11 @@ static int show_translation(int fd, int argc, char *argv[])
static int added_cli = 0;
static char show_trans_usage[] =
"Usage: show translation\n"
"Usage: show translation [recalc] [<recalc seconds>]\n"
" Displays known codec translators and the cost associated\n"
"with each conversion.\n";
"with each conversion. if the arguement 'recalc' is supplied along\n"
"with optional number of seconds to test a new test will be performed\n"
"as the chart is being displayed.\n";
static struct ast_cli_entry show_trans =
{ { "show", "translation", NULL }, show_translation, "Display translation matrix", show_trans_usage };
......@@ -362,7 +395,7 @@ int ast_register_translator(struct ast_translator *t)
ast_log(LOG_WARNING, "Format %s is larger than MAX_FORMAT\n", ast_getformatname(t->srcfmt));
return -1;
}
calc_cost(t);
calc_cost(t,1);
if (option_verbose > 1)
ast_verbose(VERBOSE_PREFIX_2 "Registered translator '%s' from format %s to %s, cost %d\n", term_color(tmp, t->name, COLOR_MAGENTA, COLOR_BLACK, sizeof(tmp)), ast_getformatname(1 << t->srcfmt), ast_getformatname(1 << t->dstfmt), t->cost);
ast_mutex_lock(&list_lock);
......@@ -372,7 +405,7 @@ int ast_register_translator(struct ast_translator *t)
}
t->next = list;
list = t;
rebuild_matrix();
rebuild_matrix(0);
ast_mutex_unlock(&list_lock);
return 0;
}
......@@ -396,7 +429,7 @@ int ast_unregister_translator(struct ast_translator *t)
ul = u;
u = u->next;
}
rebuild_matrix();
rebuild_matrix(0);
ast_mutex_unlock(&list_lock);
return (u ? 0 : -1);
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment