[asterisk-commits] mjordan: branch 1.8 r385636 - /branches/1.8/res/res_rtp_multicast.c
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Sat Apr 13 21:58:59 CDT 2013
Author: mjordan
Date: Sat Apr 13 21:58:57 2013
New Revision: 385636
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=385636
Log:
Calculate the timestamp for outbound RTP if we don't have timing information
This patch calculates the timestamp for outbound RTP when we don't have timing
information. This uses the same approach in res_rtp_asterisk. Thanks to both
Pietro and Tzafrir for providing patches.
(closes issue ASTERISK-19883)
Reported by: Giacomo Trovato
Tested by: Pietro Bertera, Tzafrir Cohen
patches:
rtp-timestamp-1.8.patch uploaded by tzafrir (License 5035)
rtp-timestamp.patch uploaded by pbertera (License 5943)
Modified:
branches/1.8/res/res_rtp_multicast.c
Modified: branches/1.8/res/res_rtp_multicast.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.8/res/res_rtp_multicast.c?view=diff&rev=385636&r1=385635&r2=385636
==============================================================================
--- branches/1.8/res/res_rtp_multicast.c (original)
+++ branches/1.8/res/res_rtp_multicast.c Sat Apr 13 21:58:57 2013
@@ -90,6 +90,8 @@
unsigned int ssrc;
/*! Sequence number, used when creating/sending the RTP packet */
uint16_t seqno;
+ unsigned int lastts;
+ struct timeval txcore;
};
/* Forward Declarations */
@@ -140,6 +142,30 @@
return 0;
}
+static int rtp_get_rate(format_t format)
+{
+ return (format == AST_FORMAT_G722) ? 8000 : ast_format_rate(format);
+}
+
+static unsigned int calc_txstamp(struct multicast_rtp *rtp, struct timeval *delivery)
+{
+ struct timeval t;
+ long ms;
+
+ if (ast_tvzero(rtp->txcore)) {
+ rtp->txcore = ast_tvnow();
+ rtp->txcore.tv_usec -= rtp->txcore.tv_usec % 20000;
+ }
+
+ t = (delivery && !ast_tvzero(*delivery)) ? *delivery : ast_tvnow();
+ if ((ms = ast_tvdiff_ms(t, rtp->txcore)) < 0) {
+ ms = 0;
+ }
+ rtp->txcore = t;
+
+ return (unsigned int) ms;
+}
+
/*! \brief Helper function which populates a control packet with useful information and sends it */
static int multicast_send_control_packet(struct ast_rtp_instance *instance, struct multicast_rtp *multicast, int command)
{
@@ -209,12 +235,15 @@
struct ast_frame *f = frame;
struct ast_sockaddr remote_address;
int hdrlen = 12, res = 0, codec;
+ int rate;
unsigned char *rtpheader;
+ unsigned int ms = calc_txstamp(multicast, &frame->delivery);
/* We only accept audio, nothing else */
if (frame->frametype != AST_FRAME_VOICE) {
return 0;
}
+ rate = rtp_get_rate(frame->subclass.codec) / 1000;
/* Grab the actual payload number for when we create the RTP packet */
if ((codec = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(instance), 1, frame->subclass.codec)) < 0) {
@@ -226,11 +255,20 @@
f = ast_frdup(frame);
}
+ /* Calucate last TS */
+ multicast->lastts = multicast->lastts + ms * rate;
+
/* Construct an RTP header for our packet */
rtpheader = (unsigned char *)(f->data.ptr - hdrlen);
put_unaligned_uint32(rtpheader, htonl((2 << 30) | (codec << 16) | (multicast->seqno)));
- put_unaligned_uint32(rtpheader + 4, htonl(f->ts * 8));
- put_unaligned_uint32(rtpheader + 8, htonl(multicast->ssrc));
+ put_unaligned_uint32(rtpheader + 4, htonl(multicast->lastts));
+
+ if (ast_test_flag(f, AST_FRFLAG_HAS_TIMING_INFO)) {
+ put_unaligned_uint32(rtpheader + 4, htonl(f->ts * 8));
+ }
+ else {
+ put_unaligned_uint32(rtpheader + 8, htonl(multicast->ssrc));
+ }
/* Increment sequence number and wrap to 0 if it overflows 16 bits. */
multicast->seqno = 0xFFFF & (multicast->seqno + 1);
More information about the asterisk-commits
mailing list