]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
add rtp_bug IGNORE_DTMF_DURATION to speed up dtmf detection of RFC2833 on strange...
authorAnthony Minessale <anthm@freeswitch.org>
Fri, 7 Jan 2011 22:04:24 +0000 (16:04 -0600)
committerAnthony Minessale <anthm@freeswitch.org>
Fri, 7 Jan 2011 22:04:24 +0000 (16:04 -0600)
src/include/switch_types.h
src/mod/endpoints/mod_sofia/sofia_glue.c
src/switch_rtp.c

index 3fbf9c48a605eb5661dae77675c890119a562328..9a5e09db7c6eff0cb6e6af92135c048dc7039514 100644 (file)
@@ -632,9 +632,13 @@ typedef enum {
          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;
 
index ffba5ff0a31a2cad115863fcf95b3d6ef9ec715c..a5298440593d28a877cfde54e38d90183cd175c2 100644 (file)
@@ -6188,6 +6188,14 @@ void sofia_glue_parse_rtp_bugs(uint32_t *flag_pole, const char *str)
        if (switch_stristr("~NEVER_SEND_MARKER", str)) {
                *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)
index 41d5fc98dd0b17e340a8b794071de1b308b5e39a..eb8b6a19d35b77c9080114aae91e04f72af22662 100644 (file)
@@ -133,6 +133,7 @@ struct switch_rtp_rfc2833_data {
        char last_digit;
        switch_queue_t *dtmf_inqueue;
        switch_mutex_t *dtmf_mutex;
+       uint8_t in_digit_queued;
 };
 
 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();
                        }
                }
@@ -2819,7 +2821,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
                }
 #ifdef DEBUG_2833
                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
 
@@ -2869,7 +2871,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
                                }
                        }
 #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]);
 #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;
 #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,
                                           ts, duration, rtp_session->recv_msg.header.m, end, end && !rtp_session->dtmf_data.in_digit_ts ? "ignored" : "");
 #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 */
                                if (rtp_session->dtmf_data.in_digit_ts) {
                                        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++;
                                }
 
@@ -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;
                                                        rtp_session->dtmf_data.flip = 0;
 #ifdef DEBUG_2833
-                                                       printf("you're welcome!\n");
+                                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "you're welcome!\n");
 #endif
                                                }
 #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);
 #endif
-                                               switch_rtp_queue_rfc2833_in(rtp_session, &dtmf);
+                                               
+                                               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);
+                                               }
+
                                                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_sanity = 0;
+                                               rtp_session->dtmf_data.in_digit_queued = 0;
                                                do_cng = 1;
                                        } else {
                                                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;
                        } else {
 #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);
 #endif
                                switch_cond_next();
@@ -3540,7 +3562,7 @@ static int rtp_common_write(switch_rtp_t *rtp_session,
 #ifdef RTP_DEBUG_WRITE_DELTA
                {
                        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
                rtp_session->send_time = now;