--- main/format.c (Asterisk 13.4) +++ main/format.c (working copy) @@ -320,9 +320,19 @@ void ast_format_generate_sdp_fmtp(const struct ast_format *format, unsigned int payload, struct ast_str **str) { - if (!format->interface || !format->interface->format_generate_sdp_fmtp) { + const struct ast_format_interface *interface = format->interface; + + if (!interface) { + struct format_interface *format_interface = ao2_find(interfaces, format->codec->name, OBJ_SEARCH_KEY); + if (format_interface) { + interface = format_interface->interface; + ao2_ref(format_interface, -1); + } + } + + if (!interface || !interface->format_generate_sdp_fmtp) { return; } - format->interface->format_generate_sdp_fmtp(format, payload, str); + interface->format_generate_sdp_fmtp(format, payload, str); } --- res/res_format_attr_opus.c (Asterisk 13.4) +++ res/res_format_attr_opus.c (working copy) @@ -135,5 +135,5 @@ if (!attr) { - return; + attr = &default_opus_attr; } @@ -181,10 +181,18 @@ if (!jointformat) { return NULL; } attr_res = ast_format_get_attribute_data(jointformat); + if (0 == attr1->maxplayrate) { + attr_res->maxplayrate = attr2->maxplayrate; + } else if (0 == attr2->maxplayrate) { + attr_res->maxplayrate = attr1->maxplayrate; + } else { + attr_res->maxplayrate = MIN(attr1->maxplayrate, attr2->maxplayrate); + } + /* Only do dtx if both sides want it. DTX is a trade off between * computational complexity and bandwidth. */ attr_res->dtx = attr1->dtx && attr2->dtx ? 1 : 0; /* Only do FEC if both sides want it. If a peer specifically requests not