2 * jitterbuf: an application-independent jitterbuffer
5 * Copyright (C) 2004-2005, Horizon Wimba, Inc.
8 * Steve Kann <stevek@stevek.com>
10 * This program is free software, distributed under the terms of
11 * the GNU Lesser (Library) General Public License
13 * Copyright on this file is disclaimed to Digium for inclusion in Asterisk
18 * jitterbuf: an application-independent jitterbuffer
30 /*! \name configuration constants */
32 /*! Number of historical timestamps to use in calculating jitter and drift */
33 #define JB_HISTORY_SZ 500
34 /*! what percentage of timestamps should we drop from the history when we examine it;
35 * this might eventually be something made configurable */
36 #define JB_HISTORY_DROPPCT 3
37 /*! the maximum droppct we can handle (say it was configurable). */
38 #define JB_HISTORY_DROPPCT_MAX 4
39 /*! the size of the buffer we use to keep the top and botton timestamps for dropping */
40 #define JB_HISTORY_MAXBUF_SZ JB_HISTORY_SZ * JB_HISTORY_DROPPCT_MAX / 100
41 /*! amount of additional jitterbuffer adjustment */
42 #define JB_TARGET_EXTRA 40
43 /*! ms between growing and shrinking; may not be honored if jitterbuffer runs out of space */
44 #define JB_ADJUST_DELAY 40
59 JB_TYPE_CONTROL
, /*!< 0 */
60 JB_TYPE_VOICE
, /*!< 1 */
61 JB_TYPE_VIDEO
, /*!< 2 - reserved */
62 JB_TYPE_SILENCE
/*!< 3 */
65 typedef struct jb_conf
{
67 long max_jitterbuf
; /*!< defines a hard clamp to use in setting the jitter buffer delay */
68 long resync_threshold
; /*!< the jb will resync when delay increases to (2 * jitter) + this param */
69 long max_contig_interp
; /*!< the max interp frames to return in a row */
70 long target_extra
; /*!< amount of additional jitterbuffer adjustment, overrides JB_TARGET_EXTRA */
73 typedef struct jb_info
{
77 long frames_in
; /*!< number of frames input to the jitterbuffer.*/
78 long frames_out
; /*!< number of frames output from the jitterbuffer.*/
79 long frames_late
; /*!< number of frames which were too late, and dropped.*/
80 long frames_lost
; /*!< number of missing frames.*/
81 long frames_dropped
; /*!< number of frames dropped (shrinkage) */
82 long frames_ooo
; /*!< number of frames received out-of-order */
83 long frames_cur
; /*!< number of frames presently in jb, awaiting delivery.*/
84 long jitter
; /*!< jitter measured within current history interval*/
85 long min
; /*!< minimum lateness within current history interval */
86 long current
; /*!< the present jitterbuffer adjustment */
87 long target
; /*!< the target jitterbuffer adjustment */
88 long losspct
; /*!< recent lost frame percentage (* 1000) */
89 long next_voice_ts
; /*!< the ts of the next frame to be read from the jb - in receiver's time */
90 long last_voice_ms
; /*!< the duration of the last voice frame */
91 long silence_begin_ts
; /*!< the time of the last CNG frame, when in silence */
92 long last_adjustment
; /*!< the time of the last adjustment */
93 long last_delay
; /*!< the last now added to history */
94 long cnt_delay_discont
; /*!< the count of discontinuous delays */
95 long resync_offset
; /*!< the amount to offset ts to support resyncs */
96 long cnt_contig_interp
; /*!< the number of contiguous interp frames returned */
99 typedef struct jb_frame
{
100 void *data
; /* the frame data */
101 long ts
; /* the relative delivery time expected */
102 long ms
; /* the time covered by this frame, in sec/8000 */
103 enum jb_frame_type type
; /* the type of frame */
104 struct jb_frame
*next
, *prev
;
107 typedef struct jitterbuf
{
111 long history
[JB_HISTORY_SZ
]; /*!< history */
112 int hist_ptr
; /*!< points to index in history for next entry */
113 long hist_maxbuf
[JB_HISTORY_MAXBUF_SZ
]; /*!< a sorted buffer of the max delays (highest first) */
114 long hist_minbuf
[JB_HISTORY_MAXBUF_SZ
]; /*!< a sorted buffer of the min delays (lowest first) */
115 int hist_maxbuf_valid
; /*!< are the "maxbuf"/minbuf valid? */
116 unsigned int dropem
:1; /*!< flag to indicate dropping frames (overload) */
118 jb_frame
*frames
; /*!< queued frames */
119 jb_frame
*free
; /*!< free frames (avoid malloc?) */
123 /*! \brief new jitterbuf */
124 jitterbuf
* jb_new(void);
126 /*! \brief destroy jitterbuf */
127 void jb_destroy(jitterbuf
*jb
);
129 /*! \brief reset jitterbuf
130 * \note The jitterbuffer should be empty before you call this, otherwise
131 * you will leak queued frames, and some internal structures */
132 void jb_reset(jitterbuf
*jb
);
134 /*!\brief queue a frame
136 * data=frame data, timings (in ms): ms=length of frame (for voice), ts=ts (sender's time)
137 * now=now (in receiver's time) return value is one of
138 * JB_OK: Frame added. Last call to jb_next() still valid
139 * JB_DROP: Drop this frame immediately
140 * JB_SCHED: Frame added. Call jb_next() to get a new time for the next frame
142 enum jb_return_code
jb_put(jitterbuf
*jb
, void *data
, const enum jb_frame_type type
, long ms
, long ts
, long now
);
144 /*! \brief get a frame for time now (receiver's time) return value is one of
145 * JB_OK: You've got frame!
146 * JB_DROP: Here's an audio frame you should just drop. Ask me again for this time..
147 * JB_NOFRAME: There's no frame scheduled for this time.
148 * JB_INTERP: Please interpolate an interpl-length frame for this time (either we need to grow, or there was a lost frame)
149 * JB_EMPTY: The jb is empty.
151 enum jb_return_code
jb_get(jitterbuf
*jb
, jb_frame
*frame
, long now
, long interpl
);
153 /*! \brief unconditionally get frames from jitterbuf until empty */
154 enum jb_return_code
jb_getall(jitterbuf
*jb
, jb_frame
*frameout
);
156 /*! \brief when is the next frame due out, in receiver's time (0=EMPTY)
157 * This value may change as frames are added (esp non-audio frames) */
158 long jb_next(jitterbuf
*jb
);
160 /*! \brief get jitterbuf info: only "statistics" may be valid */
161 enum jb_return_code
jb_getinfo(jitterbuf
*jb
, jb_info
*stats
);
163 /*! \brief set jitterbuf conf */
164 enum jb_return_code
jb_setconf(jitterbuf
*jb
, jb_conf
*conf
);
166 typedef void __attribute__((format (printf
, 1, 2))) (*jb_output_function_t
)(const char *fmt
, ...);
167 void jb_setoutput(jb_output_function_t err
, jb_output_function_t warn
, jb_output_function_t dbg
);