Jitter buffer features and operations
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.
Features
Some of the features of PJMEDIA’s jitter buffer are as follows.
Adaptive to jitter change
The jitter buffer adapts to change in network jitter, increasing or decreasing the prefetch value and the buffering latency as necessary.
Handle network and device jitters
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.
Low latency
The jitter buffer provides the minimum latency possible without sacrificing the continuous flow requirement.
Duplicate/old frame
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 pjmedia_jbuf_put_frame2()
function:
PJ_TRUE, jitter buffer will ignore the duplicate frame and set the discarded argument of
pjmedia_jbuf_put_frame2()
to non-zero.PJ_FALSE, the jitter buffer will override the old frame with this newer frame, and set the discarded argument of
pjmedia_jbuf_put_frame2()
to FALSE.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.
Non octet-aligned
The jitter buffer is able to store frames that are not octet/byte aligned.
Sequence number jump/restart
The jitter buffer detects and handles large jump in frame’s sequence number.
DTX
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.
Minimum prefetching
The jitter buffer can be configured with a minimum latency (prefetching).
Fixed mode operation
The jitter buffer can be set to to operate in fixed/non-adaptive mode.
This can be done by calling pjmedia_jbuf_set_fixed()
function.
Return frame type/status
The jitter buffer returns frame status in pjmedia_jbuf_get_frame()
.
See pjmedia_jb_frame_type
for possible values.
Operations
Some of the jitter buffer’s operational terms will be described below.
Progressive discard
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 = 7
frames.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) = 2242
msec or discard rate istarget_time / overflow = 2242 / 7 = 320
ms 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 usePJMEDIA_JBUF_DISC_MIN_GAP
instead, so the discard rate will not be faster thanPJMEDIA_JBUF_DISC_MIN_GAP
.
Static discard
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.