From 9272e1f68a84cd47b2b8b5a481c0a3e8e8534c4b Mon Sep 17 00:00:00 2001 From: Mark Spencer Date: Thu, 19 May 2005 00:34:28 +0000 Subject: More jitter buffer fixes for large resync (bug #4311) git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@5719 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- jitterbuf.c | 48 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 37 insertions(+), 11 deletions(-) (limited to 'jitterbuf.c') diff --git a/jitterbuf.c b/jitterbuf.c index 96dff632d..9611048e0 100755 --- a/jitterbuf.c +++ b/jitterbuf.c @@ -106,14 +106,37 @@ static int longcmp(const void *a, const void *b) } #endif -static void history_put(jitterbuf *jb, long ts, long now) +static int history_put(jitterbuf *jb, long ts, long now, long ms) { - long delay = now - ts; + long delay = now - (ts - jb->info.resync_offset); + long threshold = 2 * jb->info.jitter + jb->info.resync_threshold; long kicked; /* don't add special/negative times to history */ if (ts <= 0) - return; + return 0; + + /* check for drastic change in delay */ + if (jb->info.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 = 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]; @@ -125,7 +148,7 @@ static void history_put(jitterbuf *jb, long ts, long now) * 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; + return 0; /* don't do this until we've filled history * (reduces some edge cases below) */ @@ -149,13 +172,13 @@ static void history_put(jitterbuf *jb, long ts, long now) /* if we got here, we don't need to invalidate, 'cause this delay didn't * affect things */ - return; + return 0; /* end optimization */ invalidate: jb->hist_maxbuf_valid = 0; - return; + return 0; } static void history_calc_maxbuf(jitterbuf *jb) @@ -281,6 +304,7 @@ static void queue_put(jitterbuf *jb, void *data, int type, long ms, long ts) { jb_frame *frame; jb_frame *p; + long resync_ts = ts - jb->info.resync_offset; frame = jb->free; if (frame) { @@ -297,7 +321,7 @@ static void queue_put(jitterbuf *jb, void *data, int type, long ms, long ts) jb->info.frames_cur++; frame->data = data; - frame->ts = ts; + frame->ts = resync_ts; frame->ms = ms; frame->type = type; @@ -310,7 +334,7 @@ static void queue_put(jitterbuf *jb, void *data, int type, long ms, long ts) jb->frames = frame; frame->next = frame; frame->prev = frame; - } else if (ts < jb->frames->ts) { + } else if (resync_ts < jb->frames->ts) { frame->next = jb->frames; frame->prev = jb->frames->prev; @@ -325,9 +349,9 @@ static void queue_put(jitterbuf *jb, void *data, int type, long ms, long ts) p = jb->frames; /* frame is out of order */ - if (ts < p->prev->ts) jb->info.frames_ooo++; + if (resync_ts < p->prev->ts) jb->info.frames_ooo++; - while (ts < p->prev->ts && p->prev != jb->frames) + while (resync_ts < p->prev->ts && p->prev != jb->frames) p = p->prev; frame->next = p; @@ -474,7 +498,8 @@ int jb_put(jitterbuf *jb, void *data, int type, long ms, long ts, long now) if (type == JB_TYPE_VOICE) { /* presently, I'm only adding VOICE frames to history and drift calculations; mostly because with the * IAX integrations, I'm sending retransmitted control frames with their awkward timestamps through */ - history_put(jb,ts,now); + if (history_put(jb,ts,now,ms)) + return JB_DROP; } queue_put(jb,data,type,ms,ts); @@ -750,6 +775,7 @@ int jb_setinfo(jitterbuf *jb, jb_info *settings) /* take selected settings from the struct */ jb->info.max_jitterbuf = settings->max_jitterbuf; + jb->info.resync_threshold = settings->resync_threshold; return JB_OK; } -- cgit v1.2.3