diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c index 37c305890..6f8d5cb7c 100755 --- a/channels/chan_iax2.c +++ b/channels/chan_iax2.c @@ -2222,6 +2222,7 @@ static int schedule_delivery(struct iax_frame *fr, int reallydeliver, int update { #ifdef NEWJB int type, len; + int ret; #else int x; int ms; @@ -2387,10 +2388,11 @@ static int schedule_delivery(struct iax_frame *fr, int reallydeliver, int update /* insert into jitterbuffer */ /* TODO: Perhaps we could act immediately if it's not droppable and late */ - if(jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts, - calc_rxstamp(iaxs[fr->callno],fr->ts)) == JB_DROP) { + ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts, + calc_rxstamp(iaxs[fr->callno],fr->ts)); + if (ret == JB_DROP) { iax2_frame_free(fr); - } else { + } else if (ret == JB_SCHED) { update_jbsched(iaxs[fr->callno]); } #else diff --git a/jitterbuf.c b/jitterbuf.c index 9611048e0..da017c128 100755 --- a/jitterbuf.c +++ b/jitterbuf.c @@ -300,10 +300,12 @@ static void history_get(jitterbuf *jb) jb->info.jitter = jitter; } -static void queue_put(jitterbuf *jb, void *data, int type, long ms, long ts) +/* returns 1 if frame was inserted into head of queue, 0 otherwise */ +static int queue_put(jitterbuf *jb, void *data, int type, long ms, long ts) { jb_frame *frame; jb_frame *p; + int head = 0; long resync_ts = ts - jb->info.resync_offset; frame = jb->free; @@ -315,7 +317,7 @@ static void queue_put(jitterbuf *jb, void *data, int type, long ms, long ts) if (!frame) { jb_err("cannot allocate frame\n"); - return; + return 0; } jb->info.frames_cur++; @@ -334,6 +336,7 @@ static void queue_put(jitterbuf *jb, void *data, int type, long ms, long ts) jb->frames = frame; frame->next = frame; frame->prev = frame; + head = 1; } else if (resync_ts < jb->frames->ts) { frame->next = jb->frames; frame->prev = jb->frames->prev; @@ -345,6 +348,7 @@ static void queue_put(jitterbuf *jb, void *data, int type, long ms, long ts) jb->info.frames_ooo++; jb->frames = frame; + head = 1; } else { p = jb->frames; @@ -360,6 +364,7 @@ static void queue_put(jitterbuf *jb, void *data, int type, long ms, long ts) frame->next->prev = frame; frame->prev->next = frame; } + return head; } static long queue_next(jitterbuf *jb) @@ -502,8 +507,10 @@ int jb_put(jitterbuf *jb, void *data, int type, long ms, long ts, long now) return JB_DROP; } - queue_put(jb,data,type,ms,ts); - + /* if put into head of queue, caller needs to reschedule */ + if (queue_put(jb,data,type,ms,ts)) { + return JB_SCHED; + } return JB_OK; } diff --git a/jitterbuf.h b/jitterbuf.h index 1cec72643..85de0131d 100755 --- a/jitterbuf.h +++ b/jitterbuf.h @@ -42,6 +42,7 @@ extern "C" { #define JB_NOFRAME 2 #define JB_INTERP 3 #define JB_DROP 4 +#define JB_SCHED 5 /* frame types */ #define JB_TYPE_CONTROL 0 @@ -112,7 +113,11 @@ void jb_destroy(jitterbuf *jb); void jb_reset(jitterbuf *jb); /* queue a frame data=frame data, timings (in ms): ms=length of frame (for voice), ts=ts (sender's time) - * now=now (in receiver's time)*/ + * now=now (in receiver's time) return value is one of + * JB_OK: Frame added. Last call to jb_next() still valid + * JB_DROP: Drop this frame immediately + * JB_SCHED: Frame added. Call jb_next() to get a new time for the next frame + */ int jb_put(jitterbuf *jb, void *data, int type, long ms, long ts, long now); /* get a frame for time now (receiver's time) return value is one of