Asterisk - The Open Source Telephony Project  GIT-master-e8cda4b
Macros | Functions | Variables
jitterbuf.c File Reference

jitterbuf: an application-independent jitterbuffer More...

#include "asterisk.h"
#include "jitterbuf.h"
#include "asterisk/utils.h"

Go to the source code of this file.

Macros

#define jb_dbg(...)   (dbgf ? dbgf(__VA_ARGS__) : (void)0)
 
#define jb_dbg2(...)   ((void)0)
 
#define jb_err(...)   (errf ? errf(__VA_ARGS__) : (void)0)
 
#define JB_LONGMAX   2147483647L
 
#define JB_LONGMIN   (-JB_LONGMAX - 1L)
 
#define jb_warn(...)   (warnf ? warnf(__VA_ARGS__) : (void)0)
 

Functions

static enum jb_return_code _jb_get (jitterbuf *jb, jb_frame *frameout, long now, long interpl)
 
static jb_frame_queue_get (jitterbuf *jb, long ts, int all)
 
static int check_resync (jitterbuf *jb, long ts, long now, long ms, const enum jb_frame_type type, long *delay)
 
static void decrement_losspct (jitterbuf *jb)
 
static void history_calc_maxbuf (jitterbuf *jb)
 
static void history_get (jitterbuf *jb)
 
static int history_put (jitterbuf *jb, long ts, long now, long ms, long delay)
 
static void increment_losspct (jitterbuf *jb)
 
void jb_destroy (jitterbuf *jb)
 destroy jitterbuf More...
 
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: Here's an audio frame you should just drop. Ask me again for this time.. JB_NOFRAME: There's no frame scheduled for this time. JB_INTERP: Please interpolate an interpl-length frame for this time (either we need to grow, or there was a lost frame) JB_EMPTY: The jb is empty. More...
 
enum jb_return_code jb_getall (jitterbuf *jb, jb_frame *frameout)
 unconditionally get frames from jitterbuf until empty More...
 
enum jb_return_code jb_getinfo (jitterbuf *jb, jb_info *stats)
 get jitterbuf info: only "statistics" may be valid More...
 
int jb_is_late (jitterbuf *jb, long ts)
 Checks if the given time stamp is late. More...
 
jitterbufjb_new ()
 new jitterbuf More...
 
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 added (esp non-audio frames) More...
 
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 More...
 
void jb_reset (jitterbuf *jb)
 reset jitterbuf More...
 
enum jb_return_code jb_setconf (jitterbuf *jb, jb_conf *conf)
 set jitterbuf conf More...
 
void jb_setoutput (jb_output_function_t err, jb_output_function_t warn, jb_output_function_t dbg)
 
static jb_framequeue_get (jitterbuf *jb, long ts)
 
static jb_framequeue_getall (jitterbuf *jb)
 
static long queue_last (jitterbuf *jb)
 
static long queue_next (jitterbuf *jb)
 
static int queue_put (jitterbuf *jb, void *data, const enum jb_frame_type type, long ms, long ts)
 

Variables

static jb_output_function_t dbgf
 
static jb_output_function_t errf
 
static jb_output_function_t warnf
 

Detailed Description

jitterbuf: an application-independent jitterbuffer

Author
Steve Kann steve.nosp@m.k@st.nosp@m.evek..nosp@m.com

Definition in file jitterbuf.c.

Macro Definition Documentation

◆ jb_dbg

#define jb_dbg (   ...)    (dbgf ? dbgf(__VA_ARGS__) : (void)0)

Definition at line 45 of file jitterbuf.c.

Referenced by _jb_get(), and queue_getall().

◆ jb_dbg2

#define jb_dbg2 (   ...)    ((void)0)

Definition at line 50 of file jitterbuf.c.

Referenced by jb_destroy(), jb_new(), and jb_put().

◆ jb_err

#define jb_err (   ...)    (errf ? errf(__VA_ARGS__) : (void)0)

Definition at line 44 of file jitterbuf.c.

Referenced by queue_getall(), and queue_put().

◆ JB_LONGMAX

#define JB_LONGMAX   2147483647L

define these here, just for ancient compiler systems

Definition at line 40 of file jitterbuf.c.

Referenced by history_calc_maxbuf(), and jb_next().

◆ JB_LONGMIN

#define JB_LONGMIN   (-JB_LONGMAX - 1L)

Definition at line 41 of file jitterbuf.c.

Referenced by history_calc_maxbuf().

◆ jb_warn

#define jb_warn (   ...)    (warnf ? warnf(__VA_ARGS__) : (void)0)

Definition at line 43 of file jitterbuf.c.

Referenced by check_resync(), and jb_get().

Function Documentation

◆ _jb_get()

static enum jb_return_code _jb_get ( jitterbuf jb,
jb_frame frameout,
long  now,
long  interpl 
)
static

Definition at line 550 of file jitterbuf.c.

References jb_info::cnt_contig_interp, jb_info::conf, jb_info::current, decrement_losspct(), jb_info::frames_dropped, jb_info::frames_late, jb_info::frames_lost, jb_info::frames_out, history_get(), increment_losspct(), jitterbuf::info, sip_to_pjsip::info(), JB_ADJUST_DELAY, jb_dbg, JB_DROP, JB_INTERP, JB_NOFRAME, JB_OK, JB_TYPE_SILENCE, JB_TYPE_VOICE, jb_info::jitter, jb_info::last_adjustment, jb_info::last_voice_ms, jb_conf::max_contig_interp, jb_conf::max_jitterbuf, jb_info::min, jb_frame::ms, jb_info::next_voice_ts, queue_get(), queue_last(), queue_next(), jb_info::silence_begin_ts, jb_info::target, jb_conf::target_extra, jb_frame::ts, and jb_frame::type.

Referenced by jb_get().

