Common implementation-independent jitterbuffer stuff. More...
#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.
Data Structures | |
| struct | ast_jb_impl |
| Jitterbuffer implementation private struct. More... | |
Defines | |
| #define | jb_framelog(...) |
| Macros for the frame log files. | |
Typedefs | |
| typedef void *(* | jb_create_impl )(struct ast_jb_conf *general_config, long resynch_threshold) |
| Create. | |
| typedef void(* | jb_destroy_impl )(void *jb) |
| Destroy. | |
| typedef void(* | jb_empty_and_reset_impl )(void *jb) |
| Empty and reset jb. | |
| typedef void(* | jb_force_resynch_impl )(void *jb) |
| Force resynch. | |
| typedef int(* | jb_get_impl )(void *jb, struct ast_frame **fout, long now, long interpl) |
| Get frame for now. | |
| typedef long(* | jb_next_impl )(void *jb) |
| Get next. | |
| typedef int(* | jb_put_first_impl )(void *jb, struct ast_frame *fin, long now) |
| Put first frame. | |
| typedef int(* | jb_put_impl )(void *jb, struct ast_frame *fin, long now) |
| Put frame. | |
| typedef int(* | jb_remove_impl )(void *jb, struct ast_frame **fout) |
| Remove first frame. | |
Enumerations | |
| enum | { JB_USE = (1 << 0), JB_TIMEBASE_INITIALIZED = (1 << 1), JB_CREATED = (1 << 2) } |
| enum | { JB_IMPL_OK, JB_IMPL_DROP, JB_IMPL_INTERP, JB_IMPL_NOFRAME } |
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. | |
| 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 int | adaptive_to_abstract_code [] |
| static struct ast_jb_impl | avail_impl [] |
| static int | default_impl = 0 |
| static int | fixed_to_abstract_code [] |
| static char * | jb_get_actions [] = {"Delivered", "Dropped", "Interpolated", "No"} |
Common implementation-independent jitterbuffer stuff.
Definition in file abstract_jb.c.
| #define jb_framelog | ( | ... | ) |
Macros for the frame log files.
Definition at line 162 of file abstract_jb.c.
Referenced by ast_jb_put(), create_jb(), and jb_get_and_deliver().
| typedef void*(* jb_create_impl)(struct ast_jb_conf *general_config, long resynch_threshold) |
Create.
Definition at line 55 of file abstract_jb.c.
| typedef void(* jb_destroy_impl)(void *jb) |
Destroy.
Definition at line 57 of file abstract_jb.c.
| typedef void(* jb_empty_and_reset_impl)(void *jb) |
Empty and reset jb.
Definition at line 71 of file abstract_jb.c.
| typedef void(* jb_force_resynch_impl)(void *jb) |
Force resynch.
Definition at line 69 of file abstract_jb.c.
| typedef int(* jb_get_impl)(void *jb, struct ast_frame **fout, long now, long interpl) |
Get frame for now.
Definition at line 63 of file abstract_jb.c.
| typedef long(* jb_next_impl)(void *jb) |
Get next.
Definition at line 65 of file abstract_jb.c.
| typedef int(* jb_put_first_impl)(void *jb, struct ast_frame *fin, long now) |
Put first frame.
Definition at line 59 of file abstract_jb.c.
| typedef int(* jb_put_impl)(void *jb, struct ast_frame *fin, long now) |
Put frame.
Definition at line 61 of file abstract_jb.c.
| typedef int(* jb_remove_impl)(void *jb, struct ast_frame **fout) |
Remove first frame.
Definition at line 67 of file abstract_jb.c.
| 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 };
| anonymous enum |
Abstract return codes
Definition at line 145 of file abstract_jb.c.
00145 { 00146 JB_IMPL_OK, 00147 JB_IMPL_DROP, 00148 JB_IMPL_INTERP, 00149 JB_IMPL_NOFRAME 00150 };
| 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 597 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. |
Called from ast_channel_free() when a channel is destroyed.
Definition at line 522 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, and ast_jb_impl::remove.
Referenced by ast_channel_free().
00523 { 00524 struct ast_jb *jb = &chan->jb; 00525 struct ast_jb_impl *jbimpl = jb->impl; 00526 void *jbobj = jb->jbobj; 00527 struct ast_frame *f; 00528 00529 if (jb->logfile) { 00530 fclose(jb->logfile); 00531 jb->logfile = NULL; 00532 } 00533 00534 if (ast_test_flag(jb, JB_CREATED)) { 00535 /* Remove and free all frames still queued in jb */ 00536 while (jbimpl->remove(jbobj, &f) == JB_IMPL_OK) { 00537 ast_frfree(f); 00538 } 00539 00540 jbimpl->destroy(jbobj); 00541 jb->jbobj = NULL; 00542 00543 ast_clear_flag(jb, JB_CREATED); 00544 00545 ast_verb(3, "%s jitterbuffer destroyed on channel %s\n", jbimpl->name, chan->name); 00546 } 00547 }
| 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.
| zero | if there are no jitter buffers in use | |
| non-zero | if there are |
Definition at line 201 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().
00202 { 00203 struct ast_jb *jb0 = &c0->jb; 00204 struct ast_jb *jb1 = &c1->jb; 00205 struct ast_jb_conf *conf0 = &jb0->conf; 00206 struct ast_jb_conf *conf1 = &jb1->conf; 00207 int c0_wants_jitter = c0->tech->properties & AST_CHAN_TP_WANTSJITTER; 00208 int c0_creates_jitter = c0->tech->properties & AST_CHAN_TP_CREATESJITTER; 00209 int c0_jb_enabled = ast_test_flag(conf0, AST_JB_ENABLED); 00210 int c0_force_jb = ast_test_flag(conf0, AST_JB_FORCED); 00211 int c0_jb_timebase_initialized = ast_test_flag(jb0, JB_TIMEBASE_INITIALIZED); 00212 int c0_jb_created = ast_test_flag(jb0, JB_CREATED); 00213 int c1_wants_jitter = c1->tech->properties & AST_CHAN_TP_WANTSJITTER; 00214 int c1_creates_jitter = c1->tech->properties & AST_CHAN_TP_CREATESJITTER; 00215 int c1_jb_enabled = ast_test_flag(conf1, AST_JB_ENABLED); 00216 int c1_force_jb = ast_test_flag(conf1, AST_JB_FORCED); 00217 int c1_jb_timebase_initialized = ast_test_flag(jb1, JB_TIMEBASE_INITIALIZED); 00218 int c1_jb_created = ast_test_flag(jb1, JB_CREATED); 00219 int inuse = 0; 00220 00221 /* Determine whether audio going to c0 needs a jitter buffer */ 00222 if (((!c0_wants_jitter && c1_creates_jitter) || (c0_force_jb && c1_creates_jitter)) && c0_jb_enabled) { 00223 ast_set_flag(jb0, JB_USE); 00224 if (!c0_jb_timebase_initialized) { 00225 if (c1_jb_timebase_initialized) { 00226 memcpy(&jb0->timebase, &jb1->timebase, sizeof(struct timeval)); 00227 } else { 00228 gettimeofday(&jb0->timebase, NULL); 00229 } 00230 ast_set_flag(jb0, JB_TIMEBASE_INITIALIZED); 00231 } 00232 00233 if (!c0_jb_created) { 00234 jb_choose_impl(c0); 00235 } 00236 00237 inuse = 1; 00238 } 00239 00240 /* Determine whether audio going to c1 needs a jitter buffer */ 00241 if (((!c1_wants_jitter && c0_creates_jitter) || (c1_force_jb && c0_creates_jitter)) && c1_jb_enabled) { 00242 ast_set_flag(jb1, JB_USE); 00243 if (!c1_jb_timebase_initialized) { 00244 if (c0_jb_timebase_initialized) { 00245 memcpy(&jb1->timebase, &jb0->timebase, sizeof(struct timeval)); 00246 } else { 00247 gettimeofday(&jb1->timebase, NULL); 00248 } 00249 ast_set_flag(jb1, JB_TIMEBASE_INITIALIZED); 00250 } 00251 00252 if (!c1_jb_created) { 00253 jb_choose_impl(c1); 00254 } 00255 00256 inuse = 1; 00257 } 00258 00259 return inuse; 00260 }
| 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 608 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().
00609 { 00610 struct ast_jb *jb0 = &c0->jb; 00611 struct ast_jb *jb1 = &c1->jb; 00612 int c0_use_jb = ast_test_flag(jb0, JB_USE); 00613 int c0_jb_is_created = ast_test_flag(jb0, JB_CREATED); 00614 int c1_use_jb = ast_test_flag(jb1, JB_USE); 00615 int c1_jb_is_created = ast_test_flag(jb1, JB_CREATED); 00616 00617 if (c0_use_jb && c0_jb_is_created && jb0->impl->empty_and_reset) { 00618 jb0->impl->empty_and_reset(jb0->jbobj); 00619 } 00620 00621 if (c1_use_jb && c1_jb_is_created && jb1->impl->empty_and_reset) { 00622 jb1->impl->empty_and_reset(jb1->jbobj); 00623 } 00624 }
| 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 367 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().
00368 { 00369 struct ast_jb *jb0 = &c0->jb; 00370 struct ast_jb *jb1 = &c1->jb; 00371 int c0_use_jb = ast_test_flag(jb0, JB_USE); 00372 int c0_jb_is_created = ast_test_flag(jb0, JB_CREATED); 00373 int c1_use_jb = ast_test_flag(jb1, JB_USE); 00374 int c1_jb_is_created = ast_test_flag(jb1, JB_CREATED); 00375 00376 if (c0_use_jb && c0_jb_is_created) 00377 jb_get_and_deliver(c0); 00378 00379 if (c1_use_jb && c1_jb_is_created) 00380 jb_get_and_deliver(c1); 00381 }
| 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 603 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 262 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().
00263 { 00264 struct ast_jb *jb0 = &c0->jb; 00265 struct ast_jb *jb1 = &c1->jb; 00266 int c0_use_jb = ast_test_flag(jb0, JB_USE); 00267 int c0_jb_is_created = ast_test_flag(jb0, JB_CREATED); 00268 int c1_use_jb = ast_test_flag(jb1, JB_USE); 00269 int c1_jb_is_created = ast_test_flag(jb1, JB_CREATED); 00270 int wait, wait0, wait1; 00271 struct timeval tv_now; 00272 00273 if (time_left == 0) { 00274 /* No time left - the bridge will be retried */ 00275 /* TODO: Test disable this */ 00276 /*return 0;*/ 00277 } 00278 00279 if (time_left < 0) { 00280 time_left = INT_MAX; 00281 } 00282 00283 gettimeofday(&tv_now, NULL); 00284 00285 wait0 = (c0_use_jb && c0_jb_is_created) ? jb0->next - get_now(jb0, &tv_now) : time_left; 00286 wait1 = (c1_use_jb && c1_jb_is_created) ? jb1->next - get_now(jb1, &tv_now) : time_left; 00287 00288 wait = wait0 < wait1 ? wait0 : wait1; 00289 wait = wait < time_left ? wait : time_left; 00290 00291 if (wait == INT_MAX) { 00292 wait = -1; 00293 } else if (wait < 1) { 00294 /* don't let wait=0, because this can cause the pbx thread to loop without any sleeping at all */ 00295 wait = 1; 00296 } 00297 00298 return wait; 00299 }
| 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.
| 0 | if the frame was queued | |
| -1 | if not |
Definition at line 302 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().
00303 { 00304 struct ast_jb *jb = &chan->jb; 00305 struct ast_jb_impl *jbimpl = jb->impl; 00306 void *jbobj = jb->jbobj; 00307 struct ast_frame *frr; 00308 long now = 0; 00309 00310 if (!ast_test_flag(jb, JB_USE)) 00311 return -1; 00312 00313 if (f->frametype != AST_FRAME_VOICE) { 00314 if (f->frametype == AST_FRAME_DTMF && ast_test_flag(jb, JB_CREATED)) { 00315 jb_framelog("JB_PUT {now=%ld}: Received DTMF frame. Force resynching jb...\n", now); 00316 jbimpl->force_resync(jbobj); 00317 } 00318 00319 return -1; 00320 } 00321 00322 /* We consider an enabled jitterbuffer should receive frames with valid timing info. */ 00323 if (!ast_test_flag(f, AST_FRFLAG_HAS_TIMING_INFO) || f->len < 2 || f->ts < 0) { 00324 ast_log(LOG_WARNING, "%s received frame with invalid timing info: " 00325 "has_timing_info=%d, len=%ld, ts=%ld, src=%s\n", 00326 chan->name, ast_test_flag(f, AST_FRFLAG_HAS_TIMING_INFO), f->len, f->ts, f->src); 00327 return -1; 00328 } 00329 00330 frr = ast_frdup(f); 00331 00332 if (!frr) { 00333 ast_log(LOG_ERROR, "Failed to isolate frame for the jitterbuffer on channel '%s'\n", chan->name); 00334 return -1; 00335 } 00336 00337 if (!ast_test_flag(jb, JB_CREATED)) { 00338 if (create_jb(chan, frr)) { 00339 ast_frfree(frr); 00340 /* Disable the jitterbuffer */ 00341 ast_clear_flag(jb, JB_USE); 00342 return -1; 00343 } 00344 00345 ast_set_flag(jb, JB_CREATED); 00346 return 0; 00347 } else { 00348 now = get_now(jb, NULL); 00349 if (jbimpl->put(jbobj, frr, now) != JB_IMPL_OK) { 00350 jb_framelog("JB_PUT {now=%ld}: Dropped frame with ts=%ld and len=%ld\n", now, frr->ts, frr->len); 00351 ast_frfree(frr); 00352 /*return -1;*/ 00353 /* TODO: Check this fix - should return 0 here, because the dropped frame shouldn't 00354 be delivered at all */ 00355 return 0; 00356 } 00357 00358 jb->next = jbimpl->next(jbobj); 00359 00360 jb_framelog("JB_PUT {now=%ld}: Queued frame with ts=%ld and len=%ld\n", now, frr->ts, frr->len); 00361 00362 return 0; 00363 } 00364 }
| 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. |
Called from a channel driver to build a jitterbuffer configuration typically when reading a configuration file. It is not necessary 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 563 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(), jingle_load_config(), load_module(), process_dahdi(), reload_config(), store_config(), and store_config_core().
00564 { 00565 int prefixlen = sizeof(AST_JB_CONF_PREFIX) - 1; 00566 const char *name; 00567 int tmp; 00568 00569 if (strncasecmp(AST_JB_CONF_PREFIX, varname, prefixlen)) 00570 return -1; 00571 00572 name = varname + prefixlen; 00573 00574 if (!strcasecmp(name, AST_JB_CONF_ENABLE)) { 00575 ast_set2_flag(conf, ast_true(value), AST_JB_ENABLED); 00576 } else if (!strcasecmp(name, AST_JB_CONF_FORCE)) { 00577 ast_set2_flag(conf, ast_true(value), AST_JB_FORCED); 00578 } else if (!strcasecmp(name, AST_JB_CONF_MAX_SIZE)) { 00579 if ((tmp = atoi(value)) > 0) 00580 conf->max_size = tmp; 00581 } else if (!strcasecmp(name, AST_JB_CONF_RESYNCH_THRESHOLD)) { 00582 if ((tmp = atoi(value)) > 0) 00583 conf->resync_threshold = tmp; 00584 } else if (!strcasecmp(name, AST_JB_CONF_IMPL)) { 00585 if (!ast_strlen_zero(value)) 00586 snprintf(conf->impl, sizeof(conf->impl), "%s", value); 00587 } else if (!strcasecmp(name, AST_JB_CONF_LOG)) { 00588 ast_set2_flag(conf, ast_true(value), AST_JB_LOG); 00589 } else { 00590 return -1; 00591 } 00592 00593 return 0; 00594 }
| static int create_jb | ( | struct ast_channel * | chan, | |
| struct ast_frame * | first_frame | |||
| ) | [static] |
Definition at line 444 of file abstract_jb.c.
References ast_assert, ast_bridged_channel(), AST_CHANNEL_NAME, ast_frfree, AST_JB_IMPL_NAME_SIZE, AST_JB_LOG, ast_log(), ast_test_flag, ast_verb, ast_jb::conf, ast_jb_impl::create, get_now(), ast_jb::impl, ast_channel::jb, jb_framelog, JB_IMPL_OK, 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().
00445 { 00446 struct ast_jb *jb = &chan->jb; 00447 struct ast_jb_conf *jbconf = &jb->conf; 00448 struct ast_jb_impl *jbimpl = jb->impl; 00449 void *jbobj; 00450 struct ast_channel *bridged; 00451 long now; 00452 char logfile_pathname[20 + AST_JB_IMPL_NAME_SIZE + 2*AST_CHANNEL_NAME + 1]; 00453 char name1[AST_CHANNEL_NAME], name2[AST_CHANNEL_NAME], *tmp; 00454 int res; 00455 00456 jbobj = jb->jbobj = jbimpl->create(jbconf, jbconf->resync_threshold); 00457 if (!jbobj) { 00458 ast_log(LOG_WARNING, "Failed to create jitterbuffer on channel '%s'\n", chan->name); 00459 return -1; 00460 } 00461 00462 now = get_now(jb, NULL); 00463 res = jbimpl->put_first(jbobj, frr, now); 00464 00465 /* The result of putting the first frame should not differ from OK. However, its possible 00466 some implementations (i.e. adaptive's when resynch_threshold is specified) to drop it. */ 00467 if (res != JB_IMPL_OK) { 00468 ast_log(LOG_WARNING, "Failed to put first frame in the jitterbuffer on channel '%s'\n", chan->name); 00469 /* 00470 jbimpl->destroy(jbobj); 00471 return -1; 00472 */ 00473 } 00474 00475 /* Init next */ 00476 jb->next = jbimpl->next(jbobj); 00477 00478 /* Init last format for a first time. */ 00479 jb->last_format = frr->subclass; 00480 00481 /* Create a frame log file */ 00482 if (ast_test_flag(jbconf, AST_JB_LOG)) { 00483 snprintf(name2, sizeof(name2), "%s", chan->name); 00484 tmp = strchr(name2, '/'); 00485 if (tmp) 00486 *tmp = '#'; 00487 00488 bridged = ast_bridged_channel(chan); 00489 /* We should always have bridged chan if a jitterbuffer is in use */ 00490 ast_assert(bridged != NULL); 00491 00492 snprintf(name1, sizeof(name1), "%s", bridged->name); 00493 tmp = strchr(name1, '/'); 00494 if (tmp) 00495 *tmp = '#'; 00496 00497 snprintf(logfile_pathname, sizeof(logfile_pathname), 00498 "/tmp/ast_%s_jb_%s--%s.log", jbimpl->name, name1, name2); 00499 jb->logfile = fopen(logfile_pathname, "w+b"); 00500 00501 if (!jb->logfile) 00502 ast_log(LOG_ERROR, "Failed to create frame log file with pathname '%s'\n", logfile_pathname); 00503 00504 if (res == JB_IMPL_OK) 00505 jb_framelog("JB_PUT_FIRST {now=%ld}: Queued frame with ts=%ld and len=%ld\n", 00506 now, frr->ts, frr->len); 00507 else 00508 jb_framelog("JB_PUT_FIRST {now=%ld}: Dropped frame with ts=%ld and len=%ld\n", 00509 now, frr->ts, frr->len); 00510 } 00511 00512 ast_verb(3, "%s jitterbuffer created on channel %s\n", jbimpl->name, chan->name); 00513 00514 /* Free the frame if it has not been queued in the jb */ 00515 if (res != JB_IMPL_OK) 00516 ast_frfree(frr); 00517 00518 return 0; 00519 }
| static long get_now | ( | struct ast_jb * | jb, | |
| struct timeval * | tv | |||
| ) | [static] |
Definition at line 550 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().
00551 { 00552 struct timeval now; 00553 00554 if (!when) { 00555 when = &now; 00556 gettimeofday(when, NULL); 00557 } 00558 00559 return ast_tvdiff_ms(*when, jb->timebase); 00560 }
| static void jb_choose_impl | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 180 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().
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 for (i = 0; i < avail_impl_count; i++) { 00193 test_impl = &avail_impl[i]; 00194 if (!strcasecmp(jbconf->impl, test_impl->name)) { 00195 jb->impl = test_impl; 00196 return; 00197 } 00198 } 00199 }
| static void * jb_create_adaptive | ( | struct ast_jb_conf * | general_config, | |
| long | resynch_threshold | |||
| ) | [static] |
Definition at line 723 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, and jb_conf::resync_threshold.
00724 { 00725 jb_conf jbconf; 00726 jitterbuf *adaptivejb; 00727 00728 adaptivejb = jb_new(); 00729 if (adaptivejb) { 00730 jbconf.max_jitterbuf = general_config->max_size; 00731 jbconf.resync_threshold = general_config->resync_threshold; 00732 jbconf.max_contig_interp = 10; 00733 jb_setconf(adaptivejb, &jbconf); 00734 } 00735 00736 return adaptivejb; 00737 }
| static void * jb_create_fixed | ( | struct ast_jb_conf * | general_config, | |
| long | resynch_threshold | |||
| ) | [static] |
Definition at line 629 of file abstract_jb.c.
References fixed_jb_new(), fixed_jb_conf::jbsize, ast_jb_conf::max_size, and fixed_jb_conf::resync_threshold.
00630 { 00631 struct fixed_jb_conf conf; 00632 00633 conf.jbsize = general_config->max_size; 00634 conf.resync_threshold = resynch_threshold; 00635 00636 return fixed_jb_new(&conf); 00637 }
| static void jb_destroy_adaptive | ( | void * | jb | ) | [static] |
Definition at line 740 of file abstract_jb.c.
References jb_destroy().
00741 { 00742 jitterbuf *adaptivejb = (jitterbuf *) jb; 00743 00744 jb_destroy(adaptivejb); 00745 }
| static void jb_destroy_fixed | ( | void * | jb | ) | [static] |
Definition at line 639 of file abstract_jb.c.
References fixed_jb_destroy().
00640 { 00641 struct fixed_jb *fixedjb = (struct fixed_jb *) jb; 00642 00643 /* destroy the jb */ 00644 fixed_jb_destroy(fixedjb); 00645 }
| static void jb_empty_and_reset_adaptive | ( | void * | jb | ) | [static] |
Definition at line 803 of file abstract_jb.c.
References ast_frfree, jb_frame::data, f, jb_getall(), JB_OK, and jb_reset().
| static void jb_empty_and_reset_fixed | ( | void * | jb | ) | [static] |
Definition at line 711 of file abstract_jb.c.
References ast_frfree, fixed_jb_frame::data, FIXED_JB_OK, and fixed_jb_remove().
00712 { 00713 struct fixed_jb *fixedjb = jb; 00714 struct fixed_jb_frame f; 00715 00716 while (fixed_jb_remove(fixedjb, &f) == FIXED_JB_OK) { 00717 ast_frfree(f.data); 00718 } 00719 }
| static void jb_force_resynch_adaptive | ( | void * | jb | ) | [static] |
Definition at line 799 of file abstract_jb.c.
| static void jb_force_resynch_fixed | ( | void * | jb | ) | [static] |
Definition at line 704 of file abstract_jb.c.
References fixed_jb_set_force_resynch().
00705 { 00706 struct fixed_jb *fixedjb = (struct fixed_jb *) jb; 00707 00708 fixed_jb_set_force_resynch(fixedjb); 00709 }
| static int jb_get_adaptive | ( | void * | jb, | |
| struct ast_frame ** | fout, | |||
| long | now, | |||
| long | interpl | |||
| ) | [static] |
Definition at line 765 of file abstract_jb.c.
References jb_frame::data, and jb_get().
| static void jb_get_and_deliver | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 384 of file abstract_jb.c.
References ast_assert, ast_codec_interp_len(), AST_FRAME_VOICE, ast_frfree, AST_FRIENDLY_OFFSET, ast_log(), ast_samp2tv(), ast_tvadd(), ast_write(), ast_frame::delivery, f, ast_jb_impl::get, get_now(), ast_jb::impl, ast_channel::jb, jb_framelog, JB_IMPL_DROP, JB_IMPL_INTERP, JB_IMPL_NOFRAME, JB_IMPL_OK, ast_jb::jbobj, ast_jb::last_format, ast_frame::len, LOG_ERROR, LOG_WARNING, ast_jb_impl::name, 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().
00385 { 00386 struct ast_jb *jb = &chan->jb; 00387 struct ast_jb_impl *jbimpl = jb->impl; 00388 void *jbobj = jb->jbobj; 00389 struct ast_frame *f, finterp = { .frametype = AST_FRAME_VOICE, }; 00390 long now; 00391 int interpolation_len, res; 00392 00393 now = get_now(jb, NULL); 00394 jb->next = jbimpl->next(jbobj); 00395 if (now < jb->next) { 00396 jb_framelog("\tJB_GET {now=%ld}: now < next=%ld\n", now, jb->next); 00397 return; 00398 } 00399 00400 while (now >= jb->next) { 00401 interpolation_len = ast_codec_interp_len(jb->last_format); 00402 00403 res = jbimpl->get(jbobj, &f, now, interpolation_len); 00404 00405 switch (res) { 00406 case JB_IMPL_OK: 00407 /* deliver the frame */ 00408 ast_write(chan, f); 00409 case JB_IMPL_DROP: 00410 jb_framelog("\tJB_GET {now=%ld}: %s frame with ts=%ld and len=%ld\n", 00411 now, jb_get_actions[res], f->ts, f->len); 00412 jb->last_format = f->subclass; 00413 ast_frfree(f); 00414 break; 00415 case JB_IMPL_INTERP: 00416 /* interpolate a frame */ 00417 f = &finterp; 00418 f->subclass = jb->last_format; 00419 f->samples = interpolation_len * 8; 00420 f->src = "JB interpolation"; 00421 f->delivery = ast_tvadd(jb->timebase, ast_samp2tv(jb->next, 1000)); 00422 f->offset = AST_FRIENDLY_OFFSET; 00423 /* deliver the interpolated frame */ 00424 ast_write(chan, f); 00425 jb_framelog("\tJB_GET {now=%ld}: Interpolated frame with len=%d\n", now, interpolation_len); 00426 break; 00427 case JB_IMPL_NOFRAME: 00428 ast_log(LOG_WARNING, 00429 "JB_IMPL_NOFRAME is returned from the %s jb when now=%ld >= next=%ld, jbnext=%ld!\n", 00430 jbimpl->name, now, jb->next, jbimpl->next(jbobj)); 00431 jb_framelog("\tJB_GET {now=%ld}: No frame for now!?\n", now); 00432 return; 00433 default: 00434 ast_log(LOG_ERROR, "This should never happen!\n"); 00435 ast_assert("JB type unknown" == NULL); 00436 break; 00437 } 00438 00439 jb->next = jbimpl->next(jbobj); 00440 } 00441 }
| static int jb_get_fixed | ( | void * | jb, | |
| struct ast_frame ** | fout, | |||
| long | now, | |||
| long | interpl | |||
| ) | [static] |
Definition at line 670 of file abstract_jb.c.
References fixed_jb_frame::data, and fixed_jb_get().
00671 { 00672 struct fixed_jb *fixedjb = (struct fixed_jb *) jb; 00673 struct fixed_jb_frame frame; 00674 int res; 00675 00676 res = fixed_jb_get(fixedjb, &frame, now, interpl); 00677 *fout = frame.data; 00678 00679 return fixed_to_abstract_code[res]; 00680 }
| static long jb_next_adaptive | ( | void * | jb | ) | [static] |
| static long jb_next_fixed | ( | void * | jb | ) | [static] |
Definition at line 683 of file abstract_jb.c.
References fixed_jb_next().
00684 { 00685 struct fixed_jb *fixedjb = (struct fixed_jb *) jb; 00686 00687 return fixed_jb_next(fixedjb); 00688 }
| static int jb_put_adaptive | ( | void * | jb, | |
| struct ast_frame * | fin, | |||
| long | now | |||
| ) | [static] |
Definition at line 754 of file abstract_jb.c.
References jb_put(), JB_TYPE_VOICE, ast_frame::len, and ast_frame::ts.
Referenced by jb_put_first_adaptive().
00755 { 00756 jitterbuf *adaptivejb = (jitterbuf *) jb; 00757 int res; 00758 00759 res = jb_put(adaptivejb, fin, JB_TYPE_VOICE, fin->len, fin->ts, now); 00760 00761 return adaptive_to_abstract_code[res]; 00762 }
| static int jb_put_first_adaptive | ( | void * | jb, | |
| struct ast_frame * | fin, | |||
| long | now | |||
| ) | [static] |
Definition at line 748 of file abstract_jb.c.
References jb_put_adaptive().
00749 { 00750 return jb_put_adaptive(jb, fin, now); 00751 }
| static int jb_put_first_fixed | ( | void * | jb, | |
| struct ast_frame * | fin, | |||
| long | now | |||
| ) | [static] |
Definition at line 648 of file abstract_jb.c.
References fixed_jb_put_first(), ast_frame::len, and ast_frame::ts.
00649 { 00650 struct fixed_jb *fixedjb = (struct fixed_jb *) jb; 00651 int res; 00652 00653 res = fixed_jb_put_first(fixedjb, fin, fin->len, fin->ts, now); 00654 00655 return fixed_to_abstract_code[res]; 00656 }
| static int jb_put_fixed | ( | void * | jb, | |
| struct ast_frame * | fin, | |||
| long | now | |||
| ) | [static] |
Definition at line 659 of file abstract_jb.c.
References fixed_jb_put(), ast_frame::len, and ast_frame::ts.
00660 { 00661 struct fixed_jb *fixedjb = (struct fixed_jb *) jb; 00662 int res; 00663 00664 res = fixed_jb_put(fixedjb, fin, fin->len, fin->ts, now); 00665 00666 return fixed_to_abstract_code[res]; 00667 }
| static int jb_remove_adaptive | ( | void * | jb, | |
| struct ast_frame ** | fout | |||
| ) | [static] |
Definition at line 786 of file abstract_jb.c.
References jb_frame::data, and jb_getall().
| static int jb_remove_fixed | ( | void * | jb, | |
| struct ast_frame ** | fout | |||
| ) | [static] |
Definition at line 691 of file abstract_jb.c.
References fixed_jb_frame::data, and fixed_jb_remove().
00692 { 00693 struct fixed_jb *fixedjb = (struct fixed_jb *) jb; 00694 struct fixed_jb_frame frame; 00695 int res; 00696 00697 res = fixed_jb_remove(fixedjb, &frame); 00698 *fout = frame.data; 00699 00700 return fixed_to_abstract_code[res]; 00701 }
int adaptive_to_abstract_code[] [static] |
{JB_IMPL_OK, JB_IMPL_NOFRAME, JB_IMPL_NOFRAME, JB_IMPL_INTERP, JB_IMPL_DROP, JB_IMPL_OK}
Definition at line 155 of file abstract_jb.c.
struct ast_jb_impl avail_impl[] [static] |
Definition at line 113 of file abstract_jb.c.
int default_impl = 0 [static] |
Definition at line 141 of file abstract_jb.c.
int fixed_to_abstract_code[] [static] |
Definition at line 153 of file abstract_jb.c.
char* jb_get_actions[] = {"Delivered", "Dropped", "Interpolated", "No"} [static] |
Definition at line 159 of file abstract_jb.c.
1.6.1