From: Mark Michelson Date: Fri, 2 Mar 2012 00:20:04 +0000 (+0000) Subject: Second attempt to get optimal translation paths when codec_resample is used. X-Git-Tag: 1.8.10.1~50 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=496d1009ddc3e59fbfb00f28cb2bfb1157aca822;p=thirdparty%2Fasterisk.git Second attempt to get optimal translation paths when codec_resample is used. This borrows code heavily from changes made in translation code in Asterisk 10. This uses the quality and sample rate change of translation in order to pick paths rather than the computational cost of translations. Computational cost is used solely in determining if a single translation step from a specific translator is better than the same translation step provided by a different translator. (closes issue ASTERISK-16821) reported by Andrew Lindh Review: https://reviewboard.asterisk.org/r/1772 git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.8@357760 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- diff --git a/main/translate.c b/main/translate.c index 61b4a4686d..e11427d20d 100644 --- a/main/translate.c +++ b/main/translate.c @@ -51,10 +51,50 @@ static AST_RWLIST_HEAD_STATIC(translators, ast_translator); * \note These must stay in this order. They are ordered by most optimal selection first. */ enum path_samp_change { - RATE_CHANGE_NONE = 0, /*!< path uses the same sample rate consistently */ - RATE_CHANGE_UPSAMP = 1, /*!< path will up the sample rate during a translation */ - RATE_CHANGE_DOWNSAMP = 2, /*!< path will have to down the sample rate during a translation. */ - RATE_CHANGE_UPSAMP_DOWNSAMP = 3, /*!< path will both up and down the sample rate during translation */ + + /* Lossless Source Translation Costs */ + + /*! [lossless -> lossless] original sampling */ + AST_TRANS_COST_LL_LL_ORIGSAMP = 400000, + /*! [lossless -> lossy] original sampling */ + AST_TRANS_COST_LL_LY_ORIGSAMP = 600000, + + /*! [lossless -> lossless] up sample */ + AST_TRANS_COST_LL_LL_UPSAMP = 800000, + /*! [lossless -> lossy] up sample */ + AST_TRANS_COST_LL_LY_UPSAMP = 825000, + + /*! [lossless -> lossless] down sample */ + AST_TRANS_COST_LL_LL_DOWNSAMP = 850000, + /*! [lossless -> lossy] down sample */ + AST_TRANS_COST_LL_LY_DOWNSAMP = 875000, + + /*! [lossless -> unknown] unknown. + * This value is for a lossless source translation + * with an unknown destination and or sample rate conversion. */ + AST_TRANS_COST_LL_UNKNOWN = 885000, + + /* Lossy Source Translation Costs */ + + /*! [lossy -> lossless] original sampling */ + AST_TRANS_COST_LY_LL_ORIGSAMP = 900000, + /*! [lossy -> lossy] original sampling */ + AST_TRANS_COST_LY_LY_ORIGSAMP = 915000, + + /*! [lossy -> lossless] up sample */ + AST_TRANS_COST_LY_LL_UPSAMP = 930000, + /*! [lossy -> lossy] up sample */ + AST_TRANS_COST_LY_LY_UPSAMP = 945000, + + /*! [lossy -> lossless] down sample */ + AST_TRANS_COST_LY_LL_DOWNSAMP = 960000, + /*! [lossy -> lossy] down sample */ + AST_TRANS_COST_LY_LY_DOWNSAMP = 975000, + + /*! [lossy -> unknown] unknown. + * This value is for a lossy source translation + * with an unknown destination and or sample rate conversion. */ + AST_TRANS_COST_LY_UNKNOWN = 985000, }; struct translator_path { @@ -417,20 +457,44 @@ static void calc_cost(struct ast_translator *t, int seconds) static enum path_samp_change get_rate_change_result(format_t src, format_t dst) { + int src_ll = src == AST_FORMAT_SLINEAR || src == AST_FORMAT_SLINEAR16; + int dst_ll = dst == AST_FORMAT_SLINEAR || src == AST_FORMAT_SLINEAR16; int src_rate = ast_format_rate(src); int dst_rate = ast_format_rate(dst); - /* if src rate is less than dst rate, a sample upgrade is required */ - if (src_rate < dst_rate) { - return RATE_CHANGE_UPSAMP; - } - - /* if src rate is larger than dst rate, a downgrade is required */ - if (src_rate > dst_rate) { - return RATE_CHANGE_DOWNSAMP; + if (src_ll) { + if (dst_ll && (src_rate == dst_rate)) { + return AST_TRANS_COST_LL_LL_ORIGSAMP; + } else if (!dst_ll && (src_rate == dst_rate)) { + return AST_TRANS_COST_LL_LY_ORIGSAMP; + } else if (dst_ll && (src_rate < dst_rate)) { + return AST_TRANS_COST_LL_LL_UPSAMP; + } else if (!dst_ll && (src_rate < dst_rate)) { + return AST_TRANS_COST_LL_LY_UPSAMP; + } else if (dst_ll && (src_rate > dst_rate)) { + return AST_TRANS_COST_LL_LL_DOWNSAMP; + } else if (!dst_ll && (src_rate > dst_rate)) { + return AST_TRANS_COST_LL_LY_DOWNSAMP; + } else { + return AST_TRANS_COST_LL_UNKNOWN; + } + } else { + if (dst_ll && (src_rate == dst_rate)) { + return AST_TRANS_COST_LY_LL_ORIGSAMP; + } else if (!dst_ll && (src_rate == dst_rate)) { + return AST_TRANS_COST_LY_LY_ORIGSAMP; + } else if (dst_ll && (src_rate < dst_rate)) { + return AST_TRANS_COST_LY_LL_UPSAMP; + } else if (!dst_ll && (src_rate < dst_rate)) { + return AST_TRANS_COST_LY_LY_UPSAMP; + } else if (dst_ll && (src_rate > dst_rate)) { + return AST_TRANS_COST_LY_LL_DOWNSAMP; + } else if (!dst_ll && (src_rate > dst_rate)) { + return AST_TRANS_COST_LY_LY_DOWNSAMP; + } else { + return AST_TRANS_COST_LY_UNKNOWN; + } } - - return RATE_CHANGE_NONE; } /*! @@ -517,12 +581,9 @@ static void rebuild_matrix(int samples) /* Is x->y->z a better choice than x->z? * There are three conditions for x->y->z to be a better choice than x->z * 1. if there is no step directly between x->z then x->y->z is the best and only current option. - * 2. if x->y->z costs less and the sample rate conversion is no less optimal. - * 3. if x->y->z results in a more optimal sample rate conversion. */ + * 2. if x->y->z results in a more optimal sample rate conversion. */ if (!tr_matrix[x][z].step) { better_choice = 1; - } else if ((newcost < tr_matrix[x][z].cost) && (new_rate_change <= tr_matrix[x][z].rate_change)) { - better_choice = 1; } else if (new_rate_change < tr_matrix[x][z].rate_change) { better_choice = 1; } else { @@ -542,16 +603,7 @@ static void rebuild_matrix(int samples) * * if both paths require a change in rate, and they are not in the same direction * then this is a up sample down sample conversion scenario. */ - if ((tr_matrix[x][y].rate_change > RATE_CHANGE_NONE) && - (tr_matrix[y][z].rate_change > RATE_CHANGE_NONE) && - (tr_matrix[x][y].rate_change != tr_matrix[y][z].rate_change)) { - - tr_matrix[x][z].rate_change = RATE_CHANGE_UPSAMP_DOWNSAMP; - } else { - /* else just set the rate change to whichever is worse */ - tr_matrix[x][z].rate_change = tr_matrix[x][y].rate_change > tr_matrix[y][z].rate_change - ? tr_matrix[x][y].rate_change : tr_matrix[y][z].rate_change; - } + tr_matrix[x][z].rate_change = tr_matrix[x][y].rate_change + tr_matrix[y][z].rate_change; ast_debug(3, "Discovered %d cost path from %s to %s, via %s\n", tr_matrix[x][z].cost, ast_getformatname(1LL << x), ast_getformatname(1LL << z), ast_getformatname(1LL << y));