551 {
552  jb_frame *frame;
553  long diff;
554  static int dbg_cnt = 0;
555 
556  /* get jitter info */
557  history_get(jb);
558 
559  if (dbg_cnt && dbg_cnt % 50 == 0) {
560  jb_dbg("\n");
561  }
562  dbg_cnt++;
563 
564  /* target */
565  jb->info.target = jb->info.jitter + jb->info.min + jb->info.conf.target_extra;
566 
567  /* if a hard clamp was requested, use it */
568  if ((jb->info.conf.max_jitterbuf) && ((jb->info.target - jb->info.min) > jb->info.conf.max_jitterbuf)) {
569  jb_dbg("clamping target from %ld to %ld\n", (jb->info.target - jb->info.min), jb->info.conf.max_jitterbuf);
570  jb->info.target = jb->info.min + jb->info.conf.max_jitterbuf;
571  }
572 
573  diff = jb->info.target - jb->info.current;
574 
575  /* jb_warn("diff = %d lms=%d last = %d now = %d\n", diff, */
576  /* jb->info.last_voice_ms, jb->info.last_adjustment, now); */
577 
578  /* let's work on non-silent case first */
579  if (!jb->info.silence_begin_ts) {
580  /* we want to grow */
581  if ((diff > 0) &&
582  /* we haven't grown in the delay length */
583  (((jb->info.last_adjustment + JB_ADJUST_DELAY) < now) ||
584  /* we need to grow more than the "length" we have left */
585  (diff > queue_last(jb) - queue_next(jb)) ) ) {
586  /* grow by interp frame length */
587  jb->info.current += interpl;
588  jb->info.next_voice_ts += interpl;
589  jb->info.last_voice_ms = interpl;
590  jb->info.last_adjustment = now;
591  jb->info.cnt_contig_interp++;
594  }
595  jb_dbg("G");
596  return JB_INTERP;
597  }
598 
599  frame = queue_get(jb, jb->info.next_voice_ts - jb->info.current);
600 
601  /* not a voice frame; just return it. */
602  if (frame && frame->type != JB_TYPE_VOICE) {
603  if (frame->type == JB_TYPE_SILENCE) {
604  jb->info.silence_begin_ts = frame->ts;
605  jb->info.cnt_contig_interp = 0;
606  }
607 
608  *frameout = *frame;
609  jb->info.frames_out++;
610  jb_dbg("o");
611  return JB_OK;
612  }
613 
614 
615  /* voice frame is later than expected */
616  if (frame && frame->ts + jb->info.current < jb->info.next_voice_ts) {
617  if (frame->ts + jb->info.current > jb->info.next_voice_ts - jb->info.last_voice_ms) {
618  /* either we interpolated past this frame in the last jb_get */
619  /* or the frame is still in order, but came a little too quick */
620  *frameout = *frame;
621  /* reset expectation for next frame */
622  jb->info.next_voice_ts = frame->ts + jb->info.current + frame->ms;
623  jb->info.frames_out++;
624  decrement_losspct(jb);
625  jb->info.cnt_contig_interp = 0;
626  jb_dbg("v");
627  return JB_OK;
628  } else {
629  /* voice frame is late */
630  *frameout = *frame;
631  jb->info.frames_out++;
632  decrement_losspct(jb);
633  jb->info.frames_late++;
634  jb->info.frames_lost--;
635  jb_dbg("l");
636  return JB_DROP;
637  }
638  }
639 
640  /* keep track of frame sizes, to allow for variable sized-frames */
641  if (frame && frame->ms > 0) {
642  jb->info.last_voice_ms = frame->ms;
643  }
644 
645  /* we want to shrink; shrink at 1 frame / 500ms */
646  /* unless we don't have a frame, then shrink 1 frame */
647  /* every 80ms (though perhaps we can shrink even faster */
648  /* in this case) */
649  if (diff < -jb->info.conf.target_extra &&
650  ((!frame && jb->info.last_adjustment + 80 < now) ||
651  (jb->info.last_adjustment + 500 < now))) {
652 
653  jb->info.last_adjustment = now;
654  jb->info.cnt_contig_interp = 0;
655 
656  if (frame) {
657  *frameout = *frame;
658  /* shrink by frame size we're throwing out */
659  jb->info.current -= frame->ms;
660  jb->info.frames_out++;
661  decrement_losspct(jb);
662  jb->info.frames_dropped++;
663  jb_dbg("s");
664  return JB_DROP;
665  } else {
666  /* shrink by last_voice_ms */
667  jb->info.current -= jb->info.last_voice_ms;
668  jb->info.frames_lost++;
669  increment_losspct(jb);
670  jb_dbg("S");
671  return JB_NOFRAME;
672  }
673  }
674 
675  /* lost frame */
676  if (!frame) {
677  /* this is a bit of a hack for now, but if we're close to
678  * target, and we find a missing frame, it makes sense to
679  * grow, because the frame might just be a bit late;
680  * otherwise, we presently get into a pattern where we return
681  * INTERP for the lost frame, then it shows up next, and we
682  * throw it away because it's late */
683  /* I've recently only been able to replicate this using
684  * iaxclient talking to app_echo on asterisk. In this case,
685  * my outgoing packets go through asterisk's (old)
686  * jitterbuffer, and then might get an unusual increasing delay
687  * there if it decides to grow?? */
688  /* Update: that might have been a different bug, that has been fixed..
689  * But, this still seemed like a good idea, except that it ended up making a single actual
690  * lost frame get interpolated two or more times, when there was "room" to grow, so it might
691  * be a bit of a bad idea overall */
692  /*if (diff > -1 * jb->info.last_voice_ms) {
693  jb->info.current += jb->info.last_voice_ms;
694  jb->info.last_adjustment = now;
695  jb_warn("g");
696  return JB_INTERP;
697  } */
698  jb->info.frames_lost++;
699  increment_losspct(jb);
700  jb->info.next_voice_ts += interpl;
701  jb->info.last_voice_ms = interpl;
702  jb->info.cnt_contig_interp++;
705  }
706  jb_dbg("L");
707  return JB_INTERP;
708  }
709 
710  /* normal case; return the frame, increment stuff */
711  *frameout = *frame;
712  jb->info.next_voice_ts += frame->ms;
713  jb->info.frames_out++;
714  jb->info.cnt_contig_interp = 0;
715  decrement_losspct(jb);
716  jb_dbg("v");
717  return JB_OK;
718  } else {
719  /* TODO: after we get the non-silent case down, we'll make the
720  * silent case -- basically, we'll just grow and shrink faster
721  * here, plus handle next_voice_ts a bit differently */
722 
723  /* to disable silent special case altogether, just uncomment this: */
724  /* jb->info.silence_begin_ts = 0; */
725 
726  /* shrink interpl len every 10ms during silence */
727  if (diff < -jb->info.conf.target_extra &&
728  jb->info.last_adjustment + 10 <= now) {
729  jb->info.current -= interpl;
730  jb->info.last_adjustment = now;
731  }
732 
733  frame = queue_get(jb, now - jb->info.current);
734  if (!frame) {
735  return JB_NOFRAME;
736  } else if (frame->type != JB_TYPE_VOICE) {
737  /* normal case; in silent mode, got a non-voice frame */
738  *frameout = *frame;
739  jb->info.frames_out++;
740  return JB_OK;
741  }
742  if (frame->ts < jb->info.silence_begin_ts) {
743  /* voice frame is late */
744  *frameout = *frame;
745  jb->info.frames_out++;
746  decrement_losspct(jb);
747  jb->info.frames_late++;
748  jb->info.frames_lost--;
749  jb_dbg("l");
750  return JB_DROP;
751  } else {
752  /* voice frame */
753  /* try setting current to target right away here */
754  jb->info.current = jb->info.target;
755  jb->info.silence_begin_ts = 0;
756  jb->info.next_voice_ts = frame->ts + jb->info.current + frame->ms;
757  jb->info.last_voice_ms = frame->ms;
758  jb->info.frames_out++;
759  decrement_losspct(jb);
760  *frameout = *frame;
761  jb_dbg("V");
762  return JB_OK;
763  }
764  }
765 }
long max_jitterbuf
Definition: jitterbuf.h:67
static void decrement_losspct(jitterbuf *jb)
Definition: jitterbuf.c:67
enum jb_frame_type type
Definition: jitterbuf.h:103
long silence_begin_ts
Definition: jitterbuf.h:91
#define jb_dbg(...)
Definition: jitterbuf.c:45
#define JB_ADJUST_DELAY
Definition: jitterbuf.h:44
long frames_lost
Definition: jitterbuf.h:80
static long queue_last(jitterbuf *jb)
Definition: jitterbuf.c:406
long last_adjustment
Definition: jitterbuf.h:92
static void increment_losspct(jitterbuf *jb)
Definition: jitterbuf.c:62
long frames_dropped
Definition: jitterbuf.h:81
jb_info info
Definition: jitterbuf.h:108
long last_voice_ms
Definition: jitterbuf.h:90
long target_extra
Definition: jitterbuf.h:70
jb_conf conf
Definition: jitterbuf.h:74
long ts
Definition: jitterbuf.h:101
long target
Definition: jitterbuf.h:87
def info(msg)
static jb_frame * queue_get(jitterbuf *jb, long ts)
Definition: jitterbuf.c:449
long frames_late
Definition: jitterbuf.h:79
long ms
Definition: jitterbuf.h:102
static long queue_next(jitterbuf *jb)
Definition: jitterbuf.c:398
long next_voice_ts
Definition: jitterbuf.h:89
long cnt_contig_interp
Definition: jitterbuf.h:96
long min
Definition: jitterbuf.h:85
long frames_out
Definition: jitterbuf.h:78
long jitter
Definition: jitterbuf.h:84
static void history_get(jitterbuf *jb)
Definition: jitterbuf.c:295
long current
Definition: jitterbuf.h:86
long max_contig_interp
Definition: jitterbuf.h:69

