]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
FS-7500: refactoring
authorAnthony Minessale <anthm@freeswitch.org>
Thu, 4 Dec 2014 02:34:49 +0000 (20:34 -0600)
committerMichael Jerris <mike@jerris.com>
Thu, 28 May 2015 17:46:50 +0000 (12:46 -0500)
16 files changed:
libs/sofia-sip/libsofia-sip-ua/sdp/sdp_parse.c
libs/sofia-sip/libsofia-sip-ua/sdp/sdp_print.c
libs/sofia-sip/libsofia-sip-ua/sdp/sofia-sip/sdp.h
src/include/switch_core.h
src/mod/applications/mod_av/mod_av.c
src/mod/applications/mod_conference/mod_conference.c
src/mod/applications/mod_fsv/mod_fsv.c
src/mod/codecs/mod_openh264/mod_openh264.cpp
src/mod/endpoints/mod_verto/mod_verto.c
src/mod/languages/mod_managed/freeswitch_wrap.cxx
src/mod/languages/mod_managed/managed/swig.cs
src/switch_core_media.c
src/switch_core_session.c
src/switch_core_state_machine.c
src/switch_ivr_bridge.c
src/switch_rtp.c

index ef3e49d98d3c9c7aecc8bd3eeb6ea9d5bff90f32..fdd3dcef30b0b35367c2f5cde26400b0a7dd6f87 100644 (file)
@@ -922,7 +922,9 @@ static void parse_bandwidth(sdp_parser_t *p, char *r, sdp_bandwidth_t **result)
 
   if (su_casematch(name, "CT"))
     modifier = sdp_bw_ct, name = NULL;
-  else if (su_casematch(name, "AS") == 0)
+  else if (su_casematch(name, "TIAS") == 1)
+    modifier = sdp_bw_tias, name = NULL;
+  else if (su_casematch(name, "AS") == 1)
     modifier = sdp_bw_as, name = NULL;
   else
     modifier = sdp_bw_x;
index 37b58e54bba445bc25b45df3aa7e802fc5267e1a..0f8e390ebf9f13c1d193eed43925674b24879359 100644 (file)
@@ -430,6 +430,7 @@ static void print_bandwidths(sdp_printer_t *p, sdp_bandwidth_t const *b)
     switch (b->b_modifier) {
     case sdp_bw_ct: name = "CT"; break;
     case sdp_bw_as: name = "AS"; break;
+    case sdp_bw_tias: name = "TIAS"; break;
     default:        name = b->b_modifier_name; break;
     }
 
index e39911221a72fb1a55416388d255d8be9077acee..8bb9c264922fd50219be7ab6743b15b657075dc5 100644 (file)
@@ -143,6 +143,7 @@ typedef enum
   sdp_bw_x,                            /**< Unknown bandwidth type */
   sdp_bw_ct,                           /**< Conference total */
   sdp_bw_as,                           /**< Application-specific */
+  sdp_bw_tias,                         /**< Application-specific */
 } sdp_bandwidth_e;
 
 /** Session or media bandwidth. */
index ca56ebebfd253aeea95b5e6f8bc585920827114a..ae57dc1c9fa6c238079f3fefb6a9ca54497c550a 100644 (file)
@@ -2656,8 +2656,8 @@ SWITCH_DECLARE(int) switch_core_gen_certs(const char *prefix);
 SWITCH_DECLARE(int) switch_core_cert_gen_fingerprint(const char *prefix, dtls_fingerprint_t *fp);
 SWITCH_DECLARE(int) switch_core_cert_expand_fingerprint(dtls_fingerprint_t *fp, const char *str);
 SWITCH_DECLARE(int) switch_core_cert_verify(dtls_fingerprint_t *fp);
