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: 249895 $")
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 if (!(safe_fd = mkstemp(safe_logfile)) > -1 || unlink(logfile_pathname) || link(safe_logfile, logfile_pathname) || unlink(safe_logfile) || !(jb->logfile = fdopen(safe_fd, "w+b"))) {
00503 jb->logfile = NULL;
00504 if (safe_fd > -1) {
00505 close(safe_fd);
00506 }
00507 ast_log(LOG_ERROR, "Failed to create frame log file with pathname '%s': %s\n", logfile_pathname, strerror(errno));
00508 }
00509
00510 if (res == JB_IMPL_OK) {
00511 jb_framelog("JB_PUT_FIRST {now=%ld}: Queued frame with ts=%ld and len=%ld\n",
00512 now, frr->ts, frr->len);
00513 } else {
00514 jb_framelog("JB_PUT_FIRST {now=%ld}: Dropped frame with ts=%ld and len=%ld\n",
00515 now, frr->ts, frr->len);
00516 }
00517 }
00518
00519 ast_verb(3, "%s jitterbuffer created on channel %s\n", jbimpl->name, chan->name);
00520
00521
00522 if (res != JB_IMPL_OK) {
00523 ast_frfree(frr);
00524 }
00525
00526 return 0;
00527 }
00528
00529
00530 void ast_jb_destroy(struct ast_channel *chan)
00531 {
00532 struct ast_jb *jb = &chan->jb;
00533 struct ast_jb_impl *jbimpl = jb->impl;
00534 void *jbobj = jb->jbobj;
00535 struct ast_frame *f;
00536
00537 if (jb->logfile) {
00538 fclose(jb->logfile);
00539 jb->logfile = NULL;
00540 }
00541
00542 if (ast_test_flag(jb, JB_CREATED)) {
00543
00544 while (jbimpl->remove(jbobj, &f) == JB_IMPL_OK) {
00545 ast_frfree(f);
00546 }
00547
00548 jbimpl->destroy(jbobj);
00549 jb->jbobj = NULL;
00550
00551 ast_clear_flag(jb, JB_CREATED);
00552
00553 ast_verb(3, "%s jitterbuffer destroyed on channel %s\n", jbimpl->name, chan->name);
00554 }
00555 }
00556
00557
00558 static long get_now(struct ast_jb *jb, struct timeval *when)
00559 {
00560 struct timeval now;
00561
00562 if (!when) {
00563 when = &now;
00564 gettimeofday(when, NULL);
00565 }
00566
00567 return ast_tvdiff_ms(*when, jb->timebase);
00568 }
00569
00570
00571 int ast_jb_read_conf(struct ast_jb_conf *conf, const char *varname, const char *value)
00572 {
00573 int prefixlen = sizeof(AST_JB_CONF_PREFIX) - 1;
00574 const char *name;
00575 int tmp;
00576
00577 if (strncasecmp(AST_JB_CONF_PREFIX, varname, prefixlen)) {
00578 return -1;
00579 }
00580
00581 name = varname + prefixlen;
00582
00583 if (!strcasecmp(name, AST_JB_CONF_ENABLE)) {
00584 ast_set2_flag(conf, ast_true(value), AST_JB_ENABLED);
00585 } else if (!strcasecmp(name, AST_JB_CONF_FORCE)) {
00586 ast_set2_flag(conf, ast_true(value), AST_JB_FORCED);
00587 } else if (!strcasecmp(name, AST_JB_CONF_MAX_SIZE)) {
00588 if ((tmp = atoi(value)) > 0)
00589 conf->max_size = tmp;
00590 } else if (!strcasecmp(name, AST_JB_CONF_RESYNCH_THRESHOLD)) {
00591 if ((tmp = atoi(value)) > 0)
00592 conf->resync_threshold = tmp;
00593 } else if (!strcasecmp(name, AST_JB_CONF_IMPL)) {
00594 if (!ast_strlen_zero(value))
00595 snprintf(conf->impl, sizeof(conf->impl), "%s", value);
00596 } else if (!strcasecmp(name, AST_JB_CONF_TARGET_EXTRA)) {
00597 if (sscanf(value, "%30d", &tmp) == 1) {
00598 conf->target_extra = tmp;
00599 }
00600 } else if (!strcasecmp(name, AST_JB_CONF_LOG)) {
00601 ast_set2_flag(conf, ast_true(value), AST_JB_LOG);
00602 } else {
00603 return -1;
00604 }
00605
00606 return 0;
00607 }
00608
00609
00610 void ast_jb_configure(struct ast_channel *chan, const struct ast_jb_conf *conf)
00611 {
00612 memcpy(&chan->jb.conf, conf, sizeof(*conf));
00613 }
00614
00615
00616 void ast_jb_get_config(const struct ast_channel *chan, struct ast_jb_conf *conf)
00617 {
00618 memcpy(conf, &chan->jb.conf, sizeof(*conf));
00619 }
00620
00621 void ast_jb_empty_and_reset(struct ast_channel *c0, struct ast_channel *c1)
00622 {
00623 struct ast_jb *jb0 = &c0->jb;
00624 struct ast_jb *jb1 = &c1->jb;
00625 int c0_use_jb = ast_test_flag(jb0, JB_USE);
00626 int c0_jb_is_created = ast_test_flag(jb0, JB_CREATED);
00627 int c1_use_jb = ast_test_flag(jb1, JB_USE);
00628 int c1_jb_is_created = ast_test_flag(jb1, JB_CREATED);
00629
00630 if (c0_use_jb && c0_jb_is_created && jb0->impl->empty_and_reset) {
00631 jb0->impl->empty_and_reset(jb0->jbobj);
00632 }
00633
00634 if (c1_use_jb && c1_jb_is_created && jb1->impl->empty_and_reset) {
00635 jb1->impl->empty_and_reset(jb1->jbobj);
00636 }
00637 }
00638
00639
00640
00641
00642 static void * jb_create_fixed(struct ast_jb_conf *general_config, long resynch_threshold)
00643 {
00644 struct fixed_jb_conf conf;
00645
00646 conf.jbsize = general_config->max_size;
00647 conf.resync_threshold = resynch_threshold;
00648
00649 return fixed_jb_new(&conf);
00650 }
00651
00652 static void jb_destroy_fixed(void *jb)
00653 {
00654 struct fixed_jb *fixedjb = (struct fixed_jb *) jb;
00655
00656
00657 fixed_jb_destroy(fixedjb);
00658 }
00659
00660
00661 static int jb_put_first_fixed(void *jb, struct ast_frame *fin, long now)
00662 {
00663 struct fixed_jb *fixedjb = (struct fixed_jb *) jb;
00664 int res;
00665
00666 res = fixed_jb_put_first(fixedjb, fin, fin->len, fin->ts, now);
00667
00668 return fixed_to_abstract_code[res];
00669 }
00670
00671
00672 static int jb_put_fixed(void *jb, struct ast_frame *fin, long now)
00673 {
00674 struct fixed_jb *fixedjb = (struct fixed_jb *) jb;
00675 int res;
00676
00677 res = fixed_jb_put(fixedjb, fin, fin->len, fin->ts, now);
00678
00679 return fixed_to_abstract_code[res];
00680 }
00681
00682
00683 static int jb_get_fixed(void *jb, struct ast_frame **fout, long now, long interpl)
00684 {
00685 struct fixed_jb *fixedjb = (struct fixed_jb *) jb;
00686 struct fixed_jb_frame frame;
00687 int res;
00688
00689 res = fixed_jb_get(fixedjb, &frame, now, interpl);
00690 *fout = frame.data;
00691
00692 return fixed_to_abstract_code[res];
00693 }
00694
00695
00696 static long jb_next_fixed(void *jb)
00697 {
00698 struct fixed_jb *fixedjb = (struct fixed_jb *) jb;
00699
00700 return fixed_jb_next(fixedjb);
00701 }
00702
00703
00704 static int jb_remove_fixed(void *jb, struct ast_frame **fout)
00705 {
00706 struct fixed_jb *fixedjb = (struct fixed_jb *) jb;
00707 struct fixed_jb_frame frame;
00708 int res;
00709
00710 res = fixed_jb_remove(fixedjb, &frame);
00711 *fout = frame.data;
00712
00713 return fixed_to_abstract_code[res];
00714 }
00715
00716
00717 static void jb_force_resynch_fixed(void *jb)
00718 {
00719 struct fixed_jb *fixedjb = (struct fixed_jb *) jb;
00720
00721 fixed_jb_set_force_resynch(fixedjb);
00722 }
00723
00724 static void jb_empty_and_reset_fixed(void *jb)
00725 {
00726 struct fixed_jb *fixedjb = jb;
00727 struct fixed_jb_frame f;
00728
00729 while (fixed_jb_remove(fixedjb, &f) == FIXED_JB_OK) {
00730 ast_frfree(f.data);
00731 }
00732 }
00733
00734
00735
00736 static void *jb_create_adaptive(struct ast_jb_conf *general_config, long resynch_threshold)
00737 {
00738 jb_conf jbconf;
00739 jitterbuf *adaptivejb;
00740
00741 adaptivejb = jb_new();
00742 if (adaptivejb) {
00743 jbconf.max_jitterbuf = general_config->max_size;
00744 jbconf.resync_threshold = general_config->resync_threshold;
00745 jbconf.max_contig_interp = 10;
00746 jbconf.target_extra = general_config->target_extra;
00747 jb_setconf(adaptivejb, &jbconf);
00748 }
00749
00750 return adaptivejb;
00751 }
00752
00753
00754 static void jb_destroy_adaptive(void *jb)
00755 {
00756 jitterbuf *adaptivejb = (jitterbuf *) jb;
00757
00758 jb_destroy(adaptivejb);
00759 }
00760
00761
00762 static int jb_put_first_adaptive(void *jb, struct ast_frame *fin, long now)
00763 {
00764 return jb_put_adaptive(jb, fin, now);
00765 }
00766
00767
00768 static int jb_put_adaptive(void *jb, struct ast_frame *fin, long now)
00769 {
00770 jitterbuf *adaptivejb = (jitterbuf *) jb;
00771 int res;
00772
00773 res = jb_put(adaptivejb, fin, JB_TYPE_VOICE, fin->len, fin->ts, now);
00774
00775 return adaptive_to_abstract_code[res];
00776 }
00777
00778
00779 static int jb_get_adaptive(void *jb, struct ast_frame **fout, long now, long interpl)
00780 {
00781 jitterbuf *adaptivejb = (jitterbuf *) jb;
00782 jb_frame frame;
00783 int res;
00784
00785 res = jb_get(adaptivejb, &frame, now, interpl);
00786 *fout = frame.data;
00787
00788 return adaptive_to_abstract_code[res];
00789 }
00790
00791
00792 static long jb_next_adaptive(void *jb)
00793 {
00794 jitterbuf *adaptivejb = (jitterbuf *) jb;
00795
00796 return jb_next(adaptivejb);
00797 }
00798
00799
00800 static int jb_remove_adaptive(void *jb, struct ast_frame **fout)
00801 {
00802 jitterbuf *adaptivejb = (jitterbuf *) jb;
00803 jb_frame frame;
00804 int res;
00805
00806 res = jb_getall(adaptivejb, &frame);
00807 *fout = frame.data;
00808
00809 return adaptive_to_abstract_code[res];
00810 }
00811
00812
00813 static void jb_force_resynch_adaptive(void *jb)
00814 {
00815 }
00816
00817 static void jb_empty_and_reset_adaptive(void *jb)
00818 {
00819 jitterbuf *adaptivejb = jb;
00820 jb_frame f;
00821
00822 while (jb_getall(adaptivejb, &f) == JB_OK) {
00823 ast_frfree(f.data);
00824 }
00825
00826 jb_reset(adaptivejb);
00827 }