]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
cache read_codec implementation to reduce risk of race conditions
authorAnthony Minessale <anthony.minessale@gmail.com>
Mon, 12 Jan 2009 18:37:44 +0000 (18:37 +0000)
committerAnthony Minessale <anthony.minessale@gmail.com>
Mon, 12 Jan 2009 18:37:44 +0000 (18:37 +0000)
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@11143 d0543943-73ff-0310-b7d9-9358b9ac24b2

src/mod/endpoints/mod_sofia/mod_sofia.c
src/mod/endpoints/mod_sofia/mod_sofia.h
src/mod/endpoints/mod_sofia/sofia_glue.c

index bcb8783db2b99f8e08e4544033f24615b7d94e47..530c19cfd25d00be51cd82741711c2d1ca0a21a2 100644 (file)
@@ -709,14 +709,14 @@ static switch_status_t sofia_read_frame(switch_core_session_t *session, switch_f
                                        }
                                        
                                        if (tech_pvt->check_frames++ < MAX_CODEC_CHECK_FRAMES) {
-                                               if (!tech_pvt->read_codec.implementation->encoded_bytes_per_packet) {
+                                               if (!tech_pvt->read_impl.encoded_bytes_per_packet) {
                                                        tech_pvt->check_frames = MAX_CODEC_CHECK_FRAMES;
                                                        goto skip;
                                                }
 
-                                               if (tech_pvt->last_ts && tech_pvt->read_frame.datalen != tech_pvt->read_codec.implementation->encoded_bytes_per_packet) {
+                                               if (tech_pvt->last_ts && tech_pvt->read_frame.datalen != tech_pvt->read_impl.encoded_bytes_per_packet) {
                                                        switch_size_t codec_ms = (int)(tech_pvt->read_frame.timestamp - 
-                                                                                                                  tech_pvt->last_ts) / (tech_pvt->read_codec.implementation->samples_per_second / 1000);
+                                                                                                                  tech_pvt->last_ts) / (tech_pvt->read_impl.samples_per_second / 1000);
 
                                                        if ((codec_ms % 10) != 0) {
                                                                tech_pvt->check_frames = MAX_CODEC_CHECK_FRAMES;
@@ -768,8 +768,8 @@ static switch_status_t sofia_read_frame(switch_core_session_t *session, switch_f
                                                                        }
                                                                        
                                                                        if (rtp_timeout_sec) {
-                                                                               tech_pvt->max_missed_packets = (tech_pvt->read_codec.implementation->samples_per_second * rtp_timeout_sec) /
-                                                                                       tech_pvt->read_codec.implementation->samples_per_packet;
+                                                                               tech_pvt->max_missed_packets = (tech_pvt->read_impl.samples_per_second * rtp_timeout_sec) /
+                                                                                       tech_pvt->read_impl.samples_per_packet;
                                                                                
                                                                                switch_rtp_set_max_missed_packets(tech_pvt->rtp_session, tech_pvt->max_missed_packets);
                                                                                if (!rtp_hold_timeout_sec) {
@@ -778,13 +778,13 @@ static switch_status_t sofia_read_frame(switch_core_session_t *session, switch_f
                                                                        }
                                                                        
                                                                        if (rtp_hold_timeout_sec) {
-                                                                               tech_pvt->max_missed_hold_packets = (tech_pvt->read_codec.implementation->samples_per_second * rtp_hold_timeout_sec) /
-                                                                                       tech_pvt->read_codec.implementation->samples_per_packet;
+                                                                               tech_pvt->max_missed_hold_packets = (tech_pvt->read_impl.samples_per_second * rtp_hold_timeout_sec) /
+                                                                                       tech_pvt->read_impl.samples_per_packet;
                                                                        }
                                                                        
                                                                        if (switch_rtp_change_interval(tech_pvt->rtp_session, 
                                                                                                                                   tech_pvt->codec_ms * 1000,
-                                                                                                                                  tech_pvt->read_codec.implementation->samples_per_packet
+                                                                                                                                  tech_pvt->read_impl.samples_per_packet
                                                                                                                                   ) != SWITCH_STATUS_SUCCESS) {
                                                                                switch_channel_hangup(tech_pvt->channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
                                                                                
@@ -806,10 +806,10 @@ static switch_status_t sofia_read_frame(switch_core_session_t *session, switch_f
                                        }
                                skip:
                                        
-                                       if ((bytes = tech_pvt->read_codec.implementation->encoded_bytes_per_packet)) {
+                                       if ((bytes = tech_pvt->read_impl.encoded_bytes_per_packet)) {
                                                frames = (tech_pvt->read_frame.datalen / bytes);
                                        }
-                                       tech_pvt->read_frame.samples = (int) (frames * tech_pvt->read_codec.implementation->samples_per_packet);
+                                       tech_pvt->read_frame.samples = (int) (frames * tech_pvt->read_impl.samples_per_packet);
 
                                        if (tech_pvt->read_frame.datalen == 0) {
                                                continue;
@@ -872,13 +872,13 @@ static switch_status_t sofia_write_frame(switch_core_session_t *session, switch_
        switch_set_flag_locked(tech_pvt, TFLAG_WRITING);
 
        if (!switch_test_flag(frame, SFF_CNG) && !switch_test_flag(frame, SFF_PROXY_PACKET)) {
-               if (tech_pvt->read_codec.implementation->encoded_bytes_per_packet) {
-                       bytes = tech_pvt->read_codec.implementation->encoded_bytes_per_packet;
+               if (tech_pvt->read_impl.encoded_bytes_per_packet) {
+                       bytes = tech_pvt->read_impl.encoded_bytes_per_packet;
                        frames = ((int) frame->datalen / bytes);
                } else
                        frames = 1;
 
-               samples = frames * tech_pvt->read_codec.implementation->samples_per_packet;
+               samples = frames * tech_pvt->read_impl.samples_per_packet;
        }
 
        tech_pvt->timestamp_send += samples;
index 98cd6ed1853262fe22a6e2b210135f17c180ae2c..0d66ac503457a9489154b3bbf9974e5028fbd182 100644 (file)
@@ -553,6 +553,8 @@ struct private_object {
        uint32_t last_codec_ms;
        nua_event_t want_event;
        switch_rtp_bug_flag_t rtp_bugs;
+       switch_codec_implementation_t read_impl;
+       switch_codec_implementation_t write_impl;
 };
 
 struct callback_t {
index aa5a656680a0554be3b328424085b20c45487705..4b097409e47f476d3c6aa7831e6bc4a34afcd0bf 100644 (file)
@@ -1654,9 +1654,13 @@ switch_status_t sofia_glue_tech_set_codec(private_object_t *tech_pvt, int force)
                switch_goto_status(SWITCH_STATUS_FALSE, end);
        }
 
+       tech_pvt->read_impl = *tech_pvt->read_codec.implementation;
+       tech_pvt->write_impl = *tech_pvt->write_codec.implementation;
+
+
        if (switch_rtp_ready(tech_pvt->rtp_session)) {
                switch_assert(tech_pvt->read_codec.implementation);
-               switch_rtp_set_default_samples_per_interval(tech_pvt->rtp_session, tech_pvt->read_codec.implementation->samples_per_packet);
+               switch_rtp_set_default_samples_per_interval(tech_pvt->rtp_session, tech_pvt->read_impl.samples_per_packet);
        }
 
        tech_pvt->read_frame.rate = tech_pvt->rm_rate;
@@ -1669,7 +1673,7 @@ switch_status_t sofia_glue_tech_set_codec(private_object_t *tech_pvt, int force)
 
        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Set Codec %s %s/%ld %d ms %d samples\n",
                                          switch_channel_get_name(tech_pvt->channel), tech_pvt->iananame, tech_pvt->rm_rate, tech_pvt->codec_ms,
-                                         tech_pvt->read_codec.implementation->samples_per_packet);
+                                         tech_pvt->read_impl.samples_per_packet);
        tech_pvt->read_frame.codec = &tech_pvt->read_codec;
 
        tech_pvt->write_codec.agreed_pt = tech_pvt->agreed_pt;
@@ -1832,8 +1836,8 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f
                goto end;
        }
 
-       bw = tech_pvt->read_codec.implementation->bits_per_second;
-       ms = tech_pvt->read_codec.implementation->microseconds_per_packet;
+       bw = tech_pvt->read_impl.bits_per_second;
+       ms = tech_pvt->read_impl.microseconds_per_packet;
 
        if (myflags) {
                flags = myflags;
@@ -1892,7 +1896,7 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f
                                                  tech_pvt->local_sdp_audio_ip,
                                                  tech_pvt->local_sdp_audio_port,
                                                  tech_pvt->remote_sdp_audio_ip,
-                                                 tech_pvt->remote_sdp_audio_port, tech_pvt->agreed_pt, tech_pvt->read_codec.implementation->microseconds_per_packet / 1000);
+                                                 tech_pvt->remote_sdp_audio_port, tech_pvt->agreed_pt, tech_pvt->read_impl.microseconds_per_packet / 1000);
        }
 
        switch_snprintf(tmp, sizeof(tmp), "%d", tech_pvt->local_sdp_audio_port);
@@ -1934,7 +1938,7 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f
                                                  tech_pvt->local_sdp_audio_ip,
                                                  tech_pvt->local_sdp_audio_port,
                                                  tech_pvt->remote_sdp_audio_ip,
-                                                 tech_pvt->remote_sdp_audio_port, tech_pvt->agreed_pt, tech_pvt->read_codec.implementation->microseconds_per_packet / 1000);
+                                                 tech_pvt->remote_sdp_audio_port, tech_pvt->agreed_pt, tech_pvt->read_impl.microseconds_per_packet / 1000);
 
        } else {
                timer_name = tech_pvt->profile->timer_name;
@@ -1949,7 +1953,7 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f
                                                                                   tech_pvt->remote_sdp_audio_ip,
                                                                                   tech_pvt->remote_sdp_audio_port,
                                                                                   tech_pvt->agreed_pt,
-                                                                                  tech_pvt->read_codec.implementation->samples_per_packet,
+                                                                                  tech_pvt->read_impl.samples_per_packet,
                                                                                   tech_pvt->codec_ms * 1000,
                                                                                   (switch_rtp_flag_t) flags, timer_name, &err, switch_core_session_get_pool(tech_pvt->session));
 
@@ -1982,7 +1986,7 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f
                                }
                        }
 
-                       stun_ping = (ival * tech_pvt->read_codec.implementation->samples_per_second) / tech_pvt->read_codec.implementation->samples_per_packet;
+                       stun_ping = (ival * tech_pvt->read_impl.samples_per_second) / tech_pvt->read_impl.samples_per_packet;
                }
 
                tech_pvt->ssrc = switch_rtp_get_ssrc(tech_pvt->rtp_session);
@@ -2012,7 +2016,7 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f
                        } else {
                                int qlen;
 
-                               qlen = len / (tech_pvt->read_codec.implementation->microseconds_per_packet / 1000);
+                               qlen = len / (tech_pvt->read_impl.microseconds_per_packet / 1000);
 
                                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Setting Jitterbuffer to %dms (%d frames)\n", len, qlen);
                                switch_rtp_activate_jitter_buffer(tech_pvt->rtp_session, qlen);
@@ -2034,8 +2038,8 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f
                }
 
                if (rtp_timeout_sec) {
-                       tech_pvt->max_missed_packets = (tech_pvt->read_codec.implementation->samples_per_second * rtp_timeout_sec) /
-                               tech_pvt->read_codec.implementation->samples_per_packet;
+                       tech_pvt->max_missed_packets = (tech_pvt->read_impl.samples_per_second * rtp_timeout_sec) /
+                               tech_pvt->read_impl.samples_per_packet;
 
                        switch_rtp_set_max_missed_packets(tech_pvt->rtp_session, tech_pvt->max_missed_packets);
                        if (!rtp_hold_timeout_sec) {
@@ -2044,8 +2048,8 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f
                }
 
                if (rtp_hold_timeout_sec) {
-                       tech_pvt->max_missed_hold_packets = (tech_pvt->read_codec.implementation->samples_per_second * rtp_hold_timeout_sec) /
-                               tech_pvt->read_codec.implementation->samples_per_packet;
+                       tech_pvt->max_missed_hold_packets = (tech_pvt->read_impl.samples_per_second * rtp_hold_timeout_sec) /
+                               tech_pvt->read_impl.samples_per_packet;
                }
 
                if (tech_pvt->te) {