From 2a35dfb51e2fce46c3989eb8ff417b2a07139d55 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 9 Mar 2011 15:17:09 -0600 Subject: [PATCH] add rtp-notimer-during-bridge (alternative to rtp-autoflush-during-bridge --- src/mod/endpoints/mod_sofia/mod_sofia.c | 72 ++++++++++++++++-------- src/mod/endpoints/mod_sofia/mod_sofia.h | 4 ++ src/mod/endpoints/mod_sofia/sofia.c | 12 ++++ src/mod/endpoints/mod_sofia/sofia_glue.c | 2 +- src/switch_rtp.c | 41 +++++++++----- 5 files changed, 94 insertions(+), 37 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 0921f1f313..ebf51b9c39 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -1444,69 +1444,97 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi case SWITCH_MESSAGE_INDICATE_BRIDGE: { - const char *var = switch_channel_get_variable(tech_pvt->channel, "sip_jitter_buffer_during_bridge"); - sofia_glue_tech_track(tech_pvt->profile, session); sofia_glue_tech_simplify(tech_pvt); - if (switch_false(var) && switch_rtp_ready(tech_pvt->rtp_session)) { + if (switch_rtp_ready(tech_pvt->rtp_session)) { const char *val; int ok = 0; - if (switch_channel_test_flag(tech_pvt->channel, CF_JITTERBUFFER) && switch_channel_test_cap_partner(tech_pvt->channel, CC_FS_RTP)) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, - "%s PAUSE Jitterbuffer\n", switch_channel_get_name(channel)); - switch_rtp_pause_jitter_buffer(tech_pvt->rtp_session, SWITCH_TRUE); + if (!(val = switch_channel_get_variable(tech_pvt->channel, "sip_jitter_buffer_during_bridge")) || switch_false(val)) { + if (switch_channel_test_flag(tech_pvt->channel, CF_JITTERBUFFER) && switch_channel_test_cap_partner(tech_pvt->channel, CC_FS_RTP)) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, + "%s PAUSE Jitterbuffer\n", switch_channel_get_name(channel)); + switch_rtp_pause_jitter_buffer(tech_pvt->rtp_session, SWITCH_TRUE); + sofia_set_flag(tech_pvt, TFLAG_JB_PAUSED); + } } - + if (sofia_test_flag(tech_pvt, TFLAG_PASS_RFC2833) && switch_channel_test_flag_partner(channel, CF_FS_RTP)) { switch_rtp_set_flag(tech_pvt->rtp_session, SWITCH_RTP_FLAG_PASS_RFC2833); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s activate passthru 2833 mode.\n", switch_channel_get_name(channel)); } - if ((val = switch_channel_get_variable(channel, "rtp_autoflush_during_bridge"))) { + + if ((val = switch_channel_get_variable(channel, "rtp_notimer_during_bridge"))) { ok = switch_true(val); } else { - ok = sofia_test_pflag(tech_pvt->profile, PFLAG_RTP_AUTOFLUSH_DURING_BRIDGE); + ok = sofia_test_pflag(tech_pvt->profile, PFLAG_RTP_NOTIMER_DURING_BRIDGE); + } + + if (ok && !switch_rtp_test_flag(tech_pvt->rtp_session, SWITCH_RTP_FLAG_USE_TIMER)) { + ok = 0; + } + + if (ok) { + switch_rtp_clear_flag(tech_pvt->rtp_session, SWITCH_RTP_FLAG_USE_TIMER); + switch_rtp_set_flag(tech_pvt->rtp_session, SWITCH_RTP_FLAG_NOBLOCK); + sofia_set_flag(tech_pvt, TFLAG_NOTIMER_DURING_BRIDGE); + } + + if (ok && sofia_test_flag(tech_pvt, TFLAG_NOTIMER_DURING_BRIDGE)) { + /* these are not compat */ + ok = 0; + } else { + if ((val = switch_channel_get_variable(channel, "rtp_autoflush_during_bridge"))) { + ok = switch_true(val); + } else { + ok = sofia_test_pflag(tech_pvt->profile, PFLAG_RTP_AUTOFLUSH_DURING_BRIDGE); + } } if (ok) { rtp_flush_read_buffer(tech_pvt->rtp_session, SWITCH_RTP_FLUSH_STICK); + sofia_set_flag(tech_pvt, TFLAG_AUTOFLUSH_DURING_BRIDGE); } else { rtp_flush_read_buffer(tech_pvt->rtp_session, SWITCH_RTP_FLUSH_ONCE); } + } } goto end; case SWITCH_MESSAGE_INDICATE_UNBRIDGE: if (switch_rtp_ready(tech_pvt->rtp_session)) { - const char *val; - int ok = 0; sofia_glue_tech_track(tech_pvt->profile, session); - if (switch_channel_test_flag(tech_pvt->channel, CF_JITTERBUFFER)) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, - "%s RESUME Jitterbuffer\n", switch_channel_get_name(channel)); - switch_rtp_pause_jitter_buffer(tech_pvt->rtp_session, SWITCH_FALSE); + if (sofia_test_flag(tech_pvt, TFLAG_JB_PAUSED)) { + sofia_clear_flag(tech_pvt, TFLAG_JB_PAUSED); + if (switch_channel_test_flag(tech_pvt->channel, CF_JITTERBUFFER)) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, + "%s RESUME Jitterbuffer\n", switch_channel_get_name(channel)); + switch_rtp_pause_jitter_buffer(tech_pvt->rtp_session, SWITCH_FALSE); + } } + if (switch_rtp_test_flag(tech_pvt->rtp_session, SWITCH_RTP_FLAG_PASS_RFC2833)) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s deactivate passthru 2833 mode.\n", switch_channel_get_name(channel)); switch_rtp_clear_flag(tech_pvt->rtp_session, SWITCH_RTP_FLAG_PASS_RFC2833); } - - if ((val = switch_channel_get_variable(channel, "rtp_autoflush_during_bridge"))) { - ok = switch_true(val); - } else { - ok = sofia_test_pflag(tech_pvt->profile, PFLAG_RTP_AUTOFLUSH_DURING_BRIDGE); + + if (sofia_test_flag(tech_pvt, TFLAG_NOTIMER_DURING_BRIDGE)) { + switch_rtp_set_flag(tech_pvt->rtp_session, SWITCH_RTP_FLAG_USE_TIMER); + switch_rtp_clear_flag(tech_pvt->rtp_session, SWITCH_RTP_FLAG_NOBLOCK); + sofia_clear_flag(tech_pvt, TFLAG_NOTIMER_DURING_BRIDGE); } - if (ok) { + if (sofia_test_flag(tech_pvt, TFLAG_AUTOFLUSH_DURING_BRIDGE)) { rtp_flush_read_buffer(tech_pvt->rtp_session, SWITCH_RTP_FLUSH_UNSTICK); + sofia_clear_flag(tech_pvt, TFLAG_AUTOFLUSH_DURING_BRIDGE); } else { rtp_flush_read_buffer(tech_pvt->rtp_session, SWITCH_RTP_FLUSH_ONCE); } diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h index c46e6395a0..c3b60da317 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.h +++ b/src/mod/endpoints/mod_sofia/mod_sofia.h @@ -231,6 +231,7 @@ typedef enum { PFLAG_PRESENCE_ON_FIRST_REGISTER, PFLAG_NO_CONNECTION_REUSE, PFLAG_RENEG_ON_HOLD, + PFLAG_RTP_NOTIMER_DURING_BRIDGE, /* No new flags below this line */ PFLAG_MAX } PFLAGS; @@ -289,6 +290,9 @@ typedef enum { TFLAG_RECOVERING_BRIDGE, TFLAG_T38_PASSTHRU, TFLAG_RECOVERED, + TFLAG_AUTOFLUSH_DURING_BRIDGE, + TFLAG_NOTIMER_DURING_BRIDGE, + TFLAG_JB_PAUSED, /* No new flags below this line */ TFLAG_MAX } TFLAGS; diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index b6d6b74aa6..8e38393efb 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -2525,6 +2525,12 @@ switch_status_t reconfig_sofia(sofia_profile_t *profile) } else { sofia_clear_pflag(profile, PFLAG_RTP_AUTOFLUSH_DURING_BRIDGE); } + } else if (!strcasecmp(var, "rtp-notimer-during-bridge")) { + if (switch_true(val)) { + sofia_set_pflag(profile, PFLAG_RTP_NOTIMER_DURING_BRIDGE); + } else { + sofia_clear_pflag(profile, PFLAG_RTP_NOTIMER_DURING_BRIDGE); + } } else if (!strcasecmp(var, "manual-redirect")) { if (switch_true(val)) { sofia_set_pflag(profile, PFLAG_MANUAL_REDIRECT); @@ -3202,6 +3208,12 @@ switch_status_t config_sofia(int reload, char *profile_name) } else { sofia_clear_pflag(profile, PFLAG_RTP_AUTOFLUSH_DURING_BRIDGE); } + } else if (!strcasecmp(var, "rtp-notimer-during-bridge")) { + if (switch_true(val)) { + sofia_set_pflag(profile, PFLAG_RTP_NOTIMER_DURING_BRIDGE); + } else { + sofia_clear_pflag(profile, PFLAG_RTP_NOTIMER_DURING_BRIDGE); + } } else if (!strcasecmp(var, "manual-redirect")) { if (switch_true(val)) { sofia_set_pflag(profile, PFLAG_MANUAL_REDIRECT); diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index 8d7fb6bc57..91cf5b6fba 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -3176,7 +3176,7 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f if ((val = switch_channel_get_variable(tech_pvt->channel, "jitterbuffer_msec")) || (val = tech_pvt->profile->jb_msec)) { int jb_msec = atoi(val); - int maxlen = 0, max_drift = 0; + int maxlen = 0, max_drift = 1000; char *p, *q; if ((p = strchr(val, ':'))) { diff --git a/src/switch_rtp.c b/src/switch_rtp.c index f5a7022928..6b8c6b0dc6 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -2182,7 +2182,10 @@ SWITCH_DECLARE(void) switch_rtp_set_flag(switch_rtp_t *rtp_session, switch_rtp_f rtp_session->autoadj_window = 20; rtp_session->autoadj_tally = 0; rtp_flush_read_buffer(rtp_session, SWITCH_RTP_FLUSH_ONCE); + } else if (flags & SWITCH_RTP_FLAG_NOBLOCK) { + switch_socket_opt_set(rtp_session->sock_input, SWITCH_SO_NONBLOCK, TRUE); } + } SWITCH_DECLARE(uint32_t) switch_rtp_test_flag(switch_rtp_t *rtp_session, switch_rtp_flag_t flags) @@ -2193,6 +2196,10 @@ SWITCH_DECLARE(uint32_t) switch_rtp_test_flag(switch_rtp_t *rtp_session, switch_ SWITCH_DECLARE(void) switch_rtp_clear_flag(switch_rtp_t *rtp_session, switch_rtp_flag_t flags) { switch_clear_flag_locked(rtp_session, flags); + + if (flags & SWITCH_RTP_FLAG_NOBLOCK) { + switch_socket_opt_set(rtp_session->sock_input, SWITCH_SO_NONBLOCK, FALSE); + } } static void do_2833(switch_rtp_t *rtp_session, switch_core_session_t *session) @@ -2240,7 +2247,7 @@ static void do_2833(switch_rtp_t *rtp_session, switch_core_session_t *session) if (loops != 1) { rtp_session->last_write_ts = rtp_session->dtmf_data.timestamp_dtmf + rtp_session->dtmf_data.out_digit_sub_sofar; rtp_session->sending_dtmf = 0; - if (rtp_session->timer.interval) { + if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_USE_TIMER)) { rtp_session->last_write_samplecount = rtp_session->timer.samplecount; rtp_session->next_write_samplecount = rtp_session->timer.samplecount + samples * 5; } @@ -2251,7 +2258,7 @@ static void do_2833(switch_rtp_t *rtp_session, switch_core_session_t *session) if (!rtp_session->dtmf_data.out_digit_dur && rtp_session->dtmf_data.dtmf_queue && switch_queue_size(rtp_session->dtmf_data.dtmf_queue)) { void *pop; - if (rtp_session->timer.interval) { + if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_USE_TIMER)) { if (rtp_session->timer.samplecount < rtp_session->next_write_samplecount) { return; } @@ -2275,7 +2282,7 @@ static void do_2833(switch_rtp_t *rtp_session, switch_core_session_t *session) rtp_session->dtmf_data.timestamp_dtmf = rtp_session->last_write_ts + samples; - if (rtp_session->timer.interval) { + if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_USE_TIMER)) { offset = rtp_session->timer.samplecount - rtp_session->last_write_samplecount; if (offset > 0) { rtp_session->dtmf_data.timestamp_dtmf = (uint32_t) (rtp_session->dtmf_data.timestamp_dtmf + offset); @@ -2491,10 +2498,14 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t stfu_n_reset(rtp_session->jb); } + if (!switch_test_flag(rtp_session, SWITCH_RTP_FLAG_USE_TIMER) && rtp_session->timer.interval) { + switch_core_timer_sync(&rtp_session->timer); + } + if (stfu_n_eat(rtp_session->jb, rtp_session->last_read_ts, rtp_session->recv_msg.header.pt, rtp_session->recv_msg.body, *bytes - rtp_header_len, rtp_session->timer.samplecount) == STFU_ITS_TOO_LATE) { - printf("doh\n"); + goto more; } @@ -2657,7 +2668,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ return -1; } - if (rtp_session->timer.interval) { + if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_USE_TIMER)) { sleep_mss = rtp_session->timer.interval * 1000; } @@ -2668,7 +2679,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ int read_pretriggered = 0; bytes = 0; - if (rtp_session->timer.interval) { + if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_USE_TIMER)) { if ((switch_test_flag(rtp_session, SWITCH_RTP_FLAG_AUTOFLUSH) || switch_test_flag(rtp_session, SWITCH_RTP_FLAG_STICKY_FLUSH)) && rtp_session->read_pollfd) { if (switch_poll(rtp_session->read_pollfd, 1, &fdr, 0) == SWITCH_STATUS_SUCCESS) { @@ -2722,8 +2733,8 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ if (!switch_rtp_ready(rtp_session)) { break; } - - if (!rtp_session->timer.interval && rtp_session->read_pollfd) { + + if (!switch_test_flag(rtp_session, SWITCH_RTP_FLAG_USE_TIMER) && rtp_session->read_pollfd) { int pt = poll_sec * 1000000; if (rtp_session->dtmf_data.out_digit_dur > 0 || rtp_session->dtmf_data.in_digit_sanity) { @@ -3160,7 +3171,8 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ goto end; } - if (check || (bytes && !rtp_session->timer.interval)) { + + if (check || (bytes && !switch_test_flag(rtp_session, SWITCH_RTP_FLAG_USE_TIMER))) { if (!bytes && switch_test_flag(rtp_session, SWITCH_RTP_FLAG_USE_TIMER)) { /* We're late! We're Late! */ if (!switch_test_flag(rtp_session, SWITCH_RTP_FLAG_NOBLOCK) && status == SWITCH_STATUS_BREAK) { switch_cond_next(); @@ -3186,7 +3198,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ do_continue: - if (!bytes && !rtp_session->timer.interval) { + if (!bytes && !switch_test_flag(rtp_session, SWITCH_RTP_FLAG_USE_TIMER)) { switch_yield(sleep_mss); } @@ -3522,7 +3534,7 @@ static int rtp_common_write(switch_rtp_t *rtp_session, if (rtp_session->ts <= rtp_session->last_write_ts && !(rtp_session->rtp_bugs & RTP_BUG_NEVER_SEND_MARKER)) { m++; } - } else if (rtp_session->timer.timer_interface) { + } else if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_USE_TIMER)) { rtp_session->ts = rtp_session->timer.samplecount; if (rtp_session->ts <= rtp_session->last_write_ts && rtp_session->ts > 0) { @@ -3540,11 +3552,12 @@ static int rtp_common_write(switch_rtp_t *rtp_session, m++; } - if (rtp_session->timer.interval && (rtp_session->timer.samplecount - rtp_session->last_write_samplecount) > rtp_session->samples_per_interval * 10) { + if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_USE_TIMER) && + (rtp_session->timer.samplecount - rtp_session->last_write_samplecount) > rtp_session->samples_per_interval * 10) { m++; } - if (!rtp_session->timer.interval && + if (!switch_test_flag(rtp_session, SWITCH_RTP_FLAG_USE_TIMER) && ((unsigned) ((switch_micro_time_now() - rtp_session->last_write_timestamp))) > (rtp_session->ms_per_packet * 10)) { m++; } @@ -3785,7 +3798,7 @@ static int rtp_common_write(switch_rtp_t *rtp_session, rtp_session->stats.outbound.media_bytes += bytes; } - if (rtp_session->timer.interval) { + if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_USE_TIMER)) { rtp_session->last_write_samplecount = rtp_session->timer.samplecount; } else { rtp_session->last_write_timestamp = (uint32_t) switch_micro_time_now();