Asterisk 1.4!!!
Asterisk 1.4.0 was released toward the end of December. Since then, the number of people switching their systems to the 1.4 code base has been increasing. One of the new features in Asterisk 1.4 is a new jitterbuffer implementation. So, since a lot of people want to use it, a lot of people want to know this new feature fits into Asterisk. I have received multiple direct emails and numerous questions on IRC about it. So, I'm hoping I can provide some information here that will answer most questions.
Note that I did not write this code. I am just the developer from Digium that reviewed it and merged it in. The implementation is due to the efforts of Slav Klenov & Vanheuverzwijn Joachim and Securax, Ltd. They received financial contributions for this project from Roy Sigurd Karlsbakk of Briiz Telecom AS.
Now, on to the jitterbuffer ...
This implementation is often reffered to as the "generic" jitterbuffer since it is not tied into any specific channel driver. However, the adaptive jitterbuffer that is in Asterisk 1.2 is itself a generic jitterbuffer. It is just that in Asterisk 1.2, the integration into Asterisk was done directly in chan_iax2. Now, in 1.4, the integration lives in the core of Asterisk. A fixed jitterbuffer implementation was added as well. So, in 1.4, you can choose between the adaptive and fixed jitterbuffer implementations.
Which channel drivers does the new implementation benefit?
The 1.4 jitterbuffer mainly helps out any of the RTP channel drivers - chan_sip, chan_h323, chan_mgcp, and chan_skinny. In theory, it should be able to work for chan_iax2 as well. However, the code that was directly in chan_iax2 in Asterisk 1.2 is still there. So, chan_iax2 uses the adaptive jitterbuffer directly.
How do I enable the 1.4 jitterbuffer?
This is where things get interesting and where most of the confusion begins. First, let me go back to a fundamental Asterisk concept. An Asterisk channel is created when a call comes in. Then, that channel goes through the dialplan and executes applications. Then, if that channel happens to run something like the Dial application, a second channel is created for an outbound call. If that outbound channel is answered, the two channels are then bridged. Bridging two channels together allows them to pass audio between each other. Frames received on one channel are passed to the bridge and transmitted out the other channel.
Let's take a scenario where a SIPi phone makes a call out a Zap PSTNi interface. The Rx represents where audio is received from the network and comes into Asterisk. The Tx represents where audio is taken from Asterisk and transmitted back out over the network.
Channel1 - SIP/myphone (inbound) Channel2 - Zap/1 (outbound)
Rx ============||--------||============ Tx
|| Bridge ||
Tx ============||--------||============ Rx
In this case, the audio received on the SIP channel is coming in over the network and needs to be de-jittered. Furthermore, the bridge sees that the channel on the other side is not an IP channel, so it actually makes sense to use a jitterbuffer.
Here is where the bridge puts the jitterbuffer: (noted using JB)
Channel1 - SIP/myphone (inbound) Channel2 - Zap/1 (outbound)
Rx ============||--------||(JB)======== Tx
|| Bridge ||
Tx ============||--------||============ Rx
So, in this illustration, the jitterbuffer is sitting in the path of audio coming from the SIP channel, but before it goes out to the Zap channel. However, it actually lives on the Zap channel. Because of this, the configuration for this is actually done in zapata.conf.
So, in zapata.conf, you would have at least the following option set:
jbenable=yes
This configuration basically says "For traffic coming into zap channels that have jitter, use a jitterbuffer". Because of this, the jitterbuffer can also be configured for channel drivers such as chan_alsa and chan_oss, using the same logic.
You may also set jitterbuffer configuration in sip.conf for SIP channels. However, it is very important to understand that this configuration applies to outbound channels, only. Furthermore, in the case of chan_sip, it will never actually get used unless forced to do so. This is because the bridge will see that the traffic is going back out over a channel that will create more jitter, so ideally the jitterbuffer is only used at the endpoint. However, it is useful to be able to de-jitter traffic in the middle of the jitterbuffer at the endpoint is not very good.
jbforce=yes
What are some downfalls to the current implementation?
For Asterisk 1.6, we plan to further improve this jitterbuffer implentation. Since this only takes effect on bridged channels, it doesn't work when a channel is not bridged and is just talking to an Asterisk application, such as Voicemail or MeetMe.
The future implementation will look more like this:
Channel1 - SIP/myphone (inbound)
Rx ========(JB)||---------------||
|| app_voicemail ||
Tx ============||---------------||
However, there are some some architectural issues to be solved before this can happen that mostly revolve around the question of when is it appropriate to use a jitterbuffer.
For example, you can't just assume that because the inbound channel is SIP, you want to use a jitterbuffer. It may then be immediately bridged to another SIP channel where you wouldn't want to use it anymore. Rest assured that we'll solve it. There are just only so many developers, and the list of features we'd like to implement is extremely long.
I hope this explains the situation with the jitterbuffer in Asterisk 1.4. The guys that implemented this spent a significant amount of time doing development and testing and they did an amazing job. It works extremely well and I haven't heard a single complaint, aside from misunderstandings.
Thanks for your support of Asterisk,
--
Russell
