diff --git a/channel.c b/channel.c index 743cbc53cacb8fb5e68bd1fd83d3163eb1a40d7d..ea14aba6dea0899ff86262033a340a871c8c28fe 100644 --- a/channel.c +++ b/channel.c @@ -2744,8 +2744,9 @@ int ast_channel_make_compatible(struct ast_channel *chan, struct ast_channel *pe /* if the best path is not 'pass through', then transcoding is needed; if desired, force transcode path - to use SLINEAR between channels */ - if ((src != dst) && ast_opt_transcode_via_slin) + to use SLINEAR between channels, but only if there is + no direct conversion available */ + if ((src != dst) && ast_opt_transcode_via_slin && ast_translate_path_steps(dst, src)) dst = AST_FORMAT_SLINEAR; if (ast_set_read_format(chan, dst) < 0) { ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", chan->name, dst); @@ -2763,10 +2764,12 @@ int ast_channel_make_compatible(struct ast_channel *chan, struct ast_channel *pe ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", peer->name, src, chan->name, dst); return -1; } + /* if the best path is not 'pass through', then transcoding is needed; if desired, force transcode path - to use SLINEAR between channels */ - if ((src != dst) && ast_opt_transcode_via_slin) + to use SLINEAR between channels, but only if there is + no direct conversion available */ + if ((src != dst) && ast_opt_transcode_via_slin && ast_translate_path_steps(dst, src)) dst = AST_FORMAT_SLINEAR; if (ast_set_read_format(peer, dst) < 0) { ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", peer->name, dst); diff --git a/include/asterisk/translate.h b/include/asterisk/translate.h index a83cfa41eec5673b9924307a0d783663542a9176..21643fe32866bf517f32b79ad0a3ff2e0d24e741 100644 --- a/include/asterisk/translate.h +++ b/include/asterisk/translate.h @@ -1,7 +1,7 @@ /* * Asterisk -- An open source telephony toolkit. * - * Copyright (C) 1999 - 2005, Digium, Inc. + * Copyright (C) 1999 - 2006, Digium, Inc. * * Mark Spencer <markster@digium.com> * @@ -145,7 +145,7 @@ struct ast_trans_pvt; * \brief Register a translator * \param t populated ast_translator structure * This registers a codec translator with asterisk - * Returns 0 on success, -1 on failure + * \return 0 on success, -1 on failure */ int ast_register_translator(struct ast_translator *t, void *module); @@ -153,7 +153,7 @@ int ast_register_translator(struct ast_translator *t, void *module); * \brief Unregister a translator * \param t translator to unregister * Unregisters the given tranlator - * Returns 0 on success, -1 on failure + * \return 0 on success, -1 on failure */ int ast_unregister_translator(struct ast_translator *t); @@ -171,7 +171,7 @@ int ast_translator_best_choice(int *dsts, int *srcs); * \param dest destination format * \param source source format * Build a path (possibly NULL) from source to dest - * Returns ast_trans_pvt on success, NULL on failure + * \return ast_trans_pvt on success, NULL on failure * */ struct ast_trans_pvt *ast_translator_build_path(int dest, int source); @@ -189,10 +189,18 @@ void ast_translator_free_path(struct ast_trans_pvt *tr); * \param consume Whether or not to free the original frame * Apply an input frame into the translator and receive zero or one output frames. Consume * determines whether the original frame should be freed - * Returns an ast_frame of the new translation format on success, NULL on failure + * \return an ast_frame of the new translation format on success, NULL on failure */ struct ast_frame *ast_translate(struct ast_trans_pvt *tr, struct ast_frame *f, int consume); +/*! + * \brief Returns the number of steps required to convert from 'src' to 'dest'. + * \param dest Destination format + * \param src Source format + * \return the number of translation steps required, or -1 if no path is available + */ +unsigned int ast_translate_path_steps(unsigned int dest, unsigned int src); + #if defined(__cplusplus) || defined(c_plusplus) } #endif diff --git a/translate.c b/translate.c index 20da091138b796b3019e624f5e0f3ef01c823e94..dce4b08270d49810cee602d4f331b9c922b68f9d 100644 --- a/translate.c +++ b/translate.c @@ -62,6 +62,8 @@ struct translator_path { * indicates the total cost of translation and the first step. * The full path can be reconstricted iterating on the matrix * until step->dstfmt == desired_format. + * + * Array indexes are 'src' and 'dest', in that order. */ static struct translator_path tr_matrix[MAX_FORMAT][MAX_FORMAT]; @@ -651,3 +653,11 @@ int ast_translator_best_choice(int *dst, int *srcs) return best; } } + +unsigned int ast_translate_path_steps(unsigned int dest, unsigned int src) +{ + if (!tr_matrix[src][dest].step) + return -1; + else + return tr_matrix[src][dest].multistep; +}