◆ _queue_get()

static jb_frame* _queue_get ( jitterbuf jb,
long  ts,
int  all 
)
static

Definition at line 414 of file jitterbuf.c.

References jitterbuf::frames, jb_info::frames_cur, jitterbuf::free, jitterbuf::info, jb_frame::next, NULL, jb_frame::prev, and jb_frame::ts.

Referenced by queue_get(), and queue_getall().

415 {
416  jb_frame *frame;
417  frame = jb->frames;
418 
419  if (!frame)
420  return NULL;
421 
422  /*jb_warn("queue_get: ASK %ld FIRST %ld\n", ts, frame->ts); */
423 
424  if (all || ts >= frame->ts) {
425  /* remove this frame */
426  frame->prev->next = frame->next;
427  frame->next->prev = frame->prev;
428 
429  if (frame->next == frame)
430  jb->frames = NULL;
431  else
432  jb->frames = frame->next;
433 
434 
435  /* insert onto "free" single-linked list */
436  frame->next = jb->free;
437  jb->free = frame;
438 
439  jb->info.frames_cur--;
440 
441  /* we return the frame pointer, even though it's on free list,
442  * but caller must copy data */
443  return frame;
444  }
445 
446  return NULL;
447 }
jb_frame * frames
Definition: jitterbuf.h:118
#define NULL
Definition: resample.c:96
struct jb_frame * prev
Definition: jitterbuf.h:104
jb_frame * free
Definition: jitterbuf.h:119
jb_info info
Definition: jitterbuf.h:108
long ts
Definition: jitterbuf.h:101
struct jb_frame * next
Definition: jitterbuf.h:104
long frames_cur
Definition: jitterbuf.h:83

◆ check_resync()

static int check_resync ( jitterbuf jb,
long  ts,
long  now,
long  ms,
const enum jb_frame_type  type,
long *  delay 
)
static

Definition at line 116 of file jitterbuf.c.

References ast_debug, jb_info::cnt_delay_discont, jb_info::conf, jitterbuf::dropem, jitterbuf::frames, jb_info::frames_dropped, jitterbuf::hist_maxbuf_valid, jitterbuf::hist_ptr, jitterbuf::info, JB_TYPE_CONTROL, jb_warn, jb_info::jitter, jb_info::last_delay, jb_conf::max_jitterbuf, jb_frame::prev, jb_info::resync_offset, jb_conf::resync_threshold, and jb_frame::ts.

Referenced by jb_put().

