From a80bce7e584beb20b2abebf2da42748c888bdec8 Mon Sep 17 00:00:00 2001 From: Mark Spencer <markster@digium.com> Date: Mon, 17 May 2004 22:59:27 +0000 Subject: [PATCH] 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 --- translate.c | 135 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 84 insertions(+), 51 deletions(-) diff --git a/translate.c b/translate.c index 48efc58d57..1a9529542c 100755 --- a/translate.c +++ b/translate.c @@ -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); } -- GitLab