add dynamic buffers

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@2583 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Anthony Minessale 2006-09-08 18:57:24 +00:00
parent 4960fbc73f
commit f689b62fb6
9 changed files with 143 additions and 14 deletions

View File

@ -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); 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 /*! \brief Get the length of a switch_buffer_t
* \param buffer any buffer of type switch_buffer_t * \param buffer any buffer of type switch_buffer_t
* \return int size of the buffer. * \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 * \param buffer any buffer of type switch_buffer_t
*/ */
SWITCH_DECLARE(void) switch_buffer_zero(switch_buffer_t *buffer); 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 SWITCH_END_EXTERN_C

View File

@ -136,6 +136,12 @@ SWITCH_DECLARE(switch_status_t) switch_channel_init(switch_channel_t *channel,
switch_channel_state_t state, switch_channel_state_t state,
uint32_t flags); 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 \brief Set the given channel's caller profile
\param channel channel to assign the profile to \param channel channel to assign the profile to

View File

@ -40,6 +40,10 @@ static char *global_cf_name = "conference.conf";
#define CONF_EVENT_MAINT "conference::maintenence" #define CONF_EVENT_MAINT "conference::maintenence"
#define CONF_DEFAULT_LEADIN 20 #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 { typedef enum {
FILE_STOP_CURRENT, FILE_STOP_CURRENT,
FILE_STOP_ALL FILE_STOP_ALL
@ -2355,7 +2359,7 @@ static void conference_function(switch_core_session_t *session, char *data)
switch_core_session_get_pool(session)); switch_core_session_get_pool(session));
/* Setup an audio buffer for the resampled audio */ /* 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"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error Creating Audio Buffer!\n");
goto done; 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 */ /* 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"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error Creating Audio Buffer!\n");
goto codec_done1; goto codec_done1;
} }
/* Setup an audio buffer for the outgoing audio */ /* 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"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error Creating Audio Buffer!\n");
goto codec_done1; 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); switch_core_codec_destroy(&member.write_codec);
done: done:
switch_buffer_destroy(&member.resample_buffer);
switch_buffer_destroy(&member.audio_buffer);
switch_buffer_destroy(&member.mux_buffer);
/* Release the config registry handle */ /* Release the config registry handle */
if (cxml) { if (cxml) {
switch_xml_free(cxml); switch_xml_free(cxml);

View File

@ -42,7 +42,8 @@
#include <swift.h> #include <swift.h>
#include <switch.h> #include <switch.h>
#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"; 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; 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"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Write Buffer Failed!\n");
return SWITCH_STATUS_MEMERR; 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->port = NULL;
//cepstral->engine = NULL; //cepstral->engine = NULL;
switch_buffer_destroy(&cepstral->audio_buffer);
return SWITCH_STATUS_SUCCESS; return SWITCH_STATUS_SUCCESS;
} }

View File

@ -370,6 +370,8 @@ static switch_status_t wanpipe_on_hangup(switch_core_session_t *session)
teletone_destroy_session(&tech_pvt->tone_session); teletone_destroy_session(&tech_pvt->tone_session);
switch_buffer_destroy(&tech_pvt->dtmf_buffer);
return SWITCH_STATUS_SUCCESS; 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) { if (!tech_pvt->dtmf_buffer) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Allocate 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"); switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_ERROR, "Failed to allocate DTMF Buffer!\n");
return SWITCH_STATUS_FALSE; return SWITCH_STATUS_FALSE;
} else { } else {

View File

@ -32,7 +32,8 @@
#ifndef HAVE_CURL #ifndef HAVE_CURL
#define HAVE_CURL #define HAVE_CURL
#endif #endif
#define JS_BUFFER_SIZE 131072 #define JS_BUFFER_SIZE 1024 * 32
#define JS_BLOCK_SIZE JS_BUFFER_SIZE
#ifdef __ICC #ifdef __ICC
#pragma warning (disable:310 193 1418) #pragma warning (disable:310 193 1418)
#endif #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->pool = pool;
tto->obj = obj; tto->obj = obj;
tto->cx = cx; tto->cx = cx;
@ -2027,6 +2028,8 @@ static void teletone_destroy(JSContext *cx, JSObject *obj)
switch_core_timer_destroy(tto->timer); switch_core_timer_destroy(tto->timer);
} }
teletone_destroy_session(&tto->ts); teletone_destroy_session(&tto->ts);
switch_buffer_destroy(&tto->audio_buffer);
switch_buffer_destroy(&tto->loop_buffer);
switch_core_codec_destroy(&tto->codec); switch_core_codec_destroy(&tto->codec);
pool = tto->pool; pool = tto->pool;
tto->pool = NULL; tto->pool = NULL;
@ -2088,7 +2091,7 @@ static JSBool teletone_generate(JSContext *cx, JSObject *obj, uintN argc, jsval
} }
loops--; loops--;
if (!tto->loop_buffer) { 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);
} }
} }

