Table of Contents
The main function of a jitter buffer is to ensure that it’s user receive continuous flow of incoming frames regardless of the jitter in the incoming packet arrival time.
Some of the features of PJMEDIA’s jitter buffer are as follows.
The jitter buffer adapts to change in network jitter, increasing or decreasing the prefetch value and the buffering latency as necessary.
The sound device’s jitter/bursts, as explained in Sound device timing problem, may ultimately cause jitter in frame retrieval from the jitter buffer. The jitter buffer accommodates this (device) jitter as well as jitter from the network.
The jitter buffer provides the minimum latency possible without sacrificing the continuous flow requirement.
The jitter buffer handles the receipt of duplicate or old frames.
A duplicate frame is a frame which has the same frame number of an
existing frame in it’s buffer. In this case, the handling depends on the
value of discarded argument in
PJ_TRUE, jitter buffer will ignore the duplicate frame and set the discarded argument of
PJ_FALSE, the jitter buffer will override the old frame with this newer frame, and set the discarded argument of
if NULL, then PJ_FALSE is assumed.
An old frame (which sequence number is older than what has been played)
is always discarded, and discarded argument of
pjmedia_jbuf_put_frame2() function will be set.
The jitter buffer is able to store frames that are not octet/byte aligned.
The jitter buffer detects and handles large jump in frame’s sequence number.
The jitter buffer handles discontinuous transmission (DTX) without triggering restart. Note that user MAY use RTP timestamp or sequence number as jbuf’s frame sequence number, hence DTX MAY or MAY NOT be reflected with a jump in the frame sequence number.
The jitter buffer can be configured with a minimum latency (prefetching).
The jitter buffer can be set to to operate in fixed/non-adaptive mode.
This can be done by calling
Some of the jitter buffer’s operational terms will be described below.
The optimal latency of the jitter buffer is defined as the minimum buffering needed to handle current jitters (both from network and sound device).
When the latency in the jitter buffer is longer than the optimal latency, the jitter buffer begins to discard some frames. The progressive discard drops frames at various rates depending on the difference between the actual latency and the optimal/target latency.
There are some configurable macro settings that affects the discard rate:
For example, when the optimal latency is 3 frames and current latency is 10 frames, the jitter buffer will schedule to discard a frame with calculations as follow:
Difference between actual and target latencies (we call this overflow) is set as
10-3 = 7frames.
Use the following formula for calculating the target time for adjusting the latency (i.e: by discarding the overflow of 7 frames above):
T = PJMEDIA_JBUF_PRO_DISC_T1 + (PJMEDIA_JBUF_PRO_DISC_T2 - PJMEDIA_JBUF_PRO_DISC_T1) \* (burst_level - PJMEDIA_JBUF_PRO_DISC_MIN_BURST) / (PJMEDIA_JBUF_PRO_DISC_MAX_BURST-PJMEDIA_JBUF_PRO_DISC_MIN_BURST); /* Default settings: PJMEDIA_JBUF_PRO_DISC_T1 = 2000ms PJMEDIA_JBUF_PRO_DISC_T2 = 10000ms PJMEDIA_JBUF_PRO_DISC_MIN_BURST = 1 PJMEDIA_JBUF_PRO_DISC_MIN_BURST = 100 */
At this point, the target time is
2000 + (8000 * 3/99) = 2242msec or discard rate is
target_time / overflow = 2242 / 7 = 320ms per frame. So the jitter buffer will discard a frame with timestamp 320ms (or frame to be played 320ms later). There are also few notes:
If the frame with that timestamp is not available in the jitter buffer yet, the calculation will be done again later. If the burst level is changed when the calculation is redone, the frame to discard may be changed too (no longer frame with timestamp 320ms).
If the scheduled frame timestamp is lower than
PJMEDIA_JBUF_DISC_MIN_GAP(i.e: 200ms), the jitter buffer will use
PJMEDIA_JBUF_DISC_MIN_GAPinstead, so the discard rate will not be faster than
With this setting, the jitter buffer’s latency is set as twice the
optimal level. This algorithm discard rate is fixed to
PJMEDIA_JBUF_DISC_MIN_GAP, so it
will discard a frame every 200ms (the default value) until the
target latency is reached.