117 {
118  long numts = 0;
119  long threshold = 2 * jb->info.jitter + jb->info.conf.resync_threshold;
120 
121  /* Check for overfill of the buffer */
122  if (jb->frames) {
123  numts = jb->frames->prev->ts - jb->frames->ts;
124  }
125 
126  if (numts >= (jb->info.conf.max_jitterbuf)) {
127  if (!jb->dropem) {
128  ast_debug(1, "Attempting to exceed Jitterbuf max %ld timeslots\n",
129  jb->info.conf.max_jitterbuf);
130  jb->dropem = 1;
131  }
132  jb->info.frames_dropped++;
133  return -1;
134  } else {
135  jb->dropem = 0;
136  }
137 
138  /* check for drastic change in delay */
139  if (jb->info.conf.resync_threshold != -1) {
140  if (labs(*delay - jb->info.last_delay) > threshold) {
141  jb->info.cnt_delay_discont++;
142  /* resync the jitterbuffer on 3 consecutive discontinuities,
143  * or immediately if a control frame */
144  if ((jb->info.cnt_delay_discont > 3) || (type == JB_TYPE_CONTROL)) {
145  jb->info.cnt_delay_discont = 0;
146  jb->hist_ptr = 0;
147  jb->hist_maxbuf_valid = 0;
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);
149  jb->info.resync_offset = ts - now;
150  jb->info.last_delay = *delay = 0; /* after resync, frame is right on time */
151  } else {
152  jb->info.frames_dropped++;
153  return -1;
154  }
155  } else {
156  jb->info.last_delay = *delay;
157  jb->info.cnt_delay_discont = 0;
158  }
159  }
160  return 0;
161 }
long max_jitterbuf
Definition: jitterbuf.h:67
static const char type[]
Definition: chan_ooh323.c:109
int hist_maxbuf_valid
Definition: jitterbuf.h:115
jb_frame * frames
Definition: jitterbuf.h:118
long cnt_delay_discont
Definition: jitterbuf.h:94
long last_delay
Definition: jitterbuf.h:93
struct jb_frame * prev
Definition: jitterbuf.h:104
int hist_ptr
Definition: jitterbuf.h:112
threshold
Definition: dsp.h:70
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:444
long resync_threshold
Definition: jitterbuf.h:68
long frames_dropped
Definition: jitterbuf.h:81
jb_info info
Definition: jitterbuf.h:108
jb_conf conf
Definition: jitterbuf.h:74
long ts
Definition: jitterbuf.h:101
unsigned int dropem
Definition: jitterbuf.h:116
long resync_offset
Definition: jitterbuf.h:95
long jitter
Definition: jitterbuf.h:84
#define jb_warn(...)
Definition: jitterbuf.c:43

◆ decrement_losspct()

static void decrement_losspct ( jitterbuf jb)
static

Definition at line 67 of file jitterbuf.c.

References jitterbuf::info, and jb_info::losspct.

Referenced by _jb_get().

68 {
69  jb->info.losspct = (499 * jb->info.losspct)/500;
70 }
long losspct
Definition: jitterbuf.h:88
jb_info info
Definition: jitterbuf.h:108

◆ history_calc_maxbuf()

static void history_calc_maxbuf ( jitterbuf jb)
static

Definition at line 214 of file jitterbuf.c.

References jitterbuf::hist_maxbuf, jitterbuf::hist_maxbuf_valid, jitterbuf::hist_minbuf, jitterbuf::hist_ptr, jitterbuf::history, JB_HISTORY_MAXBUF_SZ, JB_HISTORY_SZ, JB_LONGMAX, and JB_LONGMIN.

Referenced by history_get().

215 {
216  int i,j;
217 
218  if (jb->hist_ptr == 0)
219  return;
220 
221 
222  /* initialize maxbuf/minbuf to the latest value */
223  for (i=0;i<JB_HISTORY_MAXBUF_SZ;i++) {
224 /*
225  * jb->hist_maxbuf[i] = jb->history[(jb->hist_ptr-1) % JB_HISTORY_SZ];
226  * jb->hist_minbuf[i] = jb->history[(jb->hist_ptr-1) % JB_HISTORY_SZ];
227  */
228  jb->hist_maxbuf[i] = JB_LONGMIN;
229  jb->hist_minbuf[i] = JB_LONGMAX;
230  }
231 
232  /* use insertion sort to populate maxbuf */
233  /* we want it to be the top "n" values, in order */
234 
235  /* start at the beginning, or JB_HISTORY_SZ frames ago */
236  i = (jb->hist_ptr > JB_HISTORY_SZ) ? (jb->hist_ptr - JB_HISTORY_SZ) : 0;
237 
238  for (;i<jb->hist_ptr;i++) {
239  long toins = jb->history[i % JB_HISTORY_SZ];
240 
241  /* if the maxbuf should get this */
242  if (toins > jb->hist_maxbuf[JB_HISTORY_MAXBUF_SZ-1]) {
243 
244  /* insertion-sort it into the maxbuf */
245  for (j=0;j<JB_HISTORY_MAXBUF_SZ;j++) {
246  /* found where it fits */
247  if (toins > jb->hist_maxbuf[j]) {
248  /* move over */
249  if (j != JB_HISTORY_MAXBUF_SZ - 1) {
250  memmove(jb->hist_maxbuf + j + 1, jb->hist_maxbuf + j, (JB_HISTORY_MAXBUF_SZ - (j + 1)) * sizeof(jb->hist_maxbuf[0]));
251  }
252  /* insert */
253  jb->hist_maxbuf[j] = toins;
254 
255  break;
256  }
257  }
258  }
259 
260  /* if the minbuf should get this */
261  if (toins < jb->hist_minbuf[JB_HISTORY_MAXBUF_SZ-1]) {
262 
263  /* insertion-sort it into the maxbuf */
264  for (j=0;j<JB_HISTORY_MAXBUF_SZ;j++) {
265  /* found where it fits */
266  if (toins < jb->hist_minbuf[j]) {
267  /* move over */
268  if (j != JB_HISTORY_MAXBUF_SZ - 1) {
269  memmove(jb->hist_minbuf + j + 1, jb->hist_minbuf + j, (JB_HISTORY_MAXBUF_SZ - (j + 1)) * sizeof(jb->hist_minbuf[0]));
270  }
271  /* insert */
272  jb->hist_minbuf[j] = toins;
273 
274  break;
275  }
276  }
277  }
278 
279  if (0) {
280  int k;
281  fprintf(stderr, "toins = %ld\n", toins);
282  fprintf(stderr, "maxbuf =");
283  for (k=0;k<JB_HISTORY_MAXBUF_SZ;k++)
284  fprintf(stderr, "%ld ", jb->hist_maxbuf[k]);
285  fprintf(stderr, "\nminbuf =");
286  for (k=0;k<JB_HISTORY_MAXBUF_SZ;k++)
287  fprintf(stderr, "%ld ", jb->hist_minbuf[k]);
288  fprintf(stderr, "\n");
289  }
290  }
291 
292  jb->hist_maxbuf_valid = 1;
293 }
long hist_minbuf[JB_HISTORY_MAXBUF_SZ]
Definition: jitterbuf.h:114
int hist_maxbuf_valid
Definition: jitterbuf.h:115
#define JB_LONGMAX
Definition: jitterbuf.c:40
int hist_ptr
Definition: jitterbuf.h:112
#define JB_LONGMIN
Definition: jitterbuf.c:41
long hist_maxbuf[JB_HISTORY_MAXBUF_SZ]
Definition: jitterbuf.h:113
#define JB_HISTORY_SZ
Definition: jitterbuf.h:33
#define JB_HISTORY_MAXBUF_SZ
Definition: jitterbuf.h:40
long history[JB_HISTORY_SZ]
Definition: jitterbuf.h:111

