diff --git a/src/include/switch_loadable_module.h b/src/include/switch_loadable_module.h index 31f7a273d0..ce67bcf613 100644 --- a/src/include/switch_loadable_module.h +++ b/src/include/switch_loadable_module.h @@ -171,10 +171,10 @@ SWITCH_DECLARE(switch_directory_interface_t *) switch_loadable_module_get_direct \param arraylen the max size in elements of the array \return the number of elements added to the array */ -SWITCH_DECLARE(int) switch_loadable_module_get_codecs(switch_memory_pool_t *pool, - switch_codec_interface_t **array, +SWITCH_DECLARE(int) switch_loadable_module_get_codecs(switch_memory_pool_t *pool, const switch_codec_implementation_t **array, int arraylen); + /*! \brief Retrieve the list of loaded codecs into an array based on another array showing the sorted order \param array the array to populate @@ -184,10 +184,8 @@ SWITCH_DECLARE(int) switch_loadable_module_get_codecs(switch_memory_pool_t *pool \return the number of elements added to the array \note this function only considers codecs that are listed in the "prefs" array and ignores the rest. */ -SWITCH_DECLARE(int) switch_loadable_module_get_codecs_sorted(switch_codec_interface_t **array, - int arraylen, - char **prefs, - int preflen); +SWITCH_DECLARE(int) switch_loadable_module_get_codecs_sorted(const switch_codec_implementation_t **array, + int arraylen, char **prefs, int preflen); /*! \brief Execute a registered API command diff --git a/src/include/switch_module_interfaces.h b/src/include/switch_module_interfaces.h index ecee1353d2..f9fd792ff6 100644 --- a/src/include/switch_module_interfaces.h +++ b/src/include/switch_module_interfaces.h @@ -444,6 +444,8 @@ struct switch_codec { /*! \brief A table of settings and callbacks that define a paticular implementation of a codec */ struct switch_codec_implementation { + /*! enumeration defining the type of the codec */ + const switch_codec_type_t codec_type; /*! the IANA code number */ switch_payload_t ianacode; /*! the IANA code name */ @@ -497,8 +499,6 @@ struct switch_codec_implementation { struct switch_codec_interface { /*! the name of the interface */ const char *interface_name; - /*! enumeration defining the type of the codec */ - const switch_codec_type_t codec_type; /*! a list of codec implementations related to the codec */ const switch_codec_implementation_t *implementations; const struct switch_codec_interface *next; diff --git a/src/mod/codecs/mod_g711/mod_g711.c b/src/mod/codecs/mod_g711/mod_g711.c index 3fc5a6cd49..98a115d545 100644 --- a/src/mod/codecs/mod_g711/mod_g711.c +++ b/src/mod/codecs/mod_g711/mod_g711.c @@ -190,6 +190,7 @@ static switch_status_t switch_g711a_destroy(switch_codec_t *codec) #if 0 static const switch_codec_implementation_t g711u_8k_60ms_implementation = { + /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, /*.ianacode */ 0, /*.iananame */ "PCMU", /*.samples_per_second */ 8000, @@ -206,9 +207,10 @@ static const switch_codec_implementation_t g711u_8k_60ms_implementation = { /*.decode */ switch_g711u_decode, /*.destroy */ switch_g711u_destroy }; - +#endif static const switch_codec_implementation_t g711u_8k_30ms_implementation = { + /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, /*.ianacode */ 0, /*.iananame */ "PCMU", /*.samples_per_second */ 8000, @@ -224,11 +226,11 @@ static const switch_codec_implementation_t g711u_8k_30ms_implementation = { /*.encode */ switch_g711u_encode, /*.decode */ switch_g711u_decode, /*.destroy */ switch_g711u_destroy, - /*.next */ &g711u_8k_60ms_implementation + /*.next */ NULL }; -#endif static const switch_codec_implementation_t g711u_16k_implementation = { + /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, /*.ianacode */ 0, /*.iananame */ "PCMU", /*.samples_per_second */ 16000, @@ -244,9 +246,11 @@ static const switch_codec_implementation_t g711u_16k_implementation = { /*.encode */ switch_g711u_encode, /*.decode */ switch_g711u_decode, /*.destroy */ switch_g711u_destroy, + /*.next */ &g711u_8k_30ms_implementation }; static const switch_codec_implementation_t g711u_8k_implementation = { + /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, /*.ianacode */ 0, /*.iananame */ "PCMU", /*.samples_per_second */ 8000, @@ -267,6 +271,7 @@ static const switch_codec_implementation_t g711u_8k_implementation = { static const switch_codec_implementation_t g711a_8k_implementation = { + /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, /*.ianacode */ 8, /*.iananame */ "PCMA", /*.samples_per_second */ 8000, @@ -287,13 +292,11 @@ static const switch_codec_implementation_t g711a_8k_implementation = { static const switch_codec_interface_t g711a_codec_interface = { /*.interface_name */ "g711 alaw", - /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, /*.implementations */ &g711a_8k_implementation }; static const switch_codec_interface_t g711u_codec_interface = { /*.interface_name */ "g711 ulaw", - /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, /*.implementations */ &g711u_8k_implementation, /*.next */ &g711a_codec_interface }; diff --git a/src/mod/codecs/mod_g729/mod_g729.c b/src/mod/codecs/mod_g729/mod_g729.c index 99bee56909..9d6e98d65b 100644 --- a/src/mod/codecs/mod_g729/mod_g729.c +++ b/src/mod/codecs/mod_g729/mod_g729.c @@ -219,6 +219,7 @@ static switch_status_t switch_g729_decode(switch_codec_t *codec, /* Registration */ static const switch_codec_implementation_t g729_10ms_8k_implementation = { + /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, /*.ianacode */ 18, /*.iananame */ "G729", /*.samples_per_second */ 8000, @@ -237,6 +238,7 @@ static const switch_codec_implementation_t g729_10ms_8k_implementation = { }; static const switch_codec_implementation_t g729_8k_implementation = { + /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, /*.ianacode */ 18, /*.iananame */ "G729", /*.samples_per_second */ 8000, @@ -258,7 +260,6 @@ static const switch_codec_implementation_t g729_8k_implementation = { static const switch_codec_interface_t g729_codec_interface = { /*.interface_name */ "g729", - /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, /*.implementations */ &g729_8k_implementation, }; diff --git a/src/mod/codecs/mod_gsm/mod_gsm.c b/src/mod/codecs/mod_gsm/mod_gsm.c index 7aef780074..ececdc1cbc 100644 --- a/src/mod/codecs/mod_gsm/mod_gsm.c +++ b/src/mod/codecs/mod_gsm/mod_gsm.c @@ -133,6 +133,7 @@ static switch_status_t switch_gsm_decode(switch_codec_t *codec, switch_codec_t * /* Registration */ static const switch_codec_implementation_t gsm_8k_implementation = { + /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, /*.ianacode */ 3, /*.iananame */ "gsm", /*.samples_per_second */ 8000, @@ -151,7 +152,6 @@ static const switch_codec_implementation_t gsm_8k_implementation = { }; static const switch_codec_interface_t gsm_codec_interface = { /*.interface_name */ "gsm", - /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, /*.implementations */ &gsm_8k_implementation, }; static switch_loadable_module_interface_t gsm_module_interface = { diff --git a/src/mod/codecs/mod_ilbc/mod_ilbc.c b/src/mod/codecs/mod_ilbc/mod_ilbc.c index 49d38d4494..0721c0566e 100644 --- a/src/mod/codecs/mod_ilbc/mod_ilbc.c +++ b/src/mod/codecs/mod_ilbc/mod_ilbc.c @@ -186,6 +186,7 @@ static switch_status_t switch_ilbc_decode(switch_codec_t *codec, /* Registration */ static const switch_codec_implementation_t ilbc_8k_30ms_implementation = { + /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, /*.ianacode */ 97, /*.iananame */ "iLBC", /*.samples_per_second */ 8000, @@ -204,6 +205,7 @@ static const switch_codec_implementation_t ilbc_8k_30ms_implementation = { }; static const switch_codec_implementation_t ilbc_8k_20ms_implementation = { + /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, /*.ianacode */ 97, /*.iananame */ "iLBC", /*.samples_per_second */ 8000, @@ -225,6 +227,7 @@ static const switch_codec_implementation_t ilbc_8k_20ms_implementation = { static const switch_codec_implementation_t ilbc_102_8k_30ms_implementation = { + /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, /*.ianacode */ 102, /*.iananame */ "iLBC", /*.samples_per_second */ 8000, @@ -243,6 +246,7 @@ static const switch_codec_implementation_t ilbc_102_8k_30ms_implementation = { }; static const switch_codec_implementation_t ilbc_102_8k_20ms_implementation = { + /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, /*.ianacode */ 102, /*.iananame */ "iLBC102", /*.samples_per_second */ 8000, @@ -263,6 +267,7 @@ static const switch_codec_implementation_t ilbc_102_8k_20ms_implementation = { static const switch_codec_implementation_t ilbc_8k_20ms_nonext_implementation = { + /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, /*.ianacode */ 97, /*.iananame */ "iLBC20ms", /*.samples_per_second */ 8000, @@ -283,20 +288,17 @@ static const switch_codec_implementation_t ilbc_8k_20ms_nonext_implementation = static const switch_codec_interface_t ilbc_20ms_codec_interface = { /*.interface_name */ "ilbc", - /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, /*.implementations */ &ilbc_8k_20ms_nonext_implementation }; static const switch_codec_interface_t ilbc_102_codec_interface = { /*.interface_name */ "ilbc", - /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, /*.implementations */ &ilbc_102_8k_20ms_implementation, /*.next*/ &ilbc_20ms_codec_interface }; static const switch_codec_interface_t ilbc_codec_interface = { /*.interface_name */ "ilbc", - /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, /*.implementations */ &ilbc_8k_20ms_implementation, /*.next*/ &ilbc_102_codec_interface }; diff --git a/src/mod/codecs/mod_l16/mod_l16.c b/src/mod/codecs/mod_l16/mod_l16.c index ca544e4a39..bcf43d9ece 100644 --- a/src/mod/codecs/mod_l16/mod_l16.c +++ b/src/mod/codecs/mod_l16/mod_l16.c @@ -90,6 +90,7 @@ static switch_status_t switch_raw_destroy(switch_codec_t *codec) } static const switch_codec_implementation_t raw_32k_implementation = { + /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, /*.ianacode */ 10, /*.iananame */ "L16", /*.samples_per_second = */ 32000, @@ -108,6 +109,7 @@ static const switch_codec_implementation_t raw_32k_implementation = { }; static const switch_codec_implementation_t raw_22k_implementation = { + /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, /*.ianacode */ 10, /*.iananame */ "L16", /*.samples_per_second = */ 22050, @@ -127,6 +129,7 @@ static const switch_codec_implementation_t raw_22k_implementation = { }; static const switch_codec_implementation_t raw_16k_implementation = { + /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, /*.ianacode */ 10, /*.iananame */ "L16", /*.samples_per_second = */ 16000, @@ -146,6 +149,7 @@ static const switch_codec_implementation_t raw_16k_implementation = { }; static const switch_codec_implementation_t raw_8k_implementation = { + /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, /*.ianacode */ 10, /*.iananame */ "L16", /*.samples_per_second = */ 8000, @@ -166,6 +170,7 @@ static const switch_codec_implementation_t raw_8k_implementation = { static const switch_codec_implementation_t raw_8k_30ms_implementation = { + /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, /*.ianacode */ 10, /*.iananame */ "L16", /*.samples_per_second */ 8000, @@ -186,6 +191,7 @@ static const switch_codec_implementation_t raw_8k_30ms_implementation = { static const switch_codec_implementation_t raw_8k_60ms_implementation = { + /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, /*.ianacode */ 10, /*.iananame */ "L16", /*.samples_per_second */ 8000, @@ -205,6 +211,7 @@ static const switch_codec_implementation_t raw_8k_60ms_implementation = { }; static const switch_codec_implementation_t raw_8k_120ms_implementation = { + /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, /*.ianacode */ 10, /*.iananame */ "L16", /*.samples_per_second */ 8000, @@ -226,7 +233,6 @@ static const switch_codec_implementation_t raw_8k_120ms_implementation = { static const switch_codec_interface_t raw_codec_interface = { /*.interface_name */ "raw signed linear (16 bit)", - /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, /*.implementations */ &raw_8k_120ms_implementation }; diff --git a/src/mod/codecs/mod_speex/mod_speex.c b/src/mod/codecs/mod_speex/mod_speex.c index cf8461df93..a7921cc94d 100644 --- a/src/mod/codecs/mod_speex/mod_speex.c +++ b/src/mod/codecs/mod_speex/mod_speex.c @@ -268,6 +268,7 @@ static switch_status_t switch_speex_destroy(switch_codec_t *codec) /* Registration */ static const switch_codec_implementation_t speex_32k_implementation = { + /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, /*.ianacode */ 98, /*.iananame */ "speex", /*.samples_per_second */ 32000, @@ -286,6 +287,7 @@ static const switch_codec_implementation_t speex_32k_implementation = { }; static const switch_codec_implementation_t speex_16k_implementation = { + /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, /*.ianacode */ 98, /*.iananame */ "speex", /*.samples_per_second */ 16000, @@ -305,6 +307,7 @@ static const switch_codec_implementation_t speex_16k_implementation = { }; static const switch_codec_implementation_t speex_8k_implementation = { + /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, /*.ianacode */ 98, /*.iananame */ "speex", /*.samples_per_second */ 8000, @@ -325,7 +328,6 @@ static const switch_codec_implementation_t speex_8k_implementation = { static const switch_codec_interface_t speex_codec_interface = { /*.interface_name */ "speex", - /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, /*.implementations */ &speex_8k_implementation }; diff --git a/src/mod/endpoints/mod_dingaling/mod_dingaling.c b/src/mod/endpoints/mod_dingaling/mod_dingaling.c index a599fc80ac..e11c4a13f8 100644 --- a/src/mod/endpoints/mod_dingaling/mod_dingaling.c +++ b/src/mod/endpoints/mod_dingaling/mod_dingaling.c @@ -113,7 +113,7 @@ struct private_object { switch_caller_profile_t *caller_profile; unsigned short samprate; switch_mutex_t *mutex; - switch_codec_interface_t *codecs[SWITCH_MAX_CODECS]; + const switch_codec_implementation_t *codecs[SWITCH_MAX_CODECS]; unsigned int num_codecs; int codec_index; switch_rtp_t *rtp_session; @@ -440,16 +440,16 @@ static int do_describe(struct private_object *tech_pvt, int force) if (force || !switch_test_flag(tech_pvt, TFLAG_CODEC_READY)) { if (tech_pvt->codec_index < 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Don't have my codec yet here's one\n"); - tech_pvt->codec_name = lame(tech_pvt->codecs[0]->implementations->iananame); - tech_pvt->codec_num = tech_pvt->codecs[0]->implementations->ianacode; + tech_pvt->codec_name = lame(tech_pvt->codecs[0]->iananame); + tech_pvt->codec_num = tech_pvt->codecs[0]->ianacode; tech_pvt->codec_index = 0; - payloads[0].name = lame(tech_pvt->codecs[0]->implementations->iananame); - payloads[0].id = tech_pvt->codecs[0]->implementations->ianacode; + payloads[0].name = lame(tech_pvt->codecs[0]->iananame); + payloads[0].id = tech_pvt->codecs[0]->ianacode; } else { - payloads[0].name = lame(tech_pvt->codecs[tech_pvt->codec_index]->implementations->iananame); - payloads[0].id = tech_pvt->codecs[tech_pvt->codec_index]->implementations->ianacode; + payloads[0].name = lame(tech_pvt->codecs[tech_pvt->codec_index]->iananame); + payloads[0].id = tech_pvt->codecs[tech_pvt->codec_index]->ianacode; } @@ -1546,22 +1546,22 @@ static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsessi for(x = 0; x < len; x++) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Available Payload %s %u\n", payloads[x].name, payloads[x].id); for(y = 0; y < tech_pvt->num_codecs; y++) { - char *name = tech_pvt->codecs[y]->implementations->iananame; + char *name = tech_pvt->codecs[y]->iananame; if (!strncasecmp(name, "ilbc", 4)) { name = "ilbc"; } - if (tech_pvt->codecs[y]->implementations->ianacode > 96) { + if (tech_pvt->codecs[y]->ianacode > 96) { match = strcasecmp(name, payloads[x].name) ? 0 : 1; } else { - match = (payloads[x].id == tech_pvt->codecs[y]->implementations->ianacode) ? 1 : 0; + match = (payloads[x].id == tech_pvt->codecs[y]->ianacode) ? 1 : 0; } if (match) { tech_pvt->codec_index = y; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Choosing Payload index %u %s %u\n", y, payloads[x].name, payloads[x].id); - tech_pvt->codec_name = tech_pvt->codecs[y]->implementations->iananame; - tech_pvt->codec_num = tech_pvt->codecs[y]->implementations->ianacode; + tech_pvt->codec_name = tech_pvt->codecs[y]->iananame; + tech_pvt->codec_num = tech_pvt->codecs[y]->ianacode; if (!switch_test_flag(tech_pvt, TFLAG_OUTBOUND)) { do_describe(tech_pvt, 0); } diff --git a/src/mod/endpoints/mod_exosip/mod_exosip.c b/src/mod/endpoints/mod_exosip/mod_exosip.c index 5c5ff3ec5a..7e76aca744 100644 --- a/src/mod/endpoints/mod_exosip/mod_exosip.c +++ b/src/mod/endpoints/mod_exosip/mod_exosip.c @@ -138,7 +138,7 @@ struct private_object { int ssrc; switch_time_t last_read; char *realm; - switch_codec_interface_t *codecs[SWITCH_MAX_CODECS]; + const switch_codec_implementation_t *codecs[SWITCH_MAX_CODECS]; int num_codecs; switch_payload_t te; switch_mutex_t *flag_mutex; @@ -173,7 +173,13 @@ static switch_status_t exosip_read_frame(switch_core_session_t *session, switch_ static switch_status_t exosip_write_frame(switch_core_session_t *session, switch_frame_t *frame, int timeout, switch_io_flag_t flags, int stream_id); static int config_exosip(int reload); -static switch_status_t parse_sdp_media(struct private_object *tech_pvt, sdp_media_t * media, char **dname, char **drate, char **dpayload); +static switch_status_t parse_sdp_media(struct private_object *tech_pvt, + sdp_media_t * media, + char **dname, + char **drate, + char **dpayload, + const switch_codec_implementation_t **impp); + static switch_status_t exosip_kill_channel(switch_core_session_t *session, int sig); static switch_status_t activate_rtp(struct private_object *tech_pvt); static void deactivate_rtp(struct private_object *tech_pvt); @@ -356,7 +362,7 @@ static switch_status_t exosip_on_init(switch_core_session_t *session) static const switch_codec_implementation_t *imp; for (i = 0; i < tech_pvt->num_codecs; i++) { - imp = tech_pvt->codecs[i]->implementations; + imp = tech_pvt->codecs[i]; while(NULL != imp) { uint32_t sps = imp->samples_per_second; @@ -1178,6 +1184,7 @@ static switch_status_t exosip_create_call(eXosip_event_t * event) char *displayname, *username; osip_header_t *tedious; char *val; + const switch_codec_implementation_t *imp = NULL; switch_core_session_add_stream(session, NULL); if ((tech_pvt = (struct private_object *) switch_core_session_alloc(session, sizeof(struct private_object))) != 0) { @@ -1310,10 +1317,10 @@ static switch_status_t exosip_create_call(eXosip_event_t * event) if (tech_pvt->num_codecs > 0) { int i; - static const switch_codec_implementation_t *imp; + static const switch_codec_implementation_t *imp = NULL; for (i = 0; i < tech_pvt->num_codecs; i++) { - for (imp = tech_pvt->codecs[i]->implementations; imp; imp = imp->next) { + for (imp = tech_pvt->codecs[i]; imp; imp = imp->next) { sdp_add_codec(tech_pvt->sdp_config, tech_pvt->codecs[i]->codec_type, imp->ianacode, imp->iananame, imp->samples_per_second, 0); @@ -1341,7 +1348,7 @@ static switch_status_t exosip_create_call(eXosip_event_t * event) for (pos = 0; audio_tab[pos] != NULL; pos++) { osip_rfc3264_complete_answer(tech_pvt->sdp_config, remote_sdp, tech_pvt->local_sdp, audio_tab[pos], mline); - if (parse_sdp_media(tech_pvt, audio_tab[pos], &dname, &drate, &dpayload) == SWITCH_STATUS_SUCCESS) { + if (parse_sdp_media(tech_pvt, audio_tab[pos], &dname, &drate, &dpayload, &imp) == SWITCH_STATUS_SUCCESS) { tech_pvt->payload_num = atoi(dpayload); goto done; } @@ -1381,6 +1388,12 @@ static switch_status_t exosip_create_call(eXosip_event_t * event) { int rate = atoi(drate); int ms = globals.codec_ms; + + + if (imp) { + ms = imp->microseconds_per_frame / 1000; + } + if (!strcasecmp(dname, "ilbc")) { ms = 30; } @@ -1487,13 +1500,19 @@ static void destroy_call_by_event(eXosip_event_t *event) } -static switch_status_t parse_sdp_media(struct private_object *tech_pvt, sdp_media_t * media, char **dname, char **drate, char **dpayload) +static switch_status_t parse_sdp_media(struct private_object *tech_pvt, + sdp_media_t * media, + char **dname, + char **drate, + char **dpayload, + const switch_codec_implementation_t **impp) { int pos = 0; sdp_attribute_t *attr = NULL; char *name, *payload, *rate; switch_status_t status = SWITCH_STATUS_GENERR; char workspace[512]; + const switch_codec_implementation_t *imp = NULL; while (osip_list_eol(media->a_attributes, pos) == 0) { attr = (sdp_attribute_t *) osip_list_get(media->a_attributes, pos); @@ -1523,10 +1542,8 @@ static switch_status_t parse_sdp_media(struct private_object *tech_pvt, sdp_medi } for(i = 0; !match && i < tech_pvt->num_codecs; i++) { - const switch_codec_implementation_t *imp; - - - for (imp = tech_pvt->codecs[i]->implementations; imp; imp = imp->next) { + + for (imp = tech_pvt->codecs[i]; imp; imp = imp->next) { if (pt < 97) { match = (pt == imp->ianacode) ? 1 : 0; @@ -1545,6 +1562,7 @@ static switch_status_t parse_sdp_media(struct private_object *tech_pvt, sdp_medi *dname = strdup(name); *drate = strdup(rate); *dpayload = strdup(payload); + *impp = imp; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Found negotiated codec Payload: %s Name: %s Rate: %s\n", *dpayload, *dname, *drate); return SWITCH_STATUS_SUCCESS; @@ -1654,7 +1672,7 @@ static void handle_answer(eXosip_event_t * event) struct private_object *tech_pvt; char *dpayload = NULL, *dname = NULL, *drate = NULL; switch_channel_t *channel; - + const switch_codec_implementation_t *imp = NULL; if ((tech_pvt = get_pvt_by_call_id(event->cid)) == 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "cannot answer nonexistant call [%d]!\n", event->cid); @@ -1686,22 +1704,25 @@ static void handle_answer(eXosip_event_t * event) snprintf(tech_pvt->remote_sdp_audio_ip, 50, conn->c_addr); /* Grab codec elements */ - if (parse_sdp_media(tech_pvt, remote_med, &dname, &drate, &dpayload) == SWITCH_STATUS_SUCCESS) { + if (parse_sdp_media(tech_pvt, remote_med, &dname, &drate, &dpayload, &imp) == SWITCH_STATUS_SUCCESS) { tech_pvt->payload_num = atoi(dpayload); } /* Assign them thar IDs */ tech_pvt->did = event->did; tech_pvt->tid = event->tid; - - { int rate = atoi(drate); int ms = globals.codec_ms; + if (!strcasecmp(dname, "ilbc")) { ms = 30; } + if (imp) { + ms = imp->microseconds_per_frame / 1000; + } + if (switch_core_codec_init(&tech_pvt->read_codec, dname, rate, diff --git a/src/mod/endpoints/mod_iax/mod_iax.c b/src/mod/endpoints/mod_iax/mod_iax.c index 213cb12a27..13ec157331 100644 --- a/src/mod/endpoints/mod_iax/mod_iax.c +++ b/src/mod/endpoints/mod_iax/mod_iax.c @@ -213,7 +213,7 @@ static switch_status_t iax_set_codec(struct private_object *tech_pvt, struct iax //int rate = 8000; //int codec_ms = 20; switch_channel_t *channel; - switch_codec_interface_t *codecs[SWITCH_MAX_CODECS]; + const switch_codec_implementation_t *codecs[SWITCH_MAX_CODECS]; int num_codecs = 0; unsigned int local_cap = 0, mixed_cap = 0, chosen = 0, leading = 0; int x, srate = 8000; @@ -235,7 +235,7 @@ static switch_status_t iax_set_codec(struct private_object *tech_pvt, struct iax for (x = 0; x < num_codecs; x++) { static const switch_codec_implementation_t *imp; - for (imp = codecs[x]->implementations; imp; imp = imp->next) { + for (imp = codecs[x]; imp; imp = imp->next) { unsigned int codec = iana2ast(imp->ianacode); if (io == IAX_QUERY) { @@ -251,7 +251,7 @@ static switch_status_t iax_set_codec(struct private_object *tech_pvt, struct iax mixed_cap = local_cap; } - leading = iana2ast(codecs[0]->implementations->ianacode); + leading = iana2ast(codecs[0]->ianacode); if (io == IAX_QUERY) { chosen = leading; *format = chosen; @@ -263,7 +263,7 @@ static switch_status_t iax_set_codec(struct private_object *tech_pvt, struct iax return SWITCH_STATUS_SUCCESS; } else if (switch_test_flag(&globals, GFLAG_MY_CODEC_PREFS) && (leading & mixed_cap)) { chosen = leading; - dname = codecs[0]->implementations->iananame; + dname = codecs[0]->iananame; } else { unsigned int prefs[32]; int len = 0; @@ -288,7 +288,7 @@ static switch_status_t iax_set_codec(struct private_object *tech_pvt, struct iax chosen = prefs[x]; for (z = 0; z < num_codecs; z++) { static const switch_codec_implementation_t *imp; - for (imp = codecs[z]->implementations; imp; imp = imp->next) { + for (imp = codecs[z]; imp; imp = imp->next) { if (prefs[x] == iana2ast(imp->ianacode)) { dname = imp->iananame; break; @@ -303,7 +303,7 @@ static switch_status_t iax_set_codec(struct private_object *tech_pvt, struct iax chosen = *format; for (x = 0; x < num_codecs; x++) { static const switch_codec_implementation_t *imp; - for (imp = codecs[x]->implementations; imp; imp = imp->next) { + for (imp = codecs[x]; imp; imp = imp->next) { unsigned int cap = iana2ast(imp->ianacode); if (cap == chosen) { dname = imp->iananame; @@ -314,7 +314,7 @@ static switch_status_t iax_set_codec(struct private_object *tech_pvt, struct iax } else { /* c'mon there has to be SOMETHING... */ for (x = 0; x < num_codecs; x++) { static const switch_codec_implementation_t *imp; - for (imp = codecs[x]->implementations; imp; imp = imp->next) { + for (imp = codecs[x]; imp; imp = imp->next) { unsigned int cap = iana2ast(imp->ianacode); if (cap & mixed_cap) { chosen = cap; diff --git a/src/switch_loadable_module.c b/src/switch_loadable_module.c index 475c6c79c4..da8fb9c930 100644 --- a/src/switch_loadable_module.c +++ b/src/switch_loadable_module.c @@ -633,16 +633,18 @@ SWITCH_DECLARE(switch_directory_interface_t *) switch_loadable_module_get_direct return switch_core_hash_find(loadable_modules.directory_hash, name); } -SWITCH_DECLARE(int) switch_loadable_module_get_codecs(switch_memory_pool_t *pool, switch_codec_interface_t **array, +SWITCH_DECLARE(int) switch_loadable_module_get_codecs(switch_memory_pool_t *pool, const switch_codec_implementation_t **array, int arraylen) { switch_hash_index_t *hi; void *val; + switch_codec_interface_t *codec_interface; int i = 0; for (hi = switch_hash_first(pool, loadable_modules.codec_hash); hi; hi = switch_hash_next(hi)) { switch_hash_this(hi, NULL, NULL, &val); - array[i++] = val; + codec_interface = (switch_codec_interface_t *) val; + array[i++] = codec_interface->implementations; if (i > arraylen) { break; } @@ -652,20 +654,44 @@ SWITCH_DECLARE(int) switch_loadable_module_get_codecs(switch_memory_pool_t *pool } -SWITCH_DECLARE(int) switch_loadable_module_get_codecs_sorted(switch_codec_interface_t **array, +SWITCH_DECLARE(int) switch_loadable_module_get_codecs_sorted(const switch_codec_implementation_t **array, int arraylen, char **prefs, int preflen) { int x, i = 0; switch_codec_interface_t *codec_interface; + const switch_codec_implementation_t *imp; - for (x = 0; x < preflen; x++) { - if ((codec_interface = switch_loadable_module_get_codec_interface(prefs[x])) != 0 ) { - array[i++] = codec_interface; - if (i > arraylen) { - break; + for (x = 0; x < preflen; x++) { + char *name, *p, buf[128]; + uint32_t interval = 0, len = 0; + + name = prefs[x]; + if ((p = strchr(name, '@'))) { + p++; + len = p-name; + + if (len > sizeof(buf)) { + len = sizeof(buf); + } + switch_copy_string(buf, name, len); + *(buf + len) = '\0'; + interval = atoi(p); + name = buf; + } + + if ((codec_interface = switch_loadable_module_get_codec_interface(name)) != 0 ) { + for (imp = codec_interface->implementations; imp; imp = imp->next) { + if (!interval) { + array[i++] = imp; + } else if ((imp->microseconds_per_frame / 1000) == interval) { + array[i++] = imp; + } } - } - } + if (i > arraylen) { + break; + } + } + } return i; }