View File

@ -34,10 +34,17 @@
static uint32_t buffer_id = 0; static uint32_t buffer_id = 0;
typedef enum {
SWITCH_BUFFER_FLAG_DYNAMIC = (1 << 0)
} switch_buffer_flag_t;
struct switch_buffer { struct switch_buffer {
unsigned char *data; unsigned char *data;
switch_size_t used; switch_size_t used;
switch_size_t datalen; switch_size_t datalen;
switch_size_t max_len;
switch_size_t blocksize;
uint32_t flags;
uint32_t id; uint32_t id;
}; };
@ -55,6 +62,37 @@ SWITCH_DECLARE(switch_status_t) switch_buffer_create(switch_memory_pool_t *pool,
return SWITCH_STATUS_MEMERR; 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) 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); 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); return (switch_size_t) (buffer->datalen - buffer->used);
} }
SWITCH_DECLARE(switch_size_t) switch_buffer_inuse(switch_buffer_t *buffer) 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(buffer != NULL);
assert(data != NULL); assert(data != NULL);
assert(buffer->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; freespace = buffer->datalen - buffer->used;
if (freespace < datalen) { if (freespace < datalen) {
return 0; return 0;
} else { } else {
@ -152,3 +220,13 @@ SWITCH_DECLARE(void) switch_buffer_zero(switch_buffer_t *buffer)
buffer->used = 0; 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;
}

View File

@ -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)->variables, pool);
switch_core_hash_init(&(*channel)->private_hash, 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)->dtmf_mutex, SWITCH_MUTEX_NESTED, pool);
switch_mutex_init(&(*channel)->flag_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); 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_DECLARE(switch_status_t) switch_channel_init(switch_channel_t *channel,
switch_core_session_t *session, switch_core_session_t *session,
switch_channel_state_t state, uint32_t flags) switch_channel_state_t state, uint32_t flags)

View File

@ -1465,9 +1465,9 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi
perfect = TRUE; perfect = TRUE;
} else { } else {
if (!session->raw_read_buffer) { 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_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)) { if (!switch_buffer_write(session->raw_read_buffer, read_frame->data, read_frame->datalen)) {
status = SWITCH_STATUS_MEMERR; status = SWITCH_STATUS_MEMERR;
@ -1671,13 +1671,13 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess
perfect = TRUE; perfect = TRUE;
} else { } else {
if (!session->raw_write_buffer) { 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, switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
"Engaging Write Buffer at %u bytes to accomodate %u->%u\n", "Engaging Write Buffer at %u bytes to accomodate %u->%u\n",
bytes, bytes,
write_frame->datalen, session->write_codec->implementation->bytes_per_frame); write_frame->datalen, session->write_codec->implementation->bytes_per_frame);
if ((status = 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"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Write Buffer Failed!\n");
return status; return status;
} }
@ -2643,6 +2643,10 @@ SWITCH_DECLARE(void) switch_core_session_destroy(switch_core_session_t **session
switch_event_fire(&event); 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; pool = (*session)->pool;
*session = NULL; *session = NULL;
apr_pool_destroy(pool); apr_pool_destroy(pool);