-SWITCH_DECLARE(switch_status_t) switch_core_session_refresh_video(switch_core_session_t *session);
-SWITCH_DECLARE(switch_status_t) switch_core_session_refresh_video_both_ways(switch_core_session_t *session);
+SWITCH_DECLARE(switch_status_t) switch_core_session_request_video_refresh(switch_core_session_t *session);
+SWITCH_DECLARE(switch_status_t) switch_core_session_send_and_request_video_refresh(switch_core_session_t *session);
 SWITCH_DECLARE(int) switch_system(const char *cmd, switch_bool_t wait);
 SWITCH_DECLARE(int) switch_stream_system_fork(const char *cmd, switch_stream_handle_t *stream);
 SWITCH_DECLARE(int) switch_stream_system(const char *cmd, switch_stream_handle_t *stream);
index 02453d5a6421d0c9ac32170171a7e5327bcb30ea..5035faf97b3edbcb8488becc822e11751cd426e6 100644 (file)
@@ -710,7 +710,6 @@ static switch_status_t switch_h264_decode(switch_codec_t *codec, switch_frame_t
                                context->img->stride[2] = picture->linesize[2];
 
                                frame->img = context->img;
-
                        }
 
                        av_frame_free(&picture);
@@ -718,6 +717,7 @@ static switch_status_t switch_h264_decode(switch_codec_t *codec, switch_frame_t
                }
 
                switch_buffer_zero(context->nalu_buffer);
+               //switch_set_flag(frame, SFF_USE_VIDEO_TIMESTAMP);
                return SWITCH_STATUS_SUCCESS;
        }
 
index 9b4774369e702eb8830e60c3363b1bcee652df8d..6f957143ea98c2ed3573ba7720cc86e7d8aa7b01 100644 (file)
@@ -2880,7 +2880,7 @@ static void *SWITCH_THREAD_FUNC conference_video_bridge_thread_run(switch_thread
                   switch_channel_ready(channel_a) && switch_channel_ready(channel_b))  {
 
                if (switch_channel_test_flag(channel_a, CF_VIDEO_REFRESH_REQ)) {
-                       switch_core_session_video_reinit(session_b);
+                       switch_core_session_request_video_refresh(session_b);
                        switch_channel_clear_flag(channel_a, CF_VIDEO_REFRESH_REQ);
                }
 
@@ -2985,8 +2985,8 @@ static void *SWITCH_THREAD_FUNC conference_video_thread_run(switch_thread_t *thr
                        goto do_continue;
                }
 
-               //memcpy(buf, vid_frame->packet, vid_frame->packetlen);
-               
+               //memcpy(buf, vid_frame->packet, vid_frame->packelen);
+
                switch_mutex_unlock(conference->mutex);
                switch_mutex_lock(conference->mutex);
                want_refresh = 0;
@@ -3036,7 +3036,7 @@ static void *SWITCH_THREAD_FUNC conference_video_thread_run(switch_thread_t *thr
                switch_mutex_unlock(conference->mutex);
 
                if (want_refresh && session) {
-                       switch_core_session_video_reinit(session);
+                       switch_core_session_request_video_refresh(session);
                        want_refresh = 0;
                }
 
index c3a23a6447494b88be47797a0e97eecea19a654f..74ecae7c2137c9ac1e5a4d0b3e5c9298fd1270e7 100644 (file)
@@ -111,7 +111,7 @@ SWITCH_STANDARD_APP(record_fsv_function)
 
        switch_core_session_get_read_impl(session, &read_impl);
        switch_channel_answer(channel);
-       switch_core_session_refresh_video(session);
+       switch_core_session_request_video_refresh(session);
 
        switch_channel_set_variable(channel, SWITCH_PLAYBACK_TERMINATOR_USED, "");
 
@@ -283,7 +283,7 @@ SWITCH_STANDARD_APP(play_fsv_function)
        switch_frame_t *read_frame;
        switch_codec_implementation_t read_impl = { 0 };
 
-       switch_core_session_refresh_video(session);
+       switch_core_session_request_video_refresh(session);
 
        switch_core_session_get_read_impl(session, &read_impl);
 
@@ -758,7 +758,7 @@ SWITCH_STANDARD_APP(decode_video_function)
        }
 
        switch_channel_answer(channel);
-       switch_core_session_refresh_video(session);
+       switch_core_session_request_video_refresh(session);
        switch_core_media_start_video_function(session, decode_video_thread, &max_pictures);
 
        switch_ivr_play_file(session, NULL, moh, NULL);
index 1014a8ea9c3886bda9ccf0305b628ec4fd124b7f..bce9c96f1d1699819cdb9356574cf570299b11da 100644 (file)
@@ -550,7 +550,7 @@ static switch_status_t switch_h264_decode(switch_codec_t *codec, switch_frame_t
                                switch_goto_status(SWITCH_STATUS_RESTART, end);
                        }
                }
