#include <sys/time.h>
#include "asterisk/frame_defs.h"
Go to the source code of this file.
Data Structures | |
struct | ast_jb |
General jitterbuffer state. More... | |
struct | ast_jb_conf |
General jitterbuffer configuration. More... | |
Defines | |
#define | AST_JB_CONF_ENABLE "enable" |
#define | AST_JB_CONF_FORCE "force" |
#define | AST_JB_CONF_IMPL "impl" |
#define | AST_JB_CONF_LOG "log" |
#define | AST_JB_CONF_MAX_SIZE "maxsize" |
#define | AST_JB_CONF_PREFIX "jb" |
#define | AST_JB_CONF_RESYNCH_THRESHOLD "resyncthreshold" |
#define | AST_JB_CONF_TARGET_EXTRA "targetextra" |
#define | AST_JB_IMPL_NAME_SIZE 12 |
Enumerations | |
enum | { AST_JB_ENABLED = (1 << 0), AST_JB_FORCED = (1 << 1), AST_JB_LOG = (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. | |
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. |
Definition in file abstract_jb.h.
#define AST_JB_CONF_ENABLE "enable" |
#define AST_JB_CONF_FORCE "force" |
#define AST_JB_CONF_IMPL "impl" |
#define AST_JB_CONF_LOG "log" |
#define AST_JB_CONF_MAX_SIZE "maxsize" |
#define AST_JB_CONF_PREFIX "jb" |
#define AST_JB_CONF_RESYNCH_THRESHOLD "resyncthreshold" |
#define AST_JB_CONF_TARGET_EXTRA "targetextra" |
#define AST_JB_IMPL_NAME_SIZE 12 |
anonymous enum |
Definition at line 44 of file abstract_jb.h.
00044 { 00045 AST_JB_ENABLED = (1 << 0), 00046 AST_JB_FORCED = (1 << 1), 00047 AST_JB_LOG = (1 << 2) 00048 };
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 616 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(), and unistim_new().
void ast_jb_destroy | ( | struct ast_channel * | chan | ) |
Destroys jitterbuffer on a channel.
chan | channel. |
Definition at line 536 of file abstract_jb.c.
References ast_clear_flag, ast_frfree, ast_test_flag, ast_verb, ast_jb_impl::destroy, f, ast_jb::impl, ast_channel::jb, JB_CREATED, JB_IMPL_OK, ast_jb::jbobj, ast_jb::logfile, ast_jb_impl::name, ast_channel::name, and ast_jb_impl::remove.
Referenced by ast_channel_destructor().
00537 { 00538 struct ast_jb *jb = &chan->jb; 00539 const struct ast_jb_impl *jbimpl = jb->impl; 00540 void *jbobj = jb->jbobj; 00541 struct ast_frame *f; 00542 00543 if (jb->logfile) { 00544 fclose(jb->logfile); 00545 jb->logfile = NULL; 00546 } 00547 00548 if (ast_test_flag(jb, JB_CREATED)) { 00549 /* Remove and free all frames still queued in jb */ 00550 while (jbimpl->remove(jbobj, &f) == JB_IMPL_OK) { 00551 ast_frfree(f); 00552 } 00553 00554 jbimpl->destroy(jbobj); 00555 jb->jbobj = NULL; 00556 00557 ast_clear_flag(jb, JB_CREATED); 00558 00559 ast_verb(3, "%s jitterbuffer destroyed on channel %s\n", jbimpl->name, chan->name); 00560 } 00561 }
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 205 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().
00206 { 00207 struct ast_jb *jb0 = &c0->jb; 00208 struct ast_jb *jb1 = &c1->jb; 00209 struct ast_jb_conf *conf0 = &jb0->conf; 00210 struct ast_jb_conf *conf1 = &jb1->conf; 00211 int c0_wants_jitter = c0->tech->properties & AST_CHAN_TP_WANTSJITTER; 00212 int c0_creates_jitter = c0->tech->properties & AST_CHAN_TP_CREATESJITTER; 00213 int c0_jb_enabled = ast_test_flag(conf0, AST_JB_ENABLED); 00214 int c0_force_jb = ast_test_flag(conf0, AST_JB_FORCED); 00215 int c0_jb_timebase_initialized = ast_test_flag(jb0, JB_TIMEBASE_INITIALIZED); 00216 int c0_jb_created = ast_test_flag(jb0, JB_CREATED); 00217 int c1_wants_jitter = c1->tech->properties & AST_CHAN_TP_WANTSJITTER; 00218 int c1_creates_jitter = c1->tech->properties & AST_CHAN_TP_CREATESJITTER; 00219 int c1_jb_enabled = ast_test_flag(conf1, AST_JB_ENABLED); 00220 int c1_force_jb = ast_test_flag(conf1, AST_JB_FORCED); 00221 int c1_jb_timebase_initialized = ast_test_flag(jb1, JB_TIMEBASE_INITIALIZED); 00222 int c1_jb_created = ast_test_flag(jb1, JB_CREATED); 00223 int inuse = 0; 00224 00225 /* Determine whether audio going to c0 needs a jitter buffer */ 00226 if (((!c0_wants_jitter && c1_creates_jitter) || (c0_force_jb && c1_creates_jitter)) && c0_jb_enabled) { 00227 ast_set_flag(jb0, JB_USE); 00228 if (!c0_jb_timebase_initialized) { 00229 if (c1_jb_timebase_initialized) { 00230 memcpy(&jb0->timebase, &jb1->timebase, sizeof(struct timeval)); 00231 } else { 00232 gettimeofday(&jb0->timebase, NULL); 00233 } 00234 ast_set_flag(jb0, JB_TIMEBASE_INITIALIZED); 00235 } 00236 00237 if (!c0_jb_created) { 00238 jb_choose_impl(c0); 00239 } 00240 00241 inuse = 1; 00242 } 00243 00244 /* Determine whether audio going to c1 needs a jitter buffer */ 00245 if (((!c1_wants_jitter && c0_creates_jitter) || (c1_force_jb && c0_creates_jitter)) && c1_jb_enabled) { 00246 ast_set_flag(jb1, JB_USE); 00247 if (!c1_jb_timebase_initialized) { 00248 if (c0_jb_timebase_initialized) { 00249 memcpy(&jb1->timebase, &jb0->timebase, sizeof(struct timeval)); 00250 } else { 00251 gettimeofday(&jb1->timebase, NULL); 00252 } 00253 ast_set_flag(jb1, JB_TIMEBASE_INITIALIZED); 00254 } 00255 00256 if (!c1_jb_created) { 00257 jb_choose_impl(c1); 00258 } 00259 00260 inuse = 1; 00261 } 00262 00263 return inuse; 00264 }
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 627 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().
00628 { 00629 struct ast_jb *jb0 = &c0->jb; 00630 struct ast_jb *jb1 = &c1->jb; 00631 int c0_use_jb = ast_test_flag(jb0, JB_USE); 00632 int c0_jb_is_created = ast_test_flag(jb0, JB_CREATED); 00633 int c1_use_jb = ast_test_flag(jb1, JB_USE); 00634 int c1_jb_is_created = ast_test_flag(jb1, JB_CREATED); 00635 00636 if (c0_use_jb && c0_jb_is_created && jb0->impl->empty_and_reset) { 00637 jb0->impl->empty_and_reset(jb0->jbobj); 00638 } 00639 00640 if (c1_use_jb && c1_jb_is_created && jb1->impl->empty_and_reset) { 00641 jb1->impl->empty_and_reset(jb1->jbobj); 00642 } 00643 }
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 371 of file abstract_jb.c.
References ast_test_flag, ast_channel::jb, JB_CREATED, jb_get_and_deliver(), and JB_USE.
00372 { 00373 struct ast_jb *jb0 = &c0->jb; 00374 struct ast_jb *jb1 = &c1->jb; 00375 int c0_use_jb = ast_test_flag(jb0, JB_USE); 00376 int c0_jb_is_created = ast_test_flag(jb0, JB_CREATED); 00377 int c1_use_jb = ast_test_flag(jb1, JB_USE); 00378 int c1_jb_is_created = ast_test_flag(jb1, JB_CREATED); 00379 00380 if (c0_use_jb && c0_jb_is_created) 00381 jb_get_and_deliver(c0); 00382 00383 if (c1_use_jb && c1_jb_is_created) 00384 jb_get_and_deliver(c1); 00385 }
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 622 of file abstract_jb.c.
References ast_jb::conf, and ast_channel::jb.
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 266 of file abstract_jb.c.
References ast_test_flag, get_now(), ast_channel::jb, JB_CREATED, JB_USE, and ast_jb::next.
00267 { 00268 struct ast_jb *jb0 = &c0->jb; 00269 struct ast_jb *jb1 = &c1->jb; 00270 int c0_use_jb = ast_test_flag(jb0, JB_USE); 00271 int c0_jb_is_created = ast_test_flag(jb0, JB_CREATED); 00272 int c1_use_jb = ast_test_flag(jb1, JB_USE); 00273 int c1_jb_is_created = ast_test_flag(jb1, JB_CREATED); 00274 int wait, wait0, wait1; 00275 struct timeval tv_now; 00276 00277 if (time_left == 0) { 00278 /* No time left - the bridge will be retried */ 00279 /* TODO: Test disable this */ 00280 /*return 0;*/ 00281 } 00282 00283 if (time_left < 0) { 00284 time_left = INT_MAX; 00285 } 00286 00287 gettimeofday(&tv_now, NULL); 00288 00289 wait0 = (c0_use_jb && c0_jb_is_created) ? jb0->next - get_now(jb0, &tv_now) : time_left; 00290 wait1 = (c1_use_jb && c1_jb_is_created) ? jb1->next - get_now(jb1, &tv_now) : time_left; 00291 00292 wait = wait0 < wait1 ? wait0 : wait1; 00293 wait = wait < time_left ? wait : time_left; 00294 00295 if (wait == INT_MAX) { 00296 wait = -1; 00297 } else if (wait < 1) { 00298 /* don't let wait=0, because this can cause the pbx thread to loop without any sleeping at all */ 00299 wait = 1; 00300 } 00301 00302 return wait; 00303 }
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 306 of file abstract_jb.c.
References ast_clear_flag, AST_FRAME_DTMF, AST_FRAME_VOICE, ast_frdup(), AST_FRFLAG_HAS_TIMING_INFO, ast_frfree, ast_log(), ast_set_flag, ast_test_flag, create_jb(), f, ast_jb_impl::force_resync, get_now(), ast_jb::impl, ast_channel::jb, JB_CREATED, jb_framelog, JB_IMPL_OK, JB_USE, ast_jb::jbobj, ast_frame::len, LOG_ERROR, LOG_WARNING, ast_channel::name, ast_jb::next, ast_jb_impl::next, ast_jb_impl::put, and ast_frame::ts.
00307 { 00308 struct ast_jb *jb = &chan->jb; 00309 const struct ast_jb_impl *jbimpl = jb->impl; 00310 void *jbobj = jb->jbobj; 00311 struct ast_frame *frr; 00312 long now = 0; 00313 00314 if (!ast_test_flag(jb, JB_USE)) 00315 return -1; 00316 00317 if (f->frametype != AST_FRAME_VOICE) { 00318 if (f->frametype == AST_FRAME_DTMF && ast_test_flag(jb, JB_CREATED)) { 00319 jb_framelog("JB_PUT {now=%ld}: Received DTMF frame. Force resynching jb...\n", now); 00320 jbimpl->force_resync(jbobj); 00321 } 00322 00323 return -1; 00324 } 00325 00326 /* We consider an enabled jitterbuffer should receive frames with valid timing info. */ 00327 if (!ast_test_flag(f, AST_FRFLAG_HAS_TIMING_INFO) || f->len < 2 || f->ts < 0) { 00328 ast_log(LOG_WARNING, "%s received frame with invalid timing info: " 00329 "has_timing_info=%d, len=%ld, ts=%ld, src=%s\n", 00330 chan->name, ast_test_flag(f, AST_FRFLAG_HAS_TIMING_INFO), f->len, f->ts, f->src); 00331 return -1; 00332 } 00333 00334 frr = ast_frdup(f); 00335 00336 if (!frr) { 00337 ast_log(LOG_ERROR, "Failed to isolate frame for the jitterbuffer on channel '%s'\n", chan->name); 00338 return -1; 00339 } 00340 00341 if (!ast_test_flag(jb, JB_CREATED)) { 00342 if (create_jb(chan, frr)) { 00343 ast_frfree(frr); 00344 /* Disable the jitterbuffer */ 00345 ast_clear_flag(jb, JB_USE); 00346 return -1; 00347 } 00348 00349 ast_set_flag(jb, JB_CREATED); 00350 return 0; 00351 } else { 00352 now = get_now(jb, NULL); 00353 if (jbimpl->put(jbobj, frr, now) != JB_IMPL_OK) { 00354 jb_framelog("JB_PUT {now=%ld}: Dropped frame with ts=%ld and len=%ld\n", now, frr->ts, frr->len); 00355 ast_frfree(frr); 00356 /*return -1;*/ 00357 /* TODO: Check this fix - should return 0 here, because the dropped frame shouldn't 00358 be delivered at all */ 00359 return 0; 00360 } 00361 00362 jb->next = jbimpl->next(jbobj); 00363 00364 jb_framelog("JB_PUT {now=%ld}: Queued frame with ts=%ld and len=%ld\n", now, frr->ts, frr->len); 00365 00366 return 0; 00367 } 00368 }
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 577 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(), jingle_load_config(), load_module(), process_dahdi(), reload_config(), and store_config_core().
00578 { 00579 int prefixlen = sizeof(AST_JB_CONF_PREFIX) - 1; 00580 const char *name; 00581 int tmp; 00582 00583 if (strncasecmp(AST_JB_CONF_PREFIX, varname, prefixlen)) { 00584 return -1; 00585 } 00586 00587 name = varname + prefixlen; 00588 00589 if (!strcasecmp(name, AST_JB_CONF_ENABLE)) { 00590 ast_set2_flag(conf, ast_true(value), AST_JB_ENABLED); 00591 } else if (!strcasecmp(name, AST_JB_CONF_FORCE)) { 00592 ast_set2_flag(conf, ast_true(value), AST_JB_FORCED); 00593 } else if (!strcasecmp(name, AST_JB_CONF_MAX_SIZE)) { 00594 if ((tmp = atoi(value)) > 0) 00595 conf->max_size = tmp; 00596 } else if (!strcasecmp(name, AST_JB_CONF_RESYNCH_THRESHOLD)) { 00597 if ((tmp = atoi(value)) > 0) 00598 conf->resync_threshold = tmp; 00599 } else if (!strcasecmp(name, AST_JB_CONF_IMPL)) { 00600 if (!ast_strlen_zero(value)) 00601 snprintf(conf->impl, sizeof(conf->impl), "%s", value); 00602 } else if (!strcasecmp(name, AST_JB_CONF_TARGET_EXTRA)) { 00603 if (sscanf(value, "%30d", &tmp) == 1) { 00604 conf->target_extra = tmp; 00605 } 00606 } else if (!strcasecmp(name, AST_JB_CONF_LOG)) { 00607 ast_set2_flag(conf, ast_true(value), AST_JB_LOG); 00608 } else { 00609 return -1; 00610 } 00611 00612 return 0; 00613 }