]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
add dynamic buffers
authorAnthony Minessale <anthony.minessale@gmail.com>
Fri, 8 Sep 2006 18:57:24 +0000 (18:57 +0000)
committerAnthony Minessale <anthony.minessale@gmail.com>
Fri, 8 Sep 2006 18:57:24 +0000 (18:57 +0000)
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@2583 d0543943-73ff-0310-b7d9-9358b9ac24b2

src/include/switch_buffer.h
src/include/switch_channel.h
src/mod/applications/mod_conference/mod_conference.c
src/mod/asr_tts/mod_cepstral/mod_cepstral.c
src/mod/endpoints/mod_wanpipe/mod_wanpipe.c
src/mod/languages/mod_spidermonkey/mod_spidermonkey.c
src/switch_buffer.c
src/switch_channel.c
src/switch_core.c

index ac06c9ef3b780b9a339ca7ce9edffa9180d2e411..e67f9defb09fc256397226a8c57d4056d96a5058 100644 (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
index c28c0c3156683ff337711460ac0527616a950fd7..ab19fdd4356ebf2cbb2c732a2546cbfd8909e71f 100644 (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
index c230649f8b2166f3dcbb11842ef2b930716c9fb6..2aa596a3312dfa1cdcde0ceb48861663c2b7e104 100644 (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);
index fe57d89a2fcada2b4492a812db3c38aca2551861..fd332baa5f6d8fd948f9411c53b48b4858952a51 100644 (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;
 }
 
index 6c0a7390a8b8126b6c9af40827d3a425aa80b9d0..a34be814a13b874bd3434c6e98e823947d034fbe 100644 (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 {
index 3618319c1eb7a2e34accdc1ec200da75d18416b3..01c74d3e2822c23d0992d30a1b04b7b9dbafdcd1 100644 (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);
                        }
                } 
 
index 7339aff906fd03d4b75914d9150f8d5585c5056b..1245378778eac95510edbd01428c8f31af6cdcd1 100644 (file)
 
 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;
+}
index dbf6c973748f3a506e07c101fc814275854e123c..753eb6c0be004753e8cc9f1967974df22104ad4c 100644 (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)
index 1208ba665b0a3ddfb202f6650d6fe60410f3c175..f915fe100617664cd6da9c9276b4d4f4c67e3d1a 100644 (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);