40 #define JB_LONGMAX 2147483647L
41 #define JB_LONGMIN (-JB_LONGMAX - 1L)
43 #define jb_warn(...) (warnf ? warnf(__VA_ARGS__) : (void)0)
44 #define jb_err(...) (errf ? errf(__VA_ARGS__) : (void)0)
45 #define jb_dbg(...) (dbgf ? dbgf(__VA_ARGS__) : (void)0)
48 #define jb_dbg2(...) (dbgf ? dbgf(__VA_ARGS__) : (void)0)
50 #define jb_dbg2(...) ((void)0)
53 static jb_output_function_t warnf, errf, dbgf;
55 void jb_setoutput(jb_output_function_t err, jb_output_function_t warn, jb_output_function_t dbg)
62 static void increment_losspct(
jitterbuf *jb)
67 static void decrement_losspct(
jitterbuf *jb)
77 memset(jb, 0,
sizeof(*jb));
95 jb_dbg2(
"jb_new() = %x\n", jb);
102 jb_dbg2(
"jb_destroy(%x)\n", jb);
106 while (frame != NULL) {
116 static int check_resync(
jitterbuf *jb,
long ts,
long now,
long ms,
const enum jb_frame_type type,
long *delay)
128 ast_debug(1,
"Attempting to exceed Jitterbuf max %ld timeslots\n",
140 if (labs(*delay - jb->info.
last_delay) > threshold) {
148 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);
163 static int history_put(
jitterbuf *jb,
long ts,
long now,
long ms,
long delay)
214 static void history_calc_maxbuf(
jitterbuf *jb)
242 if (toins > jb->
hist_maxbuf[JB_HISTORY_MAXBUF_SZ-1]) {
249 if (j != JB_HISTORY_MAXBUF_SZ - 1) {
261 if (toins < jb->hist_minbuf[JB_HISTORY_MAXBUF_SZ-1]) {
266 if (toins < jb->hist_minbuf[j]) {
268 if (j != JB_HISTORY_MAXBUF_SZ - 1) {
281 fprintf(stderr,
"toins = %ld\n", toins);
282 fprintf(stderr,
"maxbuf =");
285 fprintf(stderr,
"\nminbuf =");
288 fprintf(stderr,
"\n");
297 long max, min, jitter;
302 history_calc_maxbuf(jb);
311 if (idx > (JB_HISTORY_MAXBUF_SZ - 1))
312 idx = JB_HISTORY_MAXBUF_SZ - 1;
344 if ((frame = jb->
free)) {
345 jb->
free = frame->next;
346 }
else if (!(frame =
ast_malloc(
sizeof(*frame)))) {
347 jb_err(
"cannot allocate frame\n");
354 frame->ts = resync_ts;
368 }
else if (resync_ts < jb->frames->ts) {
370 frame->prev = jb->
frames->prev;
372 frame->next->prev = frame;
373 frame->prev->next = frame;
384 if (resync_ts < p->prev->ts) jb->info.
frames_ooo++;
386 while (resync_ts < p->prev->ts && p->prev != jb->
frames)
390 frame->prev = p->prev;
392 frame->next->prev = frame;
393 frame->prev->next = frame;
409 return jb->
frames->prev->ts;
424 if (all || ts >= frame->ts) {
426 frame->prev->next = frame->next;
427 frame->next->prev = frame->prev;
429 if (frame->next == frame)
436 frame->next = jb->
free;
451 return _queue_get(jb,ts,0);
456 return _queue_get(jb,0,1);
466 jb_dbg(
"\njb info: fin=%ld fout=%ld flate=%ld flost=%ld fdrop=%ld fcur=%ld\n",
469 jb_dbg(
"jitter=%ld current=%ld target=%ld min=%ld sil=%d len=%d len/fcur=%ld\n",
473 jb_dbg(
"jb info: Loss PCT = %ld%%, Late PCT = %ld%%\n",
476 jb_dbg(
"jb info: queue %d -> %d. last_ts %d (queue len: %d) last_ms %d\n",
480 queue_last(jb) - queue_next(jb),
496 if (p->next == NULL) {
497 jb_err(
"Queue is BROKEN at item [%d]", i);
501 }
while (p->next != jb->
frames);
517 jb_dbg(
"[%d]=%ld ", i++, p->ts);
519 }
while (p->next != jb->
frames);
528 jb_dbg2(
"jb_put(%x,%x,%ld,%ld,%ld)\n", jb, data, ms, ts, now);
530 if (check_resync(jb, ts, now, ms, type, &delay)) {
537 history_put(jb, ts, now, ms, delay);
543 if (queue_put(jb,data,type,ms,ts)) {
550 static enum jb_return_code _jb_get(
jitterbuf *jb,
jb_frame *frameout,
long now,
long interpl)
554 static int dbg_cnt = 0;
559 if (dbg_cnt && dbg_cnt % 50 == 0) {
569 jb_dbg(
"clamping target from %ld to %ld\n", (jb->info.
target - jb->info.
min), jb->info.conf.
max_jitterbuf);
585 (diff > queue_last(jb) - queue_next(jb)) ) ) {
624 decrement_losspct(jb);
632 decrement_losspct(jb);
641 if (frame && frame->ms > 0) {
649 if (diff < -jb->info.conf.target_extra &&
661 decrement_losspct(jb);
669 increment_losspct(jb);
699 increment_losspct(jb);
715 decrement_losspct(jb);
727 if (diff < -jb->info.conf.target_extra &&
733 frame = queue_get(jb, now - jb->info.
current);
746 decrement_losspct(jb);
759 decrement_losspct(jb);
771 long next = queue_next(jb);
776 return next + jb->info.
target;
787 enum jb_return_code ret = _jb_get(jb, frameout, now, interpl);
790 int thists = ((ret == JB_OK) || (ret == JB_DROP)) ? frameout->ts : 0;
791 jb_warn(
"jb_get(%x,%x,%ld) = %d (%d)\n", jb, frameout, now, ret, thists);
792 if (thists && thists < lastts) jb_warn(
"XXXX timestamp roll-back!!!\n");
795 if (ret == JB_INTERP)
804 frame = queue_getall(jb);
long hist_minbuf[JB_HISTORY_MAXBUF_SZ]
Asterisk main include file. File version handling, generic pbx functions.
#define JB_HISTORY_DROPPCT
enum jb_return_code jb_getall(jitterbuf *jb, jb_frame *frameout)
unconditionally get frames from jitterbuf until empty
enum jb_return_code jb_put(jitterbuf *jb, void *data, const enum jb_frame_type type, long ms, long ts, long now)
queue a frame
long jb_next(jitterbuf *jb)
when is the next frame due out, in receiver's time (0=EMPTY) This value may change as frames are adde...
enum jb_return_code jb_getinfo(jitterbuf *jb, jb_info *stats)
get jitterbuf info: only "statistics" may be valid
All configuration options for http media cache.
enum jb_return_code jb_get(jitterbuf *jb, jb_frame *frameout, long now, long interpl)
get a frame for time now (receiver's time) return value is one of JB_OK: You've got frame! JB_DROP: H...
long hist_maxbuf[JB_HISTORY_MAXBUF_SZ]
#define ast_malloc(len)
A wrapper for malloc()
#define ast_debug(level,...)
Log a DEBUG message.
#define JB_HISTORY_MAXBUF_SZ
long history[JB_HISTORY_SZ]
jitterbuf: an application-independent jitterbuffer jitterbuf.c
enum jb_return_code jb_setconf(jitterbuf *jb, jb_conf *conf)
set jitterbuf conf
int jb_is_late(jitterbuf *jb, long ts)
Checks if the given time stamp is late.
#define ast_calloc(num, len)
A wrapper for calloc()
void jb_destroy(jitterbuf *jb)
destroy jitterbuf
void jb_reset(jitterbuf *jb)
reset jitterbuf
jitterbuf * jb_new()
new jitterbuf