Opened 9 years ago

Closed 9 years ago

Last modified 9 years ago

#969 closed enhancement (fixed)

Improvement in jitter buffer algoritm for low bandwidth network (thanks Emil Sturniolo for the suggestion)

Reported by: bennylp Owned by: nanang
Priority: normal Milestone: release-1.6
Component: pjmedia Version: trunk
Keywords: Cc:
Backport to 1.x milestone: Backported:

Description (last modified by nanang)

On low bandwidth network, high jitter and frame lost are usually the issues. The first issue is basically jitter buffer (JB) responsibility area.

One simple way to detect jitter is by detecting the existence of burst, i.e: number of incoming frames from network between two playout clockticks, where without jitter, it should be always equal to one. Current JB uses such mechanism to measure actual burst level and use the burst level to manage the latency (due to clock drift) by periodically dropping/discarding frames. However as clock drift usually increases the latency very smoothly, JB will only drop/discard a frame at least every 200ms.

In fact, it's been reported that as the burst is rather extreme in low bandwidth network, discard rate of 200ms seems to be insufficient as frequently JB tends to get full (high latency). Moreover, when it is full, it will drop 1/4th of its size when new frame arrives. This causes large portion of a conversation to be dropped. So, the issues identified here are latency and audio cut.

A better algorithm to optimize latency and avoid bulk drops, let's say progressive discard algorithm, will progressively discard frames as the buffer fills up.

The algorithm specifications:

  1. Instead of dropping large consecutive frames, it should discard frames in spread.
  2. The discard rate/aggressiveness should be adaptive to the network condition, notice some useful real-time indicators such as latency/size, burst level.
  3. JB discards a frame by marking the frame with specific internal frame type, such as PJMEDIA_JB_DISCARDED_FRAME.
  4. Discarded frames will not be returned to application, it will just get ignored/skipped in GET operation. So application will never get a frame with type PJMEDIA_JB_DISCARDED_FRAME.
  5. Avoid discarding back-to-back frames.
  6. Pass jbuf_test (of pjmedia_test), it may also need a test case of periodic large-burst spikes.

Change History (6)

comment:1 Changed 9 years ago by bennylp

  • Milestone changed from release-1.5 to release-1.6

comment:2 Changed 9 years ago by nanang

  • Description modified (diff)
  • Summary changed from Improvement in jitter buffer algoritm to make space for new frames when it is full (thanks Emil Sturniolo for the suggestion) to Improvement in jitter buffer algoritm for low bandwidth network (thanks Emil Sturniolo for the suggestion)

comment:3 Changed 9 years ago by nanang

In r3065:

  • implemented progressive discard algorithm, discard rate is calculated from ratio of effective size to effective burst level.
  • updated jbuf to clarify prefetch and burst level distinction, previously they are stored in same var, i.e: jb_prefetch, while the semantic is actually different.
  • updated STABLE_HISTORY_LIMIT in jbuf, it is now 20 (was 100), to adjust burst level faster.
  • added test case of periodic-spike-burst-case in jbtest.dat for testing the new algorithm.
  • updated stream to limit the rate of jbuf empty/lost log messages, it will only log first empty/lost event, then log again once jbuf returning normal frame (also counter of previous empty/lost frames).
  • minor updates on jbuf.c: variable names, logs, added burst to jbuf state.
  • minor updates on jbuf_test.c: handle comment in test session header, seq jump is now 20 (was 5000).

comment:4 Changed 9 years ago by bennylp

Related to this, in r3067:

  • make maximum PLC generated frames configurable (PJMEDIA_MAX_PLC_DURATION_MSEC)

comment:5 Changed 9 years ago by nanang

  • Resolution set to fixed
  • Status changed from new to closed

In r3111: minor update, removed 'experimental feature' comment on progressive discard.

comment:6 Changed 9 years ago by nanang

(In [3154]) Re #969: Fixed bug division by zero in JB progressive discard code, caused by possibility of uninitialized burst level after JB switches status INITIALIZING -> PROCESSING (thanks Janos Tolgyesi and Tamàs Solymosi for the report and investigation).

Note: See TracTickets for help on using tickets.