restructure codec code

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@1818 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Anthony Minessale 2006-07-10 22:08:02 +00:00
parent e9fc56225f
commit 2838ad4a9b
12 changed files with 123 additions and 64 deletions

View File

@ -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 \param arraylen the max size in elements of the array
\return the number of elements added to 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_DECLARE(int) switch_loadable_module_get_codecs(switch_memory_pool_t *pool, const switch_codec_implementation_t **array,
switch_codec_interface_t **array,
int arraylen); int arraylen);
/*! /*!
\brief Retrieve the list of loaded codecs into an array based on another array showing the sorted order \brief Retrieve the list of loaded codecs into an array based on another array showing the sorted order
\param array the array to populate \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 \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. \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, SWITCH_DECLARE(int) switch_loadable_module_get_codecs_sorted(const switch_codec_implementation_t **array,
int arraylen, int arraylen, char **prefs, int preflen);
char **prefs,
int preflen);
/*! /*!
\brief Execute a registered API command \brief Execute a registered API command

View File

@ -444,6 +444,8 @@ struct switch_codec {
/*! \brief A table of settings and callbacks that define a paticular implementation of a codec */ /*! \brief A table of settings and callbacks that define a paticular implementation of a codec */
struct switch_codec_implementation { struct switch_codec_implementation {
/*! enumeration defining the type of the codec */
const switch_codec_type_t codec_type;
/*! the IANA code number */ /*! the IANA code number */
switch_payload_t ianacode; switch_payload_t ianacode;
/*! the IANA code name */ /*! the IANA code name */
@ -497,8 +499,6 @@ struct switch_codec_implementation {
struct switch_codec_interface { struct switch_codec_interface {
/*! the name of the interface */ /*! the name of the interface */
const char *interface_name; 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 */ /*! a list of codec implementations related to the codec */
const switch_codec_implementation_t *implementations; const switch_codec_implementation_t *implementations;
const struct switch_codec_interface *next; const struct switch_codec_interface *next;

View File

@ -190,6 +190,7 @@ static switch_status_t switch_g711a_destroy(switch_codec_t *codec)
#if 0 #if 0
static const switch_codec_implementation_t g711u_8k_60ms_implementation = { static const switch_codec_implementation_t g711u_8k_60ms_implementation = {
/*.codec_type */ SWITCH_CODEC_TYPE_AUDIO,
/*.ianacode */ 0, /*.ianacode */ 0,
/*.iananame */ "PCMU", /*.iananame */ "PCMU",
/*.samples_per_second */ 8000, /*.samples_per_second */ 8000,
@ -206,9 +207,10 @@ static const switch_codec_implementation_t g711u_8k_60ms_implementation = {
/*.decode */ switch_g711u_decode, /*.decode */ switch_g711u_decode,
/*.destroy */ switch_g711u_destroy /*.destroy */ switch_g711u_destroy
}; };
#endif
static const switch_codec_implementation_t g711u_8k_30ms_implementation = { static const switch_codec_implementation_t g711u_8k_30ms_implementation = {
/*.codec_type */ SWITCH_CODEC_TYPE_AUDIO,
/*.ianacode */ 0, /*.ianacode */ 0,
/*.iananame */ "PCMU", /*.iananame */ "PCMU",
/*.samples_per_second */ 8000, /*.samples_per_second */ 8000,
@ -224,11 +226,11 @@ static const switch_codec_implementation_t g711u_8k_30ms_implementation = {
/*.encode */ switch_g711u_encode, /*.encode */ switch_g711u_encode,
/*.decode */ switch_g711u_decode, /*.decode */ switch_g711u_decode,
/*.destroy */ switch_g711u_destroy, /*.destroy */ switch_g711u_destroy,
/*.next */ &g711u_8k_60ms_implementation /*.next */ NULL
}; };
#endif
static const switch_codec_implementation_t g711u_16k_implementation = { static const switch_codec_implementation_t g711u_16k_implementation = {
/*.codec_type */ SWITCH_CODEC_TYPE_AUDIO,
/*.ianacode */ 0, /*.ianacode */ 0,
/*.iananame */ "PCMU", /*.iananame */ "PCMU",
/*.samples_per_second */ 16000, /*.samples_per_second */ 16000,
@ -244,9 +246,11 @@ static const switch_codec_implementation_t g711u_16k_implementation = {
/*.encode */ switch_g711u_encode, /*.encode */ switch_g711u_encode,
/*.decode */ switch_g711u_decode, /*.decode */ switch_g711u_decode,
/*.destroy */ switch_g711u_destroy, /*.destroy */ switch_g711u_destroy,
/*.next */ &g711u_8k_30ms_implementation
}; };
static const switch_codec_implementation_t g711u_8k_implementation = { static const switch_codec_implementation_t g711u_8k_implementation = {
/*.codec_type */ SWITCH_CODEC_TYPE_AUDIO,
/*.ianacode */ 0, /*.ianacode */ 0,
/*.iananame */ "PCMU", /*.iananame */ "PCMU",
/*.samples_per_second */ 8000, /*.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 = { static const switch_codec_implementation_t g711a_8k_implementation = {
/*.codec_type */ SWITCH_CODEC_TYPE_AUDIO,
/*.ianacode */ 8, /*.ianacode */ 8,
/*.iananame */ "PCMA", /*.iananame */ "PCMA",
/*.samples_per_second */ 8000, /*.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 = { static const switch_codec_interface_t g711a_codec_interface = {
/*.interface_name */ "g711 alaw", /*.interface_name */ "g711 alaw",
/*.codec_type */ SWITCH_CODEC_TYPE_AUDIO,
/*.implementations */ &g711a_8k_implementation /*.implementations */ &g711a_8k_implementation
}; };
static const switch_codec_interface_t g711u_codec_interface = { static const switch_codec_interface_t g711u_codec_interface = {
/*.interface_name */ "g711 ulaw", /*.interface_name */ "g711 ulaw",
/*.codec_type */ SWITCH_CODEC_TYPE_AUDIO,
/*.implementations */ &g711u_8k_implementation, /*.implementations */ &g711u_8k_implementation,
/*.next */ &g711a_codec_interface /*.next */ &g711a_codec_interface
}; };

View File

@ -219,6 +219,7 @@ static switch_status_t switch_g729_decode(switch_codec_t *codec,
/* Registration */ /* Registration */
static const switch_codec_implementation_t g729_10ms_8k_implementation = { static const switch_codec_implementation_t g729_10ms_8k_implementation = {
/*.codec_type */ SWITCH_CODEC_TYPE_AUDIO,
/*.ianacode */ 18, /*.ianacode */ 18,
/*.iananame */ "G729", /*.iananame */ "G729",
/*.samples_per_second */ 8000, /*.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 = { static const switch_codec_implementation_t g729_8k_implementation = {
/*.codec_type */ SWITCH_CODEC_TYPE_AUDIO,
/*.ianacode */ 18, /*.ianacode */ 18,
/*.iananame */ "G729", /*.iananame */ "G729",
/*.samples_per_second */ 8000, /*.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 = { static const switch_codec_interface_t g729_codec_interface = {
/*.interface_name */ "g729", /*.interface_name */ "g729",
/*.codec_type */ SWITCH_CODEC_TYPE_AUDIO,
/*.implementations */ &g729_8k_implementation, /*.implementations */ &g729_8k_implementation,
}; };

View File

@ -133,6 +133,7 @@ static switch_status_t switch_gsm_decode(switch_codec_t *codec, switch_codec_t *
/* Registration */ /* Registration */
static const switch_codec_implementation_t gsm_8k_implementation = { static const switch_codec_implementation_t gsm_8k_implementation = {
/*.codec_type */ SWITCH_CODEC_TYPE_AUDIO,
/*.ianacode */ 3, /*.ianacode */ 3,
/*.iananame */ "gsm", /*.iananame */ "gsm",
/*.samples_per_second */ 8000, /*.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 = { static const switch_codec_interface_t gsm_codec_interface = {
/*.interface_name */ "gsm", /*.interface_name */ "gsm",
/*.codec_type */ SWITCH_CODEC_TYPE_AUDIO,
/*.implementations */ &gsm_8k_implementation, /*.implementations */ &gsm_8k_implementation,
}; };
static switch_loadable_module_interface_t gsm_module_interface = { static switch_loadable_module_interface_t gsm_module_interface = {

View File

@ -186,6 +186,7 @@ static switch_status_t switch_ilbc_decode(switch_codec_t *codec,
/* Registration */ /* Registration */
static const switch_codec_implementation_t ilbc_8k_30ms_implementation = { static const switch_codec_implementation_t ilbc_8k_30ms_implementation = {
/*.codec_type */ SWITCH_CODEC_TYPE_AUDIO,
/*.ianacode */ 97, /*.ianacode */ 97,
/*.iananame */ "iLBC", /*.iananame */ "iLBC",
/*.samples_per_second */ 8000, /*.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 = { static const switch_codec_implementation_t ilbc_8k_20ms_implementation = {
/*.codec_type */ SWITCH_CODEC_TYPE_AUDIO,
/*.ianacode */ 97, /*.ianacode */ 97,
/*.iananame */ "iLBC", /*.iananame */ "iLBC",
/*.samples_per_second */ 8000, /*.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 = { static const switch_codec_implementation_t ilbc_102_8k_30ms_implementation = {
/*.codec_type */ SWITCH_CODEC_TYPE_AUDIO,
/*.ianacode */ 102, /*.ianacode */ 102,
/*.iananame */ "iLBC", /*.iananame */ "iLBC",
/*.samples_per_second */ 8000, /*.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 = { static const switch_codec_implementation_t ilbc_102_8k_20ms_implementation = {
/*.codec_type */ SWITCH_CODEC_TYPE_AUDIO,
/*.ianacode */ 102, /*.ianacode */ 102,
/*.iananame */ "iLBC102", /*.iananame */ "iLBC102",
/*.samples_per_second */ 8000, /*.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 = { static const switch_codec_implementation_t ilbc_8k_20ms_nonext_implementation = {
/*.codec_type */ SWITCH_CODEC_TYPE_AUDIO,
/*.ianacode */ 97, /*.ianacode */ 97,
/*.iananame */ "iLBC20ms", /*.iananame */ "iLBC20ms",
/*.samples_per_second */ 8000, /*.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 = { static const switch_codec_interface_t ilbc_20ms_codec_interface = {
/*.interface_name */ "ilbc", /*.interface_name */ "ilbc",
/*.codec_type */ SWITCH_CODEC_TYPE_AUDIO,
/*.implementations */ &ilbc_8k_20ms_nonext_implementation /*.implementations */ &ilbc_8k_20ms_nonext_implementation
}; };
static const switch_codec_interface_t ilbc_102_codec_interface = { static const switch_codec_interface_t ilbc_102_codec_interface = {
/*.interface_name */ "ilbc", /*.interface_name */ "ilbc",
/*.codec_type */ SWITCH_CODEC_TYPE_AUDIO,
/*.implementations */ &ilbc_102_8k_20ms_implementation, /*.implementations */ &ilbc_102_8k_20ms_implementation,
/*.next*/ &ilbc_20ms_codec_interface /*.next*/ &ilbc_20ms_codec_interface
}; };
static const switch_codec_interface_t ilbc_codec_interface = { static const switch_codec_interface_t ilbc_codec_interface = {
/*.interface_name */ "ilbc", /*.interface_name */ "ilbc",
/*.codec_type */ SWITCH_CODEC_TYPE_AUDIO,
/*.implementations */ &ilbc_8k_20ms_implementation, /*.implementations */ &ilbc_8k_20ms_implementation,
/*.next*/ &ilbc_102_codec_interface /*.next*/ &ilbc_102_codec_interface
}; };

View File

@ -90,6 +90,7 @@ static switch_status_t switch_raw_destroy(switch_codec_t *codec)
} }
static const switch_codec_implementation_t raw_32k_implementation = { static const switch_codec_implementation_t raw_32k_implementation = {
/*.codec_type */ SWITCH_CODEC_TYPE_AUDIO,
/*.ianacode */ 10, /*.ianacode */ 10,
/*.iananame */ "L16", /*.iananame */ "L16",
/*.samples_per_second = */ 32000, /*.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 = { static const switch_codec_implementation_t raw_22k_implementation = {
/*.codec_type */ SWITCH_CODEC_TYPE_AUDIO,
/*.ianacode */ 10, /*.ianacode */ 10,
/*.iananame */ "L16", /*.iananame */ "L16",
/*.samples_per_second = */ 22050, /*.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 = { static const switch_codec_implementation_t raw_16k_implementation = {
/*.codec_type */ SWITCH_CODEC_TYPE_AUDIO,
/*.ianacode */ 10, /*.ianacode */ 10,
/*.iananame */ "L16", /*.iananame */ "L16",
/*.samples_per_second = */ 16000, /*.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 = { static const switch_codec_implementation_t raw_8k_implementation = {
/*.codec_type */ SWITCH_CODEC_TYPE_AUDIO,
/*.ianacode */ 10, /*.ianacode */ 10,
/*.iananame */ "L16", /*.iananame */ "L16",
/*.samples_per_second = */ 8000, /*.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 = { static const switch_codec_implementation_t raw_8k_30ms_implementation = {
/*.codec_type */ SWITCH_CODEC_TYPE_AUDIO,
/*.ianacode */ 10, /*.ianacode */ 10,
/*.iananame */ "L16", /*.iananame */ "L16",
/*.samples_per_second */ 8000, /*.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 = { static const switch_codec_implementation_t raw_8k_60ms_implementation = {
/*.codec_type */ SWITCH_CODEC_TYPE_AUDIO,
/*.ianacode */ 10, /*.ianacode */ 10,
/*.iananame */ "L16", /*.iananame */ "L16",
/*.samples_per_second */ 8000, /*.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 = { static const switch_codec_implementation_t raw_8k_120ms_implementation = {
/*.codec_type */ SWITCH_CODEC_TYPE_AUDIO,
/*.ianacode */ 10, /*.ianacode */ 10,
/*.iananame */ "L16", /*.iananame */ "L16",
/*.samples_per_second */ 8000, /*.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 = { static const switch_codec_interface_t raw_codec_interface = {
/*.interface_name */ "raw signed linear (16 bit)", /*.interface_name */ "raw signed linear (16 bit)",
/*.codec_type */ SWITCH_CODEC_TYPE_AUDIO,
/*.implementations */ &raw_8k_120ms_implementation /*.implementations */ &raw_8k_120ms_implementation
}; };

View File

@ -268,6 +268,7 @@ static switch_status_t switch_speex_destroy(switch_codec_t *codec)
/* Registration */ /* Registration */
static const switch_codec_implementation_t speex_32k_implementation = { static const switch_codec_implementation_t speex_32k_implementation = {
/*.codec_type */ SWITCH_CODEC_TYPE_AUDIO,
/*.ianacode */ 98, /*.ianacode */ 98,
/*.iananame */ "speex", /*.iananame */ "speex",
/*.samples_per_second */ 32000, /*.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 = { static const switch_codec_implementation_t speex_16k_implementation = {
/*.codec_type */ SWITCH_CODEC_TYPE_AUDIO,
/*.ianacode */ 98, /*.ianacode */ 98,
/*.iananame */ "speex", /*.iananame */ "speex",
/*.samples_per_second */ 16000, /*.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 = { static const switch_codec_implementation_t speex_8k_implementation = {
/*.codec_type */ SWITCH_CODEC_TYPE_AUDIO,
/*.ianacode */ 98, /*.ianacode */ 98,
/*.iananame */ "speex", /*.iananame */ "speex",
/*.samples_per_second */ 8000, /*.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 = { static const switch_codec_interface_t speex_codec_interface = {
/*.interface_name */ "speex", /*.interface_name */ "speex",
/*.codec_type */ SWITCH_CODEC_TYPE_AUDIO,
/*.implementations */ &speex_8k_implementation /*.implementations */ &speex_8k_implementation
}; };

View File

@ -113,7 +113,7 @@ struct private_object {
switch_caller_profile_t *caller_profile; switch_caller_profile_t *caller_profile;
unsigned short samprate; unsigned short samprate;
switch_mutex_t *mutex; 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; unsigned int num_codecs;
int codec_index; int codec_index;
switch_rtp_t *rtp_session; 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 (force || !switch_test_flag(tech_pvt, TFLAG_CODEC_READY)) {
if (tech_pvt->codec_index < 0) { 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"); 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_name = lame(tech_pvt->codecs[0]->iananame);
tech_pvt->codec_num = tech_pvt->codecs[0]->implementations->ianacode; tech_pvt->codec_num = tech_pvt->codecs[0]->ianacode;
tech_pvt->codec_index = 0; tech_pvt->codec_index = 0;
payloads[0].name = lame(tech_pvt->codecs[0]->implementations->iananame); payloads[0].name = lame(tech_pvt->codecs[0]->iananame);
payloads[0].id = tech_pvt->codecs[0]->implementations->ianacode; payloads[0].id = tech_pvt->codecs[0]->ianacode;
} else { } else {
payloads[0].name = lame(tech_pvt->codecs[tech_pvt->codec_index]->implementations->iananame); payloads[0].name = lame(tech_pvt->codecs[tech_pvt->codec_index]->iananame);
payloads[0].id = tech_pvt->codecs[tech_pvt->codec_index]->implementations->ianacode; 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++) { 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); 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++) { 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)) { if (!strncasecmp(name, "ilbc", 4)) {
name = "ilbc"; 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; match = strcasecmp(name, payloads[x].name) ? 0 : 1;
} else { } 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) { if (match) {
tech_pvt->codec_index = y; 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); 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_name = tech_pvt->codecs[y]->iananame;
tech_pvt->codec_num = tech_pvt->codecs[y]->implementations->ianacode; tech_pvt->codec_num = tech_pvt->codecs[y]->ianacode;
if (!switch_test_flag(tech_pvt, TFLAG_OUTBOUND)) { if (!switch_test_flag(tech_pvt, TFLAG_OUTBOUND)) {
do_describe(tech_pvt, 0); do_describe(tech_pvt, 0);
} }

View File

@ -138,7 +138,7 @@ struct private_object {
int ssrc; int ssrc;
switch_time_t last_read; switch_time_t last_read;
char *realm; char *realm;
switch_codec_interface_t *codecs[SWITCH_MAX_CODECS]; const switch_codec_implementation_t *codecs[SWITCH_MAX_CODECS];
int num_codecs; int num_codecs;
switch_payload_t te; switch_payload_t te;
switch_mutex_t *flag_mutex; 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, 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); switch_io_flag_t flags, int stream_id);
static int config_exosip(int reload); 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 exosip_kill_channel(switch_core_session_t *session, int sig);
static switch_status_t activate_rtp(struct private_object *tech_pvt); static switch_status_t activate_rtp(struct private_object *tech_pvt);
static void deactivate_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; static const switch_codec_implementation_t *imp;
for (i = 0; i < tech_pvt->num_codecs; i++) { for (i = 0; i < tech_pvt->num_codecs; i++) {
imp = tech_pvt->codecs[i]->implementations; imp = tech_pvt->codecs[i];
while(NULL != imp) { while(NULL != imp) {
uint32_t sps = imp->samples_per_second; 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; char *displayname, *username;
osip_header_t *tedious; osip_header_t *tedious;
char *val; char *val;
const switch_codec_implementation_t *imp = NULL;
switch_core_session_add_stream(session, NULL); switch_core_session_add_stream(session, NULL);
if ((tech_pvt = (struct private_object *) switch_core_session_alloc(session, sizeof(struct private_object))) != 0) { 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) { if (tech_pvt->num_codecs > 0) {
int i; 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 (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, sdp_add_codec(tech_pvt->sdp_config, tech_pvt->codecs[i]->codec_type, imp->ianacode, imp->iananame,
imp->samples_per_second, 0); 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++) { 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], osip_rfc3264_complete_answer(tech_pvt->sdp_config, remote_sdp, tech_pvt->local_sdp, audio_tab[pos],
mline); 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); tech_pvt->payload_num = atoi(dpayload);
goto done; goto done;
} }
@ -1381,6 +1388,12 @@ static switch_status_t exosip_create_call(eXosip_event_t * event)
{ {
int rate = atoi(drate); int rate = atoi(drate);
int ms = globals.codec_ms; int ms = globals.codec_ms;
if (imp) {
ms = imp->microseconds_per_frame / 1000;
}
if (!strcasecmp(dname, "ilbc")) { if (!strcasecmp(dname, "ilbc")) {
ms = 30; 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; int pos = 0;
sdp_attribute_t *attr = NULL; sdp_attribute_t *attr = NULL;
char *name, *payload, *rate; char *name, *payload, *rate;
switch_status_t status = SWITCH_STATUS_GENERR; switch_status_t status = SWITCH_STATUS_GENERR;
char workspace[512]; char workspace[512];
const switch_codec_implementation_t *imp = NULL;
while (osip_list_eol(media->a_attributes, pos) == 0) { while (osip_list_eol(media->a_attributes, pos) == 0) {
attr = (sdp_attribute_t *) osip_list_get(media->a_attributes, pos); 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++) { for(i = 0; !match && i < tech_pvt->num_codecs; i++) {
const switch_codec_implementation_t *imp;
for (imp = tech_pvt->codecs[i]; imp; imp = imp->next) {
for (imp = tech_pvt->codecs[i]->implementations; imp; imp = imp->next) {
if (pt < 97) { if (pt < 97) {
match = (pt == imp->ianacode) ? 1 : 0; 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); *dname = strdup(name);
*drate = strdup(rate); *drate = strdup(rate);
*dpayload = strdup(payload); *dpayload = strdup(payload);
*impp = imp;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Found negotiated codec Payload: %s Name: %s Rate: %s\n", switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Found negotiated codec Payload: %s Name: %s Rate: %s\n",
*dpayload, *dname, *drate); *dpayload, *dname, *drate);
return SWITCH_STATUS_SUCCESS; return SWITCH_STATUS_SUCCESS;
@ -1654,7 +1672,7 @@ static void handle_answer(eXosip_event_t * event)
struct private_object *tech_pvt; struct private_object *tech_pvt;
char *dpayload = NULL, *dname = NULL, *drate = NULL; char *dpayload = NULL, *dname = NULL, *drate = NULL;
switch_channel_t *channel; switch_channel_t *channel;
const switch_codec_implementation_t *imp = NULL;
if ((tech_pvt = get_pvt_by_call_id(event->cid)) == 0) { 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); 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); snprintf(tech_pvt->remote_sdp_audio_ip, 50, conn->c_addr);
/* Grab codec elements */ /* 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); tech_pvt->payload_num = atoi(dpayload);
} }
/* Assign them thar IDs */ /* Assign them thar IDs */
tech_pvt->did = event->did; tech_pvt->did = event->did;
tech_pvt->tid = event->tid; tech_pvt->tid = event->tid;
{ {
int rate = atoi(drate); int rate = atoi(drate);
int ms = globals.codec_ms; int ms = globals.codec_ms;
if (!strcasecmp(dname, "ilbc")) { if (!strcasecmp(dname, "ilbc")) {
ms = 30; ms = 30;
} }
if (imp) {
ms = imp->microseconds_per_frame / 1000;
}
if (switch_core_codec_init(&tech_pvt->read_codec, if (switch_core_codec_init(&tech_pvt->read_codec,
dname, dname,
rate, rate,

View File

@ -213,7 +213,7 @@ static switch_status_t iax_set_codec(struct private_object *tech_pvt, struct iax
//int rate = 8000; //int rate = 8000;
//int codec_ms = 20; //int codec_ms = 20;
switch_channel_t *channel; 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; int num_codecs = 0;
unsigned int local_cap = 0, mixed_cap = 0, chosen = 0, leading = 0; unsigned int local_cap = 0, mixed_cap = 0, chosen = 0, leading = 0;
int x, srate = 8000; 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++) { for (x = 0; x < num_codecs; x++) {
static const switch_codec_implementation_t *imp; 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); unsigned int codec = iana2ast(imp->ianacode);
if (io == IAX_QUERY) { 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; mixed_cap = local_cap;
} }
leading = iana2ast(codecs[0]->implementations->ianacode); leading = iana2ast(codecs[0]->ianacode);
if (io == IAX_QUERY) { if (io == IAX_QUERY) {
chosen = leading; chosen = leading;
*format = chosen; *format = chosen;
@ -263,7 +263,7 @@ static switch_status_t iax_set_codec(struct private_object *tech_pvt, struct iax
return SWITCH_STATUS_SUCCESS; return SWITCH_STATUS_SUCCESS;
} else if (switch_test_flag(&globals, GFLAG_MY_CODEC_PREFS) && (leading & mixed_cap)) { } else if (switch_test_flag(&globals, GFLAG_MY_CODEC_PREFS) && (leading & mixed_cap)) {
chosen = leading; chosen = leading;
dname = codecs[0]->implementations->iananame; dname = codecs[0]->iananame;
} else { } else {
unsigned int prefs[32]; unsigned int prefs[32];
int len = 0; int len = 0;
@ -288,7 +288,7 @@ static switch_status_t iax_set_codec(struct private_object *tech_pvt, struct iax
chosen = prefs[x]; chosen = prefs[x];
for (z = 0; z < num_codecs; z++) { for (z = 0; z < num_codecs; z++) {
static const switch_codec_implementation_t *imp; 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)) { if (prefs[x] == iana2ast(imp->ianacode)) {
dname = imp->iananame; dname = imp->iananame;
break; break;
@ -303,7 +303,7 @@ static switch_status_t iax_set_codec(struct private_object *tech_pvt, struct iax
chosen = *format; chosen = *format;
for (x = 0; x < num_codecs; x++) { for (x = 0; x < num_codecs; x++) {
static const switch_codec_implementation_t *imp; 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); unsigned int cap = iana2ast(imp->ianacode);
if (cap == chosen) { if (cap == chosen) {
dname = imp->iananame; 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... */ } else { /* c'mon there has to be SOMETHING... */
for (x = 0; x < num_codecs; x++) { for (x = 0; x < num_codecs; x++) {
static const switch_codec_implementation_t *imp; 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); unsigned int cap = iana2ast(imp->ianacode);
if (cap & mixed_cap) { if (cap & mixed_cap) {
chosen = cap; chosen = cap;

View File

@ -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); 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) int arraylen)
{ {
switch_hash_index_t *hi; switch_hash_index_t *hi;
void *val; void *val;
switch_codec_interface_t *codec_interface;
int i = 0; int i = 0;
for (hi = switch_hash_first(pool, loadable_modules.codec_hash); hi; hi = switch_hash_next(hi)) { for (hi = switch_hash_first(pool, loadable_modules.codec_hash); hi; hi = switch_hash_next(hi)) {
switch_hash_this(hi, NULL, NULL, &val); 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) { if (i > arraylen) {
break; 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 arraylen, char **prefs, int preflen)
{ {
int x, i = 0; int x, i = 0;
switch_codec_interface_t *codec_interface; switch_codec_interface_t *codec_interface;
const switch_codec_implementation_t *imp;
for (x = 0; x < preflen; x++) { for (x = 0; x < preflen; x++) {
if ((codec_interface = switch_loadable_module_get_codec_interface(prefs[x])) != 0 ) { char *name, *p, buf[128];
array[i++] = codec_interface; uint32_t interval = 0, len = 0;
if (i > arraylen) {
break; 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; return i;
} }