[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