◆ history_get()

static void history_get ( jitterbuf jb)
static

Definition at line 295 of file jitterbuf.c.

References jitterbuf::hist_maxbuf, jitterbuf::hist_maxbuf_valid, jitterbuf::hist_minbuf, jitterbuf::hist_ptr, history_calc_maxbuf(), if(), jitterbuf::info, JB_HISTORY_DROPPCT, JB_HISTORY_MAXBUF_SZ, JB_HISTORY_SZ, jb_info::jitter, max, jb_info::min, and min.

Referenced by _jb_get(), jb_getinfo(), and jb_next().

296 {
297  long max, min, jitter;
298  int idx;
299  int count;
300 
301  if (!jb->hist_maxbuf_valid)
303 
304  /* count is how many items in history we're examining */
305  count = (jb->hist_ptr < JB_HISTORY_SZ) ? jb->hist_ptr : JB_HISTORY_SZ;
306 
307  /* idx is the "n"ths highest/lowest that we'll look for */
308  idx = count * JB_HISTORY_DROPPCT / 100;
309 
310  /* sanity checks for idx */
311  if (idx > (JB_HISTORY_MAXBUF_SZ - 1))
312  idx = JB_HISTORY_MAXBUF_SZ - 1;
313 
314  if (idx < 0) {
315  jb->info.min = 0;
316  jb->info.jitter = 0;
317  return;
318  }
319 
320  max = jb->hist_maxbuf[idx];
321  min = jb->hist_minbuf[idx];
322 
323  jitter = max - min;
324 
325  /* these debug stmts compare the difference between looking at the absolute jitter, and the
326  * values we get by throwing away the outliers */
327  /*
328  fprintf(stderr, "[%d] min=%d, max=%d, jitter=%d\n", index, min, max, jitter);
329  fprintf(stderr, "[%d] min=%d, max=%d, jitter=%d\n", 0, jb->hist_minbuf[0], jb->hist_maxbuf[0], jb->hist_maxbuf[0]-jb->hist_minbuf[0]);
330  */
331 
332  jb->info.min = min;
333  jb->info.jitter = jitter;
334 }
long hist_minbuf[JB_HISTORY_MAXBUF_SZ]
Definition: jitterbuf.h:114
#define JB_HISTORY_DROPPCT
Definition: jitterbuf.h:36
int hist_maxbuf_valid
Definition: jitterbuf.h:115
if(!yyg->yy_init)
Definition: ast_expr2f.c:868
int hist_ptr
Definition: jitterbuf.h:112
long hist_maxbuf[JB_HISTORY_MAXBUF_SZ]
Definition: jitterbuf.h:113
#define JB_HISTORY_SZ
Definition: jitterbuf.h:33
#define JB_HISTORY_MAXBUF_SZ
Definition: jitterbuf.h:40
jb_info info
Definition: jitterbuf.h:108
long min
Definition: jitterbuf.h:85
static void history_calc_maxbuf(jitterbuf *jb)
Definition: jitterbuf.c:214
long jitter
Definition: jitterbuf.h:84
#define min(a, b)
Definition: f2c.h:197
#define max(a, b)
Definition: f2c.h:198

◆ history_put()

static int history_put ( jitterbuf jb,
long  ts,
long  now,
long  ms,
long  delay 
)
static

Definition at line 163 of file jitterbuf.c.

References jitterbuf::hist_maxbuf, jitterbuf::hist_maxbuf_valid, jitterbuf::hist_ptr, jitterbuf::history, JB_HISTORY_MAXBUF_SZ, and JB_HISTORY_SZ.

Referenced by jb_put().

164 {
165  long kicked;
166 
167  /* don't add special/negative times to history */
168  if (ts <= 0)
169  return 0;
170 
171  kicked = jb->history[jb->hist_ptr % JB_HISTORY_SZ];
172 
173  jb->history[(jb->hist_ptr++) % JB_HISTORY_SZ] = delay;
174 
175  /* optimization; the max/min buffers don't need to be recalculated, if this packet's
176  * entry doesn't change them. This happens if this packet is not involved, _and_ any packet
177  * that got kicked out of the history is also not involved
178  * We do a number of comparisons, but it's probably still worthwhile, because it will usually
179  * succeed, and should be a lot faster than going through all 500 packets in history */
180  if (!jb->hist_maxbuf_valid)
181  return 0;
182 
183  /* don't do this until we've filled history
184  * (reduces some edge cases below) */
185  if (jb->hist_ptr < JB_HISTORY_SZ)
186  goto invalidate;
187 
188  /* if the new delay would go into min */
189  if (delay < jb->hist_minbuf[JB_HISTORY_MAXBUF_SZ-1])
190  goto invalidate;
191 
192  /* or max.. */
193  if (delay > jb->hist_maxbuf[JB_HISTORY_MAXBUF_SZ-1])
194  goto invalidate;
195 
196  /* or the kicked delay would be in min */
197  if (kicked <= jb->hist_minbuf[JB_HISTORY_MAXBUF_SZ-1])
198  goto invalidate;
199 
200  if (kicked >= jb->hist_maxbuf[JB_HISTORY_MAXBUF_SZ-1])
201  goto invalidate;
202 
203  /* if we got here, we don't need to invalidate, 'cause this delay didn't
204  * affect things */
205  return 0;
206  /* end optimization */
207 
208 
209 invalidate:
210  jb->hist_maxbuf_valid = 0;
211  return 0;
212 }
int hist_maxbuf_valid
Definition: jitterbuf.h:115
int hist_ptr
Definition: jitterbuf.h:112
long hist_maxbuf[JB_HISTORY_MAXBUF_SZ]
Definition: jitterbuf.h:113
#define JB_HISTORY_SZ
Definition: jitterbuf.h:33
#define JB_HISTORY_MAXBUF_SZ
Definition: jitterbuf.h:40
long history[JB_HISTORY_SZ]
Definition: jitterbuf.h:111

