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;
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);
} 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);
}
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);
}
}
} 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);
}
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);
}