]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
adjustment
authorAnthony Minessale <anthony.minessale@gmail.com>
Thu, 18 Dec 2008 23:07:32 +0000 (23:07 +0000)
committerAnthony Minessale <anthony.minessale@gmail.com>
Thu, 18 Dec 2008 23:07:32 +0000 (23:07 +0000)
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@10876 d0543943-73ff-0310-b7d9-9358b9ac24b2

src/include/switch_core.h
src/include/switch_utils.h
src/mod/endpoints/mod_sofia/mod_sofia.c
src/mod/endpoints/mod_sofia/sofia_glue.c
src/switch_core_codec.c
src/switch_core_io.c

index 7670435c3087d5a1f1a2524866e433ec8b8d4b3f..0abeb677649f79c9fabccf4fc291ffd253879573 100644 (file)
@@ -1165,6 +1165,12 @@ SWITCH_DECLARE(void) switch_core_session_unset_read_codec(_In_ switch_core_sessi
 SWITCH_DECLARE(void) switch_core_session_unset_write_codec(_In_ switch_core_session_t *session);
 
 
+SWITCH_DECLARE(void) switch_core_session_lock_codec_write(_In_ switch_core_session_t *session);
+SWITCH_DECLARE(void) switch_core_session_unlock_codec_write(_In_ switch_core_session_t *session);
+SWITCH_DECLARE(void) switch_core_session_lock_codec_read(_In_ switch_core_session_t *session);
+SWITCH_DECLARE(void) switch_core_session_unlock_codec_read(_In_ switch_core_session_t *session);
+
+
 SWITCH_DECLARE(switch_status_t) switch_core_session_get_read_impl(switch_core_session_t *session,  switch_codec_implementation_t *impp);
 SWITCH_DECLARE(switch_status_t) switch_core_session_get_write_impl(switch_core_session_t *session,  switch_codec_implementation_t *impp);
 SWITCH_DECLARE(switch_status_t) switch_core_session_get_video_read_impl(switch_core_session_t *session,  switch_codec_implementation_t *impp);
index 5ebc534bee4ab0253766ffc2b4c3a8894cb806a6..b35a3cf7ce33c847602b09b48c2dd0a318b5f7f6 100644 (file)
@@ -56,7 +56,7 @@ SWITCH_DECLARE(int) switch_isspace(int c);
 SWITCH_DECLARE(int) switch_isupper(int c);
 SWITCH_DECLARE(int) switch_isxdigit(int c);
 
-
+#define switch_goto_status(_status, _label) status = _status; goto _label
 #define switch_samples_per_packet(rate, interval) ((uint32_t)((float)rate / (1000.0f / (float)interval)))
 #define SWITCH_SMAX 32767
 #define SWITCH_SMIN -32768
index b3575dced95b3bc5cb5f4fa87b0f56a9fad5599c..9d1fe5beda7a2fbfe1a03c813b77e5b3b66cd9e1 100644 (file)
@@ -738,14 +738,20 @@ static switch_status_t sofia_read_frame(switch_core_session_t *session, switch_f
                                                                        tech_pvt->codec_ms = codec_ms;
                                                                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, 
                                                                                                          "Changing codec ptime to %d. I bet you have a linksys/sipura =D\n", tech_pvt->codec_ms);
-                                                                       switch_core_codec_destroy(&tech_pvt->read_codec);
+
+                                                                       switch_core_session_lock_codec_write(session);
+                                                                       switch_core_session_lock_codec_read(session);
+
+                                                                       switch_core_codec_destroy(&tech_pvt->read_codec);                                                                       
                                                                        switch_core_codec_destroy(&tech_pvt->write_codec);
+                                                                       
                                                                        if (sofia_glue_tech_set_codec(tech_pvt, 2) != SWITCH_STATUS_SUCCESS) {
                                                                                *frame = NULL;
+                                                                               switch_core_session_unlock_codec_write(session);
+                                                                               switch_core_session_unlock_codec_read(session);
                                                                                return SWITCH_STATUS_GENERR;
                                                                        }
-
-
+                                                                       
                                                                        if ((val = switch_channel_get_variable(tech_pvt->channel, "rtp_timeout_sec"))) {
                                                                                int v = atoi(val);
                                                                                if (v >= 0) {
@@ -784,6 +790,10 @@ static switch_status_t sofia_read_frame(switch_core_session_t *session, switch_f
                                                                        }
 
                                                                        tech_pvt->check_frames = MAX_CODEC_CHECK_FRAMES;
+
+                                                                       switch_core_session_unlock_codec_write(session);
+                                                                       switch_core_session_unlock_codec_read(session);
+
                                                                }
                                                        
                                                        }
index 888cc4a062a6e3f13b8aae1eedc42e2d432cb7bd..40f52ac0b1a9613cc5cf3ab7bd1b5810c535453d 100644 (file)
@@ -1532,27 +1532,32 @@ switch_status_t sofia_glue_tech_set_video_codec(private_object_t *tech_pvt, int
 switch_status_t sofia_glue_tech_set_codec(private_object_t *tech_pvt, int force)
 {
        int ms;
-
+       switch_status_t status = SWITCH_STATUS_SUCCESS;
+       int resetting = 0;
+       
        if (!tech_pvt->iananame) {
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No audio codec available\n");
-               return SWITCH_STATUS_FALSE;
+               switch_goto_status(SWITCH_STATUS_FALSE, end);
        }
 
        if (tech_pvt->read_codec.implementation) {
                if (!force) {
-                       return SWITCH_STATUS_SUCCESS;
+                       switch_goto_status(SWITCH_STATUS_SUCCESS, end);
                }
                if (strcasecmp(tech_pvt->read_codec.implementation->iananame, tech_pvt->iananame) ||
                        tech_pvt->read_codec.implementation->samples_per_second != tech_pvt->rm_rate) {
 
                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Changing Codec from %s to %s\n",
                                                          tech_pvt->read_codec.implementation->iananame, tech_pvt->rm_encoding);
+                       switch_core_session_lock_codec_write(tech_pvt->session);
+                       switch_core_session_lock_codec_read(tech_pvt->session);
+                       resetting = 1;
                        switch_core_codec_destroy(&tech_pvt->read_codec);
                        switch_core_codec_destroy(&tech_pvt->write_codec);
                        switch_core_session_reset(tech_pvt->session, SWITCH_TRUE);
                } else {
                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Already using %s\n", tech_pvt->read_codec.implementation->iananame);
-                       return SWITCH_STATUS_SUCCESS;
+                       switch_goto_status(SWITCH_STATUS_SUCCESS, end);
                }
        }
        
@@ -1565,7 +1570,7 @@ switch_status_t sofia_glue_tech_set_codec(private_object_t *tech_pvt, int force)
                                                           SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE | tech_pvt->profile->codec_flags,
                                                           NULL, switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) {
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't load codec?\n");
-               return SWITCH_STATUS_FALSE;
+               switch_goto_status(SWITCH_STATUS_FALSE, end);
        }
 
        if (switch_core_codec_init(&tech_pvt->write_codec,
@@ -1577,7 +1582,7 @@ switch_status_t sofia_glue_tech_set_codec(private_object_t *tech_pvt, int force)
                                                           SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE | tech_pvt->profile->codec_flags,
                                                           NULL, switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) {
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't load codec?\n");
-               return SWITCH_STATUS_FALSE;
+               switch_goto_status(SWITCH_STATUS_FALSE, end);
        }
 
        if (switch_rtp_ready(tech_pvt->rtp_session)) {
@@ -1590,7 +1595,7 @@ switch_status_t sofia_glue_tech_set_codec(private_object_t *tech_pvt, int force)
 
        if (!tech_pvt->read_codec.implementation) {
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't load codec?\n");
-               return SWITCH_STATUS_FALSE;
+               switch_goto_status(SWITCH_STATUS_FALSE, end);
        }
 
        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Set Codec %s %s/%ld %d ms %d samples\n",
@@ -1612,7 +1617,13 @@ switch_status_t sofia_glue_tech_set_codec(private_object_t *tech_pvt, int force)
                switch_rtp_set_default_payload(tech_pvt->rtp_session, tech_pvt->pt);
        }
 
-       return SWITCH_STATUS_SUCCESS;
+ end:
+       if (resetting) {
+               switch_core_session_unlock_codec_write(tech_pvt->session);
+               switch_core_session_unlock_codec_read(tech_pvt->session);
+       }
+
+       return status;
 }
 
 
index 5fee01597133fc81d3c90e337cd9039408aebcec..33ae8b8194351f7d20c0d2509031684f4fbeb98a 100644 (file)
@@ -58,6 +58,26 @@ SWITCH_DECLARE(void) switch_core_session_unset_read_codec(switch_core_session_t
        switch_mutex_unlock(session->codec_read_mutex);
 }
 
+SWITCH_DECLARE(void) switch_core_session_lock_codec_write(switch_core_session_t *session)
+{
+       switch_mutex_lock(session->codec_write_mutex);
+}
+
+SWITCH_DECLARE(void) switch_core_session_unlock_codec_write(switch_core_session_t *session)
+{
+       switch_mutex_unlock(session->codec_write_mutex);
+}
+
+SWITCH_DECLARE(void) switch_core_session_lock_codec_read(switch_core_session_t *session)
+{
+       switch_mutex_lock(session->codec_read_mutex);
+}
+
+SWITCH_DECLARE(void) switch_core_session_unlock_codec_read(switch_core_session_t *session)
+{
+       switch_mutex_unlock(session->codec_read_mutex);
+}
+
 SWITCH_DECLARE(void) switch_core_session_unset_write_codec(switch_core_session_t *session)
 {      
        switch_mutex_t *mutex = NULL;
@@ -550,7 +570,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_codec_destroy(switch_codec_t *codec)
 {
        switch_mutex_t *mutex;
        switch_memory_pool_t *pool;
-
+       int free_pool = 0;
+       
        switch_assert(codec != NULL);   
        
        if (!codec->implementation) {
@@ -558,6 +579,10 @@ SWITCH_DECLARE(switch_status_t) switch_core_codec_destroy(switch_codec_t *codec)
                return SWITCH_STATUS_NOT_INITALIZED;
        }
 
+       if (switch_test_flag(codec, SWITCH_CODEC_FLAG_FREE_POOL)) {
+               free_pool = 1;
+       }
+
        pool = codec->memory_pool;
        mutex = codec->mutex;
 
@@ -571,7 +596,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_codec_destroy(switch_codec_t *codec)
        
        if (mutex) switch_mutex_unlock(mutex);
 
-       if (switch_test_flag(codec, SWITCH_CODEC_FLAG_FREE_POOL)) {
+       if (free_pool) {
                switch_core_destroy_memory_pool(&pool);
        }
 
index 60164bd19121b0fd96dd1d68aacd3db1a0b952b8..a69dd4059fff1aa126b4c28f5699c74633e323af 100644 (file)
@@ -643,363 +643,364 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess
                do_resample = TRUE;
        }
 
-       if (need_codec) {
-               if (!switch_test_flag(session, SSF_WARN_TRANSCODE)) {
+       if (!need_codec) {
+               do_write = TRUE;
+               goto done;
+       }
+
+       if (!switch_test_flag(session, SSF_WARN_TRANSCODE)) {
                        switch_core_session_message_t msg = { 0 };
 
                        msg.message_id = SWITCH_MESSAGE_INDICATE_TRANSCODING_NECESSARY;
                        switch_core_session_receive_message(session, &msg);
                        switch_set_flag(session, SSF_WARN_TRANSCODE);
-               }
+       }
 
-               if (frame->codec) {
-                       session->raw_write_frame.datalen = session->raw_write_frame.buflen;
-                       status = switch_core_codec_decode(frame->codec,
-                                                                                         session->write_codec,
-                                                                                         frame->data,
-                                                                                         frame->datalen,
-                                                                                         session->write_codec->implementation->actual_samples_per_second,
-                                                                                         session->raw_write_frame.data, &session->raw_write_frame.datalen, &session->raw_write_frame.rate, &flag);
+       if (frame->codec) {
+               session->raw_write_frame.datalen = session->raw_write_frame.buflen;
+               status = switch_core_codec_decode(frame->codec,
+                                                                                 session->write_codec,
+                                                                                 frame->data,
+                                                                                 frame->datalen,
+                                                                                 session->write_codec->implementation->actual_samples_per_second,
+                                                                                 session->raw_write_frame.data, &session->raw_write_frame.datalen, &session->raw_write_frame.rate, &flag);
 
 
 
 
-                       if (do_resample && status == SWITCH_STATUS_SUCCESS) {
-                               status = SWITCH_STATUS_RESAMPLE;
-                       }
+               if (do_resample && status == SWITCH_STATUS_SUCCESS) {
+                       status = SWITCH_STATUS_RESAMPLE;
+               }
 
-                       switch (status) {
-                       case SWITCH_STATUS_RESAMPLE:
-                               write_frame = &session->raw_write_frame;
-                               if (!session->write_resampler) {
-                                       switch_mutex_lock(session->resample_mutex);
-                                       status = switch_resample_create(&session->write_resampler,
-                                                                                                       frame->codec->implementation->actual_samples_per_second,
-                                                                                                       frame->codec->implementation->decoded_bytes_per_packet,
-                                                                                                       session->write_codec->implementation->actual_samples_per_second,
-                                                                                                       session->write_codec->implementation->decoded_bytes_per_packet, session->pool);
-                                       switch_mutex_unlock(session->resample_mutex);
-                                       if (status != SWITCH_STATUS_SUCCESS) {
-                                               goto done;
-                                       }
-                               }
-                               break;
-                       case SWITCH_STATUS_SUCCESS:
-                               session->raw_write_frame.samples = session->raw_write_frame.datalen / sizeof(int16_t);
-                               session->raw_write_frame.timestamp = frame->timestamp;
-                               session->raw_write_frame.rate = frame->rate;
-                               session->raw_write_frame.m = frame->m;
-                               session->raw_write_frame.ssrc = frame->ssrc;
-                               session->raw_write_frame.seq = frame->seq;
-                               session->raw_write_frame.payload = frame->payload;
-                               write_frame = &session->raw_write_frame;
-                               break;
-                       case SWITCH_STATUS_BREAK:
-                               status = SWITCH_STATUS_SUCCESS; goto error;
-                       case SWITCH_STATUS_NOOP:
-                               if (session->write_resampler) {
-                                       switch_mutex_lock(session->resample_mutex);
-                                       switch_resample_destroy(&session->write_resampler);
-                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Deactivating write resampler\n");
-                                       switch_mutex_unlock(session->resample_mutex);
-                               }
-                               write_frame = frame;
-                               status = SWITCH_STATUS_SUCCESS;
-                               break;
-                       default:
-                               if (status == SWITCH_STATUS_NOT_INITALIZED) {
-                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Codec init error!\n");
-                                       goto error;
-                               }
-                               if (ptime_mismatch) {
-                                       status = perform_write(session, frame, flags, stream_id);
-                                       status = SWITCH_STATUS_SUCCESS; goto error;
+               switch (status) {
+               case SWITCH_STATUS_RESAMPLE:
+                       write_frame = &session->raw_write_frame;
+                       if (!session->write_resampler) {
+                               switch_mutex_lock(session->resample_mutex);
+                               status = switch_resample_create(&session->write_resampler,
+                                                                                               frame->codec->implementation->actual_samples_per_second,
+                                                                                               frame->codec->implementation->decoded_bytes_per_packet,
+                                                                                               session->write_codec->implementation->actual_samples_per_second,
+                                                                                               session->write_codec->implementation->decoded_bytes_per_packet, session->pool);
+                               switch_mutex_unlock(session->resample_mutex);
+                               if (status != SWITCH_STATUS_SUCCESS) {
+                                       goto done;
                                }
-                               
-                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Codec %s decoder error!\n", frame->codec->codec_interface->interface_name);
+                       }
+                       break;
+               case SWITCH_STATUS_SUCCESS:
+                       session->raw_write_frame.samples = session->raw_write_frame.datalen / sizeof(int16_t);
+                       session->raw_write_frame.timestamp = frame->timestamp;
+                       session->raw_write_frame.rate = frame->rate;
+                       session->raw_write_frame.m = frame->m;
+                       session->raw_write_frame.ssrc = frame->ssrc;
+                       session->raw_write_frame.seq = frame->seq;
+                       session->raw_write_frame.payload = frame->payload;
+                       write_frame = &session->raw_write_frame;
+                       break;
+               case SWITCH_STATUS_BREAK:
+                       status = SWITCH_STATUS_SUCCESS; goto error;
+               case SWITCH_STATUS_NOOP:
+                       if (session->write_resampler) {
+                               switch_mutex_lock(session->resample_mutex);
+                               switch_resample_destroy(&session->write_resampler);
+                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Deactivating write resampler\n");
+                               switch_mutex_unlock(session->resample_mutex);
+                       }
+                       write_frame = frame;
+                       status = SWITCH_STATUS_SUCCESS;
+                       break;
+               default:
+                       if (status == SWITCH_STATUS_NOT_INITALIZED) {
+                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Codec init error!\n");
                                goto error;
                        }
+                       if (ptime_mismatch) {
+                               status = perform_write(session, frame, flags, stream_id);
+                               status = SWITCH_STATUS_SUCCESS; goto error;
+                       }
+                               
+                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Codec %s decoder error!\n", frame->codec->codec_interface->interface_name);
+                       goto error;
                }
+       }
 
-               if (session->write_resampler) {
-                       short *data = write_frame->data;
+       if (session->write_resampler) {
+               short *data = write_frame->data;
 
-                       switch_mutex_lock(session->resample_mutex);
+               switch_mutex_lock(session->resample_mutex);
 
-                       session->write_resampler->from_len = write_frame->datalen / 2;
-                       switch_short_to_float(data, session->write_resampler->from, session->write_resampler->from_len);
+               session->write_resampler->from_len = write_frame->datalen / 2;
+               switch_short_to_float(data, session->write_resampler->from, session->write_resampler->from_len);
 
-                       session->write_resampler->to_len = (uint32_t)
-                               switch_resample_process(session->write_resampler, session->write_resampler->from,
-                                                                               session->write_resampler->from_len, session->write_resampler->to, session->write_resampler->to_size, 0);
+               session->write_resampler->to_len = (uint32_t)
+                       switch_resample_process(session->write_resampler, session->write_resampler->from,
+                                                                       session->write_resampler->from_len, session->write_resampler->to, session->write_resampler->to_size, 0);
 
-                       switch_float_to_short(session->write_resampler->to, data, session->write_resampler->to_len);
+               switch_float_to_short(session->write_resampler->to, data, session->write_resampler->to_len);
 
-                       write_frame->samples = session->write_resampler->to_len;
-                       write_frame->datalen = write_frame->samples * 2;
-                       write_frame->rate = session->write_resampler->to_rate;
-                       switch_mutex_unlock(session->resample_mutex);
-               }
+               write_frame->samples = session->write_resampler->to_len;
+               write_frame->datalen = write_frame->samples * 2;
+               write_frame->rate = session->write_resampler->to_rate;
+               switch_mutex_unlock(session->resample_mutex);
+       }
 
-               if (session->bugs) {
-                       switch_media_bug_t *bp, *dp, *last = NULL;
+       if (session->bugs) {
+               switch_media_bug_t *bp, *dp, *last = NULL;
 
-                       switch_thread_rwlock_rdlock(session->bug_rwlock);
-                       for (bp = session->bugs; bp; bp = bp->next) {
-                               switch_bool_t ok = SWITCH_TRUE;
-                               if (!bp->ready) {
-                                       continue;
-                               }
-                               if (switch_test_flag(bp, SMBF_WRITE_STREAM)) {
+               switch_thread_rwlock_rdlock(session->bug_rwlock);
+               for (bp = session->bugs; bp; bp = bp->next) {
+                       switch_bool_t ok = SWITCH_TRUE;
+                       if (!bp->ready) {
+                               continue;
+                       }
+                       if (switch_test_flag(bp, SMBF_WRITE_STREAM)) {
 
-                                       switch_mutex_lock(bp->write_mutex);
-                                       switch_buffer_write(bp->raw_write_buffer, write_frame->data, write_frame->datalen);
-                                       switch_mutex_unlock(bp->write_mutex);
-                                       if (bp->callback) {
-                                               ok = bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_WRITE);
-                                       }
+                               switch_mutex_lock(bp->write_mutex);
+                               switch_buffer_write(bp->raw_write_buffer, write_frame->data, write_frame->datalen);
+                               switch_mutex_unlock(bp->write_mutex);
+                               if (bp->callback) {
+                                       ok = bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_WRITE);
                                }
+                       }
 
-                               if (switch_test_flag(bp, SMBF_WRITE_REPLACE)) {
-                                       do_bugs = 0;
-                                       if (bp->callback) {
-                                               bp->write_replace_frame_in = write_frame;
-                                               bp->write_replace_frame_out = write_frame;
-                                               if ((ok = bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_WRITE_REPLACE)) == SWITCH_TRUE) {
-                                                       write_frame = bp->write_replace_frame_out;
-                                               }
+                       if (switch_test_flag(bp, SMBF_WRITE_REPLACE)) {
+                               do_bugs = 0;
+                               if (bp->callback) {
+                                       bp->write_replace_frame_in = write_frame;
+                                       bp->write_replace_frame_out = write_frame;
+                                       if ((ok = bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_WRITE_REPLACE)) == SWITCH_TRUE) {
+                                               write_frame = bp->write_replace_frame_out;
                                        }
                                }
+                       }
 
-                               if (bp->stop_time && bp->stop_time <= switch_timestamp(NULL)) {
-                                       ok = SWITCH_FALSE;
-                               }
+                       if (bp->stop_time && bp->stop_time <= switch_timestamp(NULL)) {
+                               ok = SWITCH_FALSE;
+                       }
 
 
-                               if (ok == SWITCH_FALSE) {
-                                       bp->ready = 0;
-                                       if (last) {
-                                               last->next = bp->next;
-                                       } else {
-                                               session->bugs = bp->next;
-                                       }
-                                       dp = bp;
-                                       bp = last;
-                                       switch_core_media_bug_close(&dp);
-                                       if (!bp) {
-                                               break;
-                                       }
-                                       continue;
+                       if (ok == SWITCH_FALSE) {
+                               bp->ready = 0;
+                               if (last) {
+                                       last->next = bp->next;
+                               } else {
+                                       session->bugs = bp->next;
                                }
-                               last = bp;
+                               dp = bp;
+                               bp = last;
+                               switch_core_media_bug_close(&dp);
+                               if (!bp) {
+                                       break;
+                               }
+                               continue;
                        }
-                       switch_thread_rwlock_unlock(session->bug_rwlock);
+                       last = bp;
                }
+               switch_thread_rwlock_unlock(session->bug_rwlock);
+       }
 
-               if (do_bugs) {
-                       do_write = TRUE;
-                       write_frame = frame;
-                       goto done;
-               }
+       if (do_bugs) {
+               do_write = TRUE;
+               write_frame = frame;
+               goto done;
+       }
 
-               if (session->write_codec) {
-                       if (write_frame->datalen == session->write_codec->implementation->decoded_bytes_per_packet) {
-                               perfect = TRUE;
-                       } else {
-                               if (!session->raw_write_buffer) {
-                                       switch_size_t bytes = session->write_codec->implementation->decoded_bytes_per_packet;
-                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
-                                                                         "Engaging Write Buffer at %u bytes to accommodate %u->%u\n",
-                                                                         (uint32_t) bytes, write_frame->datalen, session->write_codec->implementation->decoded_bytes_per_packet);
-                                       if ((status = switch_buffer_create_dynamic(&session->raw_write_buffer,
-                                                                                                                          bytes * SWITCH_BUFFER_BLOCK_FRAMES,
-                                                                                                                          bytes * SWITCH_BUFFER_START_FRAMES, 0)) != SWITCH_STATUS_SUCCESS) {
-                                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Write Buffer Failed!\n");
-                                               goto error;
-                                       }
+       if (session->write_codec) {
+               if (write_frame->datalen == session->write_codec->implementation->decoded_bytes_per_packet) {
+                       perfect = TRUE;
+               } else {
+                       if (!session->raw_write_buffer) {
+                               switch_size_t bytes = session->write_codec->implementation->decoded_bytes_per_packet;
+                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
+                                                                 "Engaging Write Buffer at %u bytes to accommodate %u->%u\n",
+                                                                 (uint32_t) bytes, write_frame->datalen, session->write_codec->implementation->decoded_bytes_per_packet);
+                               if ((status = switch_buffer_create_dynamic(&session->raw_write_buffer,
+                                                                                                                  bytes * SWITCH_BUFFER_BLOCK_FRAMES,
+                                                                                                                  bytes * SWITCH_BUFFER_START_FRAMES, 0)) != SWITCH_STATUS_SUCCESS) {
+                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Write Buffer Failed!\n");
+                                       goto error;
                                }
+                       }
 
-                               if (!(switch_buffer_write(session->raw_write_buffer, write_frame->data, write_frame->datalen))) {
-                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Write Buffer %u bytes Failed!\n", write_frame->datalen);
-                                       status = SWITCH_STATUS_MEMERR; goto error;
-                               }
+                       if (!(switch_buffer_write(session->raw_write_buffer, write_frame->data, write_frame->datalen))) {
+                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Write Buffer %u bytes Failed!\n", write_frame->datalen);
+                               status = SWITCH_STATUS_MEMERR; goto error;
                        }
+               }
 
-                       if (perfect) {
-                               enc_frame = write_frame;
-                               session->enc_write_frame.datalen = session->enc_write_frame.buflen;
+               if (perfect) {
+                       enc_frame = write_frame;
+                       session->enc_write_frame.datalen = session->enc_write_frame.buflen;
 
-                               status = switch_core_codec_encode(session->write_codec,
-                                                                                                 frame->codec,
-                                                                                                 enc_frame->data,
-                                                                                                 enc_frame->datalen,
-                                                                                                 session->write_codec->implementation->actual_samples_per_second,
-                                                                                                 session->enc_write_frame.data, &session->enc_write_frame.datalen, &session->enc_write_frame.rate, &flag);
+                       status = switch_core_codec_encode(session->write_codec,
+                                                                                         frame->codec,
+                                                                                         enc_frame->data,
+                                                                                         enc_frame->datalen,
+                                                                                         session->write_codec->implementation->actual_samples_per_second,
+                                                                                         session->enc_write_frame.data, &session->enc_write_frame.datalen, &session->enc_write_frame.rate, &flag);
 
-                               switch (status) {
-                               case SWITCH_STATUS_RESAMPLE:
-                                       /* switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Fixme 2\n"); */
-                               case SWITCH_STATUS_SUCCESS:
-                                       session->enc_write_frame.codec = session->write_codec;
-                                       session->enc_write_frame.samples = enc_frame->datalen / sizeof(int16_t);
-                                       if (frame->codec->implementation->samples_per_packet != session->write_codec->implementation->samples_per_packet) {
-                                               session->enc_write_frame.timestamp = 0;
-                                       } else {
-                                               session->enc_write_frame.timestamp = frame->timestamp;
-                                       }
-                                       session->enc_write_frame.payload = session->write_codec->implementation->ianacode;
-                                       session->enc_write_frame.m = frame->m;
-                                       session->enc_write_frame.ssrc = frame->ssrc;
-                                       session->enc_write_frame.seq = frame->seq;
-                                       write_frame = &session->enc_write_frame;
-                                       break;
-                               case SWITCH_STATUS_NOOP:
-                                       enc_frame->codec = session->write_codec;
-                                       enc_frame->samples = enc_frame->datalen / sizeof(int16_t);
-                                       enc_frame->timestamp = frame->timestamp;
-                                       enc_frame->m = frame->m;
-                                       enc_frame->seq = frame->seq;
-                                       enc_frame->ssrc = frame->ssrc;
-                                       enc_frame->payload = enc_frame->codec->implementation->ianacode;
-                                       write_frame = enc_frame;
-                                       status = SWITCH_STATUS_SUCCESS;
-                                       break;
-                               case SWITCH_STATUS_NOT_INITALIZED:
-                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Codec init error!\n");
-                                       write_frame = NULL;
-                    goto error;                                        
-                               default:
-                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Codec %s encoder error!\n",
-                                                                         session->read_codec->codec_interface->interface_name);
-                                       write_frame = NULL;
-                                       goto error;
-                               }
-                               if (flag & SFF_CNG) {
-                                       switch_set_flag(write_frame, SFF_CNG);
+                       switch (status) {
+                       case SWITCH_STATUS_RESAMPLE:
+                               /* switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Fixme 2\n"); */
+                       case SWITCH_STATUS_SUCCESS:
+                               session->enc_write_frame.codec = session->write_codec;
+                               session->enc_write_frame.samples = enc_frame->datalen / sizeof(int16_t);
+                               if (frame->codec->implementation->samples_per_packet != session->write_codec->implementation->samples_per_packet) {
+                                       session->enc_write_frame.timestamp = 0;
+                               } else {
+                                       session->enc_write_frame.timestamp = frame->timestamp;
                                }
-                               status = perform_write(session, write_frame, flags, stream_id);
+                               session->enc_write_frame.payload = session->write_codec->implementation->ianacode;
+                               session->enc_write_frame.m = frame->m;
+                               session->enc_write_frame.ssrc = frame->ssrc;
+                               session->enc_write_frame.seq = frame->seq;
+                               write_frame = &session->enc_write_frame;
+                               break;
+                       case SWITCH_STATUS_NOOP:
+                               enc_frame->codec = session->write_codec;
+                               enc_frame->samples = enc_frame->datalen / sizeof(int16_t);
+                               enc_frame->timestamp = frame->timestamp;
+                               enc_frame->m = frame->m;
+                               enc_frame->seq = frame->seq;
+                               enc_frame->ssrc = frame->ssrc;
+                               enc_frame->payload = enc_frame->codec->implementation->ianacode;
+                               write_frame = enc_frame;
+                               status = SWITCH_STATUS_SUCCESS;
+                               break;
+                       case SWITCH_STATUS_NOT_INITALIZED:
+                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Codec init error!\n");
+                               write_frame = NULL;
+                               goto error;                                     
+                       default:
+                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Codec %s encoder error!\n",
+                                                                 session->read_codec->codec_interface->interface_name);
+                               write_frame = NULL;
+                               goto error;
+                       }
+                       if (flag & SFF_CNG) {
+                               switch_set_flag(write_frame, SFF_CNG);
+                       }
+                       status = perform_write(session, write_frame, flags, stream_id);
+                       goto error;
+               } else {
+                       switch_size_t used = switch_buffer_inuse(session->raw_write_buffer);
+                       uint32_t bytes = session->write_codec->implementation->decoded_bytes_per_packet;
+                       switch_size_t frames = (used / bytes);
+
+                       status = SWITCH_STATUS_SUCCESS;
+                       if (!frames) {
                                goto error;
                        } else {
-                               switch_size_t used = switch_buffer_inuse(session->raw_write_buffer);
-                               uint32_t bytes = session->write_codec->implementation->decoded_bytes_per_packet;
-                               switch_size_t frames = (used / bytes);
+                               switch_size_t x;
+                               for (x = 0; x < frames; x++) {
+                                       if ((session->raw_write_frame.datalen = (uint32_t)
+                                                switch_buffer_read(session->raw_write_buffer, session->raw_write_frame.data, bytes)) != 0) {
+                                               int rate;
+                                               enc_frame = &session->raw_write_frame;
+                                               session->raw_write_frame.rate = session->write_codec->implementation->actual_samples_per_second;
+                                               session->enc_write_frame.datalen = session->enc_write_frame.buflen;
+
+                                               if (frame->codec && frame->codec->implementation) {
+                                                       rate = frame->codec->implementation->actual_samples_per_second;
+                                               } else {
+                                                       rate = session->write_codec->implementation->actual_samples_per_second;
+                                               }
 
-                               status = SWITCH_STATUS_SUCCESS;
-                               if (!frames) {
-                                       goto error;
-                               } else {
-                                       switch_size_t x;
-                                       for (x = 0; x < frames; x++) {
-                                               if ((session->raw_write_frame.datalen = (uint32_t)
-                                                        switch_buffer_read(session->raw_write_buffer, session->raw_write_frame.data, bytes)) != 0) {
-                                                       int rate;
-                                                       enc_frame = &session->raw_write_frame;
-                                                       session->raw_write_frame.rate = session->write_codec->implementation->actual_samples_per_second;
-                                                       session->enc_write_frame.datalen = session->enc_write_frame.buflen;
-
-                                                       if (frame->codec && frame->codec->implementation) {
-                                                               rate = frame->codec->implementation->actual_samples_per_second;
-                                                       } else {
-                                                               rate = session->write_codec->implementation->actual_samples_per_second;
-                                                       }
+                                               status = switch_core_codec_encode(session->write_codec,
+                                                                                                                 frame->codec,
+                                                                                                                 enc_frame->data,
+                                                                                                                 enc_frame->datalen,
+                                                                                                                 rate,
+                                                                                                                 session->enc_write_frame.data,
+                                                                                                                 &session->enc_write_frame.datalen, &session->enc_write_frame.rate, &flag);
+                                               switch (status) {
+                                               case SWITCH_STATUS_RESAMPLE:
+                                                       session->enc_write_frame.codec = session->write_codec;
+                                                       session->enc_write_frame.samples = enc_frame->datalen / sizeof(int16_t);
+                                                       session->enc_write_frame.m = frame->m;
+                                                       session->enc_write_frame.ssrc = frame->ssrc;
+                                                       session->enc_write_frame.payload = session->write_codec->implementation->ianacode;
+                                                       write_frame = &session->enc_write_frame;
+                                                       if (!session->write_resampler) {
+                                                               switch_mutex_lock(session->resample_mutex);
+                                                               status = switch_resample_create(&session->write_resampler,
+                                                                                                                               frame->codec->implementation->actual_samples_per_second,
+                                                                                                                               frame->codec->implementation->decoded_bytes_per_packet,
+                                                                                                                               session->write_codec->implementation->actual_samples_per_second,
+                                                                                                                               session->write_codec->implementation->decoded_bytes_per_packet, session->pool);
+                                                               switch_mutex_unlock(session->resample_mutex);
 
-                                                       status = switch_core_codec_encode(session->write_codec,
-                                                                                                                         frame->codec,
-                                                                                                                         enc_frame->data,
-                                                                                                                         enc_frame->datalen,
-                                                                                                                         rate,
-                                                                                                                         session->enc_write_frame.data,
-                                                                                                                         &session->enc_write_frame.datalen, &session->enc_write_frame.rate, &flag);
-                                                       switch (status) {
-                                                       case SWITCH_STATUS_RESAMPLE:
-                                                               session->enc_write_frame.codec = session->write_codec;
-                                                               session->enc_write_frame.samples = enc_frame->datalen / sizeof(int16_t);
-                                                               session->enc_write_frame.m = frame->m;
-                                                               session->enc_write_frame.ssrc = frame->ssrc;
-                                                               session->enc_write_frame.payload = session->write_codec->implementation->ianacode;
-                                                               write_frame = &session->enc_write_frame;
-                                                               if (!session->write_resampler) {
-                                                                       switch_mutex_lock(session->resample_mutex);
-                                                                       status = switch_resample_create(&session->write_resampler,
-                                                                                                                                       frame->codec->implementation->actual_samples_per_second,
-                                                                                                                                       frame->codec->implementation->decoded_bytes_per_packet,
-                                                                                                                                       session->write_codec->implementation->actual_samples_per_second,
-                                                                                                                                       session->write_codec->implementation->decoded_bytes_per_packet, session->pool);
-                                                                       switch_mutex_unlock(session->resample_mutex);
-
-                                                                       if (status != SWITCH_STATUS_SUCCESS) {
-                                                                               goto done;
-                                                                       }
+                                                               if (status != SWITCH_STATUS_SUCCESS) {
+                                                                       goto done;
                                                                }
-                                                               break;
-                                                       case SWITCH_STATUS_SUCCESS:
-                                                               session->enc_write_frame.codec = session->write_codec;
-                                                               session->enc_write_frame.samples = enc_frame->datalen / sizeof(int16_t);
-                                                               session->enc_write_frame.m = frame->m;
-                                                               session->enc_write_frame.ssrc = frame->ssrc;
-                                                               session->enc_write_frame.payload = session->write_codec->implementation->ianacode;
-                                                               write_frame = &session->enc_write_frame;
-                                                               break;
-                                                       case SWITCH_STATUS_NOOP:
-                                                               if (session->write_resampler) {
-                                                                       switch_mutex_lock(session->resample_mutex);
-                                                                       switch_resample_destroy(&session->write_resampler);
-                                                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Deactivating write resampler\n");
-                                                                       switch_mutex_unlock(session->resample_mutex);
-                                                               }
-                                                               enc_frame->codec = session->write_codec;
-                                                               enc_frame->samples = enc_frame->datalen / sizeof(int16_t);
-                                                               enc_frame->m = frame->m;
-                                                               enc_frame->ssrc = frame->ssrc;
-                                                               enc_frame->payload = enc_frame->codec->implementation->ianacode;
-                                                               write_frame = enc_frame;
-                                                               status = SWITCH_STATUS_SUCCESS;
-                                                               break;
-                                                       case SWITCH_STATUS_NOT_INITALIZED:
-                                                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Codec init error!\n");
-                                                               write_frame = NULL;
-                                                               goto error;
-                                                       default:
-                                                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Codec %s encoder error %d!\n",
-                                                                                                 session->read_codec->codec_interface->interface_name, status);
-                                                               write_frame = NULL;
-                                                               goto error;
                                                        }
-
-                                                       if (session->read_resampler) {
-                                                               short *data = write_frame->data;
+                                                       break;
+                                               case SWITCH_STATUS_SUCCESS:
+                                                       session->enc_write_frame.codec = session->write_codec;
+                                                       session->enc_write_frame.samples = enc_frame->datalen / sizeof(int16_t);
+                                                       session->enc_write_frame.m = frame->m;
+                                                       session->enc_write_frame.ssrc = frame->ssrc;
+                                                       session->enc_write_frame.payload = session->write_codec->implementation->ianacode;
+                                                       write_frame = &session->enc_write_frame;
+                                                       break;
+                                               case SWITCH_STATUS_NOOP:
+                                                       if (session->write_resampler) {
                                                                switch_mutex_lock(session->resample_mutex);
-
-                                                               session->read_resampler->from_len =
-                                                                       switch_short_to_float(data, session->read_resampler->from, (int) write_frame->datalen / 2);
-                                                               session->read_resampler->to_len = (uint32_t)
-                                                                       switch_resample_process(session->read_resampler, session->read_resampler->from,
-                                                                                                                       session->read_resampler->from_len,
-                                                                                                                       session->read_resampler->to, session->read_resampler->to_size, 0);
-                                                               switch_float_to_short(session->read_resampler->to, data, write_frame->datalen * 2);
-                                                               write_frame->samples = session->read_resampler->to_len;
-                                                               write_frame->datalen = session->read_resampler->to_len * 2;
-                                                               write_frame->rate = session->read_resampler->to_rate;
+                                                               switch_resample_destroy(&session->write_resampler);
+                                                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Deactivating write resampler\n");
                                                                switch_mutex_unlock(session->resample_mutex);
-
-                                                       }
-                                                       if (flag & SFF_CNG) {
-                                                               switch_set_flag(write_frame, SFF_CNG);
                                                        }
+                                                       enc_frame->codec = session->write_codec;
+                                                       enc_frame->samples = enc_frame->datalen / sizeof(int16_t);
+                                                       enc_frame->m = frame->m;
+                                                       enc_frame->ssrc = frame->ssrc;
+                                                       enc_frame->payload = enc_frame->codec->implementation->ianacode;
+                                                       write_frame = enc_frame;
+                                                       status = SWITCH_STATUS_SUCCESS;
+                                                       break;
+                                               case SWITCH_STATUS_NOT_INITALIZED:
+                                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Codec init error!\n");
+                                                       write_frame = NULL;
+                                                       goto error;
+                                               default:
+                                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Codec %s encoder error %d!\n",
+                                                                                         session->read_codec->codec_interface->interface_name, status);
+                                                       write_frame = NULL;
+                                                       goto error;
+                                               }
 
-                                                       if ((status = perform_write(session, write_frame, flags, stream_id)) != SWITCH_STATUS_SUCCESS) {
-                                                               break;
-                                                       }
+                                               if (session->read_resampler) {
+                                                       short *data = write_frame->data;
+                                                       switch_mutex_lock(session->resample_mutex);
+
+                                                       session->read_resampler->from_len =
+                                                               switch_short_to_float(data, session->read_resampler->from, (int) write_frame->datalen / 2);
+                                                       session->read_resampler->to_len = (uint32_t)
+                                                               switch_resample_process(session->read_resampler, session->read_resampler->from,
+                                                                                                               session->read_resampler->from_len,
+                                                                                                               session->read_resampler->to, session->read_resampler->to_size, 0);
+                                                       switch_float_to_short(session->read_resampler->to, data, write_frame->datalen * 2);
+                                                       write_frame->samples = session->read_resampler->to_len;
+                                                       write_frame->datalen = session->read_resampler->to_len * 2;
+                                                       write_frame->rate = session->read_resampler->to_rate;
+                                                       switch_mutex_unlock(session->resample_mutex);
+
+                                               }
+                                               if (flag & SFF_CNG) {
+                                                       switch_set_flag(write_frame, SFF_CNG);
+                                               }
+
+                                               if ((status = perform_write(session, write_frame, flags, stream_id)) != SWITCH_STATUS_SUCCESS) {
+                                                       break;
                                                }
                                        }
-                                       goto error;
                                }
+                               goto error;
                        }
                }
-       } else {
-               do_write = TRUE;
        }
-
+       
  done:
 
        if (do_write) {