00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include "asterisk.h"
00033
00034 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 369001 $")
00035
00036 #include <assert.h>
00037
00038 #include "asterisk/utils.h"
00039 #include "fixedjitterbuf.h"
00040
00041 #undef FIXED_JB_DEBUG
00042
00043 #ifdef FIXED_JB_DEBUG
00044 #define ASSERT(a)
00045 #else
00046 #define ASSERT(a) assert(a)
00047 #endif
00048
00049
00050 struct fixed_jb
00051 {
00052 struct fixed_jb_frame *frames;
00053 struct fixed_jb_frame *tail;
00054 struct fixed_jb_conf conf;
00055 long rxcore;
00056 long delay;
00057 long next_delivery;
00058 int force_resynch;
00059 };
00060
00061
00062 static struct fixed_jb_frame *alloc_jb_frame(struct fixed_jb *jb);
00063 static void release_jb_frame(struct fixed_jb *jb, struct fixed_jb_frame *frame);
00064 static void get_jb_head(struct fixed_jb *jb, struct fixed_jb_frame *frame);
00065 static int resynch_jb(struct fixed_jb *jb, void *data, long ms, long ts, long now);
00066
00067 static inline struct fixed_jb_frame *alloc_jb_frame(struct fixed_jb *jb)
00068 {
00069 return ast_calloc(1, sizeof(*jb));
00070 }
00071
00072 static inline void release_jb_frame(struct fixed_jb *jb, struct fixed_jb_frame *frame)
00073 {
00074 ast_free(frame);
00075 }
00076
00077 static void get_jb_head(struct fixed_jb *jb, struct fixed_jb_frame *frame)
00078 {
00079 struct fixed_jb_frame *fr;
00080
00081
00082 fr = jb->frames;
00083 jb->frames = fr->next;
00084 if (jb->frames) {
00085 jb->frames->prev = NULL;
00086 } else {
00087
00088 jb->tail = NULL;
00089 }
00090
00091
00092 jb->next_delivery = fr->delivery + fr->ms;
00093
00094
00095 memcpy(frame, fr, sizeof(struct fixed_jb_frame));
00096
00097
00098 release_jb_frame(jb, fr);
00099 }
00100
00101
00102 struct fixed_jb *fixed_jb_new(struct fixed_jb_conf *conf)
00103 {
00104 struct fixed_jb *jb;
00105
00106 if (!(jb = ast_calloc(1, sizeof(*jb))))
00107 return NULL;
00108
00109
00110 memcpy(&jb->conf, conf, sizeof(struct fixed_jb_conf));
00111
00112
00113 conf = &jb->conf;
00114
00115
00116 if (conf->jbsize < 1)
00117 conf->jbsize = FIXED_JB_SIZE_DEFAULT;
00118
00119 if (conf->resync_threshold < 1)
00120 conf->resync_threshold = FIXED_JB_RESYNCH_THRESHOLD_DEFAULT;
00121
00122
00123 jb->delay = conf->jbsize;
00124
00125 return jb;
00126 }
00127
00128
00129 void fixed_jb_destroy(struct fixed_jb *jb)
00130 {
00131
00132 ASSERT(jb->frames == NULL);
00133
00134 ast_free(jb);
00135 }
00136
00137
00138 static int resynch_jb(struct fixed_jb *jb, void *data, long ms, long ts, long now)
00139 {
00140 long diff, offset;
00141 struct fixed_jb_frame *frame;
00142
00143
00144 if (!jb->frames) {
00145
00146 ASSERT(jb->tail == NULL);
00147
00148 return fixed_jb_put_first(jb, data, ms, ts, now);
00149 }
00150
00151
00152
00153
00154
00155 diff = ts - jb->tail->ts;
00156
00157
00158
00159 offset = diff - jb->tail->ms;
00160
00161
00162 if (!jb->force_resynch && (offset < jb->conf.resync_threshold && offset > -jb->conf.resync_threshold))
00163 return FIXED_JB_DROP;
00164
00165
00166 jb->force_resynch = 0;
00167
00168
00169 jb->rxcore -= offset;
00170 frame = jb->frames;
00171 while (frame) {
00172 frame->ts += offset;
00173 frame = frame->next;
00174 }
00175
00176
00177 return fixed_jb_put(jb, data, ms, ts, now);
00178 }
00179
00180
00181 void fixed_jb_set_force_resynch(struct fixed_jb *jb)
00182 {
00183 jb->force_resynch = 1;
00184 }
00185
00186
00187 int fixed_jb_put_first(struct fixed_jb *jb, void *data, long ms, long ts, long now)
00188 {
00189
00190 jb->rxcore = now - ts;
00191
00192
00193 jb->next_delivery = now + jb->delay;
00194
00195
00196 return fixed_jb_put(jb, data, ms, ts, now);
00197 }
00198
00199
00200 int fixed_jb_put(struct fixed_jb *jb, void *data, long ms, long ts, long now)
00201 {
00202 struct fixed_jb_frame *frame, *next, *newframe;
00203 long delivery;
00204
00205
00206 ASSERT(data != NULL);
00207
00208 ASSERT(ms >= 2);
00209 ASSERT(ts >= 0);
00210 ASSERT(now >= 0);
00211
00212 delivery = jb->rxcore + jb->delay + ts;
00213
00214
00215 if (delivery < jb->next_delivery) {
00216
00217
00218 return resynch_jb(jb, data, ms, ts, now);
00219 }
00220
00221
00222
00223 if (delivery > jb->next_delivery + jb->delay + jb->conf.resync_threshold) {
00224
00225
00226 return resynch_jb(jb, data, ms, ts, now);
00227 }
00228
00229
00230 frame = jb->tail;
00231 while (frame && frame->delivery > delivery) {
00232 frame = frame->prev;
00233 }
00234
00235
00236 if (frame && (frame->delivery == delivery ||
00237 delivery < frame->delivery + frame->ms ||
00238 (frame->next && delivery + ms > frame->next->delivery)))
00239 {
00240
00241
00242
00243
00244
00245 return resynch_jb(jb, data, ms, ts, now);
00246 }
00247
00248
00249 jb->force_resynch = 0;
00250
00251
00252 newframe = alloc_jb_frame(jb);
00253 newframe->data = data;
00254 newframe->ts = ts;
00255 newframe->ms = ms;
00256 newframe->delivery = delivery;
00257
00258
00259 if (frame) {
00260 next = frame->next;
00261 frame->next = newframe;
00262 if (next) {
00263 newframe->next = next;
00264 next->prev = newframe;
00265 } else {
00266
00267 jb->tail = newframe;
00268 newframe->next = NULL;
00269 }
00270 newframe->prev = frame;
00271
00272 return FIXED_JB_OK;
00273 } else if (!jb->frames) {
00274
00275
00276 ASSERT(jb->tail == NULL);
00277 jb->frames = jb->tail = newframe;
00278 newframe->next = NULL;
00279 newframe->prev = NULL;
00280
00281 return FIXED_JB_OK;
00282 } else {
00283
00284 newframe->next = jb->frames;
00285 newframe->prev = NULL;
00286 jb->frames->prev = newframe;
00287 jb->frames = newframe;
00288
00289 return FIXED_JB_OK;
00290 }
00291 }
00292
00293
00294 int fixed_jb_get(struct fixed_jb *jb, struct fixed_jb_frame *frame, long now, long interpl)
00295 {
00296 ASSERT(now >= 0);
00297 ASSERT(interpl >= 2);
00298
00299 if (now < jb->next_delivery) {
00300
00301 return FIXED_JB_NOFRAME;
00302 }
00303
00304
00305 if (!jb->frames) {
00306
00307
00308 jb->next_delivery += interpl;
00309
00310 return FIXED_JB_INTERP;
00311 }
00312
00313
00314 if (now > jb->frames->delivery + jb->frames->ms) {
00315
00316 get_jb_head(jb, frame);
00317
00318 return FIXED_JB_DROP;
00319 }
00320
00321
00322 if (now < jb->frames->delivery) {
00323
00324
00325 jb->next_delivery += interpl;
00326
00327 return FIXED_JB_INTERP;
00328 }
00329
00330
00331 get_jb_head(jb, frame);
00332
00333 return FIXED_JB_OK;
00334 }
00335
00336
00337 long fixed_jb_next(struct fixed_jb *jb)
00338 {
00339 return jb->next_delivery;
00340 }
00341
00342
00343 int fixed_jb_remove(struct fixed_jb *jb, struct fixed_jb_frame *frameout)
00344 {
00345 if (!jb->frames)
00346 return FIXED_JB_NOFRAME;
00347
00348 get_jb_head(jb, frameout);
00349
00350 return FIXED_JB_OK;
00351 }