Common implementation-independent jitterbuffer stuff. More...
#include <stdio.h>
#include <sys/time.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_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, char *varname, char *value) |
Sets jitterbuffer configuration property. |
Common implementation-independent jitterbuffer stuff.
Definition in file abstract_jb.h.
#define AST_JB_CONF_ENABLE "enable" |
Definition at line 70 of file abstract_jb.h.
Referenced by ast_jb_read_conf().
#define AST_JB_CONF_FORCE "force" |
Definition at line 71 of file abstract_jb.h.
Referenced by ast_jb_read_conf().
#define AST_JB_CONF_IMPL "impl" |
Definition at line 74 of file abstract_jb.h.
Referenced by ast_jb_read_conf().
#define AST_JB_CONF_LOG "log" |
Definition at line 75 of file abstract_jb.h.
Referenced by ast_jb_read_conf().
#define AST_JB_CONF_MAX_SIZE "maxsize" |
Definition at line 72 of file abstract_jb.h.
Referenced by ast_jb_read_conf().
#define AST_JB_CONF_PREFIX "jb" |
Definition at line 69 of file abstract_jb.h.
Referenced by ast_jb_read_conf().
#define AST_JB_CONF_RESYNCH_THRESHOLD "resyncthreshold" |
Definition at line 73 of file abstract_jb.h.
Referenced by ast_jb_read_conf().
#define AST_JB_IMPL_NAME_SIZE 12 |
Definition at line 50 of file abstract_jb.h.
Referenced by create_jb().
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. |
Called from a channel driver when a channel is created and its jitterbuffer needs to be configured.
Definition at line 602 of file abstract_jb.c.
References ast_jb::conf, and ast_channel::jb.
Referenced by __oh323_rtp_create(), __oh323_update_info(), alsa_new(), dahdi_new(), gtalk_new(), mgcp_new(), misdn_new(), oss_new(), sip_new(), and skinny_new().
void ast_jb_destroy | ( | struct ast_channel * | chan | ) |
Destroys jitterbuffer on a channel.
chan | channel. |
Called from ast_channel_free() when a channel is destroyed.
Definition at line 526 of file abstract_jb.c.
References ast_clear_flag, ast_frfree, ast_test_flag, ast_verbose(), 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, option_verbose, ast_jb_impl::remove, and VERBOSE_PREFIX_3.
Referenced by ast_channel_free().
00527 { 00528 struct ast_jb *jb = &chan->jb; 00529 struct ast_jb_impl *jbimpl = jb->impl; 00530 void *jbobj = jb->jbobj; 00531 struct ast_frame *f; 00532 00533 if (jb->logfile) { 00534 fclose(jb->logfile); 00535 jb->logfile = NULL; 00536 } 00537 00538 if (ast_test_flag(jb, JB_CREATED)) { 00539 /* Remove and free all frames still queued in jb */ 00540 while (jbimpl->remove(jbobj, &f) == JB_IMPL_OK) { 00541 ast_frfree(f); 00542 } 00543 00544 jbimpl->destroy(jbobj); 00545 jb->jbobj = NULL; 00546 00547 ast_clear_flag(jb, JB_CREATED); 00548 00549 if (option_verbose > 2) 00550 ast_verbose(VERBOSE_PREFIX_3 "%s jitterbuffer destroyed on channel %s\n", jbimpl->name, chan->name); 00551 } 00552 }
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. |
Called from ast_generic_bridge() when two channels are entering in a bridge. The function checks the need of a jitterbuffer, depending on both channel's configuration and technology properties. As a result, this function sets appropriate internal jb flags to the channels, determining further behaviour of the bridged jitterbuffers.
Definition at line 204 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, inuse, 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().
00205 { 00206 struct ast_jb *jb0 = &c0->jb; 00207 struct ast_jb *jb1 = &c1->jb; 00208 struct ast_jb_conf *conf0 = &jb0->conf; 00209 struct ast_jb_conf *conf1 = &jb1->conf; 00210 int c0_wants_jitter = c0->tech->properties & AST_CHAN_TP_WANTSJITTER; 00211 int c0_creates_jitter = c0->tech->properties & AST_CHAN_TP_CREATESJITTER; 00212 int c0_jb_enabled = ast_test_flag(conf0, AST_JB_ENABLED); 00213 int c0_force_jb = ast_test_flag(conf0, AST_JB_FORCED); 00214 int c0_jb_timebase_initialized = ast_test_flag(jb0, JB_TIMEBASE_INITIALIZED); 00215 int c0_jb_created = ast_test_flag(jb0, JB_CREATED); 00216 int c1_wants_jitter = c1->tech->properties & AST_CHAN_TP_WANTSJITTER; 00217 int c1_creates_jitter = c1->tech->properties & AST_CHAN_TP_CREATESJITTER; 00218 int c1_jb_enabled = ast_test_flag(conf1, AST_JB_ENABLED); 00219 int c1_force_jb = ast_test_flag(conf1, AST_JB_FORCED); 00220 int c1_jb_timebase_initialized = ast_test_flag(jb1, JB_TIMEBASE_INITIALIZED); 00221 int c1_jb_created = ast_test_flag(jb1, JB_CREATED); 00222 int inuse = 0; 00223 00224 /* Determine whether audio going to c0 needs a jitter buffer */ 00225 if (((!c0_wants_jitter && c1_creates_jitter) || (c0_force_jb && c1_creates_jitter)) && c0_jb_enabled) { 00226 ast_set_flag(jb0, JB_USE); 00227 if (!c0_jb_timebase_initialized) { 00228 if (c1_jb_timebase_initialized) { 00229 memcpy(&jb0->timebase, &jb1->timebase, sizeof(struct timeval)); 00230 } else { 00231 gettimeofday(&jb0->timebase, NULL); 00232 } 00233 ast_set_flag(jb0, JB_TIMEBASE_INITIALIZED); 00234 } 00235 00236 if (!c0_jb_created) { 00237 jb_choose_impl(c0); 00238 } 00239 00240 inuse = 1; 00241 } 00242 00243 /* Determine whether audio going to c1 needs a jitter buffer */ 00244 if (((!c1_wants_jitter && c0_creates_jitter) || (c1_force_jb && c0_creates_jitter)) && c1_jb_enabled) { 00245 ast_set_flag(jb1, JB_USE); 00246 if (!c1_jb_timebase_initialized) { 00247 if (c0_jb_timebase_initialized) { 00248 memcpy(&jb1->timebase, &jb0->timebase, sizeof(struct timeval)); 00249 } else { 00250 gettimeofday(&jb1->timebase, NULL); 00251 } 00252 ast_set_flag(jb1, JB_TIMEBASE_INITIALIZED); 00253 } 00254 00255 if (!c1_jb_created) { 00256 jb_choose_impl(c1); 00257 } 00258 00259 inuse = 1; 00260 } 00261 00262 return inuse; 00263 }
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 613 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().
00614 { 00615 struct ast_jb *jb0 = &c0->jb; 00616 struct ast_jb *jb1 = &c1->jb; 00617 int c0_use_jb = ast_test_flag(jb0, JB_USE); 00618 int c0_jb_is_created = ast_test_flag(jb0, JB_CREATED); 00619 int c1_use_jb = ast_test_flag(jb1, JB_USE); 00620 int c1_jb_is_created = ast_test_flag(jb1, JB_CREATED); 00621 00622 if (c0_use_jb && c0_jb_is_created && jb0->impl->empty_and_reset) { 00623 jb0->impl->empty_and_reset(jb0->jbobj); 00624 } 00625 00626 if (c1_use_jb && c1_jb_is_created && jb1->impl->empty_and_reset) { 00627 jb1->impl->empty_and_reset(jb1->jbobj); 00628 } 00629 }
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. |
Called from ast_generic_bridge() to deliver any frames, that should be delivered for the moment of invocation. Does nothing if neihter of the channels is using jb or has any frames currently queued in. The function delivers frames usig ast_write() each of the channels.
Definition at line 370 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().
00371 { 00372 struct ast_jb *jb0 = &c0->jb; 00373 struct ast_jb *jb1 = &c1->jb; 00374 int c0_use_jb = ast_test_flag(jb0, JB_USE); 00375 int c0_jb_is_created = ast_test_flag(jb0, JB_CREATED); 00376 int c1_use_jb = ast_test_flag(jb1, JB_USE); 00377 int c1_jb_is_created = ast_test_flag(jb1, JB_CREATED); 00378 00379 if (c0_use_jb && c0_jb_is_created) 00380 jb_get_and_deliver(c0); 00381 00382 if (c1_use_jb && c1_jb_is_created) 00383 jb_get_and_deliver(c1); 00384 }
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 608 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. |
Called from ast_generic_bridge() to determine the maximum time to wait for activity in ast_waitfor_n() call. If neihter of the channels is using jb, this function returns the time limit passed.
Definition at line 265 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().
00266 { 00267 struct ast_jb *jb0 = &c0->jb; 00268 struct ast_jb *jb1 = &c1->jb; 00269 int c0_use_jb = ast_test_flag(jb0, JB_USE); 00270 int c0_jb_is_created = ast_test_flag(jb0, JB_CREATED); 00271 int c1_use_jb = ast_test_flag(jb1, JB_USE); 00272 int c1_jb_is_created = ast_test_flag(jb1, JB_CREATED); 00273 int wait, wait0, wait1; 00274 struct timeval tv_now; 00275 00276 if (time_left == 0) { 00277 /* No time left - the bridge will be retried */ 00278 /* TODO: Test disable this */ 00279 /*return 0;*/ 00280 } 00281 00282 if (time_left < 0) { 00283 time_left = INT_MAX; 00284 } 00285 00286 gettimeofday(&tv_now, NULL); 00287 00288 wait0 = (c0_use_jb && c0_jb_is_created) ? jb0->next - get_now(jb0, &tv_now) : time_left; 00289 wait1 = (c1_use_jb && c1_jb_is_created) ? jb1->next - get_now(jb1, &tv_now) : time_left; 00290 00291 wait = wait0 < wait1 ? wait0 : wait1; 00292 wait = wait < time_left ? wait : time_left; 00293 00294 if (wait == INT_MAX) { 00295 wait = -1; 00296 } else if (wait < 1) { 00297 /* don't let wait=0, because this can cause the pbx thread to loop without any sleeping at all */ 00298 wait = 1; 00299 } 00300 00301 return wait; 00302 }
int ast_jb_put | ( | struct ast_channel * | chan, | |
struct ast_frame * | f | |||
) |
Puts a frame into a channel jitterbuffer.
chan | channel. | |
f | frame. |
Called from ast_generic_bridge() to put a frame into a channel's jitterbuffer. The function will successfuly enqueue a frame if and only if: 1. the channel is using a jitterbuffer (as determined by ast_jb_do_usecheck()), 2. the frame's type is AST_FRAME_VOICE, 3. the frame has timing info set and has length >= 2 ms, 4. there is no some internal error happened (like failed memory allocation). Frames, successfuly queued, should be delivered by the channel's jitterbuffer, when their delivery time has came. Frames, not successfuly queued, should be delivered immediately. Dropped by the jb implementation frames are considered successfuly enqueued as far as they should not be delivered at all.
Definition at line 305 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(), ast_jb_impl::force_resync, ast_frame::frametype, 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_jb_impl::next, ast_jb::next, ast_jb_impl::put, ast_frame::src, and ast_frame::ts.
Referenced by ast_generic_bridge().
00306 { 00307 struct ast_jb *jb = &chan->jb; 00308 struct ast_jb_impl *jbimpl = jb->impl; 00309 void *jbobj = jb->jbobj; 00310 struct ast_frame *frr; 00311 long now = 0; 00312 00313 if (!ast_test_flag(jb, JB_USE)) 00314 return -1; 00315 00316 if (f->frametype != AST_FRAME_VOICE) { 00317 if (f->frametype == AST_FRAME_DTMF && ast_test_flag(jb, JB_CREATED)) { 00318 jb_framelog("JB_PUT {now=%ld}: Received DTMF frame. Force resynching jb...\n", now); 00319 jbimpl->force_resync(jbobj); 00320 } 00321 00322 return -1; 00323 } 00324 00325 /* We consider an enabled jitterbuffer should receive frames with valid timing info. */ 00326 if (!ast_test_flag(f, AST_FRFLAG_HAS_TIMING_INFO) || f->len < 2 || f->ts < 0) { 00327 ast_log(LOG_WARNING, "%s received frame with invalid timing info: " 00328 "has_timing_info=%d, len=%ld, ts=%ld, src=%s\n", 00329 chan->name, ast_test_flag(f, AST_FRFLAG_HAS_TIMING_INFO), f->len, f->ts, f->src); 00330 return -1; 00331 } 00332 00333 frr = ast_frdup(f); 00334 00335 if (!frr) { 00336 ast_log(LOG_ERROR, "Failed to isolate frame for the jitterbuffer on channel '%s'\n", chan->name); 00337 return -1; 00338 } 00339 00340 if (!ast_test_flag(jb, JB_CREATED)) { 00341 if (create_jb(chan, frr)) { 00342 ast_frfree(frr); 00343 /* Disable the jitterbuffer */ 00344 ast_clear_flag(jb, JB_USE); 00345 return -1; 00346 } 00347 00348 ast_set_flag(jb, JB_CREATED); 00349 return 0; 00350 } else { 00351 now = get_now(jb, NULL); 00352 if (jbimpl->put(jbobj, frr, now) != JB_IMPL_OK) { 00353 jb_framelog("JB_PUT {now=%ld}: Dropped frame with ts=%ld and len=%ld\n", now, frr->ts, frr->len); 00354 ast_frfree(frr); 00355 /*return -1;*/ 00356 /* TODO: Check this fix - should return 0 here, because the dropped frame shouldn't 00357 be delivered at all */ 00358 return 0; 00359 } 00360 00361 jb->next = jbimpl->next(jbobj); 00362 00363 jb_framelog("JB_PUT {now=%ld}: Queued frame with ts=%ld and len=%ld\n", now, frr->ts, frr->len); 00364 00365 return 0; 00366 } 00367 }
int ast_jb_read_conf | ( | struct ast_jb_conf * | conf, | |
char * | varname, | |||
char * | value | |||
) |
Sets jitterbuffer configuration property.
conf | configuration to store the property in. | |
varname | property name. | |
value | property value. |
Called from a channel driver to build a jitterbuffer configuration tipically when reading a configuration file. It is not neccessary for a channel driver to know each of the jb configuration property names. The jitterbuffer itself knows them. The channel driver can pass each config var it reads through this function. It will return 0 if the variable was consumed from the jb conf.
Definition at line 568 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_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, and ast_jb_conf::resync_threshold.
Referenced by _build_general_config(), gtalk_load_config(), load_module(), process_dahdi(), reload_config(), and store_config().
00569 { 00570 int prefixlen = sizeof(AST_JB_CONF_PREFIX) - 1; 00571 char *name; 00572 int tmp; 00573 00574 if (strncasecmp(AST_JB_CONF_PREFIX, varname, prefixlen)) 00575 return -1; 00576 00577 name = varname + prefixlen; 00578 00579 if (!strcasecmp(name, AST_JB_CONF_ENABLE)) { 00580 ast_set2_flag(conf, ast_true(value), AST_JB_ENABLED); 00581 } else if (!strcasecmp(name, AST_JB_CONF_FORCE)) { 00582 ast_set2_flag(conf, ast_true(value), AST_JB_FORCED); 00583 } else if (!strcasecmp(name, AST_JB_CONF_MAX_SIZE)) { 00584 if ((tmp = atoi(value)) > 0) 00585 conf->max_size = tmp; 00586 } else if (!strcasecmp(name, AST_JB_CONF_RESYNCH_THRESHOLD)) { 00587 if ((tmp = atoi(value)) > 0) 00588 conf->resync_threshold = tmp; 00589 } else if (!strcasecmp(name, AST_JB_CONF_IMPL)) { 00590 if (!ast_strlen_zero(value)) 00591 snprintf(conf->impl, sizeof(conf->impl), "%s", value); 00592 } else if (!strcasecmp(name, AST_JB_CONF_LOG)) { 00593 ast_set2_flag(conf, ast_true(value), AST_JB_LOG); 00594 } else { 00595 return -1; 00596 } 00597 00598 return 0; 00599 }