23
23
/* configuration constants */
24
24
/* Number of historical timestamps to use in calculating jitter and drift */
25
#define JB_HISTORY_SZ 500
25
#define JB_HISTORY_SZ 500
26
26
/* what percentage of timestamps should we drop from the history when we examine it;
27
27
* this might eventually be something made configurable */
28
28
#define JB_HISTORY_DROPPCT 3
29
29
/* the maximum droppct we can handle (say it was configurable). */
30
30
#define JB_HISTORY_DROPPCT_MAX 4
31
31
/* the size of the buffer we use to keep the top and botton timestamps for dropping */
32
#define JB_HISTORY_MAXBUF_SZ JB_HISTORY_SZ * JB_HISTORY_DROPPCT_MAX / 100
32
#define JB_HISTORY_MAXBUF_SZ JB_HISTORY_SZ * JB_HISTORY_DROPPCT_MAX / 100
33
33
/* amount of additional jitterbuffer adjustment */
34
34
#define JB_TARGET_EXTRA 40
35
35
/* ms between growing and shrinking; may not be honored if jitterbuffer runs out of space */
36
36
#define JB_ADJUST_DELAY 40
48
#define JB_TYPE_CONTROL 0
49
#define JB_TYPE_VOICE 1
50
#define JB_TYPE_VIDEO 2 /* reserved */
51
#define JB_TYPE_SILENCE 3
50
JB_TYPE_CONTROL, /* 0 */
51
JB_TYPE_VOICE, /* 1 */
52
JB_TYPE_VIDEO, /* 2 - reserved */
53
JB_TYPE_SILENCE /* 3 */
54
56
typedef struct jb_conf {
56
long max_jitterbuf; /* defines a hard clamp to use in setting the jitter buffer delay */
57
long resync_threshold; /* the jb will resync when delay increases to (2 * jitter) + this param */
58
long max_jitterbuf; /* defines a hard clamp to use in setting the jitter buffer delay */
59
long resync_threshold; /* the jb will resync when delay increases to (2 * jitter) + this param */
58
60
long max_contig_interp; /* the max interp frames to return in a row */
61
long target_extra; /* amount of additional jitterbuffer adjustment, overrides JB_TARGET_EXTRA */
61
64
typedef struct jb_info {
65
long frames_in; /* number of frames input to the jitterbuffer.*/
66
long frames_out; /* number of frames output from the jitterbuffer.*/
67
long frames_late; /* number of frames which were too late, and dropped.*/
68
long frames_lost; /* number of missing frames.*/
69
long frames_dropped; /* number of frames dropped (shrinkage) */
70
long frames_ooo; /* number of frames received out-of-order */
71
long frames_cur; /* number of frames presently in jb, awaiting delivery.*/
72
long jitter; /* jitter measured within current history interval*/
68
long frames_in; /* number of frames input to the jitterbuffer.*/
69
long frames_out; /* number of frames output from the jitterbuffer.*/
70
long frames_late; /* number of frames which were too late, and dropped.*/
71
long frames_lost; /* number of missing frames.*/
72
long frames_dropped; /* number of frames dropped (shrinkage) */
73
long frames_ooo; /* number of frames received out-of-order */
74
long frames_cur; /* number of frames presently in jb, awaiting delivery.*/
75
long jitter; /* jitter measured within current history interval*/
73
76
long min; /* minimum lateness within current history interval */
74
long current; /* the present jitterbuffer adjustment */
75
long target; /* the target jitterbuffer adjustment */
76
long losspct; /* recent lost frame percentage (* 1000) */
77
long current; /* the present jitterbuffer adjustment */
78
long target; /* the target jitterbuffer adjustment */
79
long losspct; /* recent lost frame percentage (* 1000) */
77
80
long next_voice_ts; /* the ts of the next frame to be read from the jb - in receiver's time */
78
81
long last_voice_ms; /* the duration of the last voice frame */
79
82
long silence_begin_ts; /* the time of the last CNG frame, when in silence */
80
long last_adjustment; /* the time of the last adjustment */
81
long last_delay; /* the last now added to history */
83
long last_adjustment; /* the time of the last adjustment */
84
long last_delay; /* the last now added to history */
82
85
long cnt_delay_discont; /* the count of discontinuous delays */
83
long resync_offset; /* the amount to offset ts to support resyncs */
84
long cnt_contig_interp; /* the number of contiguous interp frames returned */
86
long resync_offset; /* the amount to offset ts to support resyncs */
87
long cnt_contig_interp; /* the number of contiguous interp frames returned */
87
90
typedef struct jb_frame {
88
void *data; /* the frame data */
89
long ts; /* the relative delivery time expected */
90
long ms; /* the time covered by this frame, in sec/8000 */
91
int type; /* the type of frame */
91
void *data; /* the frame data */
92
long ts; /* the relative delivery time expected */
93
long ms; /* the time covered by this frame, in sec/8000 */
94
enum jb_frame_type type; /* the type of frame */
92
95
struct jb_frame *next, *prev;
99
long history[JB_HISTORY_SZ]; /* history */
102
long history[JB_HISTORY_SZ]; /* history */
100
103
int hist_ptr; /* points to index in history for next entry */
101
104
long hist_maxbuf[JB_HISTORY_MAXBUF_SZ]; /* a sorted buffer of the max delays (highest first) */
102
105
long hist_minbuf[JB_HISTORY_MAXBUF_SZ]; /* a sorted buffer of the min delays (lowest first) */
103
106
int hist_maxbuf_valid; /* are the "maxbuf"/minbuf valid? */
106
jb_frame *frames; /* queued frames */
107
jb_frame *free; /* free frames (avoid malloc?) */
108
jb_frame *frames; /* queued frames */
109
jb_frame *free; /* free frames (avoid malloc?) */
111
113
/* new jitterbuf */
112
extern jitterbuf * jb_new(void);
114
jitterbuf * jb_new(void);
114
116
/* destroy jitterbuf */
115
extern void jb_destroy(jitterbuf *jb);
117
void jb_destroy(jitterbuf *jb);
117
119
/* reset jitterbuf */
118
120
/* NOTE: The jitterbuffer should be empty before you call this, otherwise
119
121
* you will leak queued frames, and some internal structures */
120
extern void jb_reset(jitterbuf *jb);
122
void jb_reset(jitterbuf *jb);
122
/* queue a frame data=frame data, timings (in ms): ms=length of frame (for voice), ts=ts (sender's time)
123
* now=now (in receiver's time) return value is one of
124
/* queue a frame data=frame data, timings (in ms): ms=length of frame (for voice), ts=ts (sender's time)
125
* now=now (in receiver's time) return value is one of
124
126
* JB_OK: Frame added. Last call to jb_next() still valid
125
127
* JB_DROP: Drop this frame immediately
126
128
* JB_SCHED: Frame added. Call jb_next() to get a new time for the next frame
128
extern int jb_put(jitterbuf *jb, void *data, int type, long ms, long ts, long now);
130
enum jb_return_code jb_put(jitterbuf *jb, void *data, const enum jb_frame_type type, long ms, long ts, long now);
130
132
/* get a frame for time now (receiver's time) return value is one of
131
133
* JB_OK: You've got frame!
132
134
* JB_DROP: Here's an audio frame you should just drop. Ask me again for this time..
133
135
* JB_NOFRAME: There's no frame scheduled for this time.
134
* JB_INTERP: Please interpolate an interpl-length frame for this time (either we need to grow, or there was a lost frame)
136
* JB_INTERP: Please interpolate an interpl-length frame for this time (either we need to grow, or there was a lost frame)
135
137
* JB_EMPTY: The jb is empty.
137
extern int jb_get(jitterbuf *jb, jb_frame *frame, long now, long interpl);
139
enum jb_return_code jb_get(jitterbuf *jb, jb_frame *frame, long now, long interpl);
139
141
/* unconditionally get frames from jitterbuf until empty */
140
extern int jb_getall(jitterbuf *jb, jb_frame *frameout);
142
enum jb_return_code jb_getall(jitterbuf *jb, jb_frame *frameout);
142
/* when is the next frame due out, in receiver's time (0=EMPTY)
144
/* when is the next frame due out, in receiver's time (0=EMPTY)
143
145
* This value may change as frames are added (esp non-audio frames) */
144
extern long jb_next(jitterbuf *jb);
146
long jb_next(jitterbuf *jb);
146
148
/* get jitterbuf info: only "statistics" may be valid */
147
extern int jb_getinfo(jitterbuf *jb, jb_info *stats);
149
enum jb_return_code jb_getinfo(jitterbuf *jb, jb_info *stats);
149
151
/* set jitterbuf conf */
150
extern int jb_setconf(jitterbuf *jb, jb_conf *conf);
152
enum jb_return_code jb_setconf(jitterbuf *jb, jb_conf *conf);
152
typedef void (*jb_output_function_t)(const char *fmt, ...);
153
extern void jb_setoutput(jb_output_function_t err, jb_output_function_t warn, jb_output_function_t dbg);
154
typedef void (*jb_output_function_t)(const char *fmt, ...);
155
extern void jb_setoutput(jb_output_function_t err, jb_output_function_t warn, jb_output_function_t dbg);
155
157
#ifdef __cplusplus