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