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);
/*! \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

View File

@ -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

View File

@ -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);

View File

@ -42,7 +42,8 @@
#include <swift.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";
@ -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;
}

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);
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 {

View File

@ -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);
}
}

View File

@ -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;
}

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)->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)

View File

@ -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);