The generic Jitterbuffer ------------------------ The generic jitter buffer is a generic implementation of jitterbuffering that can be used in any channel bu adding just a few lines of code. It is currently implemented in IAX and SIP. Any channel using RTP can be converted to use it with a few trivial lines of code, look at chan_sip for an example. Credits: Most of this implementation is written by Slav Klenov, and some of it has been paid for by Fortel AS - see http://www.fortel.no/ Integration into CallWeaver.org and some additions and bugfixes made by Bartek (eGnarF) Kania. Configuration info ------------------ The jitter buffer currently has three actual buffers: fixed - A fixed length implementation by Slav Klenov adaptive - An adaptive jitter buffer implemented by Steve Kann more info about this can be found in README.jitterbuffer speakup - A jitterbuffer donated by SpeakUp (http://www.speakup.nl). For more information see http://www.speakup.nl/opensource/jitterbuffer The configuration parameters are identical for each channel, and are documented here instead of in each channel. NOTE: You must configure the jitterbuffer on the RECEIVING channel. So if you have something like: Phone (SIP) -> CW -> (ZAP) Phone and get jitter on the SIP-connection then you must configure the jitterbuffer on the ZAP-channel for it to work. ;------------------- GENERIC JITTER BUFFER CONFIGURATION ---------------------- ; These options are only for the third jitter-buffer variant! Disable the ; options above if you plan on using this. ; jb-enable = yes ; Enables the use of a jitterbuffer on the ; receiving side of a SIP ; channel. Defaults to "no". An ; enabled jitterbuffer will be used ; only if the sending side can create ; and the receiving side can not ; accept jitter. The SIP channel can ; accept jitter, thus a jitterbuffer ; on the receive SIP side will be used ; only if it is forced and enabled. ; jb-force = no ; Forces the use of a jitterbuffer on the ; receive side of a SIP channel. ; Defaults to "no". ; jb-min-size = 60 ; Minimum / initial length of the jitterbuffer ; jb-max-size = 200 ; Max length of the jitterbuffer in ms. ; jb-resynch-threshold = 1000 ; Jump in the frame timestamps over which ; the jitterbuffer is resynchronized. Useful ; to improve the quality of the voice, with ; big jumps in/broken timestamps, usualy sent ; from exotic devices and programs. Defaults ; to 1000. ; jb-impl = fixed ; Jitterbuffer implementation, used on the ; receiving side of a SIP channel. Three ; implementations are currenlty available: ; * "fixed" (with size always equals to ;; jb-max-size) ; * "adaptive" (with variable size, actually the ; new jb of IAX2). ; * "speakup" - contributed by SpeakUp.nl ; Defaults to fixed. ; jb-log = no ; Enables jitterbuffer frame logging. ; Defaults to "no". ;------------------------------------------------------------------------------ Information about the stevek (adaptive) jitterbuffer ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ This is the original information about the stevek jitterbuffer. Some of it is out-of-date due to the new generic jitterbuffer API, but the actual jitterbuffer is still in use and can be selected with jb-impl = adaptive The new Jitterbuffer in CallWeaver -------------------------------- Steve Kann The new jitterbuffer, PLC, and the IAX2-integration of the new jitterbuffer have been integrated into CallWeaver. The jitterbuffer is generic and has been implemented in SIP/RTP as well. Also, we've added a feature called "trunktimestamps", which adds individual timestamps to trunked frames within a trunk frame. Here's how to use this stuff: 1) The new jitterbuffer: ------------------------ You must add "jitterbuffer=yes" to either the [general] part of iax.conf, or to a peer or a user. (just like the old jitterbuffer). Also, you can set "maxjitterbuffer=n", which puts a hard-limit on the size of the jitterbuffer of "n milliseconds". It is not necessary to have the new jitterbuffer on both sides of a call; it works on the receive side only. 2) PLC: ------- The new jitterbuffer detects packet loss. PLC is done to try to recreate these lost packets in the codec decoding stage, as the encoded audio is translated to slinear. PLC is also used to mask jitterbuffer growth. This facility is enabled by default in iLBC and speex, as it has no additional cost. This facility can be enabled in adpcm, alaw, g726, gsm, lpc10, and ulaw by setting genericplc => true in the [plc] section of codecs.conf. 3) Trunktimestamps: ------------------- To use this, both sides must be using CallWeaver v1.1dev (or coming 1.2 stable). Setting "trunktimestamps=yes" in iax.conf will cause your box to send 16-bit timestamps for each trunked frame inside of a trunk frame. This will enable you to use jitterbuffer for an IAX2 trunk, something that was not possible in the old architecture. The other side must also support this functionality, or else, well, bad things will happen. If you don't use trunktimestamps, there's lots of ways the jitterbuffer can get confused because timestamps aren't necessarily sent through the trunk correctly. 4) Communication with Asterisk v1.0.x systems --------------------------------------------- You can set up communication with v1.0.x systems with the new jitterbuffer, but you can't use trunks with trunktimestamps in this communication. If you are connecting to an Asterisk server with earlier versions of the software (1.0.x), do not enable both jitterbuffer and trunking for the involved peers/users in order to be able to communicate. Earlier systems will not support trunktimestamps. You may also compile chan_iax2.c without the new jitterbuffer, enabling the old backwards compatible architecture. Look in the source code for instructions. 5) Testing and monitoring: -------------------------- You can test the effectiveness of PLC and the new jitterbuffer's detection of loss by using the new CLI command "iax2 test losspct <n>". This will simulate n percent packet loss coming _in_ to chan_iax2. You should find that with PLC and the new JB, 10 percent packet loss should lead to just a tiny amount of distortion, while without PLC, it would lead to silent gaps in your audio. "iax2 show netstats" shows you statistics for each iax2 call you have up. The columns are "RTT" which is the round-trip time for the last PING, and then a bunch of s tats for both the local side (what you're receiving), and the remote side (what the other end is telling us they are seeing). The remote stats may not be complete if the remote end isn't using the new jitterbuffer. The stats shown are: * Jit: The jitter we have measured (milliseconds) * Del: The maximum delay imposed by the jitterbuffer (milliseconds) * Lost: The number of packets we've detected as lost. * %: The percentage of packets we've detected as lost recently. * Drop: The number of packets we've purposely dropped (to lower latency). * OOO: The number of packets we've received out-of-order * Kpkts: The number of packets we've received / 1000. Reporting problems ================== There's a couple of things that can make calls sound bad using the jitterbuffer: 1) The JB and PLC can make your calls sound better, but they can't fix everything. If you lost 10 frames in a row, it can't possibly fix that. It really can't help much more than one or two consecutive frames. 2) Bad timestamps: If whatever is generating timestamps to be sent to you generates nonsensical timestamps, it can confuse the jitterbuffer. In particular, discontinuities in timestamps will really upset it: Things like timestamps sequences which go 0, 20, 40, 60, 80, 34000, 34020, 34040, 34060... It's going to think you've got about 34 seconds of jitter in this case, etc.. The right solution to this is to find out what's causing the sender to send us such nonsense, and fix that. But we should also figure out how to make the receiver more robust in cases like this. chan_iax2 will actually help fix this a bit if it's more than 3 seconds or so, but at some point we should try to think of a better way to detect this kind of thing and resynchronize. Different clock rates are handled very gracefully though; it will actually deal with a sender sending 20% faster or slower than you expect just fine. 3) Really strange network delays: If your network "pauses" for like 5 seconds, and then when it restarts, you are sent some packets that are 5 seconds old, we are going to see that as a lot of jitter. We already throw away up to the worst 20 frames like this, though, and the "maxjitterbuffer" parameter should put a limit on what we do in this case. Reporting possible bugs ----------------------- If you do find bad behaviors, here's the information that will help to diagnose this: 1) Describe a) the source of the timestamps and frames: i.e. if they're coming from another chan_iax2 box, a bridged RTP-based channel, an IAX2 softphone, etc.. b) The network between, in brief (i.e. the internet, a local lan, etc). c) What is the problem you're seeing. 2) Take a look and see what iax2 show netstats is saying about the call, and if it makes sense. 3) a tcpdump of the frames, (or, tethereal output from), so we can see the timestamps and delivery times of the frames you're receiving. You can make such a tcpdump with: tcpdump -s 2048 -w /tmp/example.dump udp and port 4569 [and host <other-end>] Report bugs in the CallWeaver bugtracker, http://bugs.digium.com. Please read the bug guidelines before you post a bug. Have fun! -SteveK