◆ increment_losspct()

static void increment_losspct ( jitterbuf jb)
static

Definition at line 62 of file jitterbuf.c.

References jitterbuf::info, and jb_info::losspct.

Referenced by _jb_get().

63 {
64  jb->info.losspct = (100000 + 499 * jb->info.losspct)/500;
65 }
long losspct
Definition: jitterbuf.h:88
jb_info info
Definition: jitterbuf.h:108

◆ jb_destroy()

void jb_destroy ( jitterbuf jb)

destroy jitterbuf

Definition at line 99 of file jitterbuf.c.

References ast_free, jitterbuf::free, jb_dbg2, jb_frame::next, and NULL.

Referenced by AST_TEST_DEFINE(), jb_destroy_adaptive(), and pvt_destructor().

100 {
101  jb_frame *frame;
102  jb_dbg2("jb_destroy(%x)\n", jb);
103 
104  /* free all the frames on the "free list" */
105  frame = jb->free;
106  while (frame != NULL) {
107  jb_frame *next = frame->next;
108  ast_free(frame);
109  frame = next;
110  }
111 
112  /* free ourselves! */
113  ast_free(jb);
114 }
#define jb_dbg2(...)
Definition: jitterbuf.c:50
#define NULL
Definition: resample.c:96
jb_frame * free
Definition: jitterbuf.h:119
#define ast_free(a)
Definition: astmm.h:182
struct misdn_stack * next
Next stack in the list of stacks.
struct jb_frame * next
Definition: jitterbuf.h:104

◆ jb_get()

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: Here's an audio frame you should just drop. Ask me again for this time.. JB_NOFRAME: There's no frame scheduled for this time. JB_INTERP: Please interpolate an interpl-length frame for this time (either we need to grow, or there was a lost frame) JB_EMPTY: The jb is empty.

Definition at line 785 of file jitterbuf.c.

References _jb_get(), jitterbuf::info, JB_DROP, JB_INTERP, JB_OK, jb_warn, jb_info::last_voice_ms, jb_frame::ms, and jb_frame::ts.

Referenced by __get_from_jb(), AST_TEST_DEFINE(), and jb_get_adaptive().

786 {
787  enum jb_return_code ret = _jb_get(jb, frameout, now, interpl);
788 #if 0
789  static int lastts=0;
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");
793  lastts = thists;
794 #endif
795  if (ret == JB_INTERP)
796  frameout->ms = jb->info.last_voice_ms;
797 
798  return ret;
799 }
jb_return_code
Definition: jitterbuf.h:47
jb_info info
Definition: jitterbuf.h:108
long last_voice_ms
Definition: jitterbuf.h:90
long ts
Definition: jitterbuf.h:101
long ms
Definition: jitterbuf.h:102
static enum jb_return_code _jb_get(jitterbuf *jb, jb_frame *frameout, long now, long interpl)
Definition: jitterbuf.c:550
#define jb_warn(...)
Definition: jitterbuf.c:43

◆ jb_getall()

enum jb_return_code jb_getall ( jitterbuf jb,
jb_frame frameout 
)

unconditionally get frames from jitterbuf until empty

Definition at line 801 of file jitterbuf.c.

References JB_NOFRAME, JB_OK, and queue_getall().

Referenced by AST_TEST_DEFINE(), complete_transfer(), jb_empty_and_reset_adaptive(), jb_remove_adaptive(), and pvt_destructor().

802 {
803  jb_frame *frame;
804  frame = queue_getall(jb);
805 
806  if (!frame) {
807  return JB_NOFRAME;
808  }
809 
810  *frameout = *frame;
811  return JB_OK;
812 }
static jb_frame * queue_getall(jitterbuf *jb)
Definition: jitterbuf.c:454

◆ jb_getinfo()

enum jb_return_code jb_getinfo ( jitterbuf jb,
jb_info stats 
)

get jitterbuf info: only "statistics" may be valid

Definition at line 815 of file jitterbuf.c.

References history_get(), jitterbuf::info, and JB_OK.

Referenced by ast_cli_netstats(), AST_TEST_DEFINE(), construct_rr(), handle_cli_iax2_show_channels(), and log_jitterstats().

816 {
817 
818  history_get(jb);
819 
820  *stats = jb->info;
821 
822  return JB_OK;
823 }
jb_info info
Definition: jitterbuf.h:108
static void history_get(jitterbuf *jb)
Definition: jitterbuf.c:295

◆ jb_is_late()

int jb_is_late ( jitterbuf jb,
long  ts 
)

Checks if the given time stamp is late.

Definition at line 846 of file jitterbuf.c.

References jb_info::current, jitterbuf::info, and jb_info::next_voice_ts.

Referenced by jb_is_late_adaptive().

847 {
848  return ts + jb->info.current < jb->info.next_voice_ts;
849 }
jb_info info
Definition: jitterbuf.h:108
long next_voice_ts
Definition: jitterbuf.h:89
long current
Definition: jitterbuf.h:86

◆ jb_new()

jitterbuf* jb_new ( void  )

new jitterbuf

Definition at line 86 of file jitterbuf.c.

References ast_calloc, jb_dbg2, jb_reset(), and NULL.

Referenced by AST_TEST_DEFINE(), jb_create_adaptive(), and new_iax().

87 {
88  jitterbuf *jb;
89 
90  if (!(jb = ast_calloc(1, sizeof(*jb))))
91  return NULL;
92 
93  jb_reset(jb);
94 
95  jb_dbg2("jb_new() = %x\n", jb);
96  return jb;
97 }
#define jb_dbg2(...)
Definition: jitterbuf.c:50
#define NULL
Definition: resample.c:96
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
void jb_reset(jitterbuf *jb)
reset jitterbuf
Definition: jitterbuf.c:72

