diff --git a/src/include/switch_core.h b/src/include/switch_core.h index 1763ecaf7d..5de4c944b7 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -77,7 +77,7 @@ SWITCH_DECLARE(void *) switch_core_hash_find(switch_hash *hash, char *key); SWITCH_DECLARE(void) switch_core_launch_thread(void *(*func)(switch_thread *, void*), void *obj); SWITCH_DECLARE(FILE *) switch_core_data_channel(switch_text_channel channel); SWITCH_DECLARE(void) switch_core_session_launch_thread(switch_core_session *session, void *(*func)(switch_thread *, void *), void *obj); -SWITCH_DECLARE(switch_status) switch_core_timer_init(switch_timer *timer, char *timer_name, int interval, int samples); +SWITCH_DECLARE(switch_status) switch_core_timer_init(switch_timer *timer, char *timer_name, int interval, int samples, switch_memory_pool *pool); SWITCH_DECLARE(int) switch_core_timer_next(switch_timer *timer); SWITCH_DECLARE(switch_status) switch_core_timer_destroy(switch_timer *timer); SWITCH_DECLARE(void) switch_core_thread_session_end(switch_core_thread_session *thread_session); @@ -101,7 +101,7 @@ SWITCH_DECLARE(switch_status) switch_core_session_add_event_hook_kill_channel(sw SWITCH_DECLARE(switch_status) switch_core_session_add_event_hook_waitfor_read(switch_core_session *session, switch_waitfor_read_hook waitfor_read); SWITCH_DECLARE(switch_status) switch_core_session_add_event_hook_waitfor_write(switch_core_session *session, switch_waitfor_write_hook waitfor_write); SWITCH_DECLARE(switch_status) switch_core_session_add_event_hook_send_dtmf(switch_core_session *session, switch_send_dtmf_hook send_dtmf); -SWITCH_DECLARE(switch_status) switch_core_codec_init(switch_codec *codec, char *codec_name, int rate, int ms, switch_codec_flag flags, const switch_codec_settings *codec_settings); +SWITCH_DECLARE(switch_status) switch_core_codec_init(switch_codec *codec, char *codec_name, int rate, int ms, switch_codec_flag flags, const switch_codec_settings *codec_settings, switch_memory_pool *pool); SWITCH_DECLARE(switch_status) switch_core_codec_encode(switch_codec *codec, switch_codec *other_codec, void *decoded_data, diff --git a/src/include/switch_loadable_module.h b/src/include/switch_loadable_module.h index 1d7e8f49a7..ba30fcae50 100644 --- a/src/include/switch_loadable_module.h +++ b/src/include/switch_loadable_module.h @@ -47,6 +47,7 @@ struct switch_loadable_module_interface { const switch_codec_interface *codec_interface; const switch_application_interface *application_interface; const switch_api_interface *api_interface; + const switch_file_interface *file_interface; }; SWITCH_DECLARE(switch_status) switch_loadable_module_init(void); @@ -59,6 +60,7 @@ SWITCH_DECLARE(switch_api_interface *) loadable_module_get_api_interface(char *n SWITCH_DECLARE(int) loadable_module_get_codecs(switch_memory_pool *pool, switch_codec_interface **array, int arraylen); SWITCH_DECLARE(int) loadable_module_get_codecs_sorted(switch_memory_pool *pool, switch_codec_interface **array, int arraylen, char **prefs, int preflen); SWITCH_DECLARE(switch_status) switch_api_execute(char *cmd, char *arg, char *retbuf, size_t len); +SWITCH_DECLARE(switch_api_interface *) loadable_module_get_file_interface(char *name); SWITCH_DECLARE(void) loadable_module_shutdown(void); #ifdef __cplusplus diff --git a/src/include/switch_module_interfaces.h b/src/include/switch_module_interfaces.h index 33cd8e0be2..c038105830 100644 --- a/src/include/switch_module_interfaces.h +++ b/src/include/switch_module_interfaces.h @@ -135,6 +135,7 @@ struct switch_endpoint_interface { struct switch_timer { int interval; + unsigned int flags; unsigned int samples; unsigned int samplecount; struct switch_timer_interface *timer_interface; @@ -158,16 +159,20 @@ struct switch_dialplan_interface { struct switch_file_interface { const char *interface_name; + switch_status (*file_open)(switch_file_handle *); + switch_status (*file_close)(switch_file_handle *); + switch_status (*file_read)(switch_file_handle *, void *data, size_t len); + switch_status (*file_write)(switch_file_handle *, void *data, size_t len); + switch_status (*file_seek)(switch_file_handle *, unsigned int samples, int whence); const struct switch_file_interface *next; const char *extens[]; - }; struct switch_file_handle { const struct switch_file_interface *file_interface; + unsigned int flags; switch_file_t *fd; unsigned int sample_count; - switch_codec_flag flags; switch_memory_pool *memory_pool; void *private; }; diff --git a/src/include/switch_types.h b/src/include/switch_types.h index 087bd82159..265bf3b039 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -109,9 +109,14 @@ typedef enum { SWITCH_CODEC_FLAG_SILENCE_START = (1 << 2), SWITCH_CODEC_FLAG_SILENCE_STOP = (1 << 3), SWITCH_CODEC_FLAG_SILENCE = (1 << 4), + SWITCH_CODEC_FLAG_FREE_POOL = (1 << 5), } switch_codec_flag; +typedef enum { + SWITCH_TIMER_FLAG_FREE_POOL = (1 << 0), +} switch_timer_flag; + typedef enum { SWITCH_CODEC_TYPE_AUDIO, SWITCH_CODEC_TYPE_VIDEO, @@ -158,6 +163,8 @@ typedef struct switch_dialplan_interface switch_dialplan_interface; typedef struct switch_codec_interface switch_codec_interface; typedef struct switch_application_interface switch_application_interface; typedef struct switch_api_interface switch_api_interface; +typedef struct switch_file_interface switch_file_interface; +typedef struct switch_file_handle switch_file_handle; typedef struct switch_core_session switch_core_session; typedef struct switch_loadable_module_interface switch_loadable_module_interface; typedef struct switch_caller_profile switch_caller_profile; diff --git a/src/mod/mod_exosip/mod_exosip.c b/src/mod/mod_exosip/mod_exosip.c index 3b07d79645..ee9e17c308 100644 --- a/src/mod/mod_exosip/mod_exosip.c +++ b/src/mod/mod_exosip/mod_exosip.c @@ -887,21 +887,23 @@ static switch_status exosip_create_call(eXosip_event_t *event) int rate = atoi(drate); if (switch_core_codec_init(&tech_pvt->read_codec, - dname, - rate, - globals.codec_ms, - SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, - NULL) != SWITCH_STATUS_SUCCESS) { + dname, + rate, + globals.codec_ms, + SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, + NULL, + switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) { switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Can't load codec?\n"); switch_channel_hangup(channel); return SWITCH_STATUS_FALSE; } else { if (switch_core_codec_init(&tech_pvt->write_codec, - dname, - rate, - globals.codec_ms, - SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, - NULL) != SWITCH_STATUS_SUCCESS) { + dname, + rate, + globals.codec_ms, + SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, + NULL, + switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) { switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Can't load codec?\n"); switch_channel_hangup(channel); return SWITCH_STATUS_FALSE; @@ -1046,12 +1048,24 @@ static void handle_answer(eXosip_event_t *event) int rate = atoi(drate); - if (switch_core_codec_init(&tech_pvt->read_codec, dname, rate, globals.codec_ms, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL) != SWITCH_STATUS_SUCCESS) { + if (switch_core_codec_init(&tech_pvt->read_codec, + dname, + rate, + globals.codec_ms, + SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, + NULL, + switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) { switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Can't load codec?\n"); switch_channel_hangup(channel); return; } else { - if (switch_core_codec_init(&tech_pvt->write_codec, dname, rate, globals.codec_ms, SWITCH_CODEC_FLAG_ENCODE |SWITCH_CODEC_FLAG_DECODE, NULL) != SWITCH_STATUS_SUCCESS) { + if (switch_core_codec_init(&tech_pvt->write_codec, + dname, + rate, + globals.codec_ms, + SWITCH_CODEC_FLAG_ENCODE |SWITCH_CODEC_FLAG_DECODE, + NULL, + switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) { switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Can't load codec?\n"); switch_channel_hangup(channel); return; diff --git a/src/mod/mod_iaxchan/mod_iaxchan.c b/src/mod/mod_iaxchan/mod_iaxchan.c index ae5f78a683..7c192da8c3 100644 --- a/src/mod/mod_iaxchan/mod_iaxchan.c +++ b/src/mod/mod_iaxchan/mod_iaxchan.c @@ -276,7 +276,8 @@ static switch_status iax_set_codec(struct private_object *tech_pvt, struct iax_s 0, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, - NULL) != SWITCH_STATUS_SUCCESS) { + NULL, + switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) { switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Can't load codec?\n"); return SWITCH_STATUS_GENERR; } else { @@ -284,7 +285,9 @@ static switch_status iax_set_codec(struct private_object *tech_pvt, struct iax_s dname, 0, 0, - SWITCH_CODEC_FLAG_ENCODE |SWITCH_CODEC_FLAG_DECODE, NULL) != SWITCH_STATUS_SUCCESS) { + SWITCH_CODEC_FLAG_ENCODE |SWITCH_CODEC_FLAG_DECODE, + NULL, + switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) { switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Can't load codec?\n"); switch_core_codec_destroy(&tech_pvt->read_codec); return SWITCH_STATUS_GENERR; @@ -476,7 +479,7 @@ static switch_status channel_outgoing_channel(switch_core_session *session, swit { if ((*new_session = switch_core_session_request(&channel_endpoint_interface, NULL))) { struct private_object *tech_pvt; - switch_channel *channel, *orig_channel; + switch_channel *channel; switch_caller_profile *caller_profile; unsigned int req = 0, cap = 0; diff --git a/src/mod/mod_playback/mod_playback.c b/src/mod/mod_playback/mod_playback.c index 207068dec0..6a1bbabf90 100644 --- a/src/mod/mod_playback/mod_playback.c +++ b/src/mod/mod_playback/mod_playback.c @@ -51,6 +51,7 @@ void playback_function(switch_core_session *session, char *data) switch_timer timer; switch_core_thread_session thread_session; switch_codec codec; + switch_memory_pool *pool = switch_core_session_get_pool(session); char *codec_name; int x; @@ -70,7 +71,7 @@ void playback_function(switch_core_session *session, char *data) write_frame.data = buf; write_frame.buflen = sizeof(buf); - if (switch_file_open(&fd, data, SWITCH_FOPEN_READ, SWITCH_FPROT_UREAD, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) { + if (switch_file_open(&fd, data, SWITCH_FOPEN_READ, SWITCH_FPROT_UREAD, pool) != SWITCH_STATUS_SUCCESS) { switch_console_printf(SWITCH_CHANNEL_CONSOLE, "OPEN FILE FAILED\n"); switch_channel_hangup(channel); return; @@ -94,7 +95,7 @@ void playback_function(switch_core_session *session, char *data) write_frame.samples = samples; /* You can use zap instead of soft if you have it loaded */ - if (switch_core_timer_init(&timer, "soft", interval, samples) != SWITCH_STATUS_SUCCESS) { + if (switch_core_timer_init(&timer, "soft", interval, samples, pool) != SWITCH_STATUS_SUCCESS) { switch_console_printf(SWITCH_CHANNEL_CONSOLE, "setup timer failed!\n"); switch_channel_hangup(channel); return; @@ -102,7 +103,7 @@ void playback_function(switch_core_session *session, char *data) switch_console_printf(SWITCH_CHANNEL_CONSOLE, "setup timer success %d bytes per %d ms!\n", len, interval); - if (switch_core_codec_init(&codec, codec_name, 8000, interval, SWITCH_CODEC_FLAG_ENCODE|SWITCH_CODEC_FLAG_DECODE, NULL) == SWITCH_STATUS_SUCCESS) { + if (switch_core_codec_init(&codec, codec_name, 8000, interval, SWITCH_CODEC_FLAG_ENCODE|SWITCH_CODEC_FLAG_DECODE, NULL, pool) == SWITCH_STATUS_SUCCESS) { switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Raw Codec Activated\n"); write_frame.codec = &codec; } else { diff --git a/src/mod/mod_portaudio/mod_portaudio.c b/src/mod/mod_portaudio/mod_portaudio.c index 3084616823..1d727e09a4 100644 --- a/src/mod/mod_portaudio/mod_portaudio.c +++ b/src/mod/mod_portaudio/mod_portaudio.c @@ -700,19 +700,22 @@ static switch_status engage_device(struct private_object *tech_pvt) assert(channel != NULL); if (switch_core_codec_init(&tech_pvt->read_codec, - "L16", - sample_rate, - codec_ms, - SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, - NULL) != SWITCH_STATUS_SUCCESS) { + "L16", + sample_rate, + codec_ms, + SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, + NULL, + switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) { switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Can't load codec?\n"); return SWITCH_STATUS_FALSE; } else { if (switch_core_codec_init(&tech_pvt->write_codec, - "L16", - sample_rate, - codec_ms, - SWITCH_CODEC_FLAG_ENCODE |SWITCH_CODEC_FLAG_DECODE, NULL) != SWITCH_STATUS_SUCCESS) { + "L16", + sample_rate, + codec_ms, + SWITCH_CODEC_FLAG_ENCODE |SWITCH_CODEC_FLAG_DECODE, + NULL, + switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) { switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Can't load codec?\n"); switch_core_codec_destroy(&tech_pvt->read_codec); return SWITCH_STATUS_FALSE; diff --git a/src/mod/mod_rawaudio/mod_rawaudio.c b/src/mod/mod_rawaudio/mod_rawaudio.c index 13bf549eeb..89e4b43d06 100644 --- a/src/mod/mod_rawaudio/mod_rawaudio.c +++ b/src/mod/mod_rawaudio/mod_rawaudio.c @@ -81,9 +81,36 @@ static switch_status switch_raw_destroy(switch_codec *codec) return SWITCH_STATUS_SUCCESS; } +switch_status raw_file_open(switch_file_handle *handle) +{ + return SWITCH_STATUS_SUCCESS; +} + +switch_status raw_file_close(switch_file_handle *handle) +{ + return SWITCH_STATUS_SUCCESS; +} + +switch_status raw_file_seek(switch_file_handle *handle, unsigned int samples, int whence) +{ + return SWITCH_STATUS_NOTIMPL; +} + /* Registration */ +static const switch_file_interface raw_file_interface = { + /*.interface_name*/ "raw", + /*.file_open*/ raw_file_open, + /*.file_close*/ raw_file_close, + /*.file_read*/ NULL, + /*.file_write*/ NULL, + /*.file_seek*/ raw_file_seek, + /*.next*/ NULL, + /*.extens*/ {"raw", "r8k"} +}; + + static const switch_codec_implementation raw_32k_implementation = { /*.samples_per_second = */ 32000, /*.bits_per_second = */ 512000, @@ -167,7 +194,9 @@ static switch_loadable_module_interface raw_module_interface = { /*.timer_interface*/ NULL, /*.dialplan_interface*/ NULL, /*.codec_interface*/ &raw_codec_interface, - /*.application_interface*/ NULL + /*.application_interface*/ NULL, + /*.api_interface*/ NULL, + /*.file_interface*/ &raw_file_interface }; diff --git a/src/mod/mod_woomerachan/mod_woomerachan.c b/src/mod/mod_woomerachan/mod_woomerachan.c index bac736d0cc..d82bce62f3 100644 --- a/src/mod/mod_woomerachan/mod_woomerachan.c +++ b/src/mod/mod_woomerachan/mod_woomerachan.c @@ -207,13 +207,13 @@ static switch_status woomerachan_on_init(switch_core_session *session) tech_pvt->frame.data = tech_pvt->databuf; - if (switch_core_codec_init(&tech_pvt->read_codec, "L16", 8000, 30, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL) != SWITCH_STATUS_SUCCESS) { + if (switch_core_codec_init(&tech_pvt->read_codec, "L16", 8000, 30, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) { switch_console_printf(SWITCH_CHANNEL_CONSOLE, "%s Cannot set read codec\n", switch_channel_get_name(channel)); switch_channel_hangup(channel); return SWITCH_STATUS_FALSE; } - if (switch_core_codec_init(&tech_pvt->write_codec, "L16", 8000, 30, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL) != SWITCH_STATUS_SUCCESS) { + if (switch_core_codec_init(&tech_pvt->write_codec, "L16", 8000, 30, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) { switch_console_printf(SWITCH_CHANNEL_CONSOLE, "%s Cannot set read codec\n", switch_channel_get_name(channel)); switch_channel_hangup(channel); return SWITCH_STATUS_FALSE; @@ -347,7 +347,7 @@ static switch_status woomerachan_outgoing_channel(switch_core_session *session, { if ((*new_session = switch_core_session_request(&woomerachan_endpoint_interface, NULL))) { struct private_object *tech_pvt; - switch_channel *channel, *orig_channel; + switch_channel *channel; if ((tech_pvt = (struct private_object *) switch_core_session_alloc(*new_session, sizeof(struct private_object)))) { diff --git a/src/switch_core.c b/src/switch_core.c index 6ba4c5b29b..254134f1da 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -202,7 +202,7 @@ SWITCH_DECLARE(switch_status) switch_core_session_set_write_codec(switch_core_se return SWITCH_STATUS_SUCCESS; } -SWITCH_DECLARE(switch_status) switch_core_codec_init(switch_codec *codec, char *codec_name, int rate, int ms, switch_codec_flag flags, const switch_codec_settings *codec_settings) +SWITCH_DECLARE(switch_status) switch_core_codec_init(switch_codec *codec, char *codec_name, int rate, int ms, switch_codec_flag flags, const switch_codec_settings *codec_settings, switch_memory_pool *pool) { const switch_codec_interface *codec_interface; const switch_codec_implementation *iptr, *implementation = NULL; @@ -229,8 +229,14 @@ SWITCH_DECLARE(switch_status) switch_core_codec_init(switch_codec *codec, char * codec->codec_interface = codec_interface; codec->implementation = implementation; codec->flags = flags; - if ((status = switch_core_new_memory_pool(&codec->memory_pool)) != SWITCH_STATUS_SUCCESS) { - return status; + + if (pool) { + codec->memory_pool = pool; + } else { + if ((status = switch_core_new_memory_pool(&codec->memory_pool)) != SWITCH_STATUS_SUCCESS) { + return status; + } + switch_set_flag(codec, SWITCH_CODEC_FLAG_FREE_POOL); } implementation->init(codec, flags, codec_settings); @@ -301,11 +307,15 @@ SWITCH_DECLARE(switch_status) switch_core_codec_destroy(switch_codec *codec) } codec->implementation->destroy(codec); - switch_core_destroy_memory_pool(&codec->memory_pool); + + if (switch_test_flag(codec, SWITCH_CODEC_FLAG_FREE_POOL)) { + switch_core_destroy_memory_pool(&codec->memory_pool); + } + return SWITCH_STATUS_SUCCESS; } -SWITCH_DECLARE(switch_status) switch_core_timer_init(switch_timer *timer, char *timer_name, int interval, int samples) +SWITCH_DECLARE(switch_status) switch_core_timer_init(switch_timer *timer, char *timer_name, int interval, int samples, switch_memory_pool *pool) { switch_timer_interface *timer_interface; switch_status status; @@ -319,8 +329,14 @@ SWITCH_DECLARE(switch_status) switch_core_timer_init(switch_timer *timer, char * timer->samples = samples; timer->samplecount = 0; timer->timer_interface = timer_interface; - if ((status = switch_core_new_memory_pool(&timer->memory_pool)) != SWITCH_STATUS_SUCCESS) { - return status; + + if (pool) { + timer->memory_pool = pool; + } else { + if ((status = switch_core_new_memory_pool(&timer->memory_pool)) != SWITCH_STATUS_SUCCESS) { + return status; + } + switch_set_flag(timer, SWITCH_TIMER_FLAG_FREE_POOL); } timer->timer_interface->timer_init(timer); @@ -352,7 +368,11 @@ SWITCH_DECLARE(switch_status) switch_core_timer_destroy(switch_timer *timer) } timer->timer_interface->timer_destroy(timer); - switch_core_destroy_memory_pool(&timer->memory_pool); + + if (switch_test_flag(timer, SWITCH_TIMER_FLAG_FREE_POOL)) { + switch_core_destroy_memory_pool(&timer->memory_pool); + } + return SWITCH_STATUS_SUCCESS; } diff --git a/src/switch_loadable_module.c b/src/switch_loadable_module.c index d35f1b0323..ef756fa658 100644 --- a/src/switch_loadable_module.c +++ b/src/switch_loadable_module.c @@ -61,6 +61,7 @@ struct switch_loadable_module_container { switch_hash *timer_hash; switch_hash *application_hash; switch_hash *api_hash; + switch_hash *file_hash; switch_memory_pool *pool; }; @@ -214,6 +215,7 @@ SWITCH_DECLARE(switch_status) switch_loadable_module_init() switch_core_hash_init(&loadable_modules.timer_hash, loadable_modules.pool); switch_core_hash_init(&loadable_modules.application_hash, loadable_modules.pool); switch_core_hash_init(&loadable_modules.api_hash, loadable_modules.pool); + switch_core_hash_init(&loadable_modules.file_hash, loadable_modules.pool); switch_core_hash_init(&loadable_modules.dialplan_hash, loadable_modules.pool); while (apr_dir_read(&finfo, finfo_flags, module_dir_handle) == APR_SUCCESS) { @@ -317,6 +319,20 @@ SWITCH_DECLARE(switch_status) switch_loadable_module_init() } } + if (new_module->interface->file_interface) { + const switch_file_interface *ptr; + + for(ptr = new_module->interface->file_interface; ptr; ptr = ptr->next) { + int i; + for (i = 0 ; ptr->extens[i]; i++) { + switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Adding File Format '%s'\n", ptr->extens[i]); + switch_core_hash_insert(loadable_modules.api_hash, + (char *) ptr->extens[i], + (void *) ptr); + } + } + } + } } @@ -375,6 +391,11 @@ SWITCH_DECLARE(switch_api_interface *) loadable_module_get_api_interface(char *n return switch_core_hash_find(loadable_modules.api_hash, name); } +SWITCH_DECLARE(switch_api_interface *) loadable_module_get_file_interface(char *name) +{ + return switch_core_hash_find(loadable_modules.file_hash, name); +} + SWITCH_DECLARE(int) loadable_module_get_codecs(switch_memory_pool *pool, switch_codec_interface **array, int arraylen) { switch_hash_index_t* hi;