summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--main/jitterbuf.c89
1 files changed, 39 insertions, 50 deletions
diff --git a/main/jitterbuf.c b/main/jitterbuf.c
index 867b6948b..a49d04e64 100644
--- a/main/jitterbuf.c
+++ b/main/jitterbuf.c
@@ -109,50 +109,60 @@ void jb_destroy(jitterbuf *jb)
ast_free(jb);
}
-
-
-#if 0
-static int longcmp(const void *a, const void *b)
-{
- return *(long *)a - *(long *)b;
-}
-#endif
-
-/*! \brief simple history manipulation
- \note maybe later we can make the history buckets variable size, or something? */
-/* drop parameter determines whether we will drop outliers to minimize
- * delay */
-static int history_put(jitterbuf *jb, long ts, long now, long ms)
+static int check_resync(jitterbuf *jb, long ts, long now, long ms, const enum jb_frame_type type, long *delay)
{
- long delay = now - (ts - jb->info.resync_offset);
+ long numts = 0;
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 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) {
+ if (abs(*delay - jb->info.last_delay) > threshold) {
jb->info.cnt_delay_discont++;
- if (jb->info.cnt_delay_discont > 3) {
- /* resync the jitterbuffer */
+ /* 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_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 */
+ 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.last_delay = *delay;
jb->info.cnt_delay_discont = 0;
}
}
+ return 0;
+}
+
+static int history_put(jitterbuf *jb, long ts, long now, long ms, long delay)
+{
+ long kicked;
+
+ /* don't add special/negative times to history */
+ if (ts <= 0)
+ return 0;
kicked = jb->history[jb->hist_ptr % JB_HISTORY_SZ];
@@ -506,33 +516,17 @@ static void jb_dbgqueue(jitterbuf *jb)
enum jb_return_code jb_put(jitterbuf *jb, void *data, const enum jb_frame_type type, long ms, long ts, long now)
{
- long numts;
-
+ long delay = now - (ts - jb->info.resync_offset);
jb_dbg2("jb_put(%x,%x,%ld,%ld,%ld)\n", jb, data, ms, ts, now);
- numts = 0;
- 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++;
+ if (check_resync(jb, ts, now, ms, type, &delay)) {
return JB_DROP;
- } else {
- jb->dropem = 0;
}
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 */
- if (history_put(jb,ts,now,ms)) {
- jb->info.frames_dropped++;
- return JB_DROP;
- }
+ history_put(jb, ts, now, ms, delay);
}
jb->info.frames_in++;
@@ -551,7 +545,6 @@ static enum jb_return_code _jb_get(jitterbuf *jb, jb_frame *frameout, long now,
long diff;
static int dbg_cnt = 0;
- /*if ((now - jb_next(jb)) > 2 * jb->info.last_voice_ms) jb_warn("SCHED: %ld", (now - jb_next(jb))); */
/* get jitter info */
history_get(jb);
@@ -632,8 +625,6 @@ static enum jb_return_code _jb_get(jitterbuf *jb, jb_frame *frameout, long now,
jb->info.frames_late++;
jb->info.frames_lost--;
jb_dbg("l");
- /*jb_warn("\nlate: wanted=%ld, this=%ld, next=%ld\n", jb->info.next_voice_ts - jb->info.current, frame->ts, queue_next(jb));
- jb_warninfo(jb); */
return JB_DROP;
}
}
@@ -748,8 +739,6 @@ static enum jb_return_code _jb_get(jitterbuf *jb, jb_frame *frameout, long now,
jb->info.frames_late++;
jb->info.frames_lost--;
jb_dbg("l");
- /*jb_warn("\nlate: wanted=%ld, this=%ld, next=%ld\n", jb->info.next_voice_ts - jb->info.current, frame->ts, queue_next(jb));
- jb_warninfo(jb); */
return JB_DROP;
} else {
/* voice frame */