◆ jb_next()

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 added (esp non-audio frames)

Definition at line 767 of file jitterbuf.c.

References jb_info::conf, jb_info::current, jitterbuf::frames, history_get(), jitterbuf::info, JB_LONGMAX, jb_info::last_adjustment, jb_info::next_voice_ts, queue_next(), jb_info::silence_begin_ts, jb_info::target, and jb_conf::target_extra.

Referenced by __get_from_jb(), AST_TEST_DEFINE(), jb_next_adaptive(), and update_jbsched().

768 {
769  if (jb->info.silence_begin_ts) {
770  if (jb->frames) {
771  long next = queue_next(jb);
772  history_get(jb);
773  /* shrink during silence */
774  if (jb->info.target - jb->info.current < -jb->info.conf.target_extra)
775  return jb->info.last_adjustment + 10;
776  return next + jb->info.target;
777  }
778  else
779  return JB_LONGMAX;
780  } else {
781  return jb->info.next_voice_ts;
782  }
783 }
long silence_begin_ts
Definition: jitterbuf.h:91
jb_frame * frames
Definition: jitterbuf.h:118
#define JB_LONGMAX
Definition: jitterbuf.c:40
long last_adjustment
Definition: jitterbuf.h:92
jb_info info
Definition: jitterbuf.h:108
long target_extra
Definition: jitterbuf.h:70
jb_conf conf
Definition: jitterbuf.h:74
long target
Definition: jitterbuf.h:87
struct misdn_stack * next
Next stack in the list of stacks.
static long queue_next(jitterbuf *jb)
Definition: jitterbuf.c:398
long next_voice_ts
Definition: jitterbuf.h:89
static void history_get(jitterbuf *jb)
Definition: jitterbuf.c:295
long current
Definition: jitterbuf.h:86

◆ jb_put()

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

