From f689b62fb694b283079f01ee3593784a2f28ea86 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 8 Sep 2006 18:57:24 +0000 Subject: [PATCH] add dynamic buffers git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@2583 d0543943-73ff-0310-b7d9-9358b9ac24b2 --- src/include/switch_buffer.h | 19 +++++ src/include/switch_channel.h | 6 ++ .../mod_conference/mod_conference.c | 14 +++- src/mod/asr_tts/mod_cepstral/mod_cepstral.c | 7 +- src/mod/endpoints/mod_wanpipe/mod_wanpipe.c | 4 +- .../mod_spidermonkey/mod_spidermonkey.c | 9 ++- src/switch_buffer.c | 78 +++++++++++++++++++ src/switch_channel.c | 8 +- src/switch_core.c | 12 ++- 9 files changed, 143 insertions(+), 14 deletions(-) diff --git a/src/include/switch_buffer.h b/src/include/switch_buffer.h index ac06c9ef3b..e67f9defb0 100644 --- a/src/include/switch_buffer.h +++ b/src/include/switch_buffer.h @@ -62,6 +62,18 @@ struct switch_buffer; */ SWITCH_DECLARE(switch_status_t) switch_buffer_create(switch_memory_pool_t *pool, switch_buffer_t **buffer, switch_size_t max_len); +/*! \brief Allocate a new dynamic switch_buffer + * \param buffer returned pointer to the new buffer + * \param blocksize length to realloc by as data is added + * \param start_len ammount of memory to reserve initially + * \param max_len length the buffer is allowed to grow to + * \return status + */ +SWITCH_DECLARE(switch_status_t) switch_buffer_create_dynamic(switch_buffer_t **buffer, + switch_size_t blocksize, + switch_size_t start_len, + switch_size_t max_len); + /*! \brief Get the length of a switch_buffer_t * \param buffer any buffer of type switch_buffer_t * \return int size of the buffer. @@ -107,6 +119,13 @@ SWITCH_DECLARE(switch_size_t) switch_buffer_toss(switch_buffer_t *buffer, switch * \param buffer any buffer of type switch_buffer_t */ SWITCH_DECLARE(void) switch_buffer_zero(switch_buffer_t *buffer); + +/*! \brief Destroy the buffer + * \param buffer buffer to destroy + * \note only neccessary on dynamic buffers (noop on pooled ones) + */ +SWITCH_DECLARE(void) switch_buffer_destroy(switch_buffer_t **buffer); + /** @} */ SWITCH_END_EXTERN_C diff --git a/src/include/switch_channel.h b/src/include/switch_channel.h index c28c0c3156..ab19fdd435 100644 --- a/src/include/switch_channel.h +++ b/src/include/switch_channel.h @@ -136,6 +136,12 @@ SWITCH_DECLARE(switch_status_t) switch_channel_init(switch_channel_t *channel, switch_channel_state_t state, uint32_t flags); +/*! + \brief Uninitalize a channel + \param channel the channel to uninit +*/ +SWITCH_DECLARE(void) switch_channel_uninit(switch_channel_t *channel); + /*! \brief Set the given channel's caller profile \param channel channel to assign the profile to diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index c230649f8b..2aa596a331 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -40,6 +40,10 @@ static char *global_cf_name = "conference.conf"; #define CONF_EVENT_MAINT "conference::maintenence" #define CONF_DEFAULT_LEADIN 20 +#define CONF_DBLOCK_SIZE CONF_BUFFER_SIZE +#define CONF_DBUFFER_SIZE CONF_BUFFER_SIZE +#define CONF_DBUFFER_MAX 0 + typedef enum { FILE_STOP_CURRENT, FILE_STOP_ALL @@ -2355,7 +2359,7 @@ static void conference_function(switch_core_session_t *session, char *data) switch_core_session_get_pool(session)); /* Setup an audio buffer for the resampled audio */ - if (switch_buffer_create(pool, &member.resample_buffer, CONF_BUFFER_SIZE) != SWITCH_STATUS_SUCCESS) { + if (switch_buffer_create_dynamic(&member.resample_buffer, CONF_DBLOCK_SIZE, CONF_DBUFFER_SIZE, CONF_DBUFFER_MAX) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error Creating Audio Buffer!\n"); goto done; } @@ -2381,13 +2385,13 @@ static void conference_function(switch_core_session_t *session, char *data) } /* Setup an audio buffer for the incoming audio */ - if (switch_buffer_create(pool, &member.audio_buffer, CONF_BUFFER_SIZE) != SWITCH_STATUS_SUCCESS) { + if (switch_buffer_create_dynamic(&member.audio_buffer, CONF_DBLOCK_SIZE, CONF_DBUFFER_SIZE, CONF_DBUFFER_MAX) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error Creating Audio Buffer!\n"); goto codec_done1; } /* Setup an audio buffer for the outgoing audio */ - if (switch_buffer_create(pool, &member.mux_buffer, CONF_BUFFER_SIZE) != SWITCH_STATUS_SUCCESS) { + if (switch_buffer_create_dynamic(&member.mux_buffer, CONF_DBLOCK_SIZE, CONF_DBUFFER_SIZE, CONF_DBUFFER_MAX) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error Creating Audio Buffer!\n"); goto codec_done1; } @@ -2435,6 +2439,10 @@ static void conference_function(switch_core_session_t *session, char *data) switch_core_codec_destroy(&member.write_codec); done: + switch_buffer_destroy(&member.resample_buffer); + switch_buffer_destroy(&member.audio_buffer); + switch_buffer_destroy(&member.mux_buffer); + /* Release the config registry handle */ if (cxml) { switch_xml_free(cxml); diff --git a/src/mod/asr_tts/mod_cepstral/mod_cepstral.c b/src/mod/asr_tts/mod_cepstral/mod_cepstral.c index fe57d89a2f..fd332baa5f 100644 --- a/src/mod/asr_tts/mod_cepstral/mod_cepstral.c +++ b/src/mod/asr_tts/mod_cepstral/mod_cepstral.c @@ -42,7 +42,8 @@ #include #include -#define MY_BUF_LEN 1024 * 256 +#define MY_BUF_LEN 1024 * 32 +#define MY_BLOCK_SIZE MY_BUF_LEN static const char modname[] = "mod_cepstral"; @@ -119,7 +120,7 @@ static switch_status_t cepstral_speech_open(switch_speech_handle_t *sh, char *vo return SWITCH_STATUS_MEMERR; } - if (switch_buffer_create(sh->memory_pool, &cepstral->audio_buffer, MY_BUF_LEN) != SWITCH_STATUS_SUCCESS) { + if (switch_buffer_create_dynamic(&cepstral->audio_buffer, MY_BLOCK_SIZE, MY_BUF_LEN, 0) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Write Buffer Failed!\n"); return SWITCH_STATUS_MEMERR; } @@ -195,6 +196,8 @@ static switch_status_t cepstral_speech_close(switch_speech_handle_t *sh, switch_ cepstral->port = NULL; //cepstral->engine = NULL; + switch_buffer_destroy(&cepstral->audio_buffer); + return SWITCH_STATUS_SUCCESS; } diff --git a/src/mod/endpoints/mod_wanpipe/mod_wanpipe.c b/src/mod/endpoints/mod_wanpipe/mod_wanpipe.c index 6c0a7390a8..a34be814a1 100644 --- a/src/mod/endpoints/mod_wanpipe/mod_wanpipe.c +++ b/src/mod/endpoints/mod_wanpipe/mod_wanpipe.c @@ -370,6 +370,8 @@ static switch_status_t wanpipe_on_hangup(switch_core_session_t *session) teletone_destroy_session(&tech_pvt->tone_session); + switch_buffer_destroy(&tech_pvt->dtmf_buffer); + return SWITCH_STATUS_SUCCESS; } @@ -623,7 +625,7 @@ static switch_status_t wanpipe_send_dtmf(switch_core_session_t *session, char *d if (!tech_pvt->dtmf_buffer) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Allocate DTMF Buffer...."); - if (switch_buffer_create(switch_core_session_get_pool(session), &tech_pvt->dtmf_buffer, 3192) != SWITCH_STATUS_SUCCESS) { + if (switch_buffer_create_dynamic(&tech_pvt->dtmf_buffer, 1024, 3192, 0) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_ERROR, "Failed to allocate DTMF Buffer!\n"); return SWITCH_STATUS_FALSE; } else { diff --git a/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c b/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c index 3618319c1e..01c74d3e28 100644 --- a/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c +++ b/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c @@ -32,7 +32,8 @@ #ifndef HAVE_CURL #define HAVE_CURL #endif -#define JS_BUFFER_SIZE 131072 +#define JS_BUFFER_SIZE 1024 * 32 +#define JS_BLOCK_SIZE JS_BUFFER_SIZE #ifdef __ICC #pragma warning (disable:310 193 1418) #endif @@ -2007,7 +2008,7 @@ static JSBool teletone_construct(JSContext *cx, JSObject *obj, uintN argc, jsval } } - switch_buffer_create(pool, &tto->audio_buffer, JS_BUFFER_SIZE); + switch_buffer_create_dynamic(&tto->audio_buffer, JS_BLOCK_SIZE, JS_BUFFER_SIZE, 0); tto->pool = pool; tto->obj = obj; tto->cx = cx; @@ -2027,6 +2028,8 @@ static void teletone_destroy(JSContext *cx, JSObject *obj) switch_core_timer_destroy(tto->timer); } teletone_destroy_session(&tto->ts); + switch_buffer_destroy(&tto->audio_buffer); + switch_buffer_destroy(&tto->loop_buffer); switch_core_codec_destroy(&tto->codec); pool = tto->pool; tto->pool = NULL; @@ -2088,7 +2091,7 @@ static JSBool teletone_generate(JSContext *cx, JSObject *obj, uintN argc, jsval } loops--; if (!tto->loop_buffer) { - switch_buffer_create(tto->pool, &tto->loop_buffer, JS_BUFFER_SIZE); + switch_buffer_create_dynamic(&tto->loop_buffer, JS_BLOCK_SIZE, JS_BUFFER_SIZE, 0); } } diff --git a/src/switch_buffer.c b/src/switch_buffer.c index 7339aff906..1245378778 100644 --- a/src/switch_buffer.c +++ b/src/switch_buffer.c @@ -34,10 +34,17 @@ static uint32_t buffer_id = 0; +typedef enum { + SWITCH_BUFFER_FLAG_DYNAMIC = (1 << 0) +} switch_buffer_flag_t; + struct switch_buffer { unsigned char *data; switch_size_t used; switch_size_t datalen; + switch_size_t max_len; + switch_size_t blocksize; + uint32_t flags; uint32_t id; }; @@ -55,6 +62,37 @@ SWITCH_DECLARE(switch_status_t) switch_buffer_create(switch_memory_pool_t *pool, return SWITCH_STATUS_MEMERR; } +SWITCH_DECLARE(switch_status_t) switch_buffer_create_dynamic(switch_buffer_t **buffer, + switch_size_t blocksize, + switch_size_t start_len, + switch_size_t max_len) +{ + switch_buffer_t *new_buffer; + + if ((new_buffer = malloc(sizeof(*new_buffer)))) { + memset(new_buffer, 0, sizeof(*new_buffer)); + + if (start_len) { + if (!(new_buffer->data = malloc(start_len))) { + free(new_buffer); + return SWITCH_STATUS_MEMERR; + } + memset(new_buffer->data, 0, start_len); + } + + new_buffer->max_len = max_len; + new_buffer->datalen = start_len; + new_buffer->id = buffer_id++; + new_buffer->blocksize = blocksize; + switch_set_flag(new_buffer, SWITCH_BUFFER_FLAG_DYNAMIC); + + *buffer = new_buffer; + return SWITCH_STATUS_SUCCESS; + } + + return SWITCH_STATUS_MEMERR; +} + SWITCH_DECLARE(switch_size_t) switch_buffer_len(switch_buffer_t *buffer) { @@ -69,7 +107,15 @@ SWITCH_DECLARE(switch_size_t) switch_buffer_freespace(switch_buffer_t *buffer) { assert(buffer != NULL); + if (switch_test_flag(buffer, SWITCH_BUFFER_FLAG_DYNAMIC)) { + if (buffer->max_len) { + return (switch_size_t) (buffer->max_len - buffer->used); + } + return 1000000; + } + return (switch_size_t) (buffer->datalen - buffer->used); + } SWITCH_DECLARE(switch_size_t) switch_buffer_inuse(switch_buffer_t *buffer) @@ -131,8 +177,30 @@ SWITCH_DECLARE(switch_size_t) switch_buffer_write(switch_buffer_t *buffer, void assert(buffer != NULL); assert(data != NULL); assert(buffer->data != NULL); + + freespace = buffer->datalen - buffer->used; + + if (switch_test_flag(buffer, SWITCH_BUFFER_FLAG_DYNAMIC)) { + if (freespace < datalen) { + switch_size_t new_size, new_block_size; + + new_size = buffer->datalen + datalen; + new_block_size = buffer->datalen + buffer->blocksize; + + if (new_block_size > new_size) { + new_size = new_block_size; + } + + if (!(buffer->data = realloc(buffer->data, new_size))) { + return 0; + } + + buffer->datalen = new_size; + } + } freespace = buffer->datalen - buffer->used; + if (freespace < datalen) { return 0; } else { @@ -152,3 +220,13 @@ SWITCH_DECLARE(void) switch_buffer_zero(switch_buffer_t *buffer) buffer->used = 0; } + +SWITCH_DECLARE(void) switch_buffer_destroy(switch_buffer_t **buffer) +{ + if (*buffer && switch_test_flag((*buffer), SWITCH_BUFFER_FLAG_DYNAMIC)) { + free((*buffer)->data); + free(*buffer); + } + + *buffer = NULL; +} diff --git a/src/switch_channel.c b/src/switch_channel.c index dbf6c97374..753eb6c0be 100644 --- a/src/switch_channel.c +++ b/src/switch_channel.c @@ -164,7 +164,8 @@ SWITCH_DECLARE(switch_status_t) switch_channel_alloc(switch_channel_t **channel, switch_core_hash_init(&(*channel)->variables, pool); switch_core_hash_init(&(*channel)->private_hash, pool); - switch_buffer_create(pool, &(*channel)->dtmf_buffer, 128); + switch_buffer_create_dynamic(&(*channel)->dtmf_buffer, 128, 128, 0); + switch_mutex_init(&(*channel)->dtmf_mutex, SWITCH_MUTEX_NESTED, pool); switch_mutex_init(&(*channel)->flag_mutex, SWITCH_MUTEX_NESTED, pool); switch_mutex_init(&(*channel)->profile_mutex, SWITCH_MUTEX_NESTED, pool); @@ -282,6 +283,11 @@ SWITCH_DECLARE(switch_size_t) switch_channel_dequeue_dtmf(switch_channel_t *chan } +SWITCH_DECLARE(void) switch_channel_uninit(switch_channel_t *channel) +{ + switch_buffer_destroy(&channel->dtmf_buffer); +} + SWITCH_DECLARE(switch_status_t) switch_channel_init(switch_channel_t *channel, switch_core_session_t *session, switch_channel_state_t state, uint32_t flags) diff --git a/src/switch_core.c b/src/switch_core.c index 1208ba665b..f915fe1006 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -1465,9 +1465,9 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi perfect = TRUE; } else { if (!session->raw_read_buffer) { - switch_size_t bytes = session->read_codec->implementation->bytes_per_frame * 10; + switch_size_t bytes = session->read_codec->implementation->bytes_per_frame * 2; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Engaging Read Buffer at %u bytes\n", bytes); - switch_buffer_create(session->pool, &session->raw_read_buffer, bytes); + switch_buffer_create_dynamic(&session->raw_read_buffer, bytes, bytes, 0); } if (!switch_buffer_write(session->raw_read_buffer, read_frame->data, read_frame->datalen)) { status = SWITCH_STATUS_MEMERR; @@ -1671,13 +1671,13 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess perfect = TRUE; } else { if (!session->raw_write_buffer) { - switch_size_t bytes = session->write_codec->implementation->bytes_per_frame * 10; + switch_size_t bytes = session->write_codec->implementation->bytes_per_frame * 2; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Engaging Write Buffer at %u bytes to accomodate %u->%u\n", bytes, write_frame->datalen, session->write_codec->implementation->bytes_per_frame); if ((status = - switch_buffer_create(session->pool, &session->raw_write_buffer, bytes)) != SWITCH_STATUS_SUCCESS) { + switch_buffer_create_dynamic(&session->raw_write_buffer, bytes, bytes, 0)) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Write Buffer Failed!\n"); return status; } @@ -2643,6 +2643,10 @@ SWITCH_DECLARE(void) switch_core_session_destroy(switch_core_session_t **session switch_event_fire(&event); } + switch_buffer_destroy(&(*session)->raw_read_buffer); + switch_buffer_destroy(&(*session)->raw_write_buffer); + switch_channel_uninit((*session)->channel); + pool = (*session)->pool; *session = NULL; apr_pool_destroy(pool);