Add README for jitter buffer (bug #3812), make src char *src a const
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@5223 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
parent
ebc1c06835
commit
1507997410
|
@ -0,0 +1,135 @@
|
|||
The new Jitterbuffer in Asterisk
|
||||
--------------------------------
|
||||
Steve Kann
|
||||
|
||||
|
||||
|
||||
The new jitterbuffer, PLC, and the IAX2-integration of the new jitterbuffer have been integrated
|
||||
into Asterisk. The jitterbuffer is generic and work is going on to implement it 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 Asterisk 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 Asterisk bugtracker, http://bugs.digium.com.
|
||||
Please read the bug guidelines before you post a bug.
|
||||
|
||||
Have fun!
|
||||
|
||||
-SteveK
|
4
frame.c
4
frame.c
|
@ -231,7 +231,7 @@ void ast_frfree(struct ast_frame *fr)
|
|||
}
|
||||
if (fr->mallocd & AST_MALLOCD_SRC) {
|
||||
if (fr->src)
|
||||
free(fr->src);
|
||||
free((char *)fr->src);
|
||||
}
|
||||
if (fr->mallocd & AST_MALLOCD_HDR) {
|
||||
#ifdef TRACE_FRAMES
|
||||
|
@ -319,7 +319,7 @@ struct ast_frame *ast_frdup(struct ast_frame *f)
|
|||
if (srclen > 0) {
|
||||
out->src = out->data + f->datalen;
|
||||
/* Must have space since we allocated for it */
|
||||
strcpy(out->src, f->src);
|
||||
strcpy((char *)out->src, f->src);
|
||||
} else
|
||||
out->src = NULL;
|
||||
out->prev = NULL;
|
||||
|
|
|
@ -84,7 +84,7 @@ struct ast_frame {
|
|||
/*! How far into "data" the data really starts */
|
||||
int offset;
|
||||
/*! Optional source of frame for debugging */
|
||||
char *src;
|
||||
const char *src;
|
||||
/*! Pointer to actual data */
|
||||
void *data;
|
||||
/*! Global delivery time */
|
||||
|
|
Loading…
Reference in New Issue