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