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