Move timestamp around in RTP.... Gotta do iax2 eventually here...
authorMark Spencer <markster@digium.com>
Sat, 13 Mar 2004 03:52:14 +0000 (03:52 +0000)
committerMark Spencer <markster@digium.com>
Sat, 13 Mar 2004 03:52:14 +0000 (03:52 +0000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@2413 65c4cc65-6c06-0410-ace0-fbb531ad65f3

frame.c
include/asterisk/frame.h
rtp.c

diff --git a/frame.c b/frame.c
index 3c5fe8c..9b2c559 100755 (executable)
--- a/frame.c
+++ b/frame.c
@@ -40,6 +40,7 @@ struct ast_smoother {
        int optimizablestream;
        float samplesperbyte;
        struct ast_frame f;
+       struct timeval delivery;
        char data[SMOOTHER_SIZE];
        char framedata[SMOOTHER_SIZE + AST_FRIENDLY_OFFSET];
        struct ast_frame *opt;
@@ -103,6 +104,9 @@ int ast_smoother_feed(struct ast_smoother *s, struct ast_frame *f)
        } else 
                s->optimizablestream = 0;
        memcpy(s->data + s->len, f->data, f->datalen);
+       /* If we're empty, reset delivery time */
+       if (!s->len)
+               s->delivery = f->delivery;
        s->len += f->datalen;
        return 0;
 }
@@ -129,12 +133,20 @@ struct ast_frame *ast_smoother_read(struct ast_smoother *s)
        s->f.offset = AST_FRIENDLY_OFFSET;
        s->f.datalen = s->size;
        s->f.samples = s->size * s->samplesperbyte;
+       s->f.delivery = s->delivery;
        /* Fill Data */
        memcpy(s->f.data, s->data, s->size);
        s->len -= s->size;
        /* Move remaining data to the front if applicable */
-       if (s->len) 
+       if (s->len) {
                memmove(s->data, s->data + s->size, s->len);
+               s->delivery.tv_sec += (s->size * s->samplesperbyte) / 8000.0;
+               s->delivery.tv_usec += (((int)(s->size * s->samplesperbyte)) % 8000) * 125;
+               if (s->delivery.tv_usec > 1000000) {
+                       s->delivery.tv_usec -= 1000000;
+                       s->delivery.tv_sec += 1;
+               }
+       }
        /* Return frame */
        return &s->f;
 }
@@ -257,6 +269,7 @@ struct ast_frame *ast_frdup(struct ast_frame *f)
        out->subclass = f->subclass;
        out->datalen = f->datalen;
        out->samples = f->samples;
+       out->delivery = f->delivery;
        out->mallocd = AST_MALLOCD_HDR;
        out->offset = AST_FRIENDLY_OFFSET;
        out->data = buf + sizeof(struct ast_frame) + AST_FRIENDLY_OFFSET;
index acbc26c..bf7844e 100755 (executable)
@@ -21,6 +21,7 @@ extern "C" {
 #endif
 
 #include <sys/types.h>
+#include <sys/time.h>
        
 /*
  * Autodetect system endianess
@@ -73,7 +74,9 @@ struct ast_frame {
        /*! Optional source of frame for debugging */
        char *src;                              
        /*! Pointer to actual data */
-       void *data;                             
+       void *data;             
+       /*! Global delivery time */             
+       struct timeval delivery;
        /*! Next/Prev for linking stand alone frames */
        struct ast_frame *prev;                 
        /*! Next/Prev for linking stand alone frames */
diff --git a/rtp.c b/rtp.c
index 0be0377..d085158 100755 (executable)
--- a/rtp.c
+++ b/rtp.c
@@ -349,6 +349,26 @@ struct ast_frame *ast_rtcp_read(struct ast_rtp *rtp)
        return &null_frame;
 }
 
+static void calc_rxstamp(struct timeval *tv, struct ast_rtp *rtp, unsigned int timestamp)
+{
+       if (!rtp->rxcore.tv_sec && !rtp->rxcore.tv_usec) {
+               gettimeofday(&rtp->rxcore, NULL);
+               rtp->rxcore.tv_usec -= timestamp / 8000;
+               rtp->rxcore.tv_usec -= (timestamp % 8000) * 125;
+               if (rtp->rxcore.tv_usec < 0) {
+                       /* Adjust appropriately if necessary */
+                       rtp->rxcore.tv_usec += 1000000;
+                       rtp->rxcore.tv_sec -= 1;
+               }
+       }
+       tv->tv_sec = rtp->rxcore.tv_sec + timestamp / 8000;
+       tv->tv_usec = rtp->rxcore.tv_usec + (timestamp % 8000) * 125;
+       if (tv->tv_usec >= 1000000) {
+               tv->tv_usec -= 1000000;
+               tv->tv_sec += 1;
+       }
+}
+
 struct ast_frame *ast_rtp_read(struct ast_rtp *rtp)
 {
        int res;
@@ -485,6 +505,7 @@ struct ast_frame *ast_rtp_read(struct ast_rtp *rtp)
                        ast_log(LOG_NOTICE, "Unable to calculate samples for format %s\n", ast_getformatname(rtp->f.subclass));
                        break;
                }
+               calc_rxstamp(&rtp->f.delivery, rtp, timestamp);
        } else {
                /* Video -- samples is # of samples vs. 90000 */
                if (!rtp->lastividtimestamp)
@@ -817,19 +838,27 @@ void ast_rtp_destroy(struct ast_rtp *rtp)
        free(rtp);
 }
 
-static unsigned int calc_txstamp(struct ast_rtp *rtp)
+static unsigned int calc_txstamp(struct ast_rtp *rtp, struct timeval *delivery)
 {
        struct timeval now;
        unsigned int ms;
        if (!rtp->txcore.tv_sec && !rtp->txcore.tv_usec) {
                gettimeofday(&rtp->txcore, NULL);
        }
-       gettimeofday(&now, NULL);
-       ms = (now.tv_sec - rtp->txcore.tv_sec) * 1000;
-       ms += (now.tv_usec - rtp->txcore.tv_usec) / 1000;
-       /* Use what we just got for next time */
-       rtp->txcore.tv_sec = now.tv_sec;
-       rtp->txcore.tv_usec = now.tv_usec;
+       if (delivery && (delivery->tv_sec || delivery->tv_usec)) {
+               /* Use previous txcore */
+               ms = (delivery->tv_sec - rtp->txcore.tv_usec) * 1000;
+               ms += (delivery->tv_usec - rtp->txcore.tv_usec) / 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;
+               /* Use what we just got for next time */
+               rtp->txcore.tv_sec = now.tv_sec;
+               rtp->txcore.tv_usec = now.tv_usec;
+       }
        return ms;
 }
 
@@ -863,7 +892,7 @@ int ast_rtp_senddigit(struct ast_rtp *rtp, char digit)
        if (!rtp->them.sin_addr.s_addr)
                return 0;
 
-       ms = calc_txstamp(rtp);
+       ms = calc_txstamp(rtp, NULL);
        /* Default prediction */
        pred = rtp->lastts + ms * 8;
        
@@ -903,7 +932,7 @@ static int ast_rtp_raw_write(struct ast_rtp *rtp, struct ast_frame *f, int codec
        int pred;
        int mark = 0;
 
-       ms = calc_txstamp(rtp);
+       ms = calc_txstamp(rtp, &f->delivery);
        /* Default prediction */
        if (f->subclass < AST_FORMAT_MAX_AUDIO) {
                pred = rtp->lastts + ms * 8;
@@ -934,7 +963,7 @@ static int ast_rtp_raw_write(struct ast_rtp *rtp, struct ast_frame *f, int codec
                        pred = rtp->lastts + g723_samples(f->data, f->datalen);
                        break;
                case AST_FORMAT_SPEEX:
-                       pred = rtp->lastts + 160;
+                   pred = rtp->lastts + 160;
                        // assumes that the RTP packet contains one Speex frame
                        break;
                default: