Merge Steven Davie's timestamp improvements
authorMark Spencer <markster@digium.com>
Wed, 30 Jun 2004 06:03:57 +0000 (06:03 +0000)
committerMark Spencer <markster@digium.com>
Wed, 30 Jun 2004 06:03:57 +0000 (06:03 +0000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@3361 65c4cc65-6c06-0410-ace0-fbb531ad65f3

channels/chan_iax2.c
rtp.c

index 8b37519..7798230 100755 (executable)
@@ -119,7 +119,9 @@ static int ping_time = 20;
 static int lagrq_time = 10;
 static int maxtrunkcall = TRUNK_CALL_START;
 static int maxnontrunkcall = 1;
-static int maxjitterbuffer=3000;
+static int maxjitterbuffer=1000;
+static int minjitterbuffer=10;
+static int jittershrinkrate=2;
 static int trunkfreq = 20;
 static int authdebug = 1;
 static int iaxcompat = 0;
@@ -1595,12 +1597,21 @@ static unsigned int calc_fakestamp(struct chan_iax2_pvt *from, struct chan_iax2_
 static int forward_delivery(struct iax_frame *fr)
 {
        struct chan_iax2_pvt *p1, *p2;
+       char tmp[80];
        p1 = iaxs[fr->callno];
        p2 = iaxs[p1->bridgecallno];
        if (!p1)
                return -1;
        if (!p2)
                return -1;
+
+       if (option_debug)
+               ast_log(LOG_DEBUG, "forward_delivery: Forwarding ts=%d on %d/%d to %d/%d on %s:%d\n",
+                               fr->ts,
+                               p1->callno, p1->peercallno,
+                               p2->callno, p2->peercallno,
+                               ast_inet_ntoa(tmp, sizeof(tmp), p2->addr.sin_addr), ntohs(p2->addr.sin_port));
+
        /* Fix relative timestamp */
        fr->ts = calc_fakestamp(p1, p2, fr->ts);
        /* Now just send it send on the 2nd one 
@@ -1701,7 +1712,7 @@ static int schedule_delivery(struct iax_frame *fr, int reallydeliver, int update
        /* If our jitter buffer is too big (by a significant margin), then we slowly
           shrink it by about 1 ms each time to avoid letting the change be perceived */
        if (max < iaxs[fr->callno]->jitterbuffer - max_jitter_buffer)
-               iaxs[fr->callno]->jitterbuffer -= 2;
+               iaxs[fr->callno]->jitterbuffer -= jittershrinkrate;
 
 
 #if 1
@@ -2590,7 +2601,8 @@ static unsigned int calc_txpeerstamp(struct iax2_trunk_peer *tpeer, int sampms,
        long int ms, pred;
 
        tpeer->trunkact = *tv;
-       mssincetx = (tv->tv_sec - tpeer->lasttxtime.tv_sec) * 1000 + (tv->tv_usec - tpeer->lasttxtime.tv_usec) / 1000;
+       mssincetx = (tv->tv_sec - tpeer->lasttxtime.tv_sec) * 1000 +
+                       (1000000 + tv->tv_usec - tpeer->lasttxtime.tv_usec) / 1000 - 1000;
        if (mssincetx > 5000 || (!tpeer->txtrunktime.tv_sec && !tpeer->txtrunktime.tv_usec)) {
                /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */
                tpeer->txtrunktime.tv_sec = tv->tv_sec;
@@ -2602,7 +2614,8 @@ static unsigned int calc_txpeerstamp(struct iax2_trunk_peer *tpeer, int sampms,
        tpeer->lasttxtime.tv_usec = tv->tv_usec;
        
        /* Calculate ms offset */
-       ms = (tv->tv_sec - tpeer->txtrunktime.tv_sec) * 1000 + (tv->tv_usec - tpeer->txtrunktime.tv_usec) / 1000;
+       ms = (tv->tv_sec - tpeer->txtrunktime.tv_sec) * 1000 +
+               (1000000 + tv->tv_usec - tpeer->txtrunktime.tv_usec) / 1000 - 1000;
        /* Predict from last value */
        pred = tpeer->lastsent + sampms;
        if (abs(ms - pred) < MAX_TIMESTAMP_SKEW)
@@ -2621,12 +2634,12 @@ static unsigned int fix_peerts(struct timeval *tv, int callno, unsigned int ts)
        if (!iaxs[callno]->rxcore.tv_sec && !iaxs[callno]->rxcore.tv_usec) {
                /* Initialize rxcore time if appropriate */
                gettimeofday(&iaxs[callno]->rxcore, NULL);
-               /* Round to nearest 20ms */
+               /* Round to nearest 20ms so traces look pretty */
                iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000;
        }
        /* Calculate difference between trunk and channel */
        ms = (tv->tv_sec - iaxs[callno]->rxcore.tv_sec) * 1000 + 
-               (tv->tv_usec - iaxs[callno]->rxcore.tv_usec) / 1000;
+               (1000000 + tv->tv_usec - iaxs[callno]->rxcore.tv_usec) / 1000 - 1000;
        /* Return as the sum of trunk time and the difference between trunk and real time */
        return ms + ts;
 }
@@ -2655,7 +2668,7 @@ static unsigned int calc_timestamp(struct chan_iax2_pvt *p, unsigned int ts, str
        }
        if (!p->offset.tv_sec && !p->offset.tv_usec) {
                gettimeofday(&p->offset, NULL);
-               /* Round to nearest 20ms */
+               /* Round to nearest 20ms for nice looking traces */
                p->offset.tv_usec -= p->offset.tv_usec % 20000;
        }
        /* If the timestamp is specified, just send it as is */
@@ -2663,10 +2676,12 @@ static unsigned int calc_timestamp(struct chan_iax2_pvt *p, unsigned int ts, str
                return ts;
        /* If we have a time that the frame arrived, always use it to make our timestamp */
        if (delivery && (delivery->tv_sec || delivery->tv_usec)) {
-               ms = (delivery->tv_sec - p->offset.tv_sec) * 1000 + (delivery->tv_usec - p->offset.tv_usec) / 1000;
+               ms = (delivery->tv_sec - p->offset.tv_sec) * 1000 +
+                       (1000000 + delivery->tv_usec - p->offset.tv_usec) / 1000 - 1000;
        } else {
                gettimeofday(&tv, NULL);
-               ms = (tv.tv_sec - p->offset.tv_sec) * 1000 + (tv.tv_usec - p->offset.tv_usec) / 1000;
+               ms = (tv.tv_sec - p->offset.tv_sec) * 1000 +
+                       (1000000 + tv.tv_usec - p->offset.tv_usec) / 1000 - 1000;
                if (ms < 0)
                        ms = 0;
                if (voice) {
@@ -2720,7 +2735,8 @@ static unsigned int calc_fakestamp(struct chan_iax2_pvt *p1, struct chan_iax2_pv
           Adding rxcore to it gives us when we would want the packet to be delivered normally.
           Subtracting txcore of the outgoing channel gives us what we'd expect */
        
-       ms = (p1->rxcore.tv_sec - p2->offset.tv_sec) * 1000 + (p1->rxcore.tv_usec - p2->offset.tv_usec) / 1000;
+       ms = (p1->rxcore.tv_sec - p2->offset.tv_sec) * 1000 +
+               (1000000 + p1->rxcore.tv_usec - p2->offset.tv_usec) / 1000 - 1000;
        fakets += ms;
        if (fakets <= p2->lastsent)
                fakets = p2->lastsent + 1;
@@ -2739,7 +2755,8 @@ static unsigned int calc_rxstamp(struct chan_iax2_pvt *p)
                gettimeofday(&p->rxcore, NULL);
 
        gettimeofday(&tv, NULL);
-       ms = (tv.tv_sec - p->rxcore.tv_sec) * 1000 + (tv.tv_usec - p->rxcore.tv_usec) / 1000;
+       ms = (tv.tv_sec - p->rxcore.tv_sec) * 1000 +
+               (1000000 + tv.tv_usec - p->rxcore.tv_usec) / 1000 - 1000;
        return ms;
 }
 
@@ -3147,16 +3164,26 @@ static int iax2_show_registry(int fd, int argc, char *argv[])
 #undef FORMAT2
 }
 
+static int jitterbufsize(struct chan_iax2_pvt *pvt) {
+       int min, i;
+       min = 99999999;
+       for (i=0; i<MEMORY_SIZE; i++) {
+               if (pvt->history[i] < min)
+                       min = pvt->history[i];
+       }
+       return pvt->jitterbuffer - min;
+}
+
 static int iax2_show_channels(int fd, int argc, char *argv[])
 {
-#define FORMAT2 "%-15.15s  %-10.10s  %-11.11s  %-11.11s  %-7.7s  %-6.6s  %s\n"
-#define FORMAT  "%-15.15s  %-10.10s  %5.5d/%5.5d  %5.5d/%5.5d  %-5.5dms  %-4.4dms  %-6.6s\n"
+#define FORMAT2 "%-15.15s  %-10.10s  %-11.11s  %-11.11s  %-7.7s  %-6.6s  %-6.6s  %s\n"
+#define FORMAT  "%-15.15s  %-10.10s  %5.5d/%5.5d  %5.5d/%5.5d  %-5.5dms  %-4.4dms  %-4.4dms  %-6.6s\n"
        int x;
        int numchans = 0;
        char iabuf[80];
        if (argc != 3)
                return RESULT_SHOWUSAGE;
-       ast_cli(fd, FORMAT2, "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "Format");
+       ast_cli(fd, FORMAT2, "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format");
        for (x=0;x<IAX_MAX_CALLS;x++) {
                ast_mutex_lock(&iaxsl[x]);
                if (iaxs[x]) {
@@ -3166,6 +3193,7 @@ static int iax2_show_channels(int fd, int argc, char *argv[])
                                                iaxs[x]->oseqno, iaxs[x]->iseqno, 
                                                iaxs[x]->lag,
                                                iaxs[x]->jitter,
+                                               jitterbufsize(iaxs[x]),
                                                ast_getformatname(iaxs[x]->voiceformat) );
                        numchans++;
                }
@@ -6380,6 +6408,10 @@ static int set_config(char *config_file, struct sockaddr_in* sin){
                        ping_time = atoi(v->value);
                else if (!strcasecmp(v->name, "maxjitterbuffer")) 
                        maxjitterbuffer = atoi(v->value);
+               else if (!strcasecmp(v->name, "minjitterbuffer")) 
+                       minjitterbuffer = atoi(v->value);
+               else if (!strcasecmp(v->name, "jittershrinkrate")) 
+                       jittershrinkrate = atoi(v->value);
                else if (!strcasecmp(v->name, "maxexcessbuffer")) 
                        max_jitter_buffer = atoi(v->value);
                else if (!strcasecmp(v->name, "lagrqtime")) 
diff --git a/rtp.c b/rtp.c
index 3f7a054..90eaf73 100755 (executable)
--- a/rtp.c
+++ b/rtp.c
@@ -38,6 +38,8 @@
 #include <asterisk/lock.h>
 #include <asterisk/utils.h>
 
+#define MAX_TIMESTAMP_SKEW     640
+
 #define RTP_MTU                1200
 
 #define TYPE_HIGH       0x0
@@ -380,6 +382,7 @@ static void calc_rxstamp(struct timeval *tv, struct ast_rtp *rtp, unsigned int t
                gettimeofday(&rtp->rxcore, NULL);
                rtp->rxcore.tv_sec -= timestamp / 8000;
                rtp->rxcore.tv_usec -= (timestamp % 8000) * 125;
+               /* Round to 20ms for nice, pretty timestamps */
                rtp->rxcore.tv_usec -= rtp->rxcore.tv_usec % 20000;
                if (rtp->rxcore.tv_usec < 0) {
                        /* Adjust appropriately if necessary */
@@ -919,18 +922,19 @@ static unsigned int calc_txstamp(struct ast_rtp *rtp, struct timeval *delivery)
        unsigned int ms;
        if (!rtp->txcore.tv_sec && !rtp->txcore.tv_usec) {
                gettimeofday(&rtp->txcore, NULL);
+               /* Round to 20ms for nice, pretty timestamps */
                rtp->txcore.tv_usec -= rtp->txcore.tv_usec % 20000;
        }
        if (delivery && (delivery->tv_sec || delivery->tv_usec)) {
                /* Use previous txcore */
                ms = (delivery->tv_sec - rtp->txcore.tv_sec) * 1000;
-               ms += (delivery->tv_usec - rtp->txcore.tv_usec) / 1000;
+               ms += (1000000 + delivery->tv_usec - rtp->txcore.tv_usec) / 1000 - 1000;
                rtp->txcore.tv_sec = delivery->tv_sec;
                rtp->txcore.tv_usec = delivery->tv_usec;
        } else {
                gettimeofday(&now, NULL);
                ms = (now.tv_sec - rtp->txcore.tv_sec) * 1000;
-               ms += (now.tv_usec - rtp->txcore.tv_usec) / 1000;
+               ms += (1000000 + now.tv_usec - rtp->txcore.tv_usec) / 1000 - 1000;
                /* Use what we just got for next time */
                rtp->txcore.tv_sec = now.tv_sec;
                rtp->txcore.tv_usec = now.tv_usec;
@@ -1058,7 +1062,7 @@ static int ast_rtp_raw_write(struct ast_rtp *rtp, struct ast_frame *f, int codec
                if (!f->delivery.tv_sec && !f->delivery.tv_usec) {
                        /* If this isn't an absolute delivery time, Check if it is close to our prediction, 
                           and if so, go with our prediction */
-                       if (abs(rtp->lastts - pred) < 640)
+                       if (abs(rtp->lastts - pred) < MAX_TIMESTAMP_SKEW)
                                rtp->lastts = pred;
                        else {
                                ast_log(LOG_DEBUG, "Difference is %d, ms is %d\n", abs(rtp->lastts - pred), ms);