-
+               //switch_set_flag(frame, SFF_USE_VIDEO_TIMESTAMP);
                switch_buffer_zero(context->nalu_buffer);
                status = SWITCH_STATUS_SUCCESS;
        }
index 8afe2fb5f0f682911f2acb5a8d9e6eef9c1f9f1d..a808014b20ce22bd0a7e5779e116964b131966ac 100644 (file)
@@ -2188,7 +2188,7 @@ static switch_status_t verto_on_init(switch_core_session_t *session)
                        switch_yield(10000);
                }
 
-               switch_core_session_refresh_video(session);
+               switch_core_session_request_video_refresh(session);
                switch_channel_set_flag(tech_pvt->channel, CF_VIDEO_BREAK);
         switch_core_session_kill_channel(tech_pvt->session, SWITCH_SIG_BREAK);
 
index 2bc1b2e86854031061922c88bdef9c413294ed5b..c4c986a18036f08257cd6af99ce5f740dfb682b3 100644 (file)
@@ -15885,13 +15885,13 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_cert_verify(void * jarg1) {
 }
 
 
-SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_session_refresh_video(void * jarg1) {
+SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_session_request_video_refresh(void * jarg1) {
   int jresult ;
   switch_core_session_t *arg1 = (switch_core_session_t *) 0 ;
   switch_status_t result;
   
   arg1 = (switch_core_session_t *)jarg1; 
-  result = (switch_status_t)switch_core_session_refresh_video(arg1);
+  result = (switch_status_t)switch_core_session_request_video_refresh(arg1);
   jresult = result; 
   return jresult;
 }
index b9338434cf24ec493b38a3922e9fb8f5894f4ddf..2102211fafec24e57a9ed7a2260e24223baa480f 100644 (file)
@@ -3164,8 +3164,8 @@ public class freeswitch {
     return ret;
   }
 
-  public static switch_status_t switch_core_session_refresh_video(SWIGTYPE_p_switch_core_session session) {
-    switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_core_session_refresh_video(SWIGTYPE_p_switch_core_session.getCPtr(session));
+  public static switch_status_t switch_core_session_request_video_refresh(SWIGTYPE_p_switch_core_session session) {
+    switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_core_session_request_video_refresh(SWIGTYPE_p_switch_core_session.getCPtr(session));
     return ret;
   }
 
@@ -11303,8 +11303,8 @@ class freeswitchPINVOKE {
   [DllImport("mod_managed", EntryPoint="CSharp_switch_core_cert_verify")]
   public static extern int switch_core_cert_verify(HandleRef jarg1);
 
-  [DllImport("mod_managed", EntryPoint="CSharp_switch_core_session_refresh_video")]
-  public static extern int switch_core_session_refresh_video(HandleRef jarg1);
+  [DllImport("mod_managed", EntryPoint="CSharp_switch_core_session_request_video_refresh")]
+  public static extern int switch_core_session_request_video_refresh(HandleRef jarg1);
 
   [DllImport("mod_managed", EntryPoint="CSharp_switch_stream_system_fork")]
   public static extern int switch_stream_system_fork(string jarg1, HandleRef jarg2);
index 32466826e14f8cef3df4b789e10cf1e30b6ff6ae..16f935d525565eeea3592de8259b817b38ac3c7b 100644 (file)
@@ -48,7 +48,7 @@ static void switch_core_media_set_r_sdp_codec_string(switch_core_session_t *sess
 #define MAX_CODEC_CHECK_FRAMES 50//x:mod_sofia.h
 #define MAX_MISMATCH_FRAMES 5//x:mod_sofia.h
 #define type2str(type) type == SWITCH_MEDIA_TYPE_VIDEO ? "video" : "audio"
-#define VIDEO_REFRESH_FREQ 1000000
+#define VIDEO_REFRESH_FREQ 50000
 
 typedef enum {
        SMF_INIT = (1 << 0),
@@ -4485,7 +4485,7 @@ static void *SWITCH_THREAD_FUNC video_helper_thread(switch_thread_t *thread, voi
 
        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s Video thread started. Echo is %s\n", 
                                          switch_channel_get_name(session->channel), switch_channel_test_flag(channel, CF_VIDEO_ECHO) ? "on" : "off");
-       switch_core_session_refresh_video(session);
+       switch_core_session_request_video_refresh(session);
 
        while (switch_channel_up_nosig(channel)) {
                if (!switch_channel_test_flag(channel, CF_VIDEO)) {
@@ -4500,7 +4500,7 @@ static void *SWITCH_THREAD_FUNC video_helper_thread(switch_thread_t *thread, voi
                        switch_thread_cond_wait(mh->cond, mh->cond_mutex);
                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s Video thread resumed  Echo is %s\n", 
                                                          switch_channel_get_name(session->channel), switch_channel_test_flag(channel, CF_VIDEO_ECHO) ? "on" : "off");
-                       switch_core_session_refresh_video(session);
+                       switch_core_session_request_video_refresh(session);
                }
 
                if (switch_channel_test_flag(channel, CF_VIDEO_PASSIVE)) {
@@ -4539,11 +4539,6 @@ static void *SWITCH_THREAD_FUNC video_helper_thread(switch_thread_t *thread, voi
                        continue;
                }
 
-               if (switch_channel_test_flag(channel, CF_VIDEO_REFRESH_REQ)) {
-                       switch_core_session_refresh_video(session);
-                       switch_channel_clear_flag(channel, CF_VIDEO_REFRESH_REQ);
-               }
-
                if (switch_test_flag(read_frame, SFF_CNG)) {
                        continue;
                }
@@ -5856,6 +5851,14 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi
                        flags[SWITCH_RTP_FLAG_USE_TIMER] = 0;
                        flags[SWITCH_RTP_FLAG_NOBLOCK] = 0;
                        flags[SWITCH_RTP_FLAG_VIDEO]++;
+                       
+                       if (v_engine->fir) {
+                               flags[SWITCH_RTP_FLAG_FIR]++;
+                       }
+
+                       if (v_engine->pli) {
+                               flags[SWITCH_RTP_FLAG_PLI]++;
+                       }
 
                        v_engine->rtp_session = switch_rtp_new(a_engine->local_sdp_ip,
                                                                                                                 v_engine->local_sdp_port,
@@ -7268,6 +7271,7 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess
                                
                                if (bw > 0) {
                                        switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "b=AS:%d\n", bw);
+                                       //switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "b=TIAS:%d\n", bw);
                                }
                                
 
@@ -7278,7 +7282,9 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess
                                }
 
                                /* DFF nack pli etc */
-                               nack = v_engine->nack = 0; //pli = v_engine->pli = 0;
+                               nack = v_engine->nack = 0;
+                               //pli = v_engine->pli = 0;
+                               
                                
                                for (pmap = v_engine->cur_payload_map; pmap && pmap->allocated; pmap = pmap->next) {
                                        if (!v_engine->codec_negotiated || 
@@ -9541,7 +9547,7 @@ SWITCH_DECLARE(switch_timer_t *) switch_core_media_get_timer(switch_core_session
 
 }
 
-SWITCH_DECLARE(switch_status_t) switch_core_session_refresh_video(switch_core_session_t *session)
+SWITCH_DECLARE(switch_status_t) switch_core_session_request_video_refresh(switch_core_session_t *session)
 {
        switch_channel_t *channel = switch_core_session_get_channel(session);
        switch_media_handle_t *smh = NULL;
@@ -9571,10 +9577,10 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_refresh_video(switch_core_se
        return SWITCH_STATUS_FALSE;
 }
 
-SWITCH_DECLARE(switch_status_t) switch_core_session_refresh_video_both_ways(switch_core_session_t *session)
+SWITCH_DECLARE(switch_status_t) switch_core_session_send_and_request_video_refresh(switch_core_session_t *session)
 {
        if (switch_channel_test_flag(session->channel, CF_VIDEO)) {
-               switch_core_session_refresh_video(session);
+               switch_core_session_request_video_refresh(session);
                switch_core_media_gen_key_frame(session);
                return SWITCH_STATUS_SUCCESS;
        }
@@ -9669,7 +9675,7 @@ SWITCH_DECLARE(void) switch_core_session_video_reinit(switch_core_session_t *ses
 
        smh->video_init = 0;
        smh->video_last_key_time = 0;
-       switch_core_session_refresh_video_both_ways(session);   
+       switch_core_session_send_and_request_video_refresh(session);    
 }
 
 SWITCH_DECLARE(switch_status_t) switch_core_session_write_video_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags,
@@ -9704,7 +9710,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_video_frame(switch_cor
        }
 
        if (!smh->video_init && smh->mparams->video_key_first && (now - smh->video_last_key_time) > smh->mparams->video_key_first) {
-               switch_core_session_refresh_video_both_ways(smh->session);
+               switch_core_media_gen_key_frame(session);
 
                if (smh->video_last_key_time) {
                        smh->video_init = 1;
@@ -9887,7 +9893,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_video_frame(switch_core
                }
 
                if (switch_test_flag((*frame), SFF_WAIT_KEY_FRAME)) {
-                       switch_core_session_refresh_video(session);
+                       switch_core_session_request_video_refresh(session);
                        switch_clear_flag((*frame), SFF_WAIT_KEY_FRAME);
                }
 
index 68a49502e65791f0e860cd9aa0788fe57c686c89..cce9acacfda39181b1d08afe7646e1e6ffafd63d 100644 (file)
@@ -2682,7 +2682,7 @@ SWITCH_DECLARE(void) switch_core_session_video_reset(switch_core_session_t *sess
        switch_channel_clear_flag(session->channel, CF_VIDEO_DECODED_READ);
        switch_channel_clear_flag(session->channel, CF_VIDEO_DEBUG_READ);
        switch_channel_clear_flag(session->channel, CF_VIDEO_DEBUG_WRITE);
-       switch_core_session_refresh_video(session);
+       switch_core_session_request_video_refresh(session);
 }
 
 SWITCH_DECLARE(switch_status_t) switch_core_session_execute_application_get_flags(switch_core_session_t *session, const char *app,
@@ -2740,7 +2740,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_execute_application_get_flag
        }
 
        if (!switch_test_flag(application_interface, SAF_SUPPORT_NOMEDIA) && (switch_channel_test_flag(session->channel, CF_VIDEO))) {
-               switch_core_session_refresh_video(session);
+               switch_core_session_request_video_refresh(session);
        }
 
        if (switch_channel_test_flag(session->channel, CF_PROXY_MODE) && !switch_test_flag(application_interface, SAF_SUPPORT_NOMEDIA)) {
index eb54bc9ca1a2885fe3ae286415274606a71044ee..6034728f21ae4693d9ccbe9f03ed5d7a258d69bd 100644 (file)
@@ -361,7 +361,7 @@ void switch_core_state_machine_init(switch_memory_pool_t *pool)
                if (state < CS_HANGUP && switch_channel_get_callstate(session->channel) == CCS_UNHELD) { \
                        switch_channel_set_callstate(session->channel, CCS_ACTIVE);     \
                }                                                                                                                               \
-               switch_core_session_refresh_video(session);                                             \
+               switch_core_session_request_video_refresh(session);                                             \
                if (!driver_state_handler->on_##__STATE || (driver_state_handler->on_##__STATE(session) == SWITCH_STATUS_SUCCESS \
                                                                                                        )) {                            \
                        while (do_extra_handlers && (application_state_handler = switch_channel_get_state_handler(session->channel, index++)) != 0) { \
index 62a3937c23702f118cf1069482ea1f46dc41f564..f4089a195a84539bde9a00ab936f57f9a5b0bedc 100644 (file)
@@ -59,8 +59,8 @@ static void video_bridge_thread(switch_core_session_t *session, void *obj)
        switch_core_session_read_lock(vh->session_a);
        switch_core_session_read_lock(vh->session_b);
 
-       switch_core_session_refresh_video(vh->session_a);
-       switch_core_session_refresh_video(vh->session_b);
+       switch_core_session_request_video_refresh(vh->session_a);
+       switch_core_session_request_video_refresh(vh->session_b);
 
        while (switch_channel_up_nosig(channel) && switch_channel_up_nosig(b_channel) && vh->up == 1) {
 
@@ -98,8 +98,8 @@ static void video_bridge_thread(switch_core_session_t *session, void *obj)
        switch_core_session_kill_channel(vh->session_b, SWITCH_SIG_BREAK);
        switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(vh->session_a), SWITCH_LOG_DEBUG, "%s video thread ended.\n", switch_channel_get_name(channel));
 
-       switch_core_session_refresh_video(vh->session_a);
-       switch_core_session_refresh_video(vh->session_b);
+       switch_core_session_request_video_refresh(vh->session_a);
+       switch_core_session_request_video_refresh(vh->session_b);
 
        switch_core_session_rwunlock(vh->session_a);
        switch_core_session_rwunlock(vh->session_b);
index 16d627fcb85b49d07fa9aca8e0389cbc783040de..6075bb6d426121ae2f851a6385675995780117ae 100644 (file)
@@ -2893,7 +2893,7 @@ static int dtls_state_ready(switch_rtp_t *rtp_session, switch_dtls_t *dtls)
                        rtp_session->fir_countdown = FIR_COUNTDOWN;
                        
                        if (rtp_session->session && switch_core_session_get_partner(rtp_session->session, &other_session) == SWITCH_STATUS_SUCCESS) {
-                               switch_core_session_refresh_video(other_session);
+                               switch_core_session_request_video_refresh(other_session);
                                switch_core_session_rwunlock(other_session);
                        }
                }
@@ -3587,7 +3587,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_create(switch_rtp_t **new_rtp_session
                }
        } else {
                if (rtp_session->flags[SWITCH_RTP_FLAG_VIDEO]) {
-                       if (switch_core_timer_init(&rtp_session->timer, "soft", 1, 90, pool) == SWITCH_STATUS_SUCCESS) {
+                       if (switch_core_timer_init(&rtp_session->timer, "soft", 10, 900, pool) == SWITCH_STATUS_SUCCESS) {
                                switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG, "Starting video timer.\n");
                        }
                } else {
@@ -5216,6 +5216,7 @@ static switch_status_t process_rtcp_report(switch_rtp_t *rtp_session, rtcp_msg_t
                
                if ((extp->header.fmt == 4) || (extp->header.fmt == 1)) { /* FIR || PLI */
                        switch_core_media_gen_key_frame(rtp_session->session);
+                       switch_channel_set_flag(switch_core_session_get_channel(rtp_session->session), CF_VIDEO_REFRESH_REQ);
                }
        } else
 
@@ -6962,6 +6963,7 @@ SWITCH_DECLARE(int) switch_rtp_write_frame(switch_rtp_t *rtp_session, switch_fra
        uint32_t len, ts = 0;
        switch_payload_t payload = 0;
        rtp_msg_t *send_msg = NULL;
+       rtp_msg_t local_send_msg = { {0} };
 
        if (!switch_rtp_ready(rtp_session) || !rtp_session->remote_addr) {
                return -1;
@@ -7116,6 +7118,8 @@ SWITCH_DECLARE(int) switch_rtp_write_frame(switch_rtp_t *rtp_session, switch_fra
 
        if (fwd) {
                send_msg = frame->packet;
+               local_send_msg = *send_msg;
+               send_msg = &local_send_msg;
                len = frame->packetlen;
                ts = 0;