]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
res_rtp_asterisk: Address jittery DTMF events in RTP streams
authorJonathan Rose <jrose@digium.com>
Wed, 23 Oct 2013 17:37:15 +0000 (17:37 +0000)
committerJonathan Rose <jrose@digium.com>
Wed, 23 Oct 2013 17:37:15 +0000 (17:37 +0000)
(closes issue ASTERISK-21170)
Reported by: NITESH BANSAL
Patches:
    dtmf-timestamp.patch uploaded by NITESH BANSAL (license 6418)
Review: https://reviewboard.asterisk.org/r/2938/
........

Merged revisions 401619 from http://svn.asterisk.org/svn/asterisk/branches/1.8

git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/11@401620 65c4cc65-6c06-0410-ace0-fbb531ad65f3

main/translate.c
res/res_rtp_asterisk.c

index a258599d2215a29936f25bdea79f305e918c46ee..08c361e46f83427bb6dfe12777db0117803efc95 100644 (file)
@@ -540,6 +540,10 @@ struct ast_frame *ast_translate(struct ast_trans_pvt *path, struct ast_frame *f,
                /* Predict next outgoing timestamp from samples in this
                   frame. */
                path->nextout = ast_tvadd(path->nextout, ast_samp2tv(out->samples, ast_format_rate(&out->subclass.format)));
+               if (f->samples != out->samples && ast_test_flag(out, AST_FRFLAG_HAS_TIMING_INFO)) {
+                       ast_debug(4, "Sample size different %u vs %u\n", f->samples, out->samples);
+                       ast_clear_flag(out, AST_FRFLAG_HAS_TIMING_INFO);
+               }
        } else {
                out->delivery = ast_tv(0, 0);
                ast_set2_flag(out, has_timing_info, AST_FRFLAG_HAS_TIMING_INFO);
index 0af845a68d2fd9563a9330a5856f991c8efb7bb3..f37812371e1de078c66870e987e17c3ff41274e3 100644 (file)
@@ -96,6 +96,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #define RTCP_PT_APP     204
 
 #define RTP_MTU                1200
+#define DTMF_SAMPLE_RATE_MS    8 /*!< DTMF samples per millisecond */
 
 #define DEFAULT_DTMF_TIMEOUT (150 * (8000 / 1000))     /*!< samples */
 
@@ -1725,6 +1726,35 @@ static void rtp_add_candidates_to_ice(struct ast_rtp_instance *instance, struct
 }
 #endif
 
+/*!
+ * \internal
+ * \brief Calculates the elapsed time from issue of the first tx packet in an
+ *        rtp session and a specified time
+ *
+ * \param rtp pointer to the rtp struct with the transmitted rtp packet
+ * \param delivery time of delivery - if NULL or zero value, will be ast_tvnow()
+ *
+ * \return time elapsed in milliseconds
+ */
+static unsigned int calc_txstamp(struct ast_rtp *rtp, struct timeval *delivery)
+{
+       struct timeval t;
+       long ms;
+
+       if (ast_tvzero(rtp->txcore)) {
+               rtp->txcore = ast_tvnow();
+               rtp->txcore.tv_usec -= rtp->txcore.tv_usec % 20000;
+       }
+
+       t = (delivery && !ast_tvzero(*delivery)) ? *delivery : ast_tvnow();
+       if ((ms = ast_tvdiff_ms(t, rtp->txcore)) < 0) {
+               ms = 0;
+       }
+       rtp->txcore = t;
+
+       return (unsigned int) ms;
+}
+
 static int ast_rtp_new(struct ast_rtp_instance *instance,
                       struct ast_sched_context *sched, struct ast_sockaddr *addr,
                       void *data)
@@ -1958,6 +1988,7 @@ static int ast_rtp_dtmf_begin(struct ast_rtp_instance *instance, char digit)
 
        rtp->dtmfmute = ast_tvadd(ast_tvnow(), ast_tv(0, 500000));
        rtp->send_duration = 160;
+       rtp->lastts += calc_txstamp(rtp, NULL) * DTMF_SAMPLE_RATE_MS;
        rtp->lastdigitts = rtp->lastts + rtp->send_duration;
 
        /* Create the actual packet that we will be sending */
@@ -2042,6 +2073,7 @@ static int ast_rtp_dtmf_continuation(struct ast_rtp_instance *instance)
        /* And now we increment some values for the next time we swing by */
        rtp->seqno++;
        rtp->send_duration += 160;
+       rtp->lastts += calc_txstamp(rtp, NULL) * DTMF_SAMPLE_RATE_MS;
 
        return 0;
 }
@@ -2121,7 +2153,7 @@ static int ast_rtp_dtmf_end_with_duration(struct ast_rtp_instance *instance, cha
        res = 0;
 
        /* Oh and we can't forget to turn off the stuff that says we are sending DTMF */
-       rtp->lastts += rtp->send_duration;
+       rtp->lastts += calc_txstamp(rtp, NULL) * DTMF_SAMPLE_RATE_MS;
 cleanup:
        rtp->sending_digit = 0;
        rtp->send_digit = 0;
@@ -2171,25 +2203,6 @@ static void ast_rtp_change_source(struct ast_rtp_instance *instance)
        return;
 }
 
-static unsigned int calc_txstamp(struct ast_rtp *rtp, struct timeval *delivery)
-{
-       struct timeval t;
-       long ms;
-
-       if (ast_tvzero(rtp->txcore)) {
-               rtp->txcore = ast_tvnow();
-               rtp->txcore.tv_usec -= rtp->txcore.tv_usec % 20000;
-       }
-
-       t = (delivery && !ast_tvzero(*delivery)) ? *delivery : ast_tvnow();
-       if ((ms = ast_tvdiff_ms(t, rtp->txcore)) < 0) {
-               ms = 0;
-       }
-       rtp->txcore = t;
-
-       return (unsigned int) ms;
-}
-
 static void timeval2ntp(struct timeval tv, unsigned int *msw, unsigned int *lsw)
 {
        unsigned int sec, usec, frac;