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: 249896 $")
00035
00036 #include "asterisk/frame.h"
00037 #include "asterisk/channel.h"
00038 #include "asterisk/term.h"
00039 #include "asterisk/utils.h"
00040
00041 #include "asterisk/abstract_jb.h"
00042 #include "fixedjitterbuf.h"
00043 #include "jitterbuf.h"
00044
00045
00046 enum {
00047 JB_USE = (1 << 0),
00048 JB_TIMEBASE_INITIALIZED = (1 << 1),
00049 JB_CREATED = (1 << 2)
00050 };
00051
00052
00053
00054
00055 typedef void * (*jb_create_impl)(struct ast_jb_conf *general_config, long resynch_threshold);
00056
00057 typedef void (*jb_destroy_impl)(void *jb);
00058
00059 typedef int (*jb_put_first_impl)(void *jb, struct ast_frame *fin, long now);
00060
00061 typedef int (*jb_put_impl)(void *jb, struct ast_frame *fin, long now);
00062
00063 typedef int (*jb_get_impl)(void *jb, struct ast_frame **fout, long now, long interpl);
00064
00065 typedef long (*jb_next_impl)(void *jb);
00066
00067 typedef int (*jb_remove_impl)(void *jb, struct ast_frame **fout);
00068
00069 typedef void (*jb_force_resynch_impl)(void *jb);
00070
00071 typedef void (*jb_empty_and_reset_impl)(void *jb);
00072
00073
00074
00075
00076 struct ast_jb_impl
00077 {
00078 char name[AST_JB_IMPL_NAME_SIZE];
00079 jb_create_impl create;
00080 jb_destroy_impl destroy;
00081 jb_put_first_impl put_first;
00082 jb_put_impl put;
00083 jb_get_impl get;
00084 jb_next_impl next;
00085 jb_remove_impl remove;
00086 jb_force_resynch_impl force_resync;
00087 jb_empty_and_reset_impl empty_and_reset;
00088 };
00089
00090
00091
00092 static void *jb_create_fixed(struct ast_jb_conf *general_config, long resynch_threshold);
00093 static void jb_destroy_fixed(void *jb);
00094 static int jb_put_first_fixed(void *jb, struct ast_frame *fin, long now);
00095 static int jb_put_fixed(void *jb, struct ast_frame *fin, long now);
00096 static int jb_get_fixed(void *jb, struct ast_frame **fout, long now, long interpl);
00097 static long jb_next_fixed(void *jb);
00098 static int jb_remove_fixed(void *jb, struct ast_frame **fout);
00099 static void jb_force_resynch_fixed(void *jb);
00100 static void jb_empty_and_reset_fixed(void *jb);
00101
00102 static void * jb_create_adaptive(struct ast_jb_conf *general_config, long resynch_threshold);
00103 static void jb_destroy_adaptive(void *jb);
00104 static int jb_put_first_adaptive(void *jb, struct ast_frame *fin, long now);
00105 static int jb_put_adaptive(void *jb, struct ast_frame *fin, long now);
00106 static int jb_get_adaptive(void *jb, struct ast_frame **fout, long now, long interpl);
00107 static long jb_next_adaptive(void *jb);
00108 static int jb_remove_adaptive(void *jb, struct ast_frame **fout);
00109 static void jb_force_resynch_adaptive(void *jb);
00110 static void jb_empty_and_reset_adaptive(void *jb);
00111
00112
00113 static struct ast_jb_impl avail_impl[] =
00114 {
00115 {
00116 .name = "fixed",
00117 .create = jb_create_fixed,
00118 .destroy = jb_destroy_fixed,
00119 .put_first = jb_put_first_fixed,
00120 .put = jb_put_fixed,
00121 .get = jb_get_fixed,
00122 .next = jb_next_fixed,
00123 .remove = jb_remove_fixed,
00124 .force_resync = jb_force_resynch_fixed,
00125 .empty_and_reset = jb_empty_and_reset_fixed,
00126 },
00127 {
00128 .name = "adaptive",
00129 .create = jb_create_adaptive,
00130 .destroy = jb_destroy_adaptive,
00131 .put_first = jb_put_first_adaptive,
00132 .put = jb_put_adaptive,
00133 .get = jb_get_adaptive,
00134 .next = jb_next_adaptive,
00135 .remove = jb_remove_adaptive,
00136 .force_resync = jb_force_resynch_adaptive,
00137 .empty_and_reset = jb_empty_and_reset_adaptive,
00138 }
00139 };
00140
00141 static int default_impl = 0;
00142
00143
00144
00145 enum {
00146 JB_IMPL_OK,
00147 JB_IMPL_DROP,
00148 JB_IMPL_INTERP,
00149 JB_IMPL_NOFRAME
00150 };
00151
00152
00153 static int fixed_to_abstract_code[] =
00154 {JB_IMPL_OK, JB_IMPL_DROP, JB_IMPL_INTERP, JB_IMPL_NOFRAME};
00155 static int adaptive_to_abstract_code[] =
00156 {JB_IMPL_OK, JB_IMPL_NOFRAME, JB_IMPL_NOFRAME, JB_IMPL_INTERP, JB_IMPL_DROP, JB_IMPL_OK};
00157
00158
00159 static char *jb_get_actions[] = {"Delivered", "Dropped", "Interpolated", "No"};
00160
00161
00162 #define jb_framelog(...) do { \
00163 if (jb->logfile) { \
00164 fprintf(jb->logfile, __VA_ARGS__); \
00165 fflush(jb->logfile); \
00166 } \
00167 } while (0)
00168
00169
00170
00171 static void jb_choose_impl(struct ast_channel *chan);
00172 static void jb_get_and_deliver(struct ast_channel *chan);
00173 static int create_jb(struct ast_channel *chan, struct ast_frame *first_frame);
00174 static long get_now(struct ast_jb *jb, struct timeval *tv);
00175
00176
00177
00178
00179
00180 static void jb_choose_impl(struct ast_channel *chan)
00181 {
00182 struct ast_jb *jb = &chan->jb;
00183 struct ast_jb_conf *jbconf = &jb->conf;
00184 struct ast_jb_impl *test_impl;
00185 int i, avail_impl_count = ARRAY_LEN(avail_impl);
00186
00187 jb->impl = &avail_impl[default_impl];
00188
00189 if (ast_strlen_zero(jbconf->impl))
00190 return;
00191
00192 for (i = 0; i < avail_impl_count; i++) {
00193 test_impl = &avail_impl[i];
00194 if (!strcasecmp(jbconf->impl, test_impl->name)) {
00195 jb->impl = test_impl;
00196 return;
00197 }
00198 }
00199 }
00200
00201 int ast_jb_do_usecheck(struct ast_channel *c0, struct ast_channel *c1)
00202 {
00203 struct ast_jb *jb0 = &c0->jb;
00204 struct ast_jb *jb1 = &c1->jb;
00205 struct ast_jb_conf *conf0 = &jb0->conf;
00206 struct ast_jb_conf *conf1 = &jb1->conf;
00207 int c0_wants_jitter = c0->tech->properties & AST_CHAN_TP_WANTSJITTER;
00208 int c0_creates_jitter = c0->tech->properties & AST_CHAN_TP_CREATESJITTER;
00209 int c0_jb_enabled = ast_test_flag(conf0, AST_JB_ENABLED);
00210 int c0_force_jb = ast_test_flag(conf0, AST_JB_FORCED);
00211 int c0_jb_timebase_initialized = ast_test_flag(jb0, JB_TIMEBASE_INITIALIZED);
00212 int c0_jb_created = ast_test_flag(jb0, JB_CREATED);
00213 int c1_wants_jitter = c1->tech->properties & AST_CHAN_TP_WANTSJITTER;
00214 int c1_creates_jitter = c1->tech->properties & AST_CHAN_TP_CREATESJITTER;
00215 int c1_jb_enabled = ast_test_flag(conf1, AST_JB_ENABLED);
00216 int c1_force_jb = ast_test_flag(conf1, AST_JB_FORCED);
00217 int c1_jb_timebase_initialized = ast_test_flag(jb1, JB_TIMEBASE_INITIALIZED);
00218 int c1_jb_created = ast_test_flag(jb1, JB_CREATED);
00219 int inuse = 0;
00220
00221
00222 if (((!c0_wants_jitter && c1_creates_jitter) || (c0_force_jb && c1_creates_jitter)) && c0_jb_enabled) {
00223 ast_set_flag(jb0, JB_USE);
00224 if (!c0_jb_timebase_initialized) {
00225 if (c1_jb_timebase_initialized) {
00226 memcpy(&jb0->timebase, &jb1->timebase, sizeof(struct timeval));
00227 } else {
00228 gettimeofday(&jb0->timebase, NULL);
00229 }
00230 ast_set_flag(jb0, JB_TIMEBASE_INITIALIZED);
00231 }
00232
00233 if (!c0_jb_created) {
00234 jb_choose_impl(c0);
00235 }
00236
00237 inuse = 1;
00238 }
00239
00240
00241 if (((!c1_wants_jitter && c0_creates_jitter) || (c1_force_jb && c0_creates_jitter)) && c1_jb_enabled) {
00242 ast_set_flag(jb1, JB_USE);
00243 if (!c1_jb_timebase_initialized) {
00244 if (c0_jb_timebase_initialized) {
00245 memcpy(&jb1->timebase, &jb0->timebase, sizeof(struct timeval));
00246 } else {
00247 gettimeofday(&jb1->timebase, NULL);
00248 }
00249 ast_set_flag(jb1, JB_TIMEBASE_INITIALIZED);
00250 }
00251
00252 if (!c1_jb_created) {
00253 jb_choose_impl(c1);
00254 }
00255
00256 inuse = 1;
00257 }
00258
00259 return inuse;
00260 }
00261
00262 int ast_jb_get_when_to_wakeup(struct ast_channel *c0, struct ast_channel *c1, int time_left)
00263 {
00264 struct ast_jb *jb0 = &c0->jb;
00265 struct ast_jb *jb1 = &c1->jb;
00266 int c0_use_jb = ast_test_flag(jb0, JB_USE);
00267 int c0_jb_is_created = ast_test_flag(jb0, JB_CREATED);
00268 int c1_use_jb = ast_test_flag(jb1, JB_USE);
00269 int c1_jb_is_created = ast_test_flag(jb1, JB_CREATED);
00270 int wait, wait0, wait1;
00271 struct timeval tv_now;
00272
00273 if (time_left == 0) {
00274
00275
00276
00277 }
00278
00279 if (time_left < 0) {
00280 time_left = INT_MAX;
00281 }
00282
00283 gettimeofday(&tv_now, NULL);
00284
00285 wait0 = (c0_use_jb && c0_jb_is_created) ? jb0->next - get_now(jb0, &tv_now) : time_left;
00286 wait1 = (c1_use_jb && c1_jb_is_created) ? jb1->next - get_now(jb1, &tv_now) : time_left;
00287
00288 wait = wait0 < wait1 ? wait0 : wait1;
00289 wait = wait < time_left ? wait : time_left;
00290
00291 if (wait == INT_MAX) {
00292 wait = -1;
00293 } else if (wait < 1) {
00294
00295 wait = 1;
00296 }
00297
00298 return wait;
00299 }
00300
00301
00302 int ast_jb_put(struct ast_channel *chan, struct ast_frame *f)
00303 {
00304 struct ast_jb *jb = &chan->jb;
00305 struct ast_jb_impl *jbimpl = jb->impl;
00306 void *jbobj = jb->jbobj;
00307 struct ast_frame *frr;
00308 long now = 0;
00309
00310 if (!ast_test_flag(jb, JB_USE))
00311 return -1;
00312
00313 if (f->frametype != AST_FRAME_VOICE) {
00314 if (f->frametype == AST_FRAME_DTMF && ast_test_flag(jb, JB_CREATED)) {
00315 jb_framelog("JB_PUT {now=%ld}: Received DTMF frame. Force resynching jb...\n", now);
00316 jbimpl->force_resync(jbobj);
00317 }
00318
00319 return -1;
00320 }
00321
00322
00323 if (!ast_test_flag(f, AST_FRFLAG_HAS_TIMING_INFO) || f->len < 2 || f->ts < 0) {
00324 ast_log(LOG_WARNING, "%s received frame with invalid timing info: "
00325 "has_timing_info=%d, len=%ld, ts=%ld, src=%s\n",
00326 chan->name, ast_test_flag(f, AST_FRFLAG_HAS_TIMING_INFO), f->len, f->ts, f->src);
00327 return -1;
00328 }
00329
00330 frr = ast_frdup(f);
00331
00332 if (!frr) {
00333 ast_log(LOG_ERROR, "Failed to isolate frame for the jitterbuffer on channel '%s'\n", chan->name);
00334 return -1;
00335 }
00336
00337 if (!ast_test_flag(jb, JB_CREATED)) {
00338 if (create_jb(chan, frr)) {
00339 ast_frfree(frr);
00340
00341 ast_clear_flag(jb, JB_USE);
00342 return -1;
00343 }
00344
00345 ast_set_flag(jb, JB_CREATED);
00346 return 0;
00347 } else {
00348 now = get_now(jb, NULL);
00349 if (jbimpl->put(jbobj, frr, now) != JB_IMPL_OK) {
00350 jb_framelog("JB_PUT {now=%ld}: Dropped frame with ts=%ld and len=%ld\n", now, frr->ts, frr->len);
00351 ast_frfree(frr);
00352
00353
00354
00355 return 0;
00356 }
00357
00358 jb->next = jbimpl->next(jbobj);
00359
00360 jb_framelog("JB_PUT {now=%ld}: Queued frame with ts=%ld and len=%ld\n", now, frr->ts, frr->len);
00361
00362 return 0;
00363 }
00364 }
00365
00366
00367 void ast_jb_get_and_deliver(struct ast_channel *c0, struct ast_channel *c1)
00368 {
00369 struct ast_jb *jb0 = &c0->jb;
00370 struct ast_jb *jb1 = &c1->jb;
00371 int c0_use_jb = ast_test_flag(jb0, JB_USE);
00372 int c0_jb_is_created = ast_test_flag(jb0, JB_CREATED);
00373 int c1_use_jb = ast_test_flag(jb1, JB_USE);
00374 int c1_jb_is_created = ast_test_flag(jb1, JB_CREATED);
00375
00376 if (c0_use_jb && c0_jb_is_created)
00377 jb_get_and_deliver(c0);
00378
00379 if (c1_use_jb && c1_jb_is_created)
00380 jb_get_and_deliver(c1);
00381 }
00382
00383
00384 static void jb_get_and_deliver(struct ast_channel *chan)
00385 {
00386 struct ast_jb *jb = &chan->jb;
00387 struct ast_jb_impl *jbimpl = jb->impl;
00388 void *jbobj = jb->jbobj;
00389 struct ast_frame *f, finterp = { .frametype = AST_FRAME_VOICE, };
00390 long now;
00391 int interpolation_len, res;
00392
00393 now = get_now(jb, NULL);
00394 jb->next = jbimpl->next(jbobj);
00395 if (now < jb->next) {
00396 jb_framelog("\tJB_GET {now=%ld}: now < next=%ld\n", now, jb->next);
00397 return;
00398 }
00399
00400 while (now >= jb->next) {
00401 interpolation_len = ast_codec_interp_len(jb->last_format);
00402
00403 res = jbimpl->get(jbobj, &f, now, interpolation_len);
00404
00405 switch (res) {
00406 case JB_IMPL_OK:
00407
00408 ast_write(chan, f);
00409 case JB_IMPL_DROP:
00410 jb_framelog("\tJB_GET {now=%ld}: %s frame with ts=%ld and len=%ld\n",
00411 now, jb_get_actions[res], f->ts, f->len);
00412 jb->last_format = f->subclass;
00413 ast_frfree(f);
00414 break;
00415 case JB_IMPL_INTERP:
00416
00417 f = &finterp;
00418 f->subclass = jb->last_format;
00419 f->samples = interpolation_len * 8;
00420 f->src = "JB interpolation";
00421 f->delivery = ast_tvadd(jb->timebase, ast_samp2tv(jb->next, 1000));
00422 f->offset = AST_FRIENDLY_OFFSET;
00423
00424 ast_write(chan, f);
00425 jb_framelog("\tJB_GET {now=%ld}: Interpolated frame with len=%d\n", now, interpolation_len);
00426 break;
00427 case JB_IMPL_NOFRAME:
00428 ast_log(LOG_WARNING,
00429 "JB_IMPL_NOFRAME is returned from the %s jb when now=%ld >= next=%ld, jbnext=%ld!\n",
00430 jbimpl->name, now, jb->next, jbimpl->next(jbobj));
00431 jb_framelog("\tJB_GET {now=%ld}: No frame for now!?\n", now);
00432 return;
00433 default:
00434 ast_log(LOG_ERROR, "This should never happen!\n");
00435 ast_assert("JB type unknown" == NULL);
00436 break;
00437 }
00438
00439 jb->next = jbimpl->next(jbobj);
00440 }
00441 }
00442
00443
00444 static int create_jb(struct ast_channel *chan, struct ast_frame *frr)
00445 {
00446 struct ast_jb *jb = &chan->jb;
00447 struct ast_jb_conf *jbconf = &jb->conf;
00448 struct ast_jb_impl *jbimpl = jb->impl;
00449 void *jbobj;
00450 struct ast_channel *bridged;
00451 long now;
00452 char logfile_pathname[20 + AST_JB_IMPL_NAME_SIZE + 2*AST_CHANNEL_NAME + 1];
00453 char name1[AST_CHANNEL_NAME], name2[AST_CHANNEL_NAME], *tmp;
00454 int res;
00455
00456 jbobj = jb->jbobj = jbimpl->create(jbconf, jbconf->resync_threshold);
00457 if (!jbobj) {
00458 ast_log(LOG_WARNING, "Failed to create jitterbuffer on channel '%s'\n", chan->name);
00459 return -1;
00460 }
00461
00462 now = get_now(jb, NULL);
00463 res = jbimpl->put_first(jbobj, frr, now);
00464
00465
00466
00467 if (res != JB_IMPL_OK) {
00468 ast_log(LOG_WARNING, "Failed to put first frame in the jitterbuffer on channel '%s'\n", chan->name);
00469
00470
00471
00472
00473 }
00474
00475
00476 jb->next = jbimpl->next(jbobj);
00477
00478
00479 jb->last_format = frr->subclass;
00480
00481
00482 if (ast_test_flag(jbconf, AST_JB_LOG)) {
00483 snprintf(name2, sizeof(name2), "%s", chan->name);
00484 tmp = strchr(name2, '/');
00485 if (tmp)
00486 *tmp = '#';
00487
00488 bridged = ast_bridged_channel(chan);
00489
00490 ast_assert(bridged != NULL);
00491
00492 snprintf(name1, sizeof(name1), "%s", bridged->name);
00493 tmp = strchr(name1, '/');
00494 if (tmp)
00495 *tmp = '#';
00496
00497 snprintf(logfile_pathname, sizeof(logfile_pathname),
00498 "/tmp/ast_%s_jb_%s--%s.log", jbimpl->name, name1, name2);
00499 jb->logfile = fopen(logfile_pathname, "w+b");
00500
00501 if (!jb->logfile)
00502 ast_log(LOG_ERROR, "Failed to create frame log file with pathname '%s'\n", logfile_pathname);
00503
00504 if (res == JB_IMPL_OK)
00505 jb_framelog("JB_PUT_FIRST {now=%ld}: Queued frame with ts=%ld and len=%ld\n",
00506 now, frr->ts, frr->len);
00507 else
00508 jb_framelog("JB_PUT_FIRST {now=%ld}: Dropped frame with ts=%ld and len=%ld\n",
00509 now, frr->ts, frr->len);
00510 }
00511
00512 ast_verb(3, "%s jitterbuffer created on channel %s\n", jbimpl->name, chan->name);
00513
00514
00515 if (res != JB_IMPL_OK)
00516 ast_frfree(frr);
00517
00518 return 0;
00519 }
00520
00521
00522 void ast_jb_destroy(struct ast_channel *chan)
00523 {
00524 struct ast_jb *jb = &chan->jb;
00525 struct ast_jb_impl *jbimpl = jb->impl;
00526 void *jbobj = jb->jbobj;
00527 struct ast_frame *f;
00528
00529 if (jb->logfile) {
00530 fclose(jb->logfile);
00531 jb->logfile = NULL;
00532 }
00533
00534 if (ast_test_flag(jb, JB_CREATED)) {
00535
00536 while (jbimpl->remove(jbobj, &f) == JB_IMPL_OK) {
00537 ast_frfree(f);
00538 }
00539
00540 jbimpl->destroy(jbobj);
00541 jb->jbobj = NULL;
00542
00543 ast_clear_flag(jb, JB_CREATED);
00544
00545 ast_verb(3, "%s jitterbuffer destroyed on channel %s\n", jbimpl->name, chan->name);
00546 }
00547 }
00548
00549
00550 static long get_now(struct ast_jb *jb, struct timeval *when)
00551 {
00552 struct timeval now;
00553
00554 if (!when) {
00555 when = &now;
00556 gettimeofday(when, NULL);
00557 }
00558
00559 return ast_tvdiff_ms(*when, jb->timebase);
00560 }
00561
00562
00563 int ast_jb_read_conf(struct ast_jb_conf *conf, const char *varname, const char *value)
00564 {
00565 int prefixlen = sizeof(AST_JB_CONF_PREFIX) - 1;
00566 const char *name;
00567 int tmp;
00568
00569 if (strncasecmp(AST_JB_CONF_PREFIX, varname, prefixlen))
00570 return -1;
00571
00572 name = varname + prefixlen;
00573
00574 if (!strcasecmp(name, AST_JB_CONF_ENABLE)) {
00575 ast_set2_flag(conf, ast_true(value), AST_JB_ENABLED);
00576 } else if (!strcasecmp(name, AST_JB_CONF_FORCE)) {
00577 ast_set2_flag(conf, ast_true(value), AST_JB_FORCED);
00578 } else if (!strcasecmp(name, AST_JB_CONF_MAX_SIZE)) {
00579 if ((tmp = atoi(value)) > 0)
00580 conf->max_size = tmp;
00581 } else if (!strcasecmp(name, AST_JB_CONF_RESYNCH_THRESHOLD)) {
00582 if ((tmp = atoi(value)) > 0)
00583 conf->resync_threshold = tmp;
00584 } else if (!strcasecmp(name, AST_JB_CONF_IMPL)) {
00585 if (!ast_strlen_zero(value))
00586 snprintf(conf->impl, sizeof(conf->impl), "%s", value);
00587 } else if (!strcasecmp(name, AST_JB_CONF_TARGET_EXTRA)) {
00588 if (sscanf(value, "%30d", &tmp) == 1) {
00589 conf->target_extra = tmp;
00590 }
00591 } else if (!strcasecmp(name, AST_JB_CONF_LOG)) {
00592 ast_set2_flag(conf, ast_true(value), AST_JB_LOG);
00593 } else {
00594 return -1;
00595 }
00596
00597 return 0;
00598 }
00599
00600
00601 void ast_jb_configure(struct ast_channel *chan, const struct ast_jb_conf *conf)
00602 {
00603 memcpy(&chan->jb.conf, conf, sizeof(*conf));
00604 }
00605
00606
00607 void ast_jb_get_config(const struct ast_channel *chan, struct ast_jb_conf *conf)
00608 {
00609 memcpy(conf, &chan->jb.conf, sizeof(*conf));
00610 }
00611
00612 void ast_jb_empty_and_reset(struct ast_channel *c0, struct ast_channel *c1)
00613 {
00614 struct ast_jb *jb0 = &c0->jb;
00615 struct ast_jb *jb1 = &c1->jb;
00616 int c0_use_jb = ast_test_flag(jb0, JB_USE);
00617 int c0_jb_is_created = ast_test_flag(jb0, JB_CREATED);
00618 int c1_use_jb = ast_test_flag(jb1, JB_USE);
00619 int c1_jb_is_created = ast_test_flag(jb1, JB_CREATED);
00620
00621 if (c0_use_jb && c0_jb_is_created && jb0->impl->empty_and_reset) {
00622 jb0->impl->empty_and_reset(jb0->jbobj);
00623 }
00624
00625 if (c1_use_jb && c1_jb_is_created && jb1->impl->empty_and_reset) {
00626 jb1->impl->empty_and_reset(jb1->jbobj);
00627 }
00628 }
00629
00630
00631
00632
00633 static void * jb_create_fixed(struct ast_jb_conf *general_config, long resynch_threshold)
00634 {
00635 struct fixed_jb_conf conf;
00636
00637 conf.jbsize = general_config->max_size;
00638 conf.resync_threshold = resynch_threshold;
00639
00640 return fixed_jb_new(&conf);
00641 }
00642
00643 static void jb_destroy_fixed(void *jb)
00644 {
00645 struct fixed_jb *fixedjb = (struct fixed_jb *) jb;
00646
00647
00648 fixed_jb_destroy(fixedjb);
00649 }
00650
00651
00652 static int jb_put_first_fixed(void *jb, struct ast_frame *fin, long now)
00653 {
00654 struct fixed_jb *fixedjb = (struct fixed_jb *) jb;
00655 int res;
00656
00657 res = fixed_jb_put_first(fixedjb, fin, fin->len, fin->ts, now);
00658
00659 return fixed_to_abstract_code[res];
00660 }
00661
00662
00663 static int jb_put_fixed(void *jb, struct ast_frame *fin, long now)
00664 {
00665 struct fixed_jb *fixedjb = (struct fixed_jb *) jb;
00666 int res;
00667
00668 res = fixed_jb_put(fixedjb, fin, fin->len, fin->ts, now);
00669
00670 return fixed_to_abstract_code[res];
00671 }
00672
00673
00674 static int jb_get_fixed(void *jb, struct ast_frame **fout, long now, long interpl)
00675 {
00676 struct fixed_jb *fixedjb = (struct fixed_jb *) jb;
00677 struct fixed_jb_frame frame;
00678 int res;
00679
00680 res = fixed_jb_get(fixedjb, &frame, now, interpl);
00681 *fout = frame.data;
00682
00683 return fixed_to_abstract_code[res];
00684 }
00685
00686
00687 static long jb_next_fixed(void *jb)
00688 {
00689 struct fixed_jb *fixedjb = (struct fixed_jb *) jb;
00690
00691 return fixed_jb_next(fixedjb);
00692 }
00693
00694
00695 static int jb_remove_fixed(void *jb, struct ast_frame **fout)
00696 {
00697 struct fixed_jb *fixedjb = (struct fixed_jb *) jb;
00698 struct fixed_jb_frame frame;
00699 int res;
00700
00701 res = fixed_jb_remove(fixedjb, &frame);
00702 *fout = frame.data;
00703
00704 return fixed_to_abstract_code[res];
00705 }
00706
00707
00708 static void jb_force_resynch_fixed(void *jb)
00709 {
00710 struct fixed_jb *fixedjb = (struct fixed_jb *) jb;
00711
00712 fixed_jb_set_force_resynch(fixedjb);
00713 }
00714
00715 static void jb_empty_and_reset_fixed(void *jb)
00716 {
00717 struct fixed_jb *fixedjb = jb;
00718 struct fixed_jb_frame f;
00719
00720 while (fixed_jb_remove(fixedjb, &f) == FIXED_JB_OK) {
00721 ast_frfree(f.data);
00722 }
00723 }
00724
00725
00726
00727 static void *jb_create_adaptive(struct ast_jb_conf *general_config, long resynch_threshold)
00728 {
00729 jb_conf jbconf;
00730 jitterbuf *adaptivejb;
00731
00732 adaptivejb = jb_new();
00733 if (adaptivejb) {
00734 jbconf.max_jitterbuf = general_config->max_size;
00735 jbconf.resync_threshold = general_config->resync_threshold;
00736 jbconf.max_contig_interp = 10;
00737 jbconf.target_extra = general_config->target_extra;
00738 jb_setconf(adaptivejb, &jbconf);
00739 }
00740
00741 return adaptivejb;
00742 }
00743
00744
00745 static void jb_destroy_adaptive(void *jb)
00746 {
00747 jitterbuf *adaptivejb = (jitterbuf *) jb;
00748
00749 jb_destroy(adaptivejb);
00750 }
00751
00752
00753 static int jb_put_first_adaptive(void *jb, struct ast_frame *fin, long now)
00754 {
00755 return jb_put_adaptive(jb, fin, now);
00756 }
00757
00758
00759 static int jb_put_adaptive(void *jb, struct ast_frame *fin, long now)
00760 {
00761 jitterbuf *adaptivejb = (jitterbuf *) jb;
00762 int res;
00763
00764 res = jb_put(adaptivejb, fin, JB_TYPE_VOICE, fin->len, fin->ts, now);
00765
00766 return adaptive_to_abstract_code[res];
00767 }
00768
00769
00770 static int jb_get_adaptive(void *jb, struct ast_frame **fout, long now, long interpl)
00771 {
00772 jitterbuf *adaptivejb = (jitterbuf *) jb;
00773 jb_frame frame;
00774 int res;
00775
00776 res = jb_get(adaptivejb, &frame, now, interpl);
00777 *fout = frame.data;
00778
00779 return adaptive_to_abstract_code[res];
00780 }
00781
00782
00783 static long jb_next_adaptive(void *jb)
00784 {
00785 jitterbuf *adaptivejb = (jitterbuf *) jb;
00786
00787 return jb_next(adaptivejb);
00788 }
00789
00790
00791 static int jb_remove_adaptive(void *jb, struct ast_frame **fout)
00792 {
00793 jitterbuf *adaptivejb = (jitterbuf *) jb;
00794 jb_frame frame;
00795 int res;
00796
00797 res = jb_getall(adaptivejb, &frame);
00798 *fout = frame.data;
00799
00800 return adaptive_to_abstract_code[res];
00801 }
00802
00803
00804 static void jb_force_resynch_adaptive(void *jb)
00805 {
00806 }
00807
00808 static void jb_empty_and_reset_adaptive(void *jb)
00809 {
00810 jitterbuf *adaptivejb = jb;
00811 jb_frame f;
00812
00813 while (jb_getall(adaptivejb, &f) == JB_OK) {
00814 ast_frfree(f.data);
00815 }
00816
00817 jb_reset(adaptivejb);
00818 }