data=frame data, timings (in ms): ms=length of frame (for voice), ts=ts (sender'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

Definition at line 525 of file jitterbuf.c.

References check_resync(), jb_info::frames_in, history_put(), jitterbuf::info, jb_dbg2, JB_DROP, JB_OK, JB_SCHED, JB_TYPE_VOICE, queue_put(), and jb_info::resync_offset.

Referenced by jb_put_adaptive(), schedule_delivery(), test_jb_late_frame_insertion(), test_jb_lost_frame_insertion(), test_jb_nominal_frame_insertion(), test_jb_out_of_order_frame_insertion(), test_jb_overflow_frame_insertion(), and test_jb_resynch_frame_insertion().

526 {
527  long delay = now - (ts - jb->info.resync_offset);
528  jb_dbg2("jb_put(%x,%x,%ld,%ld,%ld)\n", jb, data, ms, ts, now);
529 
530  if (check_resync(jb, ts, now, ms, type, &delay)) {
531  return JB_DROP;
532  }
533 
534  if (type == JB_TYPE_VOICE) {
535  /* presently, I'm only adding VOICE frames to history and drift calculations; mostly because with the
536  * IAX integrations, I'm sending retransmitted control frames with their awkward timestamps through */
537  history_put(jb, ts, now, ms, delay);
538  }
539 
540  jb->info.frames_in++;
541 
542  /* if put into head of queue, caller needs to reschedule */
543  if (queue_put(jb,data,type,ms,ts)) {
544  return JB_SCHED;
545  }
546  return JB_OK;
547 }
static const char type[]
Definition: chan_ooh323.c:109
#define jb_dbg2(...)
Definition: jitterbuf.c:50
long frames_in
Definition: jitterbuf.h:77
static int history_put(jitterbuf *jb, long ts, long now, long ms, long delay)
Definition: jitterbuf.c:163
static int queue_put(jitterbuf *jb, void *data, const enum jb_frame_type type, long ms, long ts)
Definition: jitterbuf.c:337
jb_info info
Definition: jitterbuf.h:108
long resync_offset
Definition: jitterbuf.h:95
static int check_resync(jitterbuf *jb, long ts, long now, long ms, const enum jb_frame_type type, long *delay)
Definition: jitterbuf.c:116

◆ jb_reset()

void jb_reset ( jitterbuf jb)

reset jitterbuf

Note
The jitterbuffer should be empty before you call this, otherwise you will leak queued frames, and some internal structures

Definition at line 72 of file jitterbuf.c.

References jb_info::conf, jb_info::current, jitterbuf::free, jitterbuf::info, JB_TARGET_EXTRA, jb_info::silence_begin_ts, jb_info::target, and jb_conf::target_extra.

Referenced by complete_transfer(), jb_empty_and_reset_adaptive(), and jb_new().

73 {
74  /* only save settings and free list */
75  jb_conf s = jb->info.conf;
76  jb_frame *fr = jb->free;
77  memset(jb, 0, sizeof(*jb));
78  jb->info.conf = s;
79  jb->free = fr;
80 
81  /* initialize length, using the default value */
83  jb->info.silence_begin_ts = -1;
84 }
#define JB_TARGET_EXTRA
Definition: jitterbuf.h:42
long silence_begin_ts
Definition: jitterbuf.h:91
jb_frame * free
Definition: jitterbuf.h:119
jb_info info
Definition: jitterbuf.h:108
long target_extra
Definition: jitterbuf.h:70
jb_conf conf
Definition: jitterbuf.h:74
long target
Definition: jitterbuf.h:87
long current
Definition: jitterbuf.h:86

◆ jb_setconf()

enum jb_return_code jb_setconf ( jitterbuf jb,
jb_conf conf 
)

set jitterbuf conf

Definition at line 825 of file jitterbuf.c.

References jb_info::conf, jb_info::current, jitterbuf::info, JB_OK, JB_TARGET_EXTRA, jb_conf::max_contig_interp, jb_conf::max_jitterbuf, jb_conf::resync_threshold, jb_info::target, and jb_conf::target_extra.

Referenced by AST_TEST_DEFINE(), jb_create_adaptive(), and new_iax().

826 {
827  /* take selected settings from the struct */
828 
829  jb->info.conf.max_jitterbuf = conf->max_jitterbuf;
832 
833  /* -1 indicates use of the default JB_TARGET_EXTRA value */
834  jb->info.conf.target_extra = ( conf->target_extra == -1 )
836  : conf->target_extra
837  ;
838 
839  /* update these to match new target_extra setting */
840  jb->info.current = jb->info.conf.target_extra;
841  jb->info.target = jb->info.conf.target_extra;
842 
843  return JB_OK;
844 }
long max_jitterbuf
Definition: jitterbuf.h:67
#define JB_TARGET_EXTRA
Definition: jitterbuf.h:42
long resync_threshold
Definition: jitterbuf.h:68
jb_info info
Definition: jitterbuf.h:108
long target_extra
Definition: jitterbuf.h:70
jb_conf conf
Definition: jitterbuf.h:74
long target
Definition: jitterbuf.h:87
long current
Definition: jitterbuf.h:86
long max_contig_interp
Definition: jitterbuf.h:69

◆ jb_setoutput()

void jb_setoutput ( jb_output_function_t  err,
jb_output_function_t  warn,
jb_output_function_t  dbg 
)

Definition at line 55 of file jitterbuf.c.

References dbgf, errf, and warnf.

Referenced by handle_cli_iax2_set_debug_jb(), and load_module().

56 {
57  errf = err;
58  warnf = warn;
59  dbgf = dbg;
60 }
static jb_output_function_t dbgf
Definition: jitterbuf.c:53
static jb_output_function_t warnf
Definition: jitterbuf.c:53
static jb_output_function_t errf
Definition: jitterbuf.c:53

◆ queue_get()

static jb_frame* queue_get ( jitterbuf jb,
long  ts 
)
static

Definition at line 449 of file jitterbuf.c.

References _queue_get().

Referenced by _jb_get().

450 {
451  return _queue_get(jb,ts,0);
452 }
static jb_frame * _queue_get(jitterbuf *jb, long ts, int all)
Definition: jitterbuf.c:414

◆ queue_getall()

static jb_frame* queue_getall ( jitterbuf jb)
static

◆ queue_last()

static long queue_last ( jitterbuf jb)
static

Definition at line 406 of file jitterbuf.c.

References jitterbuf::frames, jb_frame::prev, and jb_frame::ts.

Referenced by _jb_get(), and queue_getall().

407 {
408  if (jb->frames)
409  return jb->frames->prev->ts;
410  else
411  return -1;
412 }
jb_frame * frames
Definition: jitterbuf.h:118
struct jb_frame * prev
Definition: jitterbuf.h:104
long ts
Definition: jitterbuf.h:101

◆ queue_next()

static long queue_next ( jitterbuf jb)
static

Definition at line 398 of file jitterbuf.c.

References jitterbuf::frames, and jb_frame::ts.

Referenced by _jb_get(), jb_next(), and queue_getall().

399 {
400  if (jb->frames)
401  return jb->frames->ts;
402  else
403  return -1;
404 }
jb_frame * frames
Definition: jitterbuf.h:118
long ts
Definition: jitterbuf.h:101

◆ queue_put()

static int queue_put ( jitterbuf jb,
void *  data,
const enum jb_frame_type  type,
long  ms,
long  ts 
)
static

Definition at line 337 of file jitterbuf.c.

References ast_malloc, jb_frame::data, frames, jitterbuf::frames, jb_info::frames_cur, jb_info::frames_ooo, jitterbuf::free, jitterbuf::info, jb_err, jb_frame::ms, jb_frame::next, jb_frame::prev, jb_info::resync_offset, jb_frame::ts, jb_frame::type, and type.

Referenced by jb_put().

338 {
339  jb_frame *frame;
340  jb_frame *p;
341  int head = 0;
342  long resync_ts = ts - jb->info.resync_offset;
343 
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");
348  return 0;
349  }
350 
351  jb->info.frames_cur++;
352 
353  frame->data = data;
354  frame->ts = resync_ts;
355  frame->ms = ms;
356  frame->type = type;
357 
358  /*
359  * frames are a circular list, jb-frames points to the lowest ts,
360  * jb->frames->prev points to the highest ts
361  */
362 
363  if (!jb->frames) { /* queue is empty */
364  jb->frames = frame;
365  frame->next = frame;
366  frame->prev = frame;
367  head = 1;
368  } else if (resync_ts < jb->frames->ts) {
369  frame->next = jb->frames;
370  frame->prev = jb->frames->prev;
371 
372  frame->next->prev = frame;
373  frame->prev->next = frame;
374 
375  /* frame is out of order */
376  jb->info.frames_ooo++;
377 
378  jb->frames = frame;
379  head = 1;
380  } else {
381  p = jb->frames;
382 
383  /* frame is out of order */
384  if (resync_ts < p->prev->ts) jb->info.frames_ooo++;
385 
386  while (resync_ts < p->prev->ts && p->prev != jb->frames)
387  p = p->prev;
388 
389  frame->next = p;
390  frame->prev = p->prev;
391 
392  frame->next->prev = frame;
393  frame->prev->next = frame;
394  }
395  return head;
396 }
static const char type[]
Definition: chan_ooh323.c:109
enum jb_frame_type type
Definition: jitterbuf.h:103
jb_frame * frames
Definition: jitterbuf.h:118
struct jb_frame * prev
Definition: jitterbuf.h:104
jb_frame * free
Definition: jitterbuf.h:119
long frames_ooo
Definition: jitterbuf.h:82
static int frames
Definition: parser.c:51
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:193
jb_info info
Definition: jitterbuf.h:108
long ts
Definition: jitterbuf.h:101
void * data
Definition: jitterbuf.h:100
long ms
Definition: jitterbuf.h:102
#define jb_err(...)
Definition: jitterbuf.c:44
long resync_offset
Definition: jitterbuf.h:95
struct jb_frame * next
Definition: jitterbuf.h:104
long frames_cur
Definition: jitterbuf.h:83

Variable Documentation

◆ dbgf

jb_output_function_t dbgf
static

Definition at line 53 of file jitterbuf.c.

Referenced by jb_setoutput(), and queue_getall().

◆ errf

jb_output_function_t errf
static

Definition at line 53 of file jitterbuf.c.

Referenced by jb_setoutput().

◆ warnf

jb_output_function_t warnf
static

Definition at line 53 of file jitterbuf.c.

Referenced by jb_setoutput().