From: <jpg...@us...> - 2007-12-19 15:42:20
|
Revision: 1316 http://iaxclient.svn.sourceforge.net/iaxclient/?rev=1316&view=rev Author: jpgrayson Date: 2007-12-19 07:42:24 -0800 (Wed, 19 Dec 2007) Log Message: ----------- Apply patch from Lee Howard to improve timestamp semantics in libiax2. >From the tracker... I'm attaching a patch that includes various fixes/improvements to timestamping on iax2 frames in libiax2. Namely: 1) If the *next* miniframe will cause the timestamp to wrap then we need to send a full voice frame now (the one previous to the wrap). If we wait until the wrap occurs then we are leaving it up to the PBX to interpret the wrap. 2) e->ts needs to be properly set for all frames, and not just certain ones. 3) When constructing the timestamp be overly cautious about doing it and keep wrapping under check. Modified Paths: -------------- trunk/lib/libiax2/src/iax.c Modified: trunk/lib/libiax2/src/iax.c =================================================================== --- trunk/lib/libiax2/src/iax.c 2007-12-19 15:38:37 UTC (rev 1315) +++ trunk/lib/libiax2/src/iax.c 2007-12-19 15:42:24 UTC (rev 1316) @@ -1051,7 +1051,7 @@ struct iax_frame *fr; int res; int sendmini=0; - unsigned int lastsent; + unsigned int nextpred; unsigned int fts; if (!pvt) @@ -1060,14 +1060,15 @@ return -1; } - /* this must come before the next call to calc_timestamp() since - calc_timestamp() will change lastsent to the returned value */ - lastsent = pvt->lastsent; - /* Calculate actual timestamp */ fts = calc_timestamp(pvt, ts, f); - if (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) + /* If the next predicted VOICE timestamp will overflow the 16-bit + portion of the timestamp then we send a full VOICE frame to + keep the 32-bit portion of the timestamp synchronized. */ + nextpred = pvt->nextpred; + + if (((fts & 0xFFFF0000L) == (nextpred & 0xFFFF0000L)) /* High two bits are the same on timestamp, or sending on a trunk */ && (f->frametype == AST_FRAME_VOICE) /* is a voice frame */ && @@ -1083,7 +1084,7 @@ /* Bitmask taken from chan_iax2.c... I must ask Mark Spencer for this? I think not... */ if ( f->frametype == AST_FRAME_VIDEO ) { - if (((fts & 0xFFFF8000L) == (lastsent & 0xFFFF8000L)) + if (((fts & 0xFFFF8000L) == (nextpred & 0xFFFF8000L)) /* High two bits are the same on timestamp, or sending on a trunk */ && ((f->subclass & ~0x01) == pvt->svideoformat) /* is the same type */ ) @@ -2497,7 +2498,7 @@ /* don't run last_ts backwards; i.e. for retransmits and the like */ if (ts > session->last_ts && - (fh->type == AST_FRAME_IAX && + ((fh->type == AST_FRAME_IAX || fh->type == AST_FRAME_VOICE) && subclass != IAX_COMMAND_ACK && subclass != IAX_COMMAND_PONG && subclass != IAX_COMMAND_LAGRP)) @@ -2621,6 +2622,7 @@ */ e->etype = -1; e->session = session; + e->ts = ts; switch(fh->type) { case AST_FRAME_DTMF: e->etype = IAX_EVENT_DTMF; @@ -2633,7 +2635,6 @@ case AST_FRAME_VOICE: e->etype = IAX_EVENT_VOICE; e->subclass = subclass; - e->ts = ts; session->voiceformat = subclass; if (datalen) { memcpy(e->data, fh->iedata, datalen); @@ -2714,17 +2715,14 @@ case IAX_COMMAND_LAGRQ: /* Pass this along for later handling */ e->etype = IAX_EVENT_LAGRQ; - e->ts = ts; e = schedule_delivery(e, ts, updatehistory); break; case IAX_COMMAND_POKE: e->etype = IAX_EVENT_POKE; - e->ts = ts; break; case IAX_COMMAND_PING: /* PINGS and PONGS don't get scheduled; */ e->etype = IAX_EVENT_PING; - e->ts = ts; break; case IAX_COMMAND_PONG: e->etype = IAX_EVENT_PONG; @@ -2893,7 +2891,6 @@ case AST_FRAME_VIDEO: e->etype = IAX_EVENT_VIDEO; e->subclass = subclass; - e->ts = ts; session->videoformat = e->subclass; memcpy(e->data, fh->iedata, datalen); e->datalen = datalen; @@ -3011,7 +3008,8 @@ e->subclass = session->voiceformat; e->datalen = datalen; memcpy(e->data, mh->data, datalen); - e->ts = (session->last_ts & 0xFFFF0000) | ntohs(mh->ts); + e->ts = (session->last_ts & 0xFFFF0000L) | (ntohs(mh->ts) & 0xFFFF); + e->ts = unwrap_timestamp(e->ts, session->last_ts); return schedule_delivery(e, e->ts, 1); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |