Summary:ASTERISK-01253: TimeStamp problem in new rtp.c file
Reporter:Ricardo Villa (ricvil)Labels:
Date Opened:2004-03-20 17:45:11.000-0600Date Closed:2004-09-25 02:53:47
Versions:Frequency of
Environment:Attachments:( 0) sip-iax2-sip.new.rtp.gz
Description:I am the one who reported the initial TimeStamp problem under bug:  http://bugs.digium.com/bug_view_page.php?bug_id=0001195

The workaround I implemented was working perfectly but since Mark Spencer said he fixed the problem by enabling TimeStamps to get carrier through Asterisk, I decided to update to the latest CVS.


SIP to SIP calls now seem to be working well.  The Ethereal trace shows that the TimeStamps are spaced apart evenly by a factor of 160.

But SIP-IAX2-SIP are a now completely messed up.  The TimeStamps jump around in increments that are not always 160 and sometimes they even go back in time!  See the attached Ethereal trace a notice how frame 7 has an older TimeStamp than frame 8.  I tested using G711, G729, and G726 with same results.

I am also aware that somebody already reported audio problems similar to this in bug:  http://bugs.digium.com/bug_view_page.php?bug_id=0001220
But I have to disagree that the issue was not fixed.

Please see the following 3 modifications to rtp.c and their voice quality result:
1.  The rtp.c version from CVS
   Call type: SIP-IAX2-SIP
   Voice Quality:  Sounds like a Robot, horrible!
   if (!f->delivery.tv_sec && !f->delivery.tv_usec) {
                       /* If this isn't an absolute delivery time, Check if it is close to our prediction,
                          and if so, go with our prediction */
                       if (abs(rtp->lastts - pred) < 640)
                               rtp->lastts = pred;
                               ast_log(LOG_DEBUG, "Difference is %d, ms is %d\n", abs(rtp->lastts - pred), ms);

2.  older rtp.c version
   Call type: SIP-IAX2-SIP or SIP-SIP
   Voice Quality:  Sounds like a Cell-Phone
if (abs(rtp->lastts - pred) < 640)
                               rtp->lastts = pred;
                               ast_log(LOG_DEBUG, "Difference is %d, ms is %d\n", abs(rtp->lastts - pred), ms);
(this one above does not have the "delivery.tv stuff")

3.  older rtp.c version with my modification
   Call type: SIP-IAX2-SIP or SIP-SIP
   Voice Quality:  Sounds crystal clear
                       if (abs(rtp->lastts - pred) < 2560)
                               rtp->lastts = pred;
                               ast_log(LOG_DEBUG, "Difference is %d, ms is %d\n", abs(rtp->lastts - pred), ms);

(Note the differece between #2 and #3 is the 2560 which tells Asterisk to have a lot more tolerance for incoming packet delays)

The UAs used are SPA2000s which rely heavily on the TimeStamp values for jitter calculations.  If the TimeStamp values are bad then the audio on the SPA2000 is horrible.

I hope that the above information is clear.
Comments:By: Mark Spencer (markster) 2004-03-21 02:51:56.000-0600

The "perfect workaround" you use is still a workaround and is just a bandaid for the real problem and suffers from all the same issues as the original workaround, only with more capability of handling jitter.  I know there are growing pains to the maintenance of the timestamp through the system, but truly it's the only one this is ever going to work perfectly.  I've not heard any complaints about SIP -> IAX2 -> SIP with current CVS, but I'll try to lab it up here if I can tomorrow.

By: zoa (zoa) 2004-03-21 05:44:18.000-0600

Could someone explain how this value (< 2560) for the out of order packets is related to the iax2 jitter buffer ?

Is this value used for some kind of global jitter buffer (for iax2, sip, etc etc) and will be total buffer be this value + the iax2 jitter buffer ?

By: Ricardo Villa (ricvil) 2004-03-21 10:54:47.000-0600

Zoa, as far as I can tell, if the next rtp packet arrives within a timeframe under that value (256ms, or the original value of 64ms), then the predicted TimeStamp value is used (which is evenly spaced at 160), but if there is a greater delay than 256ms then a new TimeStamp is generated based on the arrival time.  This new TimeStamp will break the audio stream of any UA that relies on it for jitter calculations like the SPA2000.

By: Ricardo Villa (ricvil) 2004-03-21 11:13:09.000-0600

Mark, even if you have not heard any complaints please take a look at the attached Ethereal trace to see that the TimeStamps are completely messed up.  The reason you may have not had complaints so far is that not all UAs use that TimeStamp.  Some just simply take the payload in and decode it (Grandstream).  But others like the SPA2000, that have sophisticated jitter buffer adjustments, do rely completely on that TimeStamp.

I know my workaround is just a bandaid but since I am not a programmer then it was the only thing I could do.  I certainly support a much more elegant approach to this.  I think that your solution to allow Asterisk to carry through the original TimeStamp is probably the hardest method to implement, especially when you get transcoding between different codecs or different sample times.

For example if the incoming WAN stream is flowing at 60ms intervals and you are passing that through to the LAN side at 20ms intervals then "carrying" that TimeStamp over seems quite complicated as they do not match. (the 60ms ones are spaced at 480 and the 20ms ones are spaced at 160)

I would favor a much more simpler approach of allowing Asterisk to generate the TimeStamp on its own.  That way we can be sure that the Timestamp values will be perfectly spaced apart like 160, 320, 480 , etc...

Asterisk would simply take in the RTP payload on the WAN side, and generate the new RTP stream on the LAN side with the expected TimeStamp spacing of 160, 320, 480, etc...

By: Mark Spencer (markster) 2004-03-21 16:19:18.000-0600

Using a normal IAX call, I am unable to duplicate this problem.  My RTP traffic, even on a system so heavily loaded that the traffic is going out in bursts, still is sending the correct timestamps on the packets (exactly 160 samples apart).  Are you using IAX2 trunking?

By: Ricardo Villa (ricvil) 2004-03-21 16:36:08.000-0600

I am not using IAX2 trunking.  My setup is:
SPA2000(G729) - Local Asterisk - IAX2(iLBC) - Remote Asterisk - Grandstream(G729)

The screwed up TimeStamps are being seen on the traffic send from the local Asterisk to the SPA2000.  Maybe its because of the iLBC codec.  I will test with other codecs on the IAX2 link and see if there is any change.

By: Ricardo Villa (ricvil) 2004-03-21 17:53:06.000-0600

I just upgraded the Remote Asterisk to the lates CVS and repeated the tests.  Looks like there is a huge improvement now.  I apologize for not realizing I needed to do this to get accurate testing results.

Now, if I take Ethereal traces on traffic going out to both UAs, most of the RTP TimeStamps are now 160 samples apart, but every now and then there is a jump of 168 or 152.  It is easy to spot these by selecting the first packet in Ethereal, fixing you eye on the TimeStamp values, and then holding the down arrow.  The last digit in the TimeStamp should always be the same, so as soon as it changes you know you had a jump different than 160 samples.

By: Mark Spencer (markster) 2004-03-22 17:52:04.000-0600

I'm not really concerned about the 1ms difference.  It would be interesting to know if this is specific to iLBC...

By: Mark Spencer (markster) 2004-03-22 17:53:39.000-0600

Fixed in CVS