diff options
author | Richard Mudgett <rmudgett@digium.com> | 2015-04-10 16:32:28 +0000 |
---|---|---|
committer | Richard Mudgett <rmudgett@digium.com> | 2015-04-10 16:32:28 +0000 |
commit | 0b805cb87526fd229e3f2811f95d3ba9b4fd64f0 (patch) | |
tree | caa99f576195a695fb7552e66e043b4ebaaf19d3 /main/translate.c | |
parent | 894153b8b1557903c1d512994aecedb326dc0951 (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.c | 60 |
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; } |