add auto-jitterbuffer-msec param and auto-disable the jitterbuffer when briding to another channel who also has a jitterbuffer so both legs will disable during a bridge

This commit is contained in:
Anthony Minessale 2011-01-05 16:25:07 -06:00
parent e06feedd9e
commit 181b543b0c
11 changed files with 104 additions and 13 deletions

View File

@ -337,6 +337,9 @@
A completed transaction is kept around for the duration of T4 in order to catch late responses.
The T4 is the maximum duration for the messages to stay in the network and the duration of SIP timer K. -->
<!-- <param name="timer-T4" value="4000" /> -->
<!-- Turn on a jitterbuffer for every call -->
<!-- <param name="auto-jitterbuffer-msec" value="60"/> -->
</settings>
</profile>

View File

@ -344,6 +344,7 @@ SWITCH_DECLARE(void) switch_channel_set_cap_value(switch_channel_t *channel, swi
SWITCH_DECLARE(void) switch_channel_clear_cap(switch_channel_t *channel, switch_channel_cap_t cap);
SWITCH_DECLARE(uint32_t) switch_channel_test_cap(switch_channel_t *channel, switch_channel_cap_t cap);
SWITCH_DECLARE(uint32_t) switch_channel_test_cap_partner(switch_channel_t *channel, switch_channel_cap_t cap);
/*!
\brief Set given flag(s) on a given channel's bridge partner

View File

@ -237,6 +237,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_activate_jitter_buffer(switch_rtp_t *
SWITCH_DECLARE(switch_status_t) switch_rtp_debug_jitter_buffer(switch_rtp_t *rtp_session, const char *name);
SWITCH_DECLARE(switch_status_t) switch_rtp_deactivate_jitter_buffer(switch_rtp_t *rtp_session);
SWITCH_DECLARE(switch_status_t) switch_rtp_pause_jitter_buffer(switch_rtp_t *rtp_session, switch_bool_t pause);
/*!
\brief Set an RTP Flag

View File

@ -1035,6 +1035,8 @@ typedef enum {
CC_MEDIA_ACK = 1,
CC_BYPASS_MEDIA,
CC_PROXY_MEDIA,
CC_JITTERBUFFER,
CC_FS_RTP,
/* WARNING: DO NOT ADD ANY FLAGS BELOW THIS LINE */
CC_FLAG_MAX
} switch_channel_cap_t;

View File

@ -1346,7 +1346,13 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
char *p;
const char *s;
if (!strncasecmp(msg->string_arg, "debug:", 6)) {
if (!strcasecmp(msg->string_arg, "pause")) {
switch_rtp_pause_jitter_buffer(tech_pvt->rtp_session, SWITCH_TRUE);
goto end;
} else if (!strcasecmp(msg->string_arg, "resume")) {
switch_rtp_pause_jitter_buffer(tech_pvt->rtp_session, SWITCH_FALSE);
goto end;
} else if (!strncasecmp(msg->string_arg, "debug:", 6)) {
s = msg->string_arg + 6;
if (s && !strcmp(s, "off")) {
s = NULL;
@ -1426,10 +1432,16 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
{
sofia_glue_tech_simplify(tech_pvt);
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 (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);
@ -1455,6 +1467,12 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
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_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",

View File

@ -501,6 +501,7 @@ struct sofia_profile {
char *challenge_realm;
char *rtcp_audio_interval_msec;
char *rtcp_video_interval_msec;
char *jb_msec;
sofia_cid_type_t cid_type;
sofia_dtmf_t dtmf_type;
int auto_restart;
@ -1050,3 +1051,4 @@ void sofia_glue_build_vid_refresh_message(switch_core_session_t *session, const
void sofia_glue_check_dtmf_type(private_object_t *tech_pvt);
void sofia_glue_parse_rtp_bugs(uint32_t *flag_pole, const char *str);
char *sofia_glue_gen_contact_str(sofia_profile_t *profile, sip_t const *sip, sofia_nat_parse_t *np);
void sofia_glue_pause_jitterbuffer(switch_core_session_t *session, switch_bool_t on);

View File

@ -2351,6 +2351,11 @@ switch_status_t reconfig_sofia(sofia_profile_t *profile)
} else {
sofia_clear_pflag(profile, PFLAG_DISABLE_HOLD);
}
} else if (!strcasecmp(var, "auto-jitterbuffer-msec")) {
int msec = atoi(val);
if (msec > 19) {
profile->jb_msec = switch_core_strdup(profile->pool, val);
}
} else if (!strcasecmp(var, "sip-trace")) {
if (switch_true(val)) {
sofia_set_flag(profile, TFLAG_TPORT_LOG);
@ -3089,6 +3094,11 @@ switch_status_t config_sofia(int reload, char *profile_name)
} else {
sofia_clear_pflag(profile, PFLAG_DISABLE_HOLD);
}
} else if (!strcasecmp(var, "auto-jitterbuffer-msec")) {
int msec = atoi(val);
if (msec > 19) {
profile->jb_msec = switch_core_strdup(profile->pool, val);
}
} else if (!strcasecmp(var, "dtmf-type")) {
if (!strcasecmp(val, "rfc2833")) {
profile->dtmf_type = DTMF_2833;

View File

@ -832,6 +832,8 @@ void sofia_glue_attach_private(switch_core_session_t *session, sofia_profile_t *
switch_channel_set_cap(tech_pvt->channel, CC_MEDIA_ACK);
switch_channel_set_cap(tech_pvt->channel, CC_BYPASS_MEDIA);
switch_channel_set_cap(tech_pvt->channel, CC_PROXY_MEDIA);
switch_channel_set_cap(tech_pvt->channel, CC_JITTERBUFFER);
switch_channel_set_cap(tech_pvt->channel, CC_FS_RTP);
switch_core_session_set_private(session, tech_pvt);
@ -3152,8 +3154,8 @@ 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"))) {
int len = atoi(val);
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;
char *p;
@ -3162,13 +3164,13 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f
maxlen = atoi(p);
}
if (len < 20 || len > 10000) {
if (jb_msec < 20 || jb_msec > 10000) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_ERROR,
"Invalid Jitterbuffer spec [%d] must be between 20 and 10000\n", len);
"Invalid Jitterbuffer spec [%d] must be between 20 and 10000\n", jb_msec);
} else {
int qlen, maxqlen = 50;
qlen = len / (tech_pvt->read_impl.microseconds_per_packet / 1000);
qlen = jb_msec / (tech_pvt->read_impl.microseconds_per_packet / 1000);
if (maxlen) {
maxqlen = maxlen / (tech_pvt->read_impl.microseconds_per_packet / 1000);
@ -3178,11 +3180,11 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f
tech_pvt->read_impl.samples_per_packet,
tech_pvt->read_impl.samples_per_second) == SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session),
SWITCH_LOG_DEBUG, "Setting Jitterbuffer to %dms (%d frames)\n", len, qlen);
SWITCH_LOG_DEBUG, "Setting Jitterbuffer to %dms (%d frames)\n", jb_msec, qlen);
switch_channel_set_flag(tech_pvt->channel, CF_JITTERBUFFER);
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session),
SWITCH_LOG_WARNING, "Error Setting Jitterbuffer to %dms (%d frames)\n", len, qlen);
SWITCH_LOG_WARNING, "Error Setting Jitterbuffer to %dms (%d frames)\n", jb_msec, qlen);
}
}
@ -6065,6 +6067,19 @@ void sofia_glue_tech_simplify(private_object_t *tech_pvt)
}
}
void sofia_glue_pause_jitterbuffer(switch_core_session_t *session, switch_bool_t on)
{
switch_core_session_message_t *msg;
msg = switch_core_session_alloc(session, sizeof(*msg));
MESSAGE_STAMP_FFL(msg);
msg->message_id = SWITCH_MESSAGE_INDICATE_JITTER_BUFFER;
msg->string_arg = switch_core_session_strdup(session, on ? "pause" : "resume");
msg->from = __FILE__;
switch_core_session_queue_message(session, msg);
}
void sofia_glue_build_vid_refresh_message(switch_core_session_t *session, const char *pl)
{
switch_core_session_message_t *msg;

View File

@ -1261,6 +1261,24 @@ SWITCH_DECLARE(uint32_t) switch_channel_test_cap(switch_channel_t *channel, swit
return channel->caps[cap] ? 1 : 0;
}
SWITCH_DECLARE(uint32_t) switch_channel_test_cap_partner(switch_channel_t *channel, switch_channel_cap_t cap)
{
const char *uuid;
int r = 0;
switch_assert(channel != NULL);
if ((uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE))) {
switch_core_session_t *session;
if ((session = switch_core_session_locate(uuid))) {
r = switch_channel_test_cap(switch_core_session_get_channel(session), cap);
switch_core_session_rwunlock(session);
}
}
return r;
}
SWITCH_DECLARE(char *) switch_channel_get_flag_string(switch_channel_t *channel)
{
switch_stream_handle_t stream = { 0 };

View File

@ -1142,7 +1142,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_multi_threaded_bridge(switch_core_ses
if (switch_channel_test_flag(peer_channel, CF_ANSWERED) || switch_channel_test_flag(peer_channel, CF_EARLY_MEDIA) ||
switch_channel_test_flag(peer_channel, CF_RING_READY)) {
const char *app, *data;
switch_channel_set_state(peer_channel, CS_CONSUME_MEDIA);
if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_BRIDGE) == SWITCH_STATUS_SUCCESS) {

View File

@ -242,6 +242,7 @@ struct switch_rtp {
switch_time_t send_time;
switch_byte_t auto_adj_used;
uint8_t pause_jb;
};
struct switch_rtcp_senderinfo {
@ -1640,6 +1641,26 @@ static void jb_callback(stfu_instance_t *i, void *udata)
}
SWITCH_DECLARE(switch_status_t) switch_rtp_pause_jitter_buffer(switch_rtp_t *rtp_session, switch_bool_t pause)
{
if (!switch_rtp_ready(rtp_session) || !rtp_session->jb) {
return SWITCH_STATUS_FALSE;
}
if (!!pause == !!rtp_session->pause_jb) {
return SWITCH_STATUS_FALSE;
}
if (rtp_session->pause_jb && !pause) {
stfu_n_reset(rtp_session->jb);
}
rtp_session->pause_jb = pause ? 1 : 0;
return SWITCH_STATUS_SUCCESS;
}
SWITCH_DECLARE(switch_status_t) switch_rtp_deactivate_jitter_buffer(switch_rtp_t *rtp_session)
{
@ -2174,7 +2195,7 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t
ts = ntohl(rtp_session->recv_msg.header.ts);
if (*bytes && (!rtp_session->recv_te || rtp_session->recv_msg.header.pt != rtp_session->recv_te) &&
ts && !rtp_session->jb && ts == rtp_session->last_cng_ts) {
ts && !rtp_session->jb && !rtp_session->pause_jb && ts == rtp_session->last_cng_ts) {
/* we already sent this frame..... */
*bytes = 0;
return SWITCH_STATUS_SUCCESS;
@ -2204,7 +2225,7 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t
rtp_session->last_read_ts = ts;
if (rtp_session->jb && rtp_session->recv_msg.header.version == 2 && *bytes) {
if (rtp_session->jb && !rtp_session->pause_jb && rtp_session->recv_msg.header.version == 2 && *bytes) {
if (rtp_session->recv_msg.header.m && rtp_session->recv_msg.header.pt != rtp_session->recv_te &&
!switch_test_flag(rtp_session, SWITCH_RTP_FLAG_VIDEO) && !(rtp_session->rtp_bugs & RTP_BUG_IGNORE_MARK_BIT)) {
stfu_n_reset(rtp_session->jb);
@ -2217,7 +2238,7 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t
status = SWITCH_STATUS_FALSE;
}
if (rtp_session->jb && !rtp_session->checked_jb) {
if (rtp_session->jb && !rtp_session->pause_jb && !rtp_session->checked_jb) {
if ((jb_frame = stfu_n_read_a_frame(rtp_session->jb))) {
memcpy(rtp_session->recv_msg.body, jb_frame->data, jb_frame->dlen);