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

@ -338,6 +338,9 @@
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;
@ -1431,6 +1437,12 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
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);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
@ -1456,6 +1468,12 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
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",
switch_channel_get_name(channel));

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

@ -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);