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: 228412 $")
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_LOG)) {
00588 ast_set2_flag(conf, ast_true(value), AST_JB_LOG);
00589 } else {
00590 return -1;
00591 }
00592
00593 return 0;
00594 }
00595
00596
00597 void ast_jb_configure(struct ast_channel *chan, const struct ast_jb_conf *conf)
00598 {
00599 memcpy(&chan->jb.conf, conf, sizeof(*conf));
00600 }
00601
00602
00603 void ast_jb_get_config(const struct ast_channel *chan, struct ast_jb_conf *conf)
00604 {
00605 memcpy(conf, &chan->jb.conf, sizeof(*conf));
00606 }
00607
00608 void ast_jb_empty_and_reset(struct ast_channel *c0, struct ast_channel *c1)
00609 {
00610 struct ast_jb *jb0 = &c0->jb;
00611 struct ast_jb *jb1 = &c1->jb;
00612 int c0_use_jb = ast_test_flag(jb0, JB_USE);
00613 int c0_jb_is_created = ast_test_flag(jb0, JB_CREATED);
00614 int c1_use_jb = ast_test_flag(jb1, JB_USE);
00615 int c1_jb_is_created = ast_test_flag(jb1, JB_CREATED);
00616
00617 if (c0_use_jb && c0_jb_is_created && jb0->impl->empty_and_reset) {
00618 jb0->impl->empty_and_reset(jb0->jbobj);
00619 }
00620
00621 if (c1_use_jb && c1_jb_is_created && jb1->impl->empty_and_reset) {
00622 jb1->impl->empty_and_reset(jb1->jbobj);
00623 }
00624 }
00625
00626
00627
00628
00629 static void * jb_create_fixed(struct ast_jb_conf *general_config, long resynch_threshold)
00630 {
00631 struct fixed_jb_conf conf;
00632
00633 conf.jbsize = general_config->max_size;
00634 conf.resync_threshold = resynch_threshold;
00635
00636 return fixed_jb_new(&conf);
00637 }
00638
00639 static void jb_destroy_fixed(void *jb)
00640 {
00641 struct fixed_jb *fixedjb = (struct fixed_jb *) jb;
00642
00643
00644 fixed_jb_destroy(fixedjb);
00645 }
00646
00647
00648 static int jb_put_first_fixed(void *jb, struct ast_frame *fin, long now)
00649 {
00650 struct fixed_jb *fixedjb = (struct fixed_jb *) jb;
00651 int res;
00652
00653 res = fixed_jb_put_first(fixedjb, fin, fin->len, fin->ts, now);
00654
00655 return fixed_to_abstract_code[res];
00656 }
00657
00658
00659 static int jb_put_fixed(void *jb, struct ast_frame *fin, long now)
00660 {
00661 struct fixed_jb *fixedjb = (struct fixed_jb *) jb;
00662 int res;
00663
00664 res = fixed_jb_put(fixedjb, fin, fin->len, fin->ts, now);
00665
00666 return fixed_to_abstract_code[res];
00667 }
00668
00669
00670 static int jb_get_fixed(void *jb, struct ast_frame **fout, long now, long interpl)
00671 {
00672 struct fixed_jb *fixedjb = (struct fixed_jb *) jb;
00673 struct fixed_jb_frame frame;
00674 int res;
00675
00676 res = fixed_jb_get(fixedjb, &frame, now, interpl);
00677 *fout = frame.data;
00678
00679 return fixed_to_abstract_code[res];
00680 }
00681
00682
00683 static long jb_next_fixed(void *jb)
00684 {
00685 struct fixed_jb *fixedjb = (struct fixed_jb *) jb;
00686
00687 return fixed_jb_next(fixedjb);
00688 }
00689
00690
00691 static int jb_remove_fixed(void *jb, struct ast_frame **fout)
00692 {
00693 struct fixed_jb *fixedjb = (struct fixed_jb *) jb;
00694 struct fixed_jb_frame frame;
00695 int res;
00696
00697 res = fixed_jb_remove(fixedjb, &frame);
00698 *fout = frame.data;
00699
00700 return fixed_to_abstract_code[res];
00701 }
00702
00703
00704 static void jb_force_resynch_fixed(void *jb)
00705 {
00706 struct fixed_jb *fixedjb = (struct fixed_jb *) jb;
00707
00708 fixed_jb_set_force_resynch(fixedjb);
00709 }
00710
00711 static void jb_empty_and_reset_fixed(void *jb)
00712 {
00713 struct fixed_jb *fixedjb = jb;
00714 struct fixed_jb_frame f;
00715
00716 while (fixed_jb_remove(fixedjb, &f) == FIXED_JB_OK) {
00717 ast_frfree(f.data);
00718 }
00719 }
00720
00721
00722
00723 static void *jb_create_adaptive(struct ast_jb_conf *general_config, long resynch_threshold)
00724 {
00725 jb_conf jbconf;
00726 jitterbuf *adaptivejb;
00727
00728 adaptivejb = jb_new();
00729 if (adaptivejb) {
00730 jbconf.max_jitterbuf = general_config->max_size;
00731 jbconf.resync_threshold = general_config->resync_threshold;
00732 jbconf.max_contig_interp = 10;
00733 jb_setconf(adaptivejb, &jbconf);
00734 }
00735
00736 return adaptivejb;
00737 }
00738
00739
00740 static void jb_destroy_adaptive(void *jb)
00741 {
00742 jitterbuf *adaptivejb = (jitterbuf *) jb;
00743
00744 jb_destroy(adaptivejb);
00745 }
00746
00747
00748 static int jb_put_first_adaptive(void *jb, struct ast_frame *fin, long now)
00749 {
00750 return jb_put_adaptive(jb, fin, now);
00751 }
00752
00753
00754 static int jb_put_adaptive(void *jb, struct ast_frame *fin, long now)
00755 {
00756 jitterbuf *adaptivejb = (jitterbuf *) jb;
00757 int res;
00758
00759 res = jb_put(adaptivejb, fin, JB_TYPE_VOICE, fin->len, fin->ts, now);
00760
00761 return adaptive_to_abstract_code[res];
00762 }
00763
00764
00765 static int jb_get_adaptive(void *jb, struct ast_frame **fout, long now, long interpl)
00766 {
00767 jitterbuf *adaptivejb = (jitterbuf *) jb;
00768 jb_frame frame;
00769 int res;
00770
00771 res = jb_get(adaptivejb, &frame, now, interpl);
00772 *fout = frame.data;
00773
00774 return adaptive_to_abstract_code[res];
00775 }
00776
00777
00778 static long jb_next_adaptive(void *jb)
00779 {
00780 jitterbuf *adaptivejb = (jitterbuf *) jb;
00781
00782 return jb_next(adaptivejb);
00783 }
00784
00785
00786 static int jb_remove_adaptive(void *jb, struct ast_frame **fout)
00787 {
00788 jitterbuf *adaptivejb = (jitterbuf *) jb;
00789 jb_frame frame;
00790 int res;
00791
00792 res = jb_getall(adaptivejb, &frame);
00793 *fout = frame.data;
00794
00795 return adaptive_to_abstract_code[res];
00796 }
00797
00798
00799 static void jb_force_resynch_adaptive(void *jb)
00800 {
00801 }
00802
00803 static void jb_empty_and_reset_adaptive(void *jb)
00804 {
00805 jitterbuf *adaptivejb = jb;
00806 jb_frame f;
00807
00808 while (jb_getall(adaptivejb, &f) == JB_OK) {
00809 ast_frfree(f.data);
00810 }
00811
00812 jb_reset(adaptivejb);
00813 }