From 7622f1ad2a2b1d1587f16dfde6416a7b8ba70069 Mon Sep 17 00:00:00 2001 From: Jonathan Rose Date: Mon, 21 Jul 2014 16:26:36 +0000 Subject: chan_iax2: Restore codec choice behavior from media formats branch After merging the media formats branch, chan_iax2 was discarding codec preferences for the purpose of choosing which codec a channel would use once a call started. This patch restores the Asterisk 1.8-12 codec choice behaviors. ASTERISK-23958 #close Review: https://reviewboard.asterisk.org/r/3800/ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@419109 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- channels/chan_iax2.c | 47 +++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 41 insertions(+), 6 deletions(-) (limited to 'channels') diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c index 29db828ea..d51a17b86 100644 --- a/channels/chan_iax2.c +++ b/channels/chan_iax2.c @@ -1815,7 +1815,37 @@ static iax2_format uncompress_subclass(unsigned char csub) return csub; } -static iax2_format iax2_codec_choose(struct iax2_codec_pref *pref, iax2_format formats, int find_best) +static struct ast_format *codec_choose_from_prefs(struct iax2_codec_pref *pref, struct ast_format_cap *cap) +{ + int x; + struct ast_format *found_format = NULL; + + for (x = 0; x < IAX2_CODEC_PREF_SIZE; x++) { + struct ast_format *pref_format; + uint64_t pref_as_bitfield = iax2_codec_pref_order_value_to_format_bitfield(pref->order[x]); + + if (!pref_as_bitfield) { + break; + } + + pref_format = ast_format_compatibility_bitfield2format(pref_as_bitfield); + + found_format = ast_format_cap_get_compatible_format(cap, pref_format); + if (found_format) { + break; + } + } + + if (found_format && (ast_format_get_type(found_format) == AST_MEDIA_TYPE_AUDIO)) { + return found_format; + } + + ast_debug(4, "Could not find preferred codec - Returning zero codec.\n"); + ao2_cleanup(found_format); + return NULL; +} + +static iax2_format iax2_codec_choose(struct iax2_codec_pref *pref, iax2_format formats) { struct ast_format_cap *cap; struct ast_format *tmpfmt; @@ -1823,7 +1853,12 @@ static iax2_format iax2_codec_choose(struct iax2_codec_pref *pref, iax2_format f if ((cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) { iax2_format_compatibility_bitfield2cap(formats, cap); - tmpfmt = ast_format_cap_get_format(cap, 0); + tmpfmt = codec_choose_from_prefs(pref, cap); + if (!tmpfmt) { + ao2_ref(cap, -1); + return 0; + } + format = ast_format_compatibility_format2bitfield(tmpfmt); ao2_ref(tmpfmt, -1); ao2_ref(cap, -1); @@ -10760,7 +10795,7 @@ static int socket_process_helper(struct iax2_thread *thread) } else pref = iaxs[fr->callno]->prefs; - format = iax2_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0); + format = iax2_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability); iax2_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1); iax2_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); } @@ -10816,7 +10851,7 @@ static int socket_process_helper(struct iax2_thread *thread) pref = iaxs[fr->callno]->rprefs; using_prefs = "caller"; } - format = iax2_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1); + format = iax2_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); } else /* if no codec_prefs IE do it the old way */ format = iax2_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); } @@ -11214,7 +11249,7 @@ static int socket_process_helper(struct iax2_thread *thread) } } else /* if no codec_prefs IE do it the old way */ pref = iaxs[fr->callno]->prefs; - format = iax2_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0); + format = iax2_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability); iax2_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1); iax2_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); } @@ -11275,7 +11310,7 @@ static int socket_process_helper(struct iax2_thread *thread) pref = iaxs[fr->callno]->rprefs; using_prefs = "caller"; } - format = iax2_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1); + format = iax2_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); } else /* if no codec_prefs IE do it the old way */ format = iax2_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); } -- cgit v1.2.3