#include "asterisk.h"
#include "asterisk/frame.h"
#include "asterisk/channel.h"
#include "asterisk/term.h"
#include "asterisk/utils.h"
#include "asterisk/abstract_jb.h"
#include "fixedjitterbuf.h"
#include "jitterbuf.h"

Go to the source code of this file.
Defines | |
| #define | jb_framelog(...) |
| Macros for the frame log files. | |
Enumerations | |
| enum | { JB_USE = (1 << 0), JB_TIMEBASE_INITIALIZED = (1 << 1), JB_CREATED = (1 << 2) } |
Functions | |
| void | ast_jb_configure (struct ast_channel *chan, const struct ast_jb_conf *conf) |
| Configures a jitterbuffer on a channel. | |
| void | ast_jb_destroy (struct ast_channel *chan) |
| Destroys jitterbuffer on a channel. | |
| int | ast_jb_do_usecheck (struct ast_channel *c0, struct ast_channel *c1) |
| Checks the need of a jb use in a generic bridge. | |
| void | ast_jb_empty_and_reset (struct ast_channel *c0, struct ast_channel *c1) |
| drops all frames from a jitterbuffer and resets it | |
| void | ast_jb_get_and_deliver (struct ast_channel *c0, struct ast_channel *c1) |
| Deliver the queued frames that should be delivered now for both channels. | |
| void | ast_jb_get_config (const struct ast_channel *chan, struct ast_jb_conf *conf) |
| Copies a channel's jitterbuffer configuration. | |
| struct ast_jb_impl * | ast_jb_get_impl (enum ast_jb_type type) |
| int | ast_jb_get_when_to_wakeup (struct ast_channel *c0, struct ast_channel *c1, int time_left) |
| Calculates the time, left to the closest delivery moment in a bridge. | |
| int | ast_jb_put (struct ast_channel *chan, struct ast_frame *f) |
| Puts a frame into a channel jitterbuffer. | |
| int | ast_jb_read_conf (struct ast_jb_conf *conf, const char *varname, const char *value) |
| Sets jitterbuffer configuration property. | |
| static int | create_jb (struct ast_channel *chan, struct ast_frame *first_frame) |
| static long | get_now (struct ast_jb *jb, struct timeval *tv) |
| static void | jb_choose_impl (struct ast_channel *chan) |
| static void * | jb_create_adaptive (struct ast_jb_conf *general_config, long resynch_threshold) |
| static void * | jb_create_fixed (struct ast_jb_conf *general_config, long resynch_threshold) |
| static void | jb_destroy_adaptive (void *jb) |
| static void | jb_destroy_fixed (void *jb) |
| static void | jb_empty_and_reset_adaptive (void *jb) |
| static void | jb_empty_and_reset_fixed (void *jb) |
| static void | jb_force_resynch_adaptive (void *jb) |
| static void | jb_force_resynch_fixed (void *jb) |
| static int | jb_get_adaptive (void *jb, struct ast_frame **fout, long now, long interpl) |
| static void | jb_get_and_deliver (struct ast_channel *chan) |
| static int | jb_get_fixed (void *jb, struct ast_frame **fout, long now, long interpl) |
| static long | jb_next_adaptive (void *jb) |
| static long | jb_next_fixed (void *jb) |
| static int | jb_put_adaptive (void *jb, struct ast_frame *fin, long now) |
| static int | jb_put_first_adaptive (void *jb, struct ast_frame *fin, long now) |
| static int | jb_put_first_fixed (void *jb, struct ast_frame *fin, long now) |
| static int | jb_put_fixed (void *jb, struct ast_frame *fin, long now) |
| static int | jb_remove_adaptive (void *jb, struct ast_frame **fout) |
| static int | jb_remove_fixed (void *jb, struct ast_frame **fout) |
Variables | |
| static const int | adaptive_to_abstract_code [] |
| static struct ast_jb_impl | avail_impl [] |
| static int | default_impl = 0 |
| static const int | fixed_to_abstract_code [] |
| static const char *const | jb_get_actions [] = {"Delivered", "Dropped", "Interpolated", "No"} |
Definition in file abstract_jb.c.
| #define jb_framelog | ( | ... | ) |
Macros for the frame log files.
Definition at line 117 of file abstract_jb.c.
Referenced by ast_jb_put(), create_jb(), and jb_get_and_deliver().
| anonymous enum |
Internal jb flags
Definition at line 46 of file abstract_jb.c.
00046 { 00047 JB_USE = (1 << 0), 00048 JB_TIMEBASE_INITIALIZED = (1 << 1), 00049 JB_CREATED = (1 << 2) 00050 };
| void ast_jb_configure | ( | struct ast_channel * | chan, | |
| const struct ast_jb_conf * | conf | |||
| ) |
Configures a jitterbuffer on a channel.
| chan | channel to configure. | |
| conf | configuration to apply. |
Definition at line 567 of file abstract_jb.c.
References ast_jb::conf, and ast_channel::jb.
Referenced by __oh323_rtp_create(), __oh323_update_info(), alsa_new(), console_new(), dahdi_new(), gtalk_new(), jingle_new(), local_new(), mgcp_new(), misdn_new(), oss_new(), sip_new(), skinny_new(), unistim_new(), and usbradio_new().
| void ast_jb_destroy | ( | struct ast_channel * | chan | ) |
Destroys jitterbuffer on a channel.
| chan | channel. |
Definition at line 487 of file abstract_jb.c.
References ast_channel_name(), ast_clear_flag, ast_frfree, AST_JB_IMPL_OK, ast_test_flag, ast_verb, ast_jb_impl::destroy, f, ast_jb::impl, ast_channel::jb, JB_CREATED, ast_jb::jbobj, ast_jb::logfile, ast_jb_impl::name, and ast_jb_impl::remove.
Referenced by ast_channel_destructor().
00488 { 00489 struct ast_jb *jb = &chan->jb; 00490 const struct ast_jb_impl *jbimpl = jb->impl; 00491 void *jbobj = jb->jbobj; 00492 struct ast_frame *f; 00493 00494 if (jb->logfile) { 00495 fclose(jb->logfile); 00496 jb->logfile = NULL; 00497 } 00498 00499 if (ast_test_flag(jb, JB_CREATED)) { 00500 /* Remove and free all frames still queued in jb */ 00501 while (jbimpl->remove(jbobj, &f) == AST_JB_IMPL_OK) { 00502 ast_frfree(f); 00503 } 00504 00505 jbimpl->destroy(jbobj); 00506 jb->jbobj = NULL; 00507 00508 ast_clear_flag(jb, JB_CREATED); 00509 00510 ast_verb(3, "%s jitterbuffer destroyed on channel %s\n", jbimpl->name, ast_channel_name(chan)); 00511 } 00512 }
| int ast_jb_do_usecheck | ( | struct ast_channel * | c0, | |
| struct ast_channel * | c1 | |||
| ) |
Checks the need of a jb use in a generic bridge.
| c0 | first bridged channel. | |
| c1 | second bridged channel. |
| zero | if there are no jitter buffers in use | |
| non-zero | if there are |
Definition at line 157 of file abstract_jb.c.
References AST_CHAN_TP_CREATESJITTER, AST_CHAN_TP_WANTSJITTER, AST_JB_ENABLED, AST_JB_FORCED, ast_set_flag, ast_test_flag, ast_jb::conf, ast_channel::jb, jb_choose_impl(), JB_CREATED, JB_TIMEBASE_INITIALIZED, JB_USE, ast_channel_tech::properties, ast_channel::tech, and ast_jb::timebase.
Referenced by ast_generic_bridge().
00158 { 00159 struct ast_jb *jb0 = &c0->jb; 00160 struct ast_jb *jb1 = &c1->jb; 00161 struct ast_jb_conf *conf0 = &jb0->conf; 00162 struct ast_jb_conf *conf1 = &jb1->conf; 00163 int c0_wants_jitter = c0->tech->properties & AST_CHAN_TP_WANTSJITTER; 00164 int c0_creates_jitter = c0->tech->properties & AST_CHAN_TP_CREATESJITTER; 00165 int c0_jb_enabled = ast_test_flag(conf0, AST_JB_ENABLED); 00166 int c0_force_jb = ast_test_flag(conf0, AST_JB_FORCED); 00167 int c0_jb_timebase_initialized = ast_test_flag(jb0, JB_TIMEBASE_INITIALIZED); 00168 int c0_jb_created = ast_test_flag(jb0, JB_CREATED); 00169 int c1_wants_jitter = c1->tech->properties & AST_CHAN_TP_WANTSJITTER; 00170 int c1_creates_jitter = c1->tech->properties & AST_CHAN_TP_CREATESJITTER; 00171 int c1_jb_enabled = ast_test_flag(conf1, AST_JB_ENABLED); 00172 int c1_force_jb = ast_test_flag(conf1, AST_JB_FORCED); 00173 int c1_jb_timebase_initialized = ast_test_flag(jb1, JB_TIMEBASE_INITIALIZED); 00174 int c1_jb_created = ast_test_flag(jb1, JB_CREATED); 00175 int inuse = 0; 00176 00177 /* Determine whether audio going to c0 needs a jitter buffer */ 00178 if (((!c0_wants_jitter && c1_creates_jitter) || (c0_force_jb && c1_creates_jitter)) && c0_jb_enabled) { 00179 ast_set_flag(jb0, JB_USE); 00180 if (!c0_jb_timebase_initialized) { 00181 if (c1_jb_timebase_initialized) { 00182 memcpy(&jb0->timebase, &jb1->timebase, sizeof(struct timeval)); 00183 } else { 00184 gettimeofday(&jb0->timebase, NULL); 00185 } 00186 ast_set_flag(jb0, JB_TIMEBASE_INITIALIZED); 00187 } 00188 00189 if (!c0_jb_created) { 00190 jb_choose_impl(c0); 00191 } 00192 00193 inuse = 1; 00194 } 00195 00196 /* Determine whether audio going to c1 needs a jitter buffer */ 00197 if (((!c1_wants_jitter && c0_creates_jitter) || (c1_force_jb && c0_creates_jitter)) && c1_jb_enabled) { 00198 ast_set_flag(jb1, JB_USE); 00199 if (!c1_jb_timebase_initialized) { 00200 if (c0_jb_timebase_initialized) { 00201 memcpy(&jb1->timebase, &jb0->timebase, sizeof(struct timeval)); 00202 } else { 00203 gettimeofday(&jb1->timebase, NULL); 00204 } 00205 ast_set_flag(jb1, JB_TIMEBASE_INITIALIZED); 00206 } 00207 00208 if (!c1_jb_created) { 00209 jb_choose_impl(c1); 00210 } 00211 00212 inuse = 1; 00213 } 00214 00215 return inuse; 00216 }
| void ast_jb_empty_and_reset | ( | struct ast_channel * | c0, | |
| struct ast_channel * | c1 | |||
| ) |
drops all frames from a jitterbuffer and resets it
| c0 | one channel of a bridge | |
| c1 | the other channel of the bridge |
Definition at line 578 of file abstract_jb.c.
References ast_test_flag, ast_jb_impl::empty_and_reset, ast_jb::impl, ast_channel::jb, JB_CREATED, JB_USE, and ast_jb::jbobj.
Referenced by ast_generic_bridge().
00579 { 00580 struct ast_jb *jb0 = &c0->jb; 00581 struct ast_jb *jb1 = &c1->jb; 00582 int c0_use_jb = ast_test_flag(jb0, JB_USE); 00583 int c0_jb_is_created = ast_test_flag(jb0, JB_CREATED); 00584 int c1_use_jb = ast_test_flag(jb1, JB_USE); 00585 int c1_jb_is_created = ast_test_flag(jb1, JB_CREATED); 00586 00587 if (c0_use_jb && c0_jb_is_created && jb0->impl->empty_and_reset) { 00588 jb0->impl->empty_and_reset(jb0->jbobj); 00589 } 00590 00591 if (c1_use_jb && c1_jb_is_created && jb1->impl->empty_and_reset) { 00592 jb1->impl->empty_and_reset(jb1->jbobj); 00593 } 00594 }
| void ast_jb_get_and_deliver | ( | struct ast_channel * | c0, | |
| struct ast_channel * | c1 | |||
| ) |
Deliver the queued frames that should be delivered now for both channels.
| c0 | first bridged channel. | |
| c1 | second bridged channel. |
Definition at line 323 of file abstract_jb.c.
References ast_test_flag, ast_channel::jb, JB_CREATED, jb_get_and_deliver(), and JB_USE.
Referenced by ast_generic_bridge().
00324 { 00325 struct ast_jb *jb0 = &c0->jb; 00326 struct ast_jb *jb1 = &c1->jb; 00327 int c0_use_jb = ast_test_flag(jb0, JB_USE); 00328 int c0_jb_is_created = ast_test_flag(jb0, JB_CREATED); 00329 int c1_use_jb = ast_test_flag(jb1, JB_USE); 00330 int c1_jb_is_created = ast_test_flag(jb1, JB_CREATED); 00331 00332 if (c0_use_jb && c0_jb_is_created) 00333 jb_get_and_deliver(c0); 00334 00335 if (c1_use_jb && c1_jb_is_created) 00336 jb_get_and_deliver(c1); 00337 }
| void ast_jb_get_config | ( | const struct ast_channel * | chan, | |
| struct ast_jb_conf * | conf | |||
| ) |
Copies a channel's jitterbuffer configuration.
| chan | channel. | |
| conf | destination. |
Definition at line 573 of file abstract_jb.c.
References ast_jb::conf, and ast_channel::jb.
| struct ast_jb_impl* ast_jb_get_impl | ( | enum ast_jb_type | type | ) | [read] |
Definition at line 791 of file abstract_jb.c.
References ARRAY_LEN.
Referenced by jb_framedata_init().
00792 { 00793 int i; 00794 for (i = 0; i < ARRAY_LEN(avail_impl); i++) { 00795 if (avail_impl[i].type == type) { 00796 return &avail_impl[i]; 00797 } 00798 } 00799 return NULL; 00800 }
| int ast_jb_get_when_to_wakeup | ( | struct ast_channel * | c0, | |
| struct ast_channel * | c1, | |||
| int | time_left | |||
| ) |
Calculates the time, left to the closest delivery moment in a bridge.
| c0 | first bridged channel. | |
| c1 | second bridged channel. | |
| time_left | bridge time limit, or -1 if not set. |
Definition at line 218 of file abstract_jb.c.
References ast_test_flag, get_now(), ast_channel::jb, JB_CREATED, JB_USE, and ast_jb::next.
Referenced by ast_generic_bridge().
00219 { 00220 struct ast_jb *jb0 = &c0->jb; 00221 struct ast_jb *jb1 = &c1->jb; 00222 int c0_use_jb = ast_test_flag(jb0, JB_USE); 00223 int c0_jb_is_created = ast_test_flag(jb0, JB_CREATED); 00224 int c1_use_jb = ast_test_flag(jb1, JB_USE); 00225 int c1_jb_is_created = ast_test_flag(jb1, JB_CREATED); 00226 int wait, wait0, wait1; 00227 struct timeval tv_now; 00228 00229 if (time_left == 0) { 00230 /* No time left - the bridge will be retried */ 00231 /* TODO: Test disable this */ 00232 /*return 0;*/ 00233 } 00234 00235 if (time_left < 0) { 00236 time_left = INT_MAX; 00237 } 00238 00239 gettimeofday(&tv_now, NULL); 00240 00241 wait0 = (c0_use_jb && c0_jb_is_created) ? jb0->next - get_now(jb0, &tv_now) : time_left; 00242 wait1 = (c1_use_jb && c1_jb_is_created) ? jb1->next - get_now(jb1, &tv_now) : time_left; 00243 00244 wait = wait0 < wait1 ? wait0 : wait1; 00245 wait = wait < time_left ? wait : time_left; 00246 00247 if (wait == INT_MAX) { 00248 wait = -1; 00249 } else if (wait < 1) { 00250 /* don't let wait=0, because this can cause the pbx thread to loop without any sleeping at all */ 00251 wait = 1; 00252 } 00253 00254 return wait; 00255 }
| int ast_jb_put | ( | struct ast_channel * | chan, | |
| struct ast_frame * | f | |||
| ) |
Puts a frame into a channel jitterbuffer.
| chan | channel. | |
| f | frame. |
| 0 | if the frame was queued | |
| -1 | if not |
Definition at line 258 of file abstract_jb.c.
References ast_channel_name(), ast_clear_flag, AST_FRAME_DTMF, AST_FRAME_VOICE, ast_frdup(), AST_FRFLAG_HAS_TIMING_INFO, ast_frfree, AST_JB_IMPL_OK, ast_log(), ast_set_flag, ast_test_flag, create_jb(), ast_jb_impl::force_resync, ast_frame::frametype, get_now(), ast_jb::impl, ast_channel::jb, JB_CREATED, jb_framelog, JB_USE, ast_jb::jbobj, ast_frame::len, LOG_ERROR, LOG_WARNING, ast_jb_impl::next, ast_jb::next, ast_jb_impl::put, ast_frame::src, and ast_frame::ts.
Referenced by ast_generic_bridge().
00259 { 00260 struct ast_jb *jb = &chan->jb; 00261 const struct ast_jb_impl *jbimpl = jb->impl; 00262 void *jbobj = jb->jbobj; 00263 struct ast_frame *frr; 00264 long now = 0; 00265 00266 if (!ast_test_flag(jb, JB_USE)) 00267 return -1; 00268 00269 if (f->frametype != AST_FRAME_VOICE) { 00270 if (f->frametype == AST_FRAME_DTMF && ast_test_flag(jb, JB_CREATED)) { 00271 jb_framelog("JB_PUT {now=%ld}: Received DTMF frame. Force resynching jb...\n", now); 00272 jbimpl->force_resync(jbobj); 00273 } 00274 00275 return -1; 00276 } 00277 00278 /* We consider an enabled jitterbuffer should receive frames with valid timing info. */ 00279 if (!ast_test_flag(f, AST_FRFLAG_HAS_TIMING_INFO) || f->len < 2 || f->ts < 0) { 00280 ast_log(LOG_WARNING, "%s received frame with invalid timing info: " 00281 "has_timing_info=%d, len=%ld, ts=%ld, src=%s\n", 00282 ast_channel_name(chan), ast_test_flag(f, AST_FRFLAG_HAS_TIMING_INFO), f->len, f->ts, f->src); 00283 return -1; 00284 } 00285 00286 frr = ast_frdup(f); 00287 00288 if (!frr) { 00289 ast_log(LOG_ERROR, "Failed to isolate frame for the jitterbuffer on channel '%s'\n", ast_channel_name(chan)); 00290 return -1; 00291 } 00292 00293 if (!ast_test_flag(jb, JB_CREATED)) { 00294 if (create_jb(chan, frr)) { 00295 ast_frfree(frr); 00296 /* Disable the jitterbuffer */ 00297 ast_clear_flag(jb, JB_USE); 00298 return -1; 00299 } 00300 00301 ast_set_flag(jb, JB_CREATED); 00302 return 0; 00303 } else { 00304 now = get_now(jb, NULL); 00305 if (jbimpl->put(jbobj, frr, now) != AST_JB_IMPL_OK) { 00306 jb_framelog("JB_PUT {now=%ld}: Dropped frame with ts=%ld and len=%ld\n", now, frr->ts, frr->len); 00307 ast_frfree(frr); 00308 /*return -1;*/ 00309 /* TODO: Check this fix - should return 0 here, because the dropped frame shouldn't 00310 be delivered at all */ 00311 return 0; 00312 } 00313 00314 jb->next = jbimpl->next(jbobj); 00315 00316 jb_framelog("JB_PUT {now=%ld}: Queued frame with ts=%ld and len=%ld\n", now, frr->ts, frr->len); 00317 00318 return 0; 00319 } 00320 }
| int ast_jb_read_conf | ( | struct ast_jb_conf * | conf, | |
| const char * | varname, | |||
| const char * | value | |||
| ) |
Sets jitterbuffer configuration property.
| conf | configuration to store the property in. | |
| varname | property name. | |
| value | property value. |
Definition at line 528 of file abstract_jb.c.
References AST_JB_CONF_ENABLE, AST_JB_CONF_FORCE, AST_JB_CONF_IMPL, AST_JB_CONF_LOG, AST_JB_CONF_MAX_SIZE, AST_JB_CONF_PREFIX, AST_JB_CONF_RESYNCH_THRESHOLD, AST_JB_CONF_TARGET_EXTRA, AST_JB_ENABLED, AST_JB_FORCED, AST_JB_LOG, ast_set2_flag, ast_strlen_zero(), ast_true(), ast_jb_conf::impl, ast_jb_conf::max_size, name, ast_jb_conf::resync_threshold, and ast_jb_conf::target_extra.
Referenced by _build_general_config(), config_parse_variables(), gtalk_load_config(), jb_framedata_init(), jingle_load_config(), load_module(), process_dahdi(), reload_config(), store_config(), and store_config_core().
00529 { 00530 int prefixlen = sizeof(AST_JB_CONF_PREFIX) - 1; 00531 const char *name; 00532 int tmp; 00533 00534 if (strncasecmp(AST_JB_CONF_PREFIX, varname, prefixlen)) { 00535 return -1; 00536 } 00537 00538 name = varname + prefixlen; 00539 00540 if (!strcasecmp(name, AST_JB_CONF_ENABLE)) { 00541 ast_set2_flag(conf, ast_true(value), AST_JB_ENABLED); 00542 } else if (!strcasecmp(name, AST_JB_CONF_FORCE)) { 00543 ast_set2_flag(conf, ast_true(value), AST_JB_FORCED); 00544 } else if (!strcasecmp(name, AST_JB_CONF_MAX_SIZE)) { 00545 if ((tmp = atoi(value)) > 0) 00546 conf->max_size = tmp; 00547 } else if (!strcasecmp(name, AST_JB_CONF_RESYNCH_THRESHOLD)) { 00548 if ((tmp = atoi(value)) > 0) 00549 conf->resync_threshold = tmp; 00550 } else if (!strcasecmp(name, AST_JB_CONF_IMPL)) { 00551 if (!ast_strlen_zero(value)) 00552 snprintf(conf->impl, sizeof(conf->impl), "%s", value); 00553 } else if (!strcasecmp(name, AST_JB_CONF_TARGET_EXTRA)) { 00554 if (sscanf(value, "%30d", &tmp) == 1) { 00555 conf->target_extra = tmp; 00556 } 00557 } else if (!strcasecmp(name, AST_JB_CONF_LOG)) { 00558 ast_set2_flag(conf, ast_true(value), AST_JB_LOG); 00559 } else { 00560 return -1; 00561 } 00562 00563 return 0; 00564 }
| static int create_jb | ( | struct ast_channel * | chan, | |
| struct ast_frame * | first_frame | |||
| ) | [static] |
Definition at line 400 of file abstract_jb.c.
References ast_assert, ast_bridged_channel(), ast_channel_name(), AST_CHANNEL_NAME, ast_format_copy(), ast_frfree, AST_JB_IMPL_NAME_SIZE, AST_JB_IMPL_OK, AST_JB_LOG, ast_log(), ast_test_flag, ast_verb, ast_jb::conf, ast_jb_impl::create, errno, ast_frame_subclass::format, get_now(), ast_jb::impl, ast_channel::jb, jb_framelog, ast_jb::jbobj, ast_jb::last_format, ast_frame::len, LOG_ERROR, LOG_WARNING, ast_jb::logfile, ast_jb_impl::name, ast_jb_impl::next, ast_jb::next, ast_jb_impl::put_first, ast_jb_conf::resync_threshold, ast_frame::subclass, and ast_frame::ts.
Referenced by ast_jb_put().
00401 { 00402 struct ast_jb *jb = &chan->jb; 00403 struct ast_jb_conf *jbconf = &jb->conf; 00404 const struct ast_jb_impl *jbimpl = jb->impl; 00405 void *jbobj; 00406 struct ast_channel *bridged; 00407 long now; 00408 char logfile_pathname[20 + AST_JB_IMPL_NAME_SIZE + 2*AST_CHANNEL_NAME + 1]; 00409 char name1[AST_CHANNEL_NAME], name2[AST_CHANNEL_NAME], *tmp; 00410 int res; 00411 00412 jbobj = jb->jbobj = jbimpl->create(jbconf, jbconf->resync_threshold); 00413 if (!jbobj) { 00414 ast_log(LOG_WARNING, "Failed to create jitterbuffer on channel '%s'\n", ast_channel_name(chan)); 00415 return -1; 00416 } 00417 00418 now = get_now(jb, NULL); 00419 res = jbimpl->put_first(jbobj, frr, now); 00420 00421 /* The result of putting the first frame should not differ from OK. However, its possible 00422 some implementations (i.e. adaptive's when resynch_threshold is specified) to drop it. */ 00423 if (res != AST_JB_IMPL_OK) { 00424 ast_log(LOG_WARNING, "Failed to put first frame in the jitterbuffer on channel '%s'\n", ast_channel_name(chan)); 00425 /* 00426 jbimpl->destroy(jbobj); 00427 return -1; 00428 */ 00429 } 00430 00431 /* Init next */ 00432 jb->next = jbimpl->next(jbobj); 00433 00434 /* Init last format for a first time. */ 00435 ast_format_copy(&jb->last_format, &frr->subclass.format); 00436 00437 /* Create a frame log file */ 00438 if (ast_test_flag(jbconf, AST_JB_LOG)) { 00439 char safe_logfile[30] = "/tmp/logfile-XXXXXX"; 00440 int safe_fd; 00441 snprintf(name2, sizeof(name2), "%s", ast_channel_name(chan)); 00442 if ((tmp = strchr(name2, '/'))) { 00443 *tmp = '#'; 00444 } 00445 00446 bridged = ast_bridged_channel(chan); 00447 /* We should always have bridged chan if a jitterbuffer is in use */ 00448 ast_assert(bridged != NULL); 00449 00450 snprintf(name1, sizeof(name1), "%s", ast_channel_name(bridged)); 00451 if ((tmp = strchr(name1, '/'))) { 00452 *tmp = '#'; 00453 } 00454 00455 snprintf(logfile_pathname, sizeof(logfile_pathname), 00456 "/tmp/ast_%s_jb_%s--%s.log", jbimpl->name, name1, name2); 00457 unlink(logfile_pathname); 00458 safe_fd = mkstemp(safe_logfile); 00459 if (safe_fd < 0 || link(safe_logfile, logfile_pathname) || unlink(safe_logfile) || !(jb->logfile = fdopen(safe_fd, "w+b"))) { 00460 ast_log(LOG_ERROR, "Failed to create frame log file with pathname '%s': %s\n", logfile_pathname, strerror(errno)); 00461 jb->logfile = NULL; 00462 if (safe_fd > -1) { 00463 close(safe_fd); 00464 } 00465 } 00466 00467 if (res == AST_JB_IMPL_OK) { 00468 jb_framelog("JB_PUT_FIRST {now=%ld}: Queued frame with ts=%ld and len=%ld\n", 00469 now, frr->ts, frr->len); 00470 } else { 00471 jb_framelog("JB_PUT_FIRST {now=%ld}: Dropped frame with ts=%ld and len=%ld\n", 00472 now, frr->ts, frr->len); 00473 } 00474 } 00475 00476 ast_verb(3, "%s jitterbuffer created on channel %s\n", jbimpl->name, ast_channel_name(chan)); 00477 00478 /* Free the frame if it has not been queued in the jb */ 00479 if (res != AST_JB_IMPL_OK) { 00480 ast_frfree(frr); 00481 } 00482 00483 return 0; 00484 }
| static long get_now | ( | struct ast_jb * | jb, | |
| struct timeval * | tv | |||
| ) | [static] |
Definition at line 515 of file abstract_jb.c.
References ast_tvdiff_ms(), and ast_jb::timebase.
Referenced by ast_jb_get_when_to_wakeup(), ast_jb_put(), create_jb(), and jb_get_and_deliver().
00516 { 00517 struct timeval now; 00518 00519 if (!when) { 00520 when = &now; 00521 gettimeofday(when, NULL); 00522 } 00523 00524 return ast_tvdiff_ms(*when, jb->timebase); 00525 }
| static void jb_choose_impl | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 135 of file abstract_jb.c.
References ARRAY_LEN, ast_strlen_zero(), ast_jb::conf, ast_jb_conf::impl, ast_jb::impl, ast_channel::jb, and ast_jb_impl::name.
Referenced by ast_jb_do_usecheck().
00136 { 00137 struct ast_jb *jb = &chan->jb; 00138 struct ast_jb_conf *jbconf = &jb->conf; 00139 const struct ast_jb_impl *test_impl; 00140 int i, avail_impl_count = ARRAY_LEN(avail_impl); 00141 00142 jb->impl = &avail_impl[default_impl]; 00143 00144 if (ast_strlen_zero(jbconf->impl)) { 00145 return; 00146 } 00147 00148 for (i = 0; i < avail_impl_count; i++) { 00149 test_impl = &avail_impl[i]; 00150 if (!strcasecmp(jbconf->impl, test_impl->name)) { 00151 jb->impl = test_impl; 00152 return; 00153 } 00154 } 00155 }
| static void * jb_create_adaptive | ( | struct ast_jb_conf * | general_config, | |
| long | resynch_threshold | |||
| ) | [static] |
Definition at line 693 of file abstract_jb.c.
References jb_new(), jb_setconf(), jb_conf::max_contig_interp, jb_conf::max_jitterbuf, ast_jb_conf::max_size, ast_jb_conf::resync_threshold, jb_conf::resync_threshold, ast_jb_conf::target_extra, and jb_conf::target_extra.
00694 { 00695 jb_conf jbconf; 00696 jitterbuf *adaptivejb; 00697 00698 adaptivejb = jb_new(); 00699 if (adaptivejb) { 00700 jbconf.max_jitterbuf = general_config->max_size; 00701 jbconf.resync_threshold = general_config->resync_threshold; 00702 jbconf.max_contig_interp = 10; 00703 jbconf.target_extra = general_config->target_extra; 00704 jb_setconf(adaptivejb, &jbconf); 00705 } 00706 00707 return adaptivejb; 00708 }
| static void * jb_create_fixed | ( | struct ast_jb_conf * | general_config, | |
| long | resynch_threshold | |||
| ) | [static] |
Definition at line 599 of file abstract_jb.c.
References fixed_jb_new(), fixed_jb_conf::jbsize, ast_jb_conf::max_size, and fixed_jb_conf::resync_threshold.
00600 { 00601 struct fixed_jb_conf conf; 00602 00603 conf.jbsize = general_config->max_size; 00604 conf.resync_threshold = resynch_threshold; 00605 00606 return fixed_jb_new(&conf); 00607 }
| static void jb_destroy_adaptive | ( | void * | jb | ) | [static] |
Definition at line 711 of file abstract_jb.c.
References jb_destroy().
00712 { 00713 jitterbuf *adaptivejb = (jitterbuf *) jb; 00714 00715 jb_destroy(adaptivejb); 00716 }
| static void jb_destroy_fixed | ( | void * | jb | ) | [static] |
Definition at line 609 of file abstract_jb.c.
References fixed_jb_destroy().
00610 { 00611 struct fixed_jb *fixedjb = (struct fixed_jb *) jb; 00612 00613 /* destroy the jb */ 00614 fixed_jb_destroy(fixedjb); 00615 }
| static void jb_empty_and_reset_adaptive | ( | void * | jb | ) | [static] |
Definition at line 779 of file abstract_jb.c.
References ast_frfree, jb_frame::data, f, jb_getall(), JB_OK, and jb_reset().
00780 { 00781 jitterbuf *adaptivejb = jb; 00782 jb_frame f; 00783 00784 while (jb_getall(adaptivejb, &f) == JB_OK) { 00785 ast_frfree(f.data); 00786 } 00787 00788 jb_reset(adaptivejb); 00789 }
| static void jb_empty_and_reset_fixed | ( | void * | jb | ) | [static] |
Definition at line 681 of file abstract_jb.c.
References ast_frfree, fixed_jb_frame::data, FIXED_JB_OK, and fixed_jb_remove().
00682 { 00683 struct fixed_jb *fixedjb = jb; 00684 struct fixed_jb_frame f; 00685 00686 while (fixed_jb_remove(fixedjb, &f) == FIXED_JB_OK) { 00687 ast_frfree(f.data); 00688 } 00689 }
| static void jb_force_resynch_adaptive | ( | void * | jb | ) | [static] |
| static void jb_force_resynch_fixed | ( | void * | jb | ) | [static] |
Definition at line 674 of file abstract_jb.c.
References fixed_jb_set_force_resynch().
00675 { 00676 struct fixed_jb *fixedjb = (struct fixed_jb *) jb; 00677 00678 fixed_jb_set_force_resynch(fixedjb); 00679 }
| static int jb_get_adaptive | ( | void * | jb, | |
| struct ast_frame ** | fout, | |||
| long | now, | |||
| long | interpl | |||
| ) | [static] |
Definition at line 741 of file abstract_jb.c.
References jb_frame::data, and jb_get().
00742 { 00743 jitterbuf *adaptivejb = (jitterbuf *) jb; 00744 jb_frame frame; 00745 int res; 00746 00747 res = jb_get(adaptivejb, &frame, now, interpl); 00748 *fout = frame.data; 00749 00750 return adaptive_to_abstract_code[res]; 00751 }
| static void jb_get_and_deliver | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 340 of file abstract_jb.c.
References ast_assert, ast_codec_interp_len(), ast_format_copy(), AST_FRAME_VOICE, ast_frfree, AST_FRIENDLY_OFFSET, AST_JB_IMPL_DROP, AST_JB_IMPL_INTERP, AST_JB_IMPL_NOFRAME, AST_JB_IMPL_OK, ast_log(), ast_samp2tv(), ast_tvadd(), ast_write(), ast_frame::delivery, f, ast_frame_subclass::format, ast_jb_impl::get, get_now(), ast_jb::impl, ast_channel::jb, jb_framelog, ast_jb::jbobj, ast_jb::last_format, ast_frame::len, LOG_ERROR, LOG_WARNING, ast_jb_impl::name, ast_frame::next, ast_jb_impl::next, ast_jb::next, ast_frame::offset, ast_frame::samples, ast_frame::src, ast_frame::subclass, ast_jb::timebase, and ast_frame::ts.
Referenced by ast_jb_get_and_deliver().
00341 { 00342 struct ast_jb *jb = &chan->jb; 00343 const struct ast_jb_impl *jbimpl = jb->impl; 00344 void *jbobj = jb->jbobj; 00345 struct ast_frame *f, finterp = { .frametype = AST_FRAME_VOICE, }; 00346 long now; 00347 int interpolation_len, res; 00348 00349 now = get_now(jb, NULL); 00350 jb->next = jbimpl->next(jbobj); 00351 if (now < jb->next) { 00352 jb_framelog("\tJB_GET {now=%ld}: now < next=%ld\n", now, jb->next); 00353 return; 00354 } 00355 00356 while (now >= jb->next) { 00357 interpolation_len = ast_codec_interp_len(&jb->last_format); 00358 00359 res = jbimpl->get(jbobj, &f, now, interpolation_len); 00360 00361 switch (res) { 00362 case AST_JB_IMPL_OK: 00363 /* deliver the frame */ 00364 ast_write(chan, f); 00365 case AST_JB_IMPL_DROP: 00366 jb_framelog("\tJB_GET {now=%ld}: %s frame with ts=%ld and len=%ld\n", 00367 now, jb_get_actions[res], f->ts, f->len); 00368 ast_format_copy(&jb->last_format, &f->subclass.format); 00369 ast_frfree(f); 00370 break; 00371 case AST_JB_IMPL_INTERP: 00372 /* interpolate a frame */ 00373 f = &finterp; 00374 ast_format_copy(&f->subclass.format, &jb->last_format); 00375 f->samples = interpolation_len * 8; 00376 f->src = "JB interpolation"; 00377 f->delivery = ast_tvadd(jb->timebase, ast_samp2tv(jb->next, 1000)); 00378 f->offset = AST_FRIENDLY_OFFSET; 00379 /* deliver the interpolated frame */ 00380 ast_write(chan, f); 00381 jb_framelog("\tJB_GET {now=%ld}: Interpolated frame with len=%d\n", now, interpolation_len); 00382 break; 00383 case AST_JB_IMPL_NOFRAME: 00384 ast_log(LOG_WARNING, 00385 "AST_JB_IMPL_NOFRAME is returned from the %s jb when now=%ld >= next=%ld, jbnext=%ld!\n", 00386 jbimpl->name, now, jb->next, jbimpl->next(jbobj)); 00387 jb_framelog("\tJB_GET {now=%ld}: No frame for now!?\n", now); 00388 return; 00389 default: 00390 ast_log(LOG_ERROR, "This should never happen!\n"); 00391 ast_assert("JB type unknown" == NULL); 00392 break; 00393 } 00394 00395 jb->next = jbimpl->next(jbobj); 00396 } 00397 }
| static int jb_get_fixed | ( | void * | jb, | |
| struct ast_frame ** | fout, | |||
| long | now, | |||
| long | interpl | |||
| ) | [static] |
Definition at line 640 of file abstract_jb.c.
References fixed_jb_frame::data, and fixed_jb_get().
00641 { 00642 struct fixed_jb *fixedjb = (struct fixed_jb *) jb; 00643 struct fixed_jb_frame frame; 00644 int res; 00645 00646 res = fixed_jb_get(fixedjb, &frame, now, interpl); 00647 *fout = frame.data; 00648 00649 return fixed_to_abstract_code[res]; 00650 }
| static long jb_next_adaptive | ( | void * | jb | ) | [static] |
| static long jb_next_fixed | ( | void * | jb | ) | [static] |
Definition at line 653 of file abstract_jb.c.
References fixed_jb_next().
00654 { 00655 struct fixed_jb *fixedjb = (struct fixed_jb *) jb; 00656 00657 return fixed_jb_next(fixedjb); 00658 }
| static int jb_put_adaptive | ( | void * | jb, | |
| struct ast_frame * | fin, | |||
| long | now | |||
| ) | [static] |
Definition at line 730 of file abstract_jb.c.
References jb_put(), JB_TYPE_VOICE, ast_frame::len, and ast_frame::ts.
Referenced by jb_put_first_adaptive().
00731 { 00732 jitterbuf *adaptivejb = (jitterbuf *) jb; 00733 int res; 00734 00735 res = jb_put(adaptivejb, fin, JB_TYPE_VOICE, fin->len, fin->ts, now); 00736 00737 return adaptive_to_abstract_code[res]; 00738 }
| static int jb_put_first_adaptive | ( | void * | jb, | |
| struct ast_frame * | fin, | |||
| long | now | |||
| ) | [static] |
Definition at line 719 of file abstract_jb.c.
References jitterbuf::info, jb_put_adaptive(), jb_info::resync_offset, and ast_frame::ts.
00720 { 00721 jitterbuf *adaptivejb = (jitterbuf *) jb; 00722 00723 /* Initialize the offset to that of the first frame's timestamp */ 00724 adaptivejb->info.resync_offset = fin->ts; 00725 00726 return jb_put_adaptive(jb, fin, now); 00727 }
| static int jb_put_first_fixed | ( | void * | jb, | |
| struct ast_frame * | fin, | |||
| long | now | |||
| ) | [static] |
Definition at line 618 of file abstract_jb.c.
References fixed_jb_put_first(), ast_frame::len, and ast_frame::ts.
00619 { 00620 struct fixed_jb *fixedjb = (struct fixed_jb *) jb; 00621 int res; 00622 00623 res = fixed_jb_put_first(fixedjb, fin, fin->len, fin->ts, now); 00624 00625 return fixed_to_abstract_code[res]; 00626 }
| static int jb_put_fixed | ( | void * | jb, | |
| struct ast_frame * | fin, | |||
| long | now | |||
| ) | [static] |
Definition at line 629 of file abstract_jb.c.
References fixed_jb_put(), ast_frame::len, and ast_frame::ts.
00630 { 00631 struct fixed_jb *fixedjb = (struct fixed_jb *) jb; 00632 int res; 00633 00634 res = fixed_jb_put(fixedjb, fin, fin->len, fin->ts, now); 00635 00636 return fixed_to_abstract_code[res]; 00637 }
| static int jb_remove_adaptive | ( | void * | jb, | |
| struct ast_frame ** | fout | |||
| ) | [static] |
Definition at line 762 of file abstract_jb.c.
References jb_frame::data, and jb_getall().
00763 { 00764 jitterbuf *adaptivejb = (jitterbuf *) jb; 00765 jb_frame frame; 00766 int res; 00767 00768 res = jb_getall(adaptivejb, &frame); 00769 *fout = frame.data; 00770 00771 return adaptive_to_abstract_code[res]; 00772 }
| static int jb_remove_fixed | ( | void * | jb, | |
| struct ast_frame ** | fout | |||
| ) | [static] |
Definition at line 661 of file abstract_jb.c.
References fixed_jb_frame::data, and fixed_jb_remove().
00662 { 00663 struct fixed_jb *fixedjb = (struct fixed_jb *) jb; 00664 struct fixed_jb_frame frame; 00665 int res; 00666 00667 res = fixed_jb_remove(fixedjb, &frame); 00668 *fout = frame.data; 00669 00670 return fixed_to_abstract_code[res]; 00671 }
const int adaptive_to_abstract_code[] [static] |
Initial value:
{AST_JB_IMPL_OK, AST_JB_IMPL_NOFRAME, AST_JB_IMPL_NOFRAME, AST_JB_IMPL_INTERP, AST_JB_IMPL_DROP, AST_JB_IMPL_OK}
Definition at line 110 of file abstract_jb.c.
struct ast_jb_impl avail_impl[] [static] |
Definition at line 76 of file abstract_jb.c.
int default_impl = 0 [static] |
Definition at line 105 of file abstract_jb.c.
const int fixed_to_abstract_code[] [static] |
Initial value:
Definition at line 108 of file abstract_jb.c.
const char* const jb_get_actions[] = {"Delivered", "Dropped", "Interpolated", "No"} [static] |
Definition at line 114 of file abstract_jb.c.
1.5.6