Fix 'show translations'
[asterisk/asterisk.git] / translate.c
index 7884360..24ed38f 100755 (executable)
@@ -11,6 +11,7 @@
  * the GNU General Public License
  */
 
+#include <asterisk/lock.h>
 #include <asterisk/channel.h>
 #include <asterisk/channel_pvt.h>
 #include <asterisk/logger.h>
@@ -19,6 +20,7 @@
 #include <asterisk/frame.h>
 #include <asterisk/sched.h>
 #include <asterisk/cli.h>
+#include <asterisk/term.h>
 #include <sys/socket.h>
 #include <sys/time.h>
 #include <unistd.h>
@@ -37,7 +39,7 @@
 /* This could all be done more efficiently *IF* we chained packets together
    by default, but it would also complicate virtually every application. */
    
-static pthread_mutex_t list_lock = PTHREAD_MUTEX_INITIALIZER;
+static ast_mutex_t list_lock = AST_MUTEX_INITIALIZER;
 static struct ast_translator *list = NULL;
 
 struct ast_translator_dir {
@@ -106,6 +108,7 @@ struct ast_trans_pvt *ast_translator_build_path(int dest, int source)
                                tmp->step = tr_matrix[source][dest].step;
                                tmp->state = tmp->step->new();
                                if (!tmp->state) {
+                                       ast_log(LOG_WARNING, "Failed to build translator step from %d to %d\n", source, dest);
                                        free(tmp);
                                        tmp = NULL;
                                        return NULL;
@@ -122,7 +125,8 @@ struct ast_trans_pvt *ast_translator_build_path(int dest, int source)
                        }
                } else {
                        /* We shouldn't have allocated any memory */
-                       ast_log(LOG_WARNING, "No translator path from %d to %d\n", source, dest);
+                       ast_log(LOG_WARNING, "No translator path from %s to %s\n", 
+                               ast_getformatname(source), ast_getformatname(dest));
                        return NULL;
                }
        }
@@ -155,7 +159,7 @@ struct ast_frame *ast_translate(struct ast_trans_pvt *path, struct ast_frame *f,
        return NULL;
 }
 
-static void rebuild_matrix()
+static void rebuild_matrix(void)
 {
        struct ast_translator *t;
        int changed;
@@ -196,7 +200,7 @@ static void rebuild_matrix()
                                                                        tr_matrix[x][z].cost = tr_matrix[x][y].cost + 
                                                                                                                   tr_matrix[y][z].cost;
                                                                        if (option_debug)
-                                                                               ast_log(LOG_DEBUG, "Discovered %d cost path from %d to %d, via %d\n", tr_matrix[x][z].cost, x, z, y);
+                                                                               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++;
                                                                 }
                
@@ -224,7 +228,7 @@ static void calc_cost(struct ast_translator *t)
        }
        gettimeofday(&start, NULL);
        /* Call the encoder until we've processed one second of time */
-       while(sofar < 1000) {
+       while(sofar < 8000) {
                f = t->sample();
                if (!f) {
                        ast_log(LOG_WARNING, "Translator '%s' failed to produce a sample frame.\n", t->name);
@@ -235,7 +239,7 @@ static void calc_cost(struct ast_translator *t)
                t->framein(pvt, f);
                ast_frfree(f);
                while((out = t->frameout(pvt))) {
-                       sofar += out->timelen;
+                       sofar += out->samples;
                        ast_frfree(out);
                }
        }
@@ -243,35 +247,39 @@ static void calc_cost(struct ast_translator *t)
        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 14
+#define SHOW_TRANS 11
        int x,y;
        char line[80];
        if (argc != 2) 
                return RESULT_SHOWUSAGE;
-       ast_cli(fd, "                        Translation times between formats (in milliseconds)\n");
-       ast_cli(fd, "                                 Destination Format\n");
-       ast_pthread_mutex_lock(&list_lock);
-       for (x=0;x<SHOW_TRANS; x++) {
-               if (x == 1) 
-                       strcpy(line, "  Src  ");
-               else if (x == 2)
-                       strcpy(line, "  Fmt  ");
-               else
-                       strcpy(line, "       ");
-               for (y=0;y<SHOW_TRANS;y++) {
-                       if (tr_matrix[x][y].step)
-                               snprintf(line + strlen(line), sizeof(line) - strlen(line), " %4d", tr_matrix[x][y].cost);
+       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);
+       for (x=-1;x<SHOW_TRANS; x++) {
+               strcpy(line, " ");
+               for (y=-1;y<SHOW_TRANS;y++) {
+                       if (x >= 0 && y >= 0 && tr_matrix[x][y].step)
+                               snprintf(line + strlen(line), sizeof(line) - strlen(line), " %5d", tr_matrix[x][y].cost >= 99999 ? tr_matrix[x][y].cost-99999 : tr_matrix[x][y].cost);
                        else
-                               snprintf(line + strlen(line), sizeof(line) - strlen(line), "  n/a");
+                               if (((x == -1 && y >= 0) || (y == -1 && x >= 0))) {
+                                       snprintf(line + strlen(line), sizeof(line) - strlen(line), 
+                                               " %5s", ast_getformatname(1<<(x+y+1)) );
+                               } else if (x != -1 && y != -1) {
+                                       snprintf(line + strlen(line), sizeof(line) - strlen(line), "     -");
+                               } else {
+                                       snprintf(line + strlen(line), sizeof(line) - strlen(line), "      ");
+                               }
                }
                snprintf(line + strlen(line), sizeof(line) - strlen(line), "\n");
                ast_cli(fd, line);                      
        }
-       ast_pthread_mutex_unlock(&list_lock);
+       ast_mutex_unlock(&list_lock);
        return RESULT_SUCCESS;
 }
 
@@ -287,16 +295,17 @@ static struct ast_cli_entry show_trans =
 
 int ast_register_translator(struct ast_translator *t)
 {
+       char tmp[80];
        t->srcfmt = powerof(t->srcfmt);
        t->dstfmt = powerof(t->dstfmt);
        if ((t->srcfmt >= MAX_FORMAT) || (t->dstfmt >= MAX_FORMAT)) {
-               ast_log(LOG_WARNING, "Format %d is larger than MAX_FORMAT\n", t->srcfmt);
+               ast_log(LOG_WARNING, "Format %s is larger than MAX_FORMAT\n", ast_getformatname(t->srcfmt));
                return -1;
        }
        calc_cost(t);
        if (option_verbose > 1)
-               ast_verbose(VERBOSE_PREFIX_2 "Registered translator '%s' from format %d to %d, cost %d\n", t->name, t->srcfmt, t->dstfmt, t->cost);
-       ast_pthread_mutex_lock(&list_lock);
+               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);
        if (!added_cli) {
                ast_cli_register(&show_trans);
                added_cli++;
@@ -304,14 +313,14 @@ int ast_register_translator(struct ast_translator *t)
        t->next = list;
        list = t;
        rebuild_matrix();
-       ast_pthread_mutex_unlock(&list_lock);
+       ast_mutex_unlock(&list_lock);
        return 0;
 }
 
 int ast_unregister_translator(struct ast_translator *t)
 {
        struct ast_translator *u, *ul = NULL;
-       ast_pthread_mutex_lock(&list_lock);
+       ast_mutex_lock(&list_lock);
        u = list;
        while(u) {
                if (u == t) {
@@ -325,7 +334,7 @@ int ast_unregister_translator(struct ast_translator *t)
                u = u->next;
        }
        rebuild_matrix();
-       ast_pthread_mutex_unlock(&list_lock);
+       ast_mutex_unlock(&list_lock);
        return (u ? 0 : -1);
 }
 
@@ -337,7 +346,7 @@ int ast_translator_best_choice(int *dst, int *srcs)
        int bestdst=0;
        int cur = 1;
        int besttime=999999999;
-       ast_pthread_mutex_lock(&list_lock);
+       ast_mutex_lock(&list_lock);
        for (y=0;y<MAX_FORMAT;y++) {
                if ((cur & *dst) && (cur & *srcs)) {
                        /* This is a common format to both.  Pick it if we don't have one already */
@@ -364,6 +373,6 @@ int ast_translator_best_choice(int *dst, int *srcs)
                *dst = bestdst;
                best = 0;
        }
-       ast_pthread_mutex_unlock(&list_lock);
+       ast_mutex_unlock(&list_lock);
        return best;
 }