Fri Nov 12 11:47:28 2010

Asterisk developer's documentation


abstract_jb.h File Reference

Common implementation-independent jitterbuffer stuff. More...

#include <sys/time.h>
Include dependency graph for abstract_jb.h:
This graph shows which files directly or indirectly include this file:

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.

Detailed Description

Common implementation-independent jitterbuffer stuff.

Author:
Slav Klenov <slav@securax.org>

Definition in file abstract_jb.h.


Define Documentation

#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 75 of file abstract_jb.h.

Referenced by ast_jb_read_conf().

#define AST_JB_CONF_LOG   "log"

Definition at line 76 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_CONF_TARGET_EXTRA   "targetextra"

Definition at line 74 of file abstract_jb.h.

Referenced by ast_jb_read_conf().

#define AST_JB_IMPL_NAME_SIZE   12

Definition at line 48 of file abstract_jb.h.

Referenced by create_jb().


Enumeration Type Documentation

anonymous enum
Enumerator:
AST_JB_ENABLED 
AST_JB_FORCED 
AST_JB_LOG 

Definition at line 42 of file abstract_jb.h.

00042      {
00043    AST_JB_ENABLED = (1 << 0),
00044    AST_JB_FORCED =  (1 << 1),
00045    AST_JB_LOG =     (1 << 2)
00046 };


Function Documentation

void ast_jb_configure ( struct ast_channel chan,
const struct ast_jb_conf conf 
)

Configures a jitterbuffer on a channel.

Parameters:
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 610 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().

00611 {
00612    memcpy(&chan->jb.conf, conf, sizeof(*conf));
00613 }

void ast_jb_destroy ( struct ast_channel chan  ) 

Destroys jitterbuffer on a channel.

Parameters:
chan channel.

Called from ast_channel_free() when a channel is destroyed.

Definition at line 530 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_channel::name, ast_jb_impl::name, and ast_jb_impl::remove.

Referenced by ast_channel_free().

00531 {
00532    struct ast_jb *jb = &chan->jb;
00533    struct ast_jb_impl *jbimpl = jb->impl;
00534    void *jbobj = jb->jbobj;
00535    struct ast_frame *f;
00536 
00537    if (jb->logfile) {
00538       fclose(jb->logfile);
00539       jb->logfile = NULL;
00540    }
00541 
00542    if (ast_test_flag(jb, JB_CREATED)) {
00543       /* Remove and free all frames still queued in jb */
00544       while (jbimpl->remove(jbobj, &f) == JB_IMPL_OK) {
00545          ast_frfree(f);
00546       }
00547 
00548       jbimpl->destroy(jbobj);
00549       jb->jbobj = NULL;
00550 
00551       ast_clear_flag(jb, JB_CREATED);
00552 
00553       ast_verb(3, "%s jitterbuffer destroyed on channel %s\n", jbimpl->name, chan->name);
00554    }
00555 }

int ast_jb_do_usecheck ( struct ast_channel c0,
struct ast_channel c1 
)

Checks the need of a jb use in a generic bridge.

Parameters:
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.

Return values:
zero if there are no jitter buffers in use
non-zero if there are

Definition at line 202 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().

