Allow translation table to be recalculated, including with higher resolution
authorMark Spencer <markster@digium.com>
Mon, 17 May 2004 22:59:27 +0000 (22:59 +0000)
committerMark Spencer <markster@digium.com>
Mon, 17 May 2004 22:59:27 +0000 (22:59 +0000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@2996 65c4cc65-6c06-0410-ace0-fbb531ad65f3

translate.c

index 48efc58..1a95295 100755 (executable)
@@ -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);
 }