diff options
author | markster <markster@f38db490-d61c-443f-a65b-d21fe96a405b> | 2004-03-13 03:52:14 +0000 |
---|---|---|
committer | markster <markster@f38db490-d61c-443f-a65b-d21fe96a405b> | 2004-03-13 03:52:14 +0000 |
commit | 5d2aed2d6d40f577334e5df9fcfc7277a5495787 (patch) | |
tree | c30d90fcd24175084edb8bc6c193b0d727af14e0 | |
parent | 894a6228fe7ecc38bcc2f4cbe349b965f29421a4 (diff) |
Move timestamp around in RTP.... Gotta do iax2 eventually here...
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@2413 f38db490-d61c-443f-a65b-d21fe96a405b
-rwxr-xr-x | frame.c | 15 | ||||
-rwxr-xr-x | include/asterisk/frame.h | 5 | ||||
-rwxr-xr-x | rtp.c | 49 |
3 files changed, 57 insertions, 12 deletions
@@ -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; diff --git a/include/asterisk/frame.h b/include/asterisk/frame.h index acbc26ca2..bf7844e05 100755 --- a/include/asterisk/frame.h +++ b/include/asterisk/frame.h @@ -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 */ @@ -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: |