[asterisk-commits] file: branch file/rtp_engine r129305 - in /team/file/rtp_engine: channels/ res/
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Tue Jul 8 19:30:11 CDT 2008
Author: file
Date: Tue Jul 8 19:30:10 2008
New Revision: 129305
URL: http://svn.digium.com/view/asterisk?view=rev&rev=129305
Log:
Hey look, two way audio.
Modified:
team/file/rtp_engine/channels/chan_sip.c
team/file/rtp_engine/res/res_rtp_asterisk.c
Modified: team/file/rtp_engine/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/file/rtp_engine/channels/chan_sip.c?view=diff&rev=129305&r1=129304&r2=129305
==============================================================================
--- team/file/rtp_engine/channels/chan_sip.c (original)
+++ team/file/rtp_engine/channels/chan_sip.c Tue Jul 8 19:30:10 2008
@@ -8171,11 +8171,11 @@
struct sockaddr_in *dest, struct sockaddr_in *vdest)
{
/* First, get our address */
- memcpy(sin, &p->rtp->remote_address, sizeof(*sin));
+ memcpy(sin, &p->rtp->local_address, sizeof(*sin));
if (p->vrtp)
- memcpy(vsin, &p->vrtp->remote_address, sizeof(*vsin));
+ memcpy(vsin, &p->vrtp->local_address, sizeof(*vsin));
if (p->trtp)
- memcpy(tsin, &p->trtp->remote_address, sizeof(*tsin));
+ memcpy(tsin, &p->trtp->local_address, sizeof(*tsin));
/* Now, try to figure out where we want them to send data */
/* Is this a re-invite to move the media out, then use the original offer from caller */
Modified: team/file/rtp_engine/res/res_rtp_asterisk.c
URL: http://svn.digium.com/view/asterisk/team/file/rtp_engine/res/res_rtp_asterisk.c?view=diff&rev=129305&r1=129304&r2=129305
==============================================================================
--- team/file/rtp_engine/res/res_rtp_asterisk.c (original)
+++ team/file/rtp_engine/res/res_rtp_asterisk.c Tue Jul 8 19:30:10 2008
@@ -225,6 +225,8 @@
static void ast_rtp_new_source(struct ast_rtp_instance *instance);
static int ast_rtp_write(struct ast_rtp_instance *instance, struct ast_frame *frame);
static struct ast_frame *ast_rtp_read(struct ast_rtp_instance *instance, int rtcp);
+static void ast_rtp_prop_set(struct ast_rtp_instance *instance, enum ast_rtp_property property, int value);
+static int ast_rtp_fd(struct ast_rtp_instance *instance, int rtcp);
/* RTP Engine Declaration */
static struct ast_rtp_engine asterisk_rtp_engine = {
@@ -236,6 +238,8 @@
.new_source = ast_rtp_new_source,
.write = ast_rtp_write,
.read = ast_rtp_read,
+ .prop_set = ast_rtp_prop_set,
+ .fd = ast_rtp_fd,
};
static inline int rtp_debug_test_addr(struct sockaddr_in *addr)
@@ -268,6 +272,35 @@
}
return 1;
+}
+
+/*! \brief Calculate normal deviation */
+static double normdev_compute(double normdev, double sample, unsigned int sample_count)
+{
+ normdev = normdev * sample_count + sample;
+ sample_count++;
+
+ return normdev / sample_count;
+}
+
+static double stddev_compute(double stddev, double sample, double normdev, double normdev_curent, unsigned int sample_count)
+{
+/*
+ for the formula check http://www.cs.umd.edu/~austinjp/constSD.pdf
+ return sqrt( (sample_count*pow(stddev,2) + sample_count*pow((sample-normdev)/(sample_count+1),2) + pow(sample-normdev_curent,2)) / (sample_count+1));
+ we can compute the sigma^2 and that way we would have to do the sqrt only 1 time at the end and would save another pow 2 compute
+ optimized formula
+*/
+#define SQUARE(x) ((x) * (x))
+
+ stddev = sample_count * stddev;
+ sample_count++;
+
+ return stddev +
+ ( sample_count * SQUARE( (sample - normdev) / sample_count ) ) +
+ ( SQUARE(sample - normdev_curent) / sample_count );
+
+#undef SQUARE
}
static int create_new_socket(const char *type)
@@ -758,6 +791,66 @@
return 0;
}
+static void calc_rxstamp(struct timeval *tv, struct ast_rtp *rtp, unsigned int timestamp, int mark)
+{
+ struct timeval now;
+ double transit;
+ double current_time;
+ double d;
+ double dtv;
+ double prog;
+
+ double normdev_rxjitter_current;
+ if ((!rtp->rxcore.tv_sec && !rtp->rxcore.tv_usec) || mark) {
+ gettimeofday(&rtp->rxcore, NULL);
+ rtp->drxcore = (double) rtp->rxcore.tv_sec + (double) rtp->rxcore.tv_usec / 1000000;
+ /* map timestamp to a real time */
+ rtp->seedrxts = timestamp; /* Their RTP timestamp started with this */
+ rtp->rxcore.tv_sec -= timestamp / 8000;
+ rtp->rxcore.tv_usec -= (timestamp % 8000) * 125;
+ /* Round to 0.1ms for nice, pretty timestamps */
+ rtp->rxcore.tv_usec -= rtp->rxcore.tv_usec % 100;
+ if (rtp->rxcore.tv_usec < 0) {
+ /* Adjust appropriately if necessary */
+ rtp->rxcore.tv_usec += 1000000;
+ rtp->rxcore.tv_sec -= 1;
+ }
+ }
+
+ gettimeofday(&now,NULL);
+ /* rxcore is the mapping between the RTP timestamp and _our_ real time from gettimeofday() */
+ 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;
+ }
+ prog = (double)((timestamp-rtp->seedrxts)/8000.);
+ dtv = (double)rtp->drxcore + (double)(prog);
+ current_time = (double)now.tv_sec + (double)now.tv_usec/1000000;
+ transit = current_time - dtv;
+ d = transit - rtp->rxtransit;
+ rtp->rxtransit = transit;
+ if (d<0)
+ d=-d;
+ rtp->rxjitter += (1./16.) * (d - rtp->rxjitter);
+
+ if (rtp->rtcp) {
+ if (rtp->rxjitter > rtp->rtcp->maxrxjitter)
+ rtp->rtcp->maxrxjitter = rtp->rxjitter;
+ if (rtp->rtcp->rxjitter_count == 1)
+ rtp->rtcp->minrxjitter = rtp->rxjitter;
+ if (rtp->rtcp && rtp->rxjitter < rtp->rtcp->minrxjitter)
+ rtp->rtcp->minrxjitter = rtp->rxjitter;
+
+ normdev_rxjitter_current = normdev_compute(rtp->rtcp->normdev_rxjitter,rtp->rxjitter,rtp->rtcp->rxjitter_count);
+ rtp->rtcp->stdev_rxjitter = stddev_compute(rtp->rtcp->stdev_rxjitter,rtp->rxjitter,rtp->rtcp->normdev_rxjitter,normdev_rxjitter_current,rtp->rtcp->rxjitter_count);
+
+ rtp->rtcp->normdev_rxjitter = normdev_rxjitter_current;
+ rtp->rtcp->rxjitter_count++;
+ }
+}
+
static struct ast_frame *ast_rtp_read(struct ast_rtp_instance *instance, int rtcp)
{
struct ast_rtp *rtp = instance->data;
@@ -891,15 +984,75 @@
return f ? f : &ast_null_frame;
}
+ rtp->lastrxformat = rtp->f.subclass = payload.code;
+ rtp->f.frametype = (rtp->f.subclass & AST_FORMAT_AUDIO_MASK) ? AST_FRAME_VOICE : (rtp->f.subclass & AST_FORMAT_VIDEO_MASK) ? AST_FRAME_VIDEO : AST_FRAME_TEXT;
+
+ rtp->rxseqno = seqno;
+ rtp->lastrxts = timestamp;
+
+ rtp->f.src = "RTP";
rtp->f.mallocd = 0;
rtp->f.datalen = res - hdrlen;
rtp->f.data.ptr = rtp->rawdata + hdrlen + AST_FRIENDLY_OFFSET;
rtp->f.offset = hdrlen + AST_FRIENDLY_OFFSET;
rtp->f.seqno = seqno;
- rtp->f.src = "RTP";
+ if (rtp->f.subclass & AST_FORMAT_AUDIO_MASK) {
+ rtp->f.samples = ast_codec_get_samples(&rtp->f);
+ if (rtp->f.subclass == AST_FORMAT_SLINEAR)
+ ast_frame_byteswap_be(&rtp->f);
+ calc_rxstamp(&rtp->f.delivery, rtp, timestamp, mark);
+ /* Add timing data to let ast_generic_bridge() put the frame into a jitterbuf */
+ ast_set_flag(&rtp->f, AST_FRFLAG_HAS_TIMING_INFO);
+ rtp->f.ts = timestamp / 8;
+ rtp->f.len = rtp->f.samples / ( (ast_format_rate(rtp->f.subclass) == 16000) ? 16 : 8 );
+ } else if (rtp->f.subclass & AST_FORMAT_VIDEO_MASK) {
+ /* Video -- samples is # of samples vs. 90000 */
+ if (!rtp->lastividtimestamp)
+ rtp->lastividtimestamp = timestamp;
+ rtp->f.samples = timestamp - rtp->lastividtimestamp;
+ rtp->lastividtimestamp = timestamp;
+ rtp->f.delivery.tv_sec = 0;
+ rtp->f.delivery.tv_usec = 0;
+ /* Pass the RTP marker bit as bit 0 in the subclass field.
+ * This is ok because subclass is actually a bitmask, and
+ * the low bits represent audio formats, that are not
+ * involved here since we deal with video.
+ */
+ if (mark)
+ rtp->f.subclass |= 0x1;
+ } else {
+ /* TEXT -- samples is # of samples vs. 1000 */
+ if (!rtp->lastitexttimestamp)
+ rtp->lastitexttimestamp = timestamp;
+ rtp->f.samples = timestamp - rtp->lastitexttimestamp;
+ rtp->lastitexttimestamp = timestamp;
+ rtp->f.delivery.tv_sec = 0;
+ rtp->f.delivery.tv_usec = 0;
+ }
return &rtp->f;
+}
+
+static void ast_rtp_prop_set(struct ast_rtp_instance *instance, enum ast_rtp_property property, int value)
+{
+ struct ast_rtp *rtp = instance->data;
+
+ if (property == AST_RTP_PROPERTY_RTCP) {
+ if (rtp->rtcp) {
+ ast_debug(1, "Ignoring duplicate RTCP property on RTP instance '%p'\n", instance);
+ return;
+ }
+ }
+
+ return;
+}
+
+static int ast_rtp_fd(struct ast_rtp_instance *instance, int rtcp)
+{
+ struct ast_rtp *rtp = instance->data;
+
+ return rtcp ? (rtp->rtcp ? rtp->rtcp->s : -1) : rtp->s;
}
static char *rtp_do_debug_ip(struct ast_cli_args *a)
More information about the asterisk-commits
mailing list