From: Steve K. <st...@st...> - 2004-03-18 19:53:42
|
Mark, We've recently uncovered a problem with the jitter buffer code in IAX2 (probably also 1, for what it's worth). We see this mostly on the chan_iax2 side, but it's also incorrect in libiax2 and iaxclient. For discussion, let's say there's a call between machines A and B. We'll describe the problem here with the jitter buffer on B: The problem occurs when: * The jitter buffer on B is currently shrinking (so it's getting set 2ms smaller each time it processes a frame from A). * A is sending a sequence of frames that are timed 2ms or less apart. This can happen if scheduling difficulties on A cause it to get temporarily behind. For example, on Win98, we get generally get scheduled once every 50-60ms, so we end up sending frames in bunches of 2 or 3. * The sequentially-timestamped frames from A arrive roughly at the same time to B. What happens here is that in this case, the frames get scheduled out-of-order, and the result is very bad voice quality. The rough sequence of processing (at B) is as follows: Start/First Packet: Jitter buffer is set to size J, first packet with timestamp "TS" is scheduled for delivery in M ms. Second Packet: Jitter buffer is set to size J-2; second packet with timestamp TS+1 is scheduled for delivery in M-1 ms. Third Packet: Jitter buffer is set to size J-4; third packet with timestamp TS+2 is scheduled for delivery in M-2ms. (etc, for as many consecutive packets there are). The out-of-order delivery of packets is really a problem, regardless of what's on the other side of the channel: Whether it's bridged to another channel, or in an application. Possible solutions: * Cheap/simple solution: Instead of enforcing a 1ms difference between consecutive frames, enforce a 3ms difference (i.e. the "shrink-interval" +1). This seems like it would work OK in the cases we see. A partial drawback seems to be that it restricts the number of frames from 1000/sec to 333/sec, but I don't see that actually being a problem. I'm not sure if this holds up in the case where packets actually arrive out-of-order. * More complicated (and expensive) solutions require looking around at the queue of scheduled packets when shrinking, and either: o Just looking to see if there is a frame scheduled for the time range where the shrinking would cause out-of-orderedness, and if so, delaying the frame in hand until after that one. o Actually re-scheduling the queue to account for the jitter buffer size change. We're going to test implementing the Cheap Solution, in a local copy of iaxclient, to see if it solves our observed and reported problem. As it stands, calls from Win9x to us are relatively unintelligible because of this, and I suspect that this also affects other platforms when they're busy. Either of these solutions, however, really needs to be implemented in both chan_iax2 as well as in iaxclient, because the error can happen on either end. The cheap solution, of course, is actually a [backwards compatibly] change to the protocol, while the "more complicated" solutions actually correct the implementation. Thoughts? |