optimize codec selection and format changing code
authorKevin P. Fleming <kpfleming@digium.com>
Mon, 4 Apr 2005 03:28:38 +0000 (03:28 +0000)
committerKevin P. Fleming <kpfleming@digium.com>
Mon, 4 Apr 2005 03:28:38 +0000 (03:28 +0000)
force all transcode paths to use AST_FORMAT_SLINEAR as the frames pass through the bridge (can be disabled using the 'transcode_via_sln' setting in th 'options' setting in asteris.conf)

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@5376 65c4cc65-6c06-0410-ace0-fbb531ad65f3

asterisk.c
channel.c
include/asterisk/options.h
translate.c

index 09b0443..47fe5f1 100755 (executable)
@@ -85,6 +85,7 @@ int option_cache_record_files = 0;
 int option_timestamp = 0;
 int option_overrideconfig = 0;
 int option_reconnect = 0;
+int option_transcode_slin = 1;
 int fully_booted = 0;
 char record_cache_dir[AST_CACHE_DIR_LEN] = AST_TMP_DIR;
 char debug_filename[AST_FILENAME_MAX] = "";
@@ -1653,6 +1654,9 @@ static void ast_readconfig(void) {
                /* Specify cache directory */
                }  else if (!strcasecmp(v->name, "record_cache_dir")) {
                        strncpy(record_cache_dir,v->value,AST_CACHE_DIR_LEN);
+               /* Build transcode paths via SLINEAR, instead of directly */
+               } else if (!strcasecmp(v->name, "transcode_via_sln")) {
+                       option_transcode_slin = ast_true(v->value);
                }
                v = v->next;
        }
index 0f73af1..4597290 100755 (executable)
--- a/channel.c
+++ b/channel.c
@@ -1814,71 +1814,59 @@ int ast_write(struct ast_channel *chan, struct ast_frame *fr)
        return res;
 }
 
-int ast_set_write_format(struct ast_channel *chan, int fmts)
+static int set_format(struct ast_channel *chan, int fmt, int *rawformat, int *format,
+                     struct ast_trans_pvt **trans, const int direction)
 {
-       int fmt;
        int native;
        int res;
        
-       ast_mutex_lock(&chan->lock);
        native = chan->nativeformats;
-       fmt = fmts;
-       
-       res = ast_translator_best_choice(&native, &fmt);
+       /* Find a translation path from the native format to one of the desired formats */
+       if (!direction)
+               /* reading */
+               res = ast_translator_best_choice(&fmt, &native);
+       else
+               /* writing */
+               res = ast_translator_best_choice(&native, &fmt);
+
        if (res < 0) {
                ast_log(LOG_NOTICE, "Unable to find a path from %s to %s\n",
-                       ast_getformatname(fmts), ast_getformatname(chan->nativeformats));
-               ast_mutex_unlock(&chan->lock);
+                       ast_getformatname(native), ast_getformatname(fmt));
                return -1;
        }
        
-       /* Now we have a good choice for both.  We'll write using our native format. */
-       chan->rawwriteformat = native;
+       /* Now we have a good choice for both. */
+       ast_mutex_lock(&chan->lock);
+       *rawformat = native;
        /* User perspective is fmt */
-       chan->writeformat = fmt;
-       /* Free any write translation we have right now */
-       if (chan->writetrans)
-               ast_translator_free_path(chan->writetrans);
-       /* Build a translation path from the user write format to the raw writing format */
-       chan->writetrans = ast_translator_build_path(chan->rawwriteformat, chan->writeformat);
-       if (option_debug)
-               ast_log(LOG_DEBUG, "Set channel %s to write format %s\n", chan->name, ast_getformatname(chan->writeformat));
+       *format = fmt;
+       /* Free any read translation we have right now */
+       if (*trans)
+               ast_translator_free_path(*trans);
+       /* Build a translation path from the raw format to the desired format */
+       if (!direction)
+               /* reading */
+               *trans = ast_translator_build_path(*format, *rawformat);
+       else
+               /* writing */
+               *trans = ast_translator_build_path(*rawformat, *format);
        ast_mutex_unlock(&chan->lock);
+       if (option_debug)
+               ast_log(LOG_DEBUG, "Set channel %s to %s format %s\n", chan->name,
+                       direction ? "write" : "read", ast_getformatname(fmt));
        return 0;
 }
 
-int ast_set_read_format(struct ast_channel *chan, int fmts)
+int ast_set_read_format(struct ast_channel *chan, int fmt)
 {
-       int fmt;
-       int native;
-       int res;
-       
-       ast_mutex_lock(&chan->lock);
-       native = chan->nativeformats;
-       fmt = fmts;
-       /* Find a translation path from the native read format to one of the user's read formats */
-       res = ast_translator_best_choice(&fmt, &native);
-       if (res < 0) {
-               ast_log(LOG_NOTICE, "Unable to find a path from %s to %s\n",
-                       ast_getformatname(chan->nativeformats), ast_getformatname(fmts));
-               ast_mutex_unlock(&chan->lock);
-               return -1;
-       }
-       
-       /* Now we have a good choice for both.  We'll write using our native format. */
-       chan->rawreadformat = native;
-       /* User perspective is fmt */
-       chan->readformat = fmt;
-       /* Free any read translation we have right now */
-       if (chan->readtrans)
-               ast_translator_free_path(chan->readtrans);
-       /* Build a translation path from the raw read format to the user reading format */
-       chan->readtrans = ast_translator_build_path(chan->readformat, chan->rawreadformat);
-       if (option_debug)
-               ast_log(LOG_DEBUG, "Set channel %s to read format %s\n", 
-                       chan->name, ast_getformatname(chan->readformat));
-       ast_mutex_unlock(&chan->lock);
-       return 0;
+       return set_format(chan, fmt, &chan->rawreadformat, &chan->readformat,
+                         &chan->readtrans, 0);
+}
+
+int ast_set_write_format(struct ast_channel *chan, int fmt)
+{
+       return set_format(chan, fmt, &chan->rawwriteformat, &chan->writeformat,
+                         &chan->writetrans, 1);
 }
 
 struct ast_channel *__ast_request_and_dial(const char *type, int format, void *data, int timeout, int *outstate, const char *cid_num, const char *cid_name, struct outgoing_helper *oh)
@@ -2257,47 +2245,51 @@ int ast_channel_make_compatible(struct ast_channel *chan, struct ast_channel *pe
        int peerf;
        int chanf;
        int res;
-       ast_mutex_lock(&peer->lock);
+
+       /* Set up translation from the chan to the peer */
        peerf = peer->nativeformats;
-       ast_mutex_unlock(&peer->lock);
-       ast_mutex_lock(&chan->lock);
        chanf = chan->nativeformats;
-       ast_mutex_unlock(&chan->lock);
        res = ast_translator_best_choice(&peerf, &chanf);
        if (res < 0) {
-               ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", chan->name, chan->nativeformats, peer->name, peer->nativeformats);
+               ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", chan->name, chanf, peer->name, peerf);
                return -1;
        }
-       /* Set read format on channel */
+       /* if desired, force all transcode paths to use SLINEAR between channels */
+       if (option_transcode_slin)
+               peerf = AST_FORMAT_SLINEAR;
+       /* Set read format on chan */
        res = ast_set_read_format(chan, peerf);
        if (res < 0) {
                ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", chan->name, chanf);
                return -1;
        }
-       /* Set write format on peer channel */
+       /* Set write format on peer */
        res = ast_set_write_format(peer, peerf);
        if (res < 0) {
                ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", peer->name, peerf);
                return -1;
        }
-       /* Now we go the other way */
+       /* Now we go the other way (peer to chan) */
        peerf = peer->nativeformats;
        chanf = chan->nativeformats;
        res = ast_translator_best_choice(&chanf, &peerf);
        if (res < 0) {
-               ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", peer->name, peer->nativeformats, chan->name, chan->nativeformats);
+               ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", peer->name, peerf, chan->name, chanf);
                return -1;
        }
-       /* Set writeformat on channel */
-       res = ast_set_write_format(chan, chanf);
+       /* if desired, force all transcode paths to use SLINEAR between channels */
+       if (option_transcode_slin)
+               chanf = AST_FORMAT_SLINEAR;
+       /* Set read format on peer */
+       res = ast_set_read_format(peer, chanf);
        if (res < 0) {
-               ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", chan->name, chanf);
+               ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", peer->name, peerf);
                return -1;
        }
-       /* Set read format on peer channel */
-       res = ast_set_read_format(peer, chanf);
+       /* Set write format on chan */
+       res = ast_set_write_format(chan, chanf);
        if (res < 0) {
-               ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", peer->name, peerf);
+               ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", chan->name, chanf);
                return -1;
        }
        return 0;
index 2a3cf23..598ea31 100755 (executable)
@@ -32,6 +32,7 @@ extern int fully_booted;
 extern int option_exec_includes;
 extern int option_cache_record_files;
 extern int option_timestamp;
+extern int option_transcode_slin;
 extern char defaultlanguage[];
 extern time_t ast_startuptime;
 extern time_t ast_lastreloadtime;
index e5af3e2..b1c7162 100755 (executable)
@@ -437,16 +437,18 @@ int ast_translator_best_choice(int *dst, int *srcs)
 {
        /* Calculate our best source format, given costs, and a desired destination */
        int x,y;
-       int best=-1;
-       int bestdst=0;
+       int best = -1;
+       int bestdst = 0;
        int cur = 1;
-       int besttime=999999999;
-       if ((*dst) & (*srcs)) {
+       int besttime = INT_MAX;
+       int common;
+
+       if ((common = (*dst) & (*srcs))) {
                /* We have a format in common */
-               for (y=0;y<MAX_FORMAT;y++) {
-                       if ((cur & *dst) && (cur & *srcs)) {
+               for (y=0; y < MAX_FORMAT; y++) {
+                       if (cur & common) {
                                /* This is a common format to both.  Pick it if we don't have one already */
-                               besttime=0;
+                               besttime = 0;
                                bestdst = cur;
                                best = cur;
                        }
@@ -455,17 +457,16 @@ int ast_translator_best_choice(int *dst, int *srcs)
        } else {
                /* We will need to translate */
                ast_mutex_lock(&list_lock);
-               for (y=0;y<MAX_FORMAT;y++) {
+               for (y=0; y < MAX_FORMAT; y++) {
                        if (cur & *dst)
-                               for (x=0;x<MAX_FORMAT;x++) {
-                                       if (tr_matrix[x][y].step &&     /* There's a step */
-                                        (tr_matrix[x][y].cost < besttime) && /* We're better than what exists now */
-                                               (*srcs & (1 << x)))                     /* x is a valid source format */
-                                               {
-                                                       best = 1 << x;
-                                                       bestdst = cur;
-                                                       besttime = tr_matrix[x][y].cost;
-                                               }
+                               for (x=0; x < MAX_FORMAT; x++) {
+                                       if ((*srcs & (1 << x)) &&                       /* x is a valid source format */
+                                           tr_matrix[x][y].step &&                     /* There's a step */
+                                           (tr_matrix[x][y].cost < besttime)) {        /* It's better than what we have so far */
+                                               best = 1 << x;
+                                               bestdst = cur;
+                                               besttime = tr_matrix[x][y].cost;
+                                       }
                                }
                        cur = cur << 1;
                }