aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/asterisk/translate.h18
-rw-r--r--main/translate.c42
2 files changed, 58 insertions, 2 deletions
diff --git a/include/asterisk/translate.h b/include/asterisk/translate.h
index 07c0ae1c2..a03f54ef2 100644
--- a/include/asterisk/translate.h
+++ b/include/asterisk/translate.h
@@ -205,12 +205,26 @@ struct ast_frame *ast_translate(struct ast_trans_pvt *tr, struct ast_frame *f, i
/*!
* \brief Returns the number of steps required to convert from 'src' to 'dest'.
- * \param dest Destination format
- * \param src Source format
+ * \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);
+/*!
+ * \brief Mask off unavailable formats from a format bitmask
+ * \param dest possible destination formats
+ * \param src source formats
+ * \return the destination formats that are available in the source or translatable
+ *
+ * The result will include all formats from 'dest' that are either present
+ * in 'src' or translatable from a format present in 'src'.
+ *
+ * Note that only a single audio format and a single video format can be
+ * present in 'src', or the function will produce unexpected results.
+ */
+unsigned int ast_translate_available_formats(unsigned int dest, unsigned int src);
+
#if defined(__cplusplus) || defined(c_plusplus)
}
#endif
diff --git a/main/translate.c b/main/translate.c
index 77feabbac..f51822f3f 100644
--- a/main/translate.c
+++ b/main/translate.c
@@ -777,3 +777,45 @@ unsigned int ast_translate_path_steps(unsigned int dest, unsigned int src)
return tr_matrix[src][dest].multistep + 1;
}
+unsigned int ast_translate_available_formats(unsigned int dest, unsigned int src)
+{
+ unsigned int res = dest;
+ unsigned int x;
+ unsigned int src_audio = powerof(src & AST_FORMAT_AUDIO_MASK);
+ unsigned int src_video = powerof(src & AST_FORMAT_VIDEO_MASK);
+
+ for (x = 1; x < AST_FORMAT_MAX_AUDIO; x <<= 1) {
+ /* if this is not a desired format, nothing to do */
+ if (!dest & x)
+ continue;
+
+ /* if the source is supplying this format, then
+ we can leave it in the result */
+ if (src & x)
+ continue;
+
+ /* if we don't have a translation path from the src
+ to this format, remove it from the result */
+ if (!tr_matrix[src_audio][powerof(x)].step)
+ res &= ~x;
+ }
+
+ /* roll over into video formats */
+ for (; x < AST_FORMAT_MAX_VIDEO; x <<= 1) {
+ /* if this is not a desired format, nothing to do */
+ if (!dest & x)
+ continue;
+
+ /* if the source is supplying this format, then
+ we can leave it in the result */
+ if (src & x)
+ continue;
+
+ /* if we don't have a translation path from the src
+ to this format, remove it from the result */
+ if (!tr_matrix[src_video][powerof(x)].step)
+ res &= ~x;
+ }
+
+ return res;
+}