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 #include "asterisk.h"
00029
00030 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 40722 $")
00031
00032 #include <stdio.h>
00033 #include <stdlib.h>
00034 #include <assert.h>
00035 #include <string.h>
00036 #include <unistd.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(struct fixed_jb_frame));
00070 }
00071
00072 static inline void release_jb_frame(struct fixed_jb *jb, struct fixed_jb_frame *frame)
00073 {
00074 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 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 }