/* * Mobicents Media Gateway * * The source code contained in this file is in in the public domain. * It can be used in any project or product without prior permission, * license or royalty payments. There is NO WARRANTY OF ANY KIND, * EXPRESS, IMPLIED OR STATUTORY, INCLUDING, WITHOUT LIMITATION, * THE IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, * AND DATA ACCURACY. We do not warrant or make any representations * regarding the use of the software or the results thereof, including * but not limited to the correctness, accuracy, reliability or * usefulness of the software. */ package org.mobicents.media.server.impl.rtp; import java.io.Serializable; import org.mobicents.media.Buffer; /** * Implements jitter buffer. * * A jitter buffer temporarily stores arriving packets in order to minimize * delay variations. If packets arrive too late then they are discarded. A * jitter buffer may be mis-configured and be either too large or too small. * * If a jitter buffer is too small then an excessive number of packets may be * discarded, which can lead to call quality degradation. If a jitter buffer is * too large then the additional delay can lead to conversational difficulty. * * A typical jitter buffer configuration is 30mS to 50mS in size. In the case of * an adaptive jitter buffer then the maximum size may be set to 100-200mS. Note * that if the jitter buffer size exceeds 100mS then the additional delay * introduced can lead to conversational difficulty. * * @author Oleg Kulikov * @author amit bhayani */ public class JitterBuffer implements Serializable { private int maxSize; private int depth; private int period; private int jitter; private BufferConcurrentLinkedQueue<RtpPacket> queue = new BufferConcurrentLinkedQueue(); private volatile boolean ready = false; /** * Creates new instance of jitter. * * @param fmt * the format of the received media * @param jitter * the size of the jitter in milliseconds. */ public JitterBuffer(int jitter, int period) { this.depth = jitter /period; this.maxSize = 4 * depth; this.period = period; this.jitter = jitter; } public int getJitter() { return jitter; } public void setPeriod(int period) { this.period = period; this.depth = jitter /period; maxSize = 4* jitter / period; } public void write(RtpPacket rtpPacket) { if (queue.size() < maxSize) { queue.offer(rtpPacket); } if (!ready && queue.size() > this.depth ) { ready = true; } } public void reset() { queue.clear(); } public RtpPacket read() { return ready && !queue.isEmpty() ? queue.poll() : null; } }