summaryrefslogtreecommitdiff
path: root/main/translate.c
diff options
context:
space:
mode:
authorRichard Mudgett <rmudgett@digium.com>2015-04-10 16:32:28 +0000
committerRichard Mudgett <rmudgett@digium.com>2015-04-10 16:32:28 +0000
commit0b805cb87526fd229e3f2811f95d3ba9b4fd64f0 (patch)
treecaa99f576195a695fb7552e66e043b4ebaaf19d3 /main/translate.c
parent894153b8b1557903c1d512994aecedb326dc0951 (diff)
translate.c: Only select audio codecs to determine the best translation choice.
Given a source capability of h264 and ulaw, a destination capability of h264 and g722 then ast_translator_best_choice() would pick h264 as the best choice even though h264 is a video codec and Asterisk only supports translation of audio codecs. When the audio starts flowing, there are warnings about a codec mismatch when the channel tries to write a frame to the peer. * Made ast_translator_best_choice() only select audio codecs. * Restore a check in channel.c:set_format() lost after v1.8 to prevent trying to set a non-audio codec. This is an intermediate patch for a series of patches aimed at improving translation path choices for ASTERISK-24841. This patch is a complete enough fix for ASTERISK-21777 as the v11 version of ast_translator_best_choice() does the same thing. However, chan_sip.c still somehow tries to call ast_codec_choose() which then calls ast_best_codec() with a capability set that doesn't contain any audio formats for the incoming call. The remaining warning message seems to be a benign transient. ASTERISK-21777 #close Reported by: Nick Ruggles ASTERISK-24380 #close Reported by: Matt Jordan Review: https://reviewboard.asterisk.org/r/4605/ ........ Merged revisions 434614 from http://svn.asterisk.org/svn/asterisk/branches/11 ........ Merged revisions 434615 from http://svn.asterisk.org/svn/asterisk/branches/13 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@434616 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'main/translate.c')
-rw-r--r--main/translate.c60
1 files changed, 27 insertions, 33 deletions
diff --git a/main/translate.c b/main/translate.c
index bb07d50ab..2b11d7b4a 100644
--- a/main/translate.c
+++ b/main/translate.c
@@ -1271,9 +1271,12 @@ int ast_translator_best_choice(struct ast_format_cap *dst_cap,
{
unsigned int besttablecost = INT_MAX;
unsigned int beststeps = INT_MAX;
+ struct ast_format *fmt;
+ struct ast_format *dst;
+ struct ast_format *src;
RAII_VAR(struct ast_format *, best, NULL, ao2_cleanup);
RAII_VAR(struct ast_format *, bestdst, NULL, ao2_cleanup);
- RAII_VAR(struct ast_format_cap *, joint_cap, NULL, ao2_cleanup);
+ struct ast_format_cap *joint_cap;
int i;
int j;
@@ -1282,80 +1285,71 @@ int ast_translator_best_choice(struct ast_format_cap *dst_cap,
return -1;
}
- if (!(joint_cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
+ joint_cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
+ if (!joint_cap) {
return -1;
}
ast_format_cap_get_compatible(dst_cap, src_cap, joint_cap);
- for (i = 0; i < ast_format_cap_count(joint_cap); ++i) {
- struct ast_format *fmt =
- ast_format_cap_get_format(joint_cap, i);
-
- if (!fmt) {
- continue;
- }
-
- if (!best) {
- /* No ao2_ref operations needed, we're done with fmt */
- best = fmt;
+ for (i = 0; i < ast_format_cap_count(joint_cap); ++i, ao2_cleanup(fmt)) {
+ fmt = ast_format_cap_get_format(joint_cap, i);
+ if (!fmt
+ || ast_format_get_type(fmt) != AST_MEDIA_TYPE_AUDIO) {
continue;
}
- if (ast_format_get_sample_rate(best) <
- ast_format_get_sample_rate(fmt)) {
+ if (!best
+ || ast_format_get_sample_rate(best) < ast_format_get_sample_rate(fmt)) {
ao2_replace(best, fmt);
}
- ao2_ref(fmt, -1);
}
+ ao2_ref(joint_cap, -1);
if (best) {
ao2_replace(*dst_fmt_out, best);
ao2_replace(*src_fmt_out, best);
return 0;
}
+
/* need to translate */
AST_RWLIST_RDLOCK(&translators);
-
- for (i = 0; i < ast_format_cap_count(dst_cap); ++i) {
- struct ast_format *dst =
- ast_format_cap_get_format(dst_cap, i);
-
- if (!dst) {
+ for (i = 0; i < ast_format_cap_count(dst_cap); ++i, ao2_cleanup(dst)) {
+ dst = ast_format_cap_get_format(dst_cap, i);
+ if (!dst
+ || ast_format_get_type(dst) != AST_MEDIA_TYPE_AUDIO) {
continue;
}
- for (j = 0; j < ast_format_cap_count(src_cap); ++j) {
- struct ast_format *src =
- ast_format_cap_get_format(src_cap, j);
- int x, y;
+ for (j = 0; j < ast_format_cap_count(src_cap); ++j, ao2_cleanup(src)) {
+ int x;
+ int y;
- if (!src) {
+ src = ast_format_cap_get_format(src_cap, j);
+ if (!src
+ || ast_format_get_type(src) != AST_MEDIA_TYPE_AUDIO) {
continue;
}
x = format2index(src);
y = format2index(dst);
if (x < 0 || y < 0) {
- ao2_ref(src, -1);
continue;
}
if (!matrix_get(x, y) || !(matrix_get(x, y)->step)) {
- ao2_ref(src, -1);
continue;
}
- if (((matrix_get(x, y)->table_cost < besttablecost) ||
- (matrix_get(x, y)->multistep < beststeps))) {
+ if (matrix_get(x, y)->table_cost < besttablecost
+ || matrix_get(x, y)->multistep < beststeps) {
/* better than what we have so far */
ao2_replace(best, src);
ao2_replace(bestdst, dst);
besttablecost = matrix_get(x, y)->table_cost;
beststeps = matrix_get(x, y)->multistep;
}
- ao2_ref(src, -1);
}
- ao2_ref(dst, -1);
}
AST_RWLIST_UNLOCK(&translators);
+
if (!best) {
return -1;
}