mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-04-16 08:49:01 +00:00
add rtp_bug IGNORE_DTMF_DURATION to speed up dtmf detection of RFC2833 on strange carriers
This commit is contained in:
parent
cd13030f25
commit
b3fc001e6c
@ -632,9 +632,13 @@ typedef enum {
|
|||||||
This flag will never send any. Sheesh....
|
This flag will never send any. Sheesh....
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
RTP_BUG_IGNORE_DTMF_DURATION = (1 << 6)
|
||||||
|
|
||||||
|
/*
|
||||||
|
Guess Who? ... Yep, Sonus (and who know's who else) likes to interweave DTMF with the audio stream making it take
|
||||||
|
2X as long as it should and sending an incorrect duration making the DTMF very delayed.
|
||||||
|
This flag will treat every dtmf as if it were 50ms and queue it on recipt of the leading packet rather than at the end.
|
||||||
|
*/
|
||||||
|
|
||||||
} switch_rtp_bug_flag_t;
|
} switch_rtp_bug_flag_t;
|
||||||
|
|
||||||
|
@ -6188,6 +6188,14 @@ void sofia_glue_parse_rtp_bugs(uint32_t *flag_pole, const char *str)
|
|||||||
if (switch_stristr("~NEVER_SEND_MARKER", str)) {
|
if (switch_stristr("~NEVER_SEND_MARKER", str)) {
|
||||||
*flag_pole &= ~RTP_BUG_NEVER_SEND_MARKER;
|
*flag_pole &= ~RTP_BUG_NEVER_SEND_MARKER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (switch_stristr("IGNORE_DTMF_DURATION", str)) {
|
||||||
|
*flag_pole |= RTP_BUG_IGNORE_DTMF_DURATION;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (switch_stristr("~IGNORE_DTMF_DURATION", str)) {
|
||||||
|
*flag_pole &= ~RTP_BUG_IGNORE_DTMF_DURATION;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
char *sofia_glue_gen_contact_str(sofia_profile_t *profile, sip_t const *sip, sofia_nat_parse_t *np)
|
char *sofia_glue_gen_contact_str(sofia_profile_t *profile, sip_t const *sip, sofia_nat_parse_t *np)
|
||||||
|
@ -133,6 +133,7 @@ struct switch_rtp_rfc2833_data {
|
|||||||
char last_digit;
|
char last_digit;
|
||||||
switch_queue_t *dtmf_inqueue;
|
switch_queue_t *dtmf_inqueue;
|
||||||
switch_mutex_t *dtmf_mutex;
|
switch_mutex_t *dtmf_mutex;
|
||||||
|
uint8_t in_digit_queued;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct switch_rtp {
|
struct switch_rtp {
|
||||||
@ -2479,7 +2480,8 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((!(io_flags & SWITCH_IO_FLAG_NOBLOCK)) && (rtp_session->dtmf_data.out_digit_dur == 0 || switch_test_flag(rtp_session, SWITCH_RTP_FLAG_VIDEO))) {
|
if ((!(io_flags & SWITCH_IO_FLAG_NOBLOCK)) &&
|
||||||
|
(rtp_session->dtmf_data.out_digit_dur == 0 || switch_test_flag(rtp_session, SWITCH_RTP_FLAG_VIDEO))) {
|
||||||
return_cng_frame();
|
return_cng_frame();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2819,7 +2821,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
|
|||||||
}
|
}
|
||||||
#ifdef DEBUG_2833
|
#ifdef DEBUG_2833
|
||||||
if (rtp_session->dtmf_data.in_digit_sanity && !(rtp_session->dtmf_data.in_digit_sanity % 100)) {
|
if (rtp_session->dtmf_data.in_digit_sanity && !(rtp_session->dtmf_data.in_digit_sanity % 100)) {
|
||||||
printf("sanity %d\n", rtp_session->dtmf_data.in_digit_sanity);
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "sanity %d\n", rtp_session->dtmf_data.in_digit_sanity);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -2869,7 +2871,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef DEBUG_2833
|
#ifdef DEBUG_2833
|
||||||
printf("packet[%d]: %02x %02x %02x %02x\n", (int) len, (unsigned) packet[0], (unsigned)
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "packet[%d]: %02x %02x %02x %02x\n", (int) len, (unsigned) packet[0], (unsigned)
|
||||||
packet[1], (unsigned) packet[2], (unsigned) packet[3]);
|
packet[1], (unsigned) packet[2], (unsigned) packet[3]);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -2878,16 +2880,28 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
|
|||||||
rtp_session->dtmf_data.in_digit_seq = in_digit_seq;
|
rtp_session->dtmf_data.in_digit_seq = in_digit_seq;
|
||||||
#ifdef DEBUG_2833
|
#ifdef DEBUG_2833
|
||||||
|
|
||||||
printf("read: %c %u %u %u %u %d %d %s\n",
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "read: %c %u %u %u %u %d %d %s\n",
|
||||||
key, in_digit_seq, rtp_session->dtmf_data.in_digit_seq,
|
key, in_digit_seq, rtp_session->dtmf_data.in_digit_seq,
|
||||||
ts, duration, rtp_session->recv_msg.header.m, end, end && !rtp_session->dtmf_data.in_digit_ts ? "ignored" : "");
|
ts, duration, rtp_session->recv_msg.header.m, end, end && !rtp_session->dtmf_data.in_digit_ts ? "ignored" : "");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (!rtp_session->dtmf_data.in_digit_queued && (rtp_session->rtp_bugs & RTP_BUG_IGNORE_DTMF_DURATION) &&
|
||||||
|
rtp_session->dtmf_data.in_digit_ts) {
|
||||||
|
switch_dtmf_t dtmf = { key, switch_core_min_dtmf_duration(0) };
|
||||||
|
#ifdef DEBUG_2833
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Early Queuing digit %c:%d\n", dtmf.digit, dtmf.duration / 8);
|
||||||
|
#endif
|
||||||
|
switch_rtp_queue_rfc2833_in(rtp_session, &dtmf);
|
||||||
|
rtp_session->dtmf_data.in_digit_queued = 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* only set sanity if we do NOT ignore the packet */
|
/* only set sanity if we do NOT ignore the packet */
|
||||||
if (rtp_session->dtmf_data.in_digit_ts) {
|
if (rtp_session->dtmf_data.in_digit_ts) {
|
||||||
rtp_session->dtmf_data.in_digit_sanity = 2000;
|
rtp_session->dtmf_data.in_digit_sanity = 2000;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rtp_session->dtmf_data.last_duration > duration && rtp_session->dtmf_data.last_duration > 0xFC17 && ts == rtp_session->dtmf_data.in_digit_ts) {
|
if (rtp_session->dtmf_data.last_duration > duration &&
|
||||||
|
rtp_session->dtmf_data.last_duration > 0xFC17 && ts == rtp_session->dtmf_data.in_digit_ts) {
|
||||||
rtp_session->dtmf_data.flip++;
|
rtp_session->dtmf_data.flip++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2902,18 +2916,26 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
|
|||||||
dtmf.duration += rtp_session->dtmf_data.flip * 0xFFFF;
|
dtmf.duration += rtp_session->dtmf_data.flip * 0xFFFF;
|
||||||
rtp_session->dtmf_data.flip = 0;
|
rtp_session->dtmf_data.flip = 0;
|
||||||
#ifdef DEBUG_2833
|
#ifdef DEBUG_2833
|
||||||
printf("you're welcome!\n");
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "you're welcome!\n");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#ifdef DEBUG_2833
|
#ifdef DEBUG_2833
|
||||||
printf("done digit=%c ts=%u start_ts=%u dur=%u ddur=%u\n",
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "done digit=%c ts=%u start_ts=%u dur=%u ddur=%u\n",
|
||||||
dtmf.digit, ts, rtp_session->dtmf_data.in_digit_ts, duration, dtmf.duration);
|
dtmf.digit, ts, rtp_session->dtmf_data.in_digit_ts, duration, dtmf.duration);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (!(rtp_session->rtp_bugs & RTP_BUG_IGNORE_DTMF_DURATION) && !rtp_session->dtmf_data.in_digit_queued) {
|
||||||
|
#ifdef DEBUG_2833
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Queuing digit %c:%d\n", dtmf.digit, dtmf.duration / 8);
|
||||||
|
#endif
|
||||||
switch_rtp_queue_rfc2833_in(rtp_session, &dtmf);
|
switch_rtp_queue_rfc2833_in(rtp_session, &dtmf);
|
||||||
|
}
|
||||||
|
|
||||||
rtp_session->dtmf_data.last_digit = rtp_session->dtmf_data.first_digit;
|
rtp_session->dtmf_data.last_digit = rtp_session->dtmf_data.first_digit;
|
||||||
|
|
||||||
rtp_session->dtmf_data.in_digit_ts = 0;
|
rtp_session->dtmf_data.in_digit_ts = 0;
|
||||||
rtp_session->dtmf_data.in_digit_sanity = 0;
|
rtp_session->dtmf_data.in_digit_sanity = 0;
|
||||||
|
rtp_session->dtmf_data.in_digit_queued = 0;
|
||||||
do_cng = 1;
|
do_cng = 1;
|
||||||
} else {
|
} else {
|
||||||
if (!switch_rtp_ready(rtp_session)) {
|
if (!switch_rtp_ready(rtp_session)) {
|
||||||
@ -2932,7 +2954,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
|
|||||||
rtp_session->dtmf_data.last_duration = duration;
|
rtp_session->dtmf_data.last_duration = duration;
|
||||||
} else {
|
} else {
|
||||||
#ifdef DEBUG_2833
|
#ifdef DEBUG_2833
|
||||||
printf("drop: %c %u %u %u %u %d %d\n",
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "drop: %c %u %u %u %u %d %d\n",
|
||||||
key, in_digit_seq, rtp_session->dtmf_data.in_digit_seq, ts, duration, rtp_session->recv_msg.header.m, end);
|
key, in_digit_seq, rtp_session->dtmf_data.in_digit_seq, ts, duration, rtp_session->recv_msg.header.m, end);
|
||||||
#endif
|
#endif
|
||||||
switch_cond_next();
|
switch_cond_next();
|
||||||
@ -3540,7 +3562,7 @@ static int rtp_common_write(switch_rtp_t *rtp_session,
|
|||||||
#ifdef RTP_DEBUG_WRITE_DELTA
|
#ifdef RTP_DEBUG_WRITE_DELTA
|
||||||
{
|
{
|
||||||
int delta = (int) (now - rtp_session->send_time) / 1000;
|
int delta = (int) (now - rtp_session->send_time) / 1000;
|
||||||
printf("WRITE %d delta %d\n", (int) bytes, delta);
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "WRITE %d delta %d\n", (int) bytes, delta);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
rtp_session->send_time = now;
|
rtp_session->send_time = now;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user