Example #1
0
enum jb_return_code jb_get(jitterbuf *jb, jb_frame *frameout, long now, long interpl)
{
	enum jb_return_code ret = _jb_get(jb, frameout, now, interpl);
#if 0
	static int lastts=0;
	int thists = ((ret == JB_OK) || (ret == JB_DROP)) ? frameout->ts : 0;
	jb_warn("jb_get(%x,%x,%ld) = %d (%d)\n", jb, frameout, now, ret, thists);
	if (thists && thists < lastts) jb_warn("XXXX timestamp roll-back!!!\n");
	lastts = thists;
#endif
	return ret;
}
Example #2
0
int jb_get(jitterbuf *jb, jb_frame *frameout, long now, long interpl) 
{
	int ret = _jb_get(jb,frameout,now,interpl);
#if 0
	static int lastts=0;
	int thists = ((ret == JB_OK) || (ret == JB_DROP)) ? frameout->ts : 0;
	jb_warn("jb_get(%x,%x,%ld) = %d (%d)\n", jb, frameout, now, ret, thists);
	if (thists && thists < lastts) jb_warn("XXXX timestamp roll-back!!!\n");
	lastts = thists;
#endif
	if(ret == JB_INTERP) 
		frameout->ms = jb->info.last_voice_ms;
	
	return ret;
}
Example #3
0
static void resync(jitterbuf *jb, long ts, long now)
{
	long delay = now - (ts - jb->info.resync_offset);
	long threshold = 2 * jb->info.jitter + jb->conf.resync_threshold;

	/* resync the jitterbuffer */
	jb->info.cnt_delay_discont = 0;
	jb->hist_ptr = 0;
	jb->hist_maxbuf_valid = 0;
	jb->force_resync = 0;
	
	jb_warn("Resyncing the jb. last_delay %ld, this delay %ld, threshold %ld, new offset %ld\n", jb->info.last_delay, delay, threshold, ts - now);
	jb->info.resync_offset = ts - now;
	jb->info.last_delay = 0; /* after resync, frame is right on time */
}
Example #4
0
static int check_resync(jitterbuf *jb, long ts, long now, long ms, const enum jb_frame_type type, long *delay)
{
	long numts = 0;
	long threshold = 2 * jb->info.jitter + jb->info.conf.resync_threshold;

	/* Check for overfill of the buffer */
	if (jb->frames) {
		numts = jb->frames->prev->ts - jb->frames->ts;
	}

	if (numts >= (jb->info.conf.max_jitterbuf)) {
		if (!jb->dropem) {
			ast_debug(1, "Attempting to exceed Jitterbuf max %ld timeslots\n",
				jb->info.conf.max_jitterbuf);
			jb->dropem = 1;
		}
		jb->info.frames_dropped++;
		return -1;
	} else {
		jb->dropem = 0;
	}

	/* check for drastic change in delay */
	if (jb->info.conf.resync_threshold != -1) {
		if (abs(*delay - jb->info.last_delay) > threshold) {
			jb->info.cnt_delay_discont++;
			/* resync the jitterbuffer on 3 consecutive discontinuities,
			 * or immediately if a control frame */
			if ((jb->info.cnt_delay_discont > 3) || (type == JB_TYPE_CONTROL)) {
				jb->info.cnt_delay_discont = 0;
				jb->hist_ptr = 0;
				jb->hist_maxbuf_valid = 0;
				jb_warn("Resyncing the jb. last_delay %ld, this delay %ld, threshold %ld, new offset %ld\n", jb->info.last_delay, *delay, threshold, ts - now);
				jb->info.resync_offset = ts - now;
				jb->info.last_delay = *delay = 0; /* after resync, frame is right on time */
			} else {
				jb->info.frames_dropped++;
				return -1;
			}
		} else {
			jb->info.last_delay = *delay;
			jb->info.cnt_delay_discont = 0;
		}
	}
	return 0;
}
Example #5
0
/* drop parameter determines whether we will drop outliers to minimize
 * delay */
static int history_put(jitterbuf *jb, long ts, long now, long ms) 
{
	long delay = now - (ts - jb->info.resync_offset);
	long threshold = 2 * jb->info.jitter + jb->info.conf.resync_threshold;
	long kicked;

	/* don't add special/negative times to history */
	if (ts <= 0) 
		return 0;

	/* check for drastic change in delay */
	if (jb->info.conf.resync_threshold != -1) {
		if (abs(delay - jb->info.last_delay) > threshold) {
			jb->info.cnt_delay_discont++;
			if (jb->info.cnt_delay_discont > 3) {
				/* resync the jitterbuffer */
				jb->info.cnt_delay_discont = 0;
				jb->hist_ptr = 0;
				jb->hist_maxbuf_valid = 0;

				jb_warn("Resyncing the jb. last_delay %ld, this delay %ld, threshold %ld, new offset %ld\n", jb->info.last_delay, delay, threshold, ts - now);
				jb->info.resync_offset = ts - now;
				jb->info.last_delay = delay = 0; /* after resync, frame is right on time */
			} else {
				return -1;
			}
		} else {
			jb->info.last_delay = delay;
			jb->info.cnt_delay_discont = 0;
		}
	}

	kicked = jb->history[jb->hist_ptr % JB_HISTORY_SZ];

	jb->history[(jb->hist_ptr++) % JB_HISTORY_SZ] = delay;

	/* optimization; the max/min buffers don't need to be recalculated, if this packet's
	 * entry doesn't change them.  This happens if this packet is not involved, _and_ any packet
	 * that got kicked out of the history is also not involved 
	 * We do a number of comparisons, but it's probably still worthwhile, because it will usually
	 * succeed, and should be a lot faster than going through all 500 packets in history */
	if (!jb->hist_maxbuf_valid)
		return 0;

	/* don't do this until we've filled history 
	 * (reduces some edge cases below) */
	if (jb->hist_ptr < JB_HISTORY_SZ)
		goto invalidate;

	/* if the new delay would go into min */
	if (delay < jb->hist_minbuf[JB_HISTORY_MAXBUF_SZ-1])
		goto invalidate;

	/* or max.. */
	if (delay > jb->hist_maxbuf[JB_HISTORY_MAXBUF_SZ-1])
		goto invalidate;

	/* or the kicked delay would be in min */
	if (kicked <= jb->hist_minbuf[JB_HISTORY_MAXBUF_SZ-1]) 
		goto invalidate;

	if (kicked >= jb->hist_maxbuf[JB_HISTORY_MAXBUF_SZ-1]) 
		goto invalidate;

	/* if we got here, we don't need to invalidate, 'cause this delay didn't 
	 * affect things */
	return 0;
	/* end optimization */


invalidate:
	jb->hist_maxbuf_valid = 0;
	return 0;
}