00203 {
00204    struct ast_jb *jb0 = &c0->jb;
00205    struct ast_jb *jb1 = &c1->jb;
00206    struct ast_jb_conf *conf0 = &jb0->conf;
00207    struct ast_jb_conf *conf1 = &jb1->conf;
00208    int c0_wants_jitter = c0->tech->properties & AST_CHAN_TP_WANTSJITTER;
00209    int c0_creates_jitter = c0->tech->properties & AST_CHAN_TP_CREATESJITTER;
00210    int c0_jb_enabled = ast_test_flag(conf0, AST_JB_ENABLED);
00211    int c0_force_jb = ast_test_flag(conf0, AST_JB_FORCED);
00212    int c0_jb_timebase_initialized = ast_test_flag(jb0, JB_TIMEBASE_INITIALIZED);
00213    int c0_jb_created = ast_test_flag(jb0, JB_CREATED);
00214    int c1_wants_jitter = c1->tech->properties & AST_CHAN_TP_WANTSJITTER;
00215    int c1_creates_jitter = c1->tech->properties & AST_CHAN_TP_CREATESJITTER;
00216    int c1_jb_enabled = ast_test_flag(conf1, AST_JB_ENABLED);
00217    int c1_force_jb = ast_test_flag(conf1, AST_JB_FORCED);
00218    int c1_jb_timebase_initialized = ast_test_flag(jb1, JB_TIMEBASE_INITIALIZED);
00219    int c1_jb_created = ast_test_flag(jb1, JB_CREATED);
00220    int inuse = 0;
00221 
00222    /* Determine whether audio going to c0 needs a jitter buffer */
00223    if (((!c0_wants_jitter && c1_creates_jitter) || (c0_force_jb && c1_creates_jitter)) && c0_jb_enabled) {
00224       ast_set_flag(jb0, JB_USE);
00225       if (!c0_jb_timebase_initialized) {
00226          if (c1_jb_timebase_initialized) {
00227             memcpy(&jb0->timebase, &jb1->timebase, sizeof(struct timeval));
00228          } else {
00229             gettimeofday(&jb0->timebase, NULL);
00230          }
00231          ast_set_flag(jb0, JB_TIMEBASE_INITIALIZED);
00232       }
00233 
00234       if (!c0_jb_created) {
00235          jb_choose_impl(c0);
00236       }
00237 
00238       inuse = 1;
00239    }
00240 
00241    /* Determine whether audio going to c1 needs a jitter buffer */
00242    if (((!c1_wants_jitter && c0_creates_jitter) || (c1_force_jb && c0_creates_jitter)) && c1_jb_enabled) {
00243       ast_set_flag(jb1, JB_USE);
00244       if (!c1_jb_timebase_initialized) {
00245          if (c0_jb_timebase_initialized) {
00246             memcpy(&jb1->timebase, &jb0->timebase, sizeof(struct timeval));
00247          } else {
00248             gettimeofday(&jb1->timebase, NULL);
00249          }
00250          ast_set_flag(jb1, JB_TIMEBASE_INITIALIZED);
00251       }
00252 
00253       if (!c1_jb_created) {
00254          jb_choose_impl(c1);
00255       }
00256 
00257       inuse = 1;
00258    }
00259 
00260    return inuse;
00261 }

void ast_jb_empty_and_reset ( struct ast_channel c0,
struct ast_channel c1 
)

drops all frames from a jitterbuffer and resets it

Parameters:
c0 one channel of a bridge
c1 the other channel of the bridge

Definition at line 621 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().

00622 {
00623    struct ast_jb *jb0 = &c0->jb;
00624    struct ast_jb *jb1 = &c1->jb;
00625    int c0_use_jb = ast_test_flag(jb0, JB_USE);
00626    int c0_jb_is_created = ast_test_flag(jb0, JB_CREATED);
00627    int c1_use_jb = ast_test_flag(jb1, JB_USE);
00628    int c1_jb_is_created = ast_test_flag(jb1, JB_CREATED);
00629 
00630    if (c0_use_jb && c0_jb_is_created && jb0->impl->empty_and_reset) {
00631       jb0->impl->empty_and_reset(jb0->jbobj);
00632    }
00633 
00634    if (c1_use_jb && c1_jb_is_created && jb1->impl->empty_and_reset) {
00635       jb1->impl->empty_and_reset(jb1->jbobj);
00636    }
00637 }

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.

Parameters:
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 368 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().

00369 {
00370    struct ast_jb *jb0 = &c0->jb;
00371    struct ast_jb *jb1 = &c1->jb;
00372    int c0_use_jb = ast_test_flag(jb0, JB_USE);
00373    int c0_jb_is_created = ast_test_flag(jb0, JB_CREATED);
00374    int c1_use_jb = ast_test_flag(jb1, JB_USE);
00375    int c1_jb_is_created = ast_test_flag(jb1, JB_CREATED);
00376 
00377    if (c0_use_jb && c0_jb_is_created)
00378       jb_get_and_deliver(c0);
00379 
00380    if (c1_use_jb && c1_jb_is_created)
00381       jb_get_and_deliver(c1);
00382 }

void ast_jb_get_config ( const struct ast_channel chan,
struct ast_jb_conf conf 
)

Copies a channel's jitterbuffer configuration.

Parameters:
chan channel.
conf destination.

Definition at line 616 of file abstract_jb.c.

References ast_jb::conf, and ast_channel::jb.

00617 {
00618    memcpy(conf, &chan->jb.conf, sizeof(*conf));
00619 }

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.

Parameters:
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.

Returns:
maximum time to wait.

Definition at line 263 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().

00264 {
00265    struct ast_jb *jb0 = &c0->jb;
00266    struct ast_jb *jb1 = &c1->jb;
00267    int c0_use_jb = ast_test_flag(jb0, JB_USE);
00268    int c0_jb_is_created = ast_test_flag(jb0, JB_CREATED);
00269    int c1_use_jb = ast_test_flag(jb1, JB_USE);
00270    int c1_jb_is_created = ast_test_flag(jb1, JB_CREATED);
00271    int wait, wait0, wait1;
00272    struct timeval tv_now;
00273 
00274    if (time_left == 0) {
00275       /* No time left - the bridge will be retried */
00276       /* TODO: Test disable this */
00277       /*return 0;*/
00278    }
00279 
00280    if (time_left < 0) {
00281       time_left = INT_MAX;
00282    }
00283 
00284    gettimeofday(&tv_now, NULL);
00285 
00286    wait0 = (c0_use_jb && c0_jb_is_created) ? jb0->next - get_now(jb0, &tv_now) : time_left;
00287    wait1 = (c1_use_jb && c1_jb_is_created) ? jb1->next - get_now(jb1, &tv_now) : time_left;
00288 
00289    wait = wait0 < wait1 ? wait0 : wait1;
00290    wait = wait < time_left ? wait : time_left;
00291 
00292    if (wait == INT_MAX) {
00293       wait = -1;
00294    } else if (wait < 1) {
00295       /* don't let wait=0, because this can cause the pbx thread to loop without any sleeping at all */
00296       wait = 1;
00297    }
00298 
00299    return wait;
00300 }

int ast_jb_put ( struct ast_channel chan,
struct ast_frame f 
)

Puts a frame into a channel jitterbuffer.

Parameters:
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.

Return values:
0 if the frame was queued
-1 if not

Definition at line 303 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_channel::name, ast_jb_impl::next, ast_jb::next, ast_jb_impl::put, ast_frame::src, and ast_frame::ts.

Referenced by ast_generic_bridge().

00304 {
00305    struct ast_jb *jb = &chan->jb;
00306    struct ast_jb_impl *jbimpl = jb->impl;
00307    void *jbobj = jb->jbobj;
00308    struct ast_frame *frr;
00309    long now = 0;
00310 
00311    if (!ast_test_flag(jb, JB_USE))
00312       return -1;
00313 
00314    if (f->frametype != AST_FRAME_VOICE) {
00315       if (f->frametype == AST_FRAME_DTMF && ast_test_flag(jb, JB_CREATED)) {
00316          jb_framelog("JB_PUT {now=%ld}: Received DTMF frame. Force resynching jb...\n", now);
00317          jbimpl->force_resync(jbobj);
00318       }
00319 
00320       return -1;
00321    }
00322 
00323    /* We consider an enabled jitterbuffer should receive frames with valid timing info. */
00324    if (!ast_test_flag(f, AST_FRFLAG_HAS_TIMING_INFO) || f->len < 2 || f->ts < 0) {
00325       ast_log(LOG_WARNING, "%s received frame with invalid timing info: "
00326          "has_timing_info=%d, len=%ld, ts=%ld, src=%s\n",
00327          chan->name, ast_test_flag(f, AST_FRFLAG_HAS_TIMING_INFO), f->len, f->ts, f->src);
00328       return -1;
00329    }
00330 
00331    frr = ast_frdup(f);
00332 
00333    if (!frr) {
00334       ast_log(LOG_ERROR, "Failed to isolate frame for the jitterbuffer on channel '%s'\n", chan->name);
00335       return -1;
00336    }
00337 
00338    if (!ast_test_flag(jb, JB_CREATED)) {
00339       if (create_jb(chan, frr)) {
00340          ast_frfree(frr);
00341          /* Disable the jitterbuffer */
00342          ast_clear_flag(jb, JB_USE);
00343          return -1;
00344       }
00345 
00346       ast_set_flag(jb, JB_CREATED);
00347       return 0;
00348    } else {
00349       now = get_now(jb, NULL);
00350       if (jbimpl->put(jbobj, frr, now) != JB_IMPL_OK) {
00351          jb_framelog("JB_PUT {now=%ld}: Dropped frame with ts=%ld and len=%ld\n", now, frr->ts, frr->len);
00352          ast_frfree(frr);
00353          /*return -1;*/
00354          /* TODO: Check this fix - should return 0 here, because the dropped frame shouldn't
00355             be delivered at all */
00356          return 0;
00357       }
00358 
00359       jb->next = jbimpl->next(jbobj);
00360 
00361       jb_framelog("JB_PUT {now=%ld}: Queued frame with ts=%ld and len=%ld\n", now, frr->ts, frr->len);
00362 
00363       return 0;
00364    }
00365 }

int ast_jb_read_conf ( struct ast_jb_conf conf,
const char *  varname,
const char *  value 
)

Sets jitterbuffer configuration property.

Parameters:
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.

Returns:
zero if the property was set to the configuration, -1 if not.

Definition at line 571 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(), store_config(), and store_config_core().

00572 {
00573    int prefixlen = sizeof(AST_JB_CONF_PREFIX) - 1;
00574    const char *name;
00575    int tmp;
00576 
00577    if (strncasecmp(AST_JB_CONF_PREFIX, varname, prefixlen)) {
00578       return -1;
00579    }
00580 
00581    name = varname + prefixlen;
00582 
00583    if (!strcasecmp(name, AST_JB_CONF_ENABLE)) {
00584       ast_set2_flag(conf, ast_true(value), AST_JB_ENABLED);
00585    } else if (!strcasecmp(name, AST_JB_CONF_FORCE)) {
00586       ast_set2_flag(conf, ast_true(value), AST_JB_FORCED);
00587    } else if (!strcasecmp(name, AST_JB_CONF_MAX_SIZE)) {
00588       if ((tmp = atoi(value)) > 0)
00589          conf->max_size = tmp;
00590    } else if (!strcasecmp(name, AST_JB_CONF_RESYNCH_THRESHOLD)) {
00591       if ((tmp = atoi(value)) > 0)
00592          conf->resync_threshold = tmp;
00593    } else if (!strcasecmp(name, AST_JB_CONF_IMPL)) {
00594       if (!ast_strlen_zero(value))
00595          snprintf(conf->impl, sizeof(conf->impl), "%s", value);
00596    } else if (!strcasecmp(name, AST_JB_CONF_TARGET_EXTRA)) {
00597       if (sscanf(value, "%30d", &tmp) == 1) {
00598          conf->target_extra = tmp;
00599       }
00600    } else if (!strcasecmp(name, AST_JB_CONF_LOG)) {
00601       ast_set2_flag(conf, ast_true(value), AST_JB_LOG);
00602    } else {
00603       return -1;
00604    }
00605 
00606    return 0;
00607 }


Generated by  doxygen 1.6.2