abstract_jb.h File Reference

Common implementation-independent jitterbuffer stuff. More...

#include <sys/time.h>
#include "asterisk/format.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...
struct  ast_jb_impl
 Jitterbuffer implementation struct. 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

Typedefs

typedef void *(* jb_create_impl )(struct ast_jb_conf *general_config)
 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  { AST_JB_ENABLED = (1 << 0), AST_JB_FORCED = (1 << 1), AST_JB_LOG = (1 << 2) }
enum  { AST_JB_IMPL_OK, AST_JB_IMPL_DROP, AST_JB_IMPL_INTERP, AST_JB_IMPL_NOFRAME }
enum  ast_jb_type { AST_JB_FIXED, AST_JB_ADAPTIVE }

Functions

void ast_jb_conf_default (struct ast_jb_conf *conf)
 Sets the contents of an ast_jb_conf struct to the default jitterbuffer settings.
void ast_jb_configure (struct ast_channel *chan, const struct ast_jb_conf *conf)
 Configures a jitterbuffer on a channel.
void ast_jb_create_framehook (struct ast_channel *chan, struct ast_jb_conf *jb_conf, int prefer_existing)
 Applies a jitterbuffer framehook to a channel based on a provided jitterbuffer config.
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_enable_for_channel (struct ast_channel *chan)
 Sets a jitterbuffer frame hook on the channel based on the channel's stored jitterbuffer configuration.
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_implast_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.


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

Referenced by ast_jb_read_conf().

#define AST_JB_CONF_FORCE   "force"

Definition at line 86 of file abstract_jb.h.

Referenced by ast_jb_read_conf().

#define AST_JB_CONF_IMPL   "impl"

Definition at line 90 of file abstract_jb.h.

Referenced by ast_jb_read_conf().

#define AST_JB_CONF_LOG   "log"

Definition at line 91 of file abstract_jb.h.

Referenced by ast_jb_read_conf().

#define AST_JB_CONF_MAX_SIZE   "maxsize"

Definition at line 87 of file abstract_jb.h.

Referenced by ast_jb_read_conf().

#define AST_JB_CONF_PREFIX   "jb"

Definition at line 84 of file abstract_jb.h.

Referenced by ast_jb_read_conf().

#define AST_JB_CONF_RESYNCH_THRESHOLD   "resyncthreshold"

Definition at line 88 of file abstract_jb.h.

Referenced by ast_jb_read_conf().

#define AST_JB_CONF_TARGET_EXTRA   "targetextra"

Definition at line 89 of file abstract_jb.h.

Referenced by ast_jb_read_conf().

#define AST_JB_IMPL_NAME_SIZE   12

Definition at line 63 of file abstract_jb.h.

Referenced by create_jb().


Typedef Documentation

typedef void*(* jb_create_impl)(struct ast_jb_conf *general_config)

Create.

Definition at line 95 of file abstract_jb.h.

typedef void(* jb_destroy_impl)(void *jb)

Destroy.

Definition at line 97 of file abstract_jb.h.

typedef void(* jb_empty_and_reset_impl)(void *jb)

Empty and reset jb.

Definition at line 111 of file abstract_jb.h.

typedef void(* jb_force_resynch_impl)(void *jb)

Force resynch.

Definition at line 109 of file abstract_jb.h.

typedef int(* jb_get_impl)(void *jb, struct ast_frame **fout, long now, long interpl)

Get frame for now.

Definition at line 103 of file abstract_jb.h.

typedef long(* jb_next_impl)(void *jb)

Get next.

Definition at line 105 of file abstract_jb.h.

typedef int(* jb_put_first_impl)(void *jb, struct ast_frame *fin, long now)

Put first frame.

Definition at line 99 of file abstract_jb.h.

typedef int(* jb_put_impl)(void *jb, struct ast_frame *fin, long now)

Put frame.

Definition at line 101 of file abstract_jb.h.

typedef int(* jb_remove_impl)(void *jb, struct ast_frame **fout)

Remove first frame.

Definition at line 107 of file abstract_jb.h.


Enumeration Type Documentation

anonymous enum

Enumerator:
AST_JB_ENABLED 
AST_JB_FORCED 
AST_JB_LOG 

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 };

anonymous enum

Abstract return codes

Enumerator:
AST_JB_IMPL_OK 
AST_JB_IMPL_DROP 
AST_JB_IMPL_INTERP 
AST_JB_IMPL_NOFRAME 

Definition at line 56 of file abstract_jb.h.

00056      {
00057    AST_JB_IMPL_OK,
00058    AST_JB_IMPL_DROP,
00059    AST_JB_IMPL_INTERP,
00060    AST_JB_IMPL_NOFRAME
00061 };

Enumerator:
AST_JB_FIXED 
AST_JB_ADAPTIVE 

Definition at line 50 of file abstract_jb.h.

00050                  {
00051    AST_JB_FIXED,
00052    AST_JB_ADAPTIVE,
00053 };


Function Documentation

void ast_jb_conf_default ( struct ast_jb_conf conf  ) 

Sets the contents of an ast_jb_conf struct to the default jitterbuffer settings.

Since:
12
Parameters:
conf Which jitterbuffer is being set

Definition at line 851 of file abstract_jb.c.

References ast_copy_string(), DEFAULT_RESYNC, DEFAULT_SIZE, DEFAULT_TARGET_EXTRA, ast_jb_conf::impl, ast_jb_conf::max_size, ast_jb_conf::resync_threshold, and ast_jb_conf::target_extra.

Referenced by jb_helper().

00852 {
00853    conf->max_size = DEFAULT_SIZE;
00854    conf->resync_threshold = DEFAULT_RESYNC;
00855    ast_copy_string(conf->impl, "fixed", sizeof(conf->impl));
00856    conf->target_extra = DEFAULT_TARGET_EXTRA;
00857 }

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 582 of file abstract_jb.c.

References ast_channel_jb().

Referenced by alsa_new(), ast_unreal_new_channels(), console_new(), dahdi_new(), mgcp_new(), misdn_new(), ooh323_new(), oss_new(), sip_new(), skinny_new(), and unistim_new().

00583 {
00584    memcpy(&ast_channel_jb(chan)->conf, conf, sizeof(*conf));
00585 }

void ast_jb_create_framehook ( struct ast_channel chan,
struct ast_jb_conf jb_conf,
int  prefer_existing 
)

Applies a jitterbuffer framehook to a channel based on a provided jitterbuffer config.

Since:
12
Parameters:
chan Which channel the jitterbuffer is being set on
jb_conf Configuration to use for the jitterbuffer
prefer_existing If this is true and a jitterbuffer already exists for the channel, use the existing jitterbuffer

Definition at line 1050 of file abstract_jb.c.

References ast_calloc, ast_channel_datastore_add(), ast_channel_datastore_find(), ast_channel_datastore_remove(), ast_channel_lock, ast_channel_set_fd(), ast_channel_unlock, ast_datastore_alloc, ast_datastore_free(), ast_framehook_attach(), ast_framehook_detach(), AST_FRAMEHOOK_INTERFACE_VERSION, AST_JITTERBUFFER_FD, ast_framehook_interface::data, ast_datastore::data, hook_destroy_cb(), hook_event_cb(), id, ast_jb_conf::impl, jb_framedata_destroy(), jb_framedata_init(), NULL, jb_framedata::timer_fd, and ast_framehook_interface::version.

Referenced by ast_jb_enable_for_channel(), and jb_helper().

01051 {
01052    struct jb_framedata *framedata;
01053    struct ast_datastore *datastore = NULL;
01054    struct ast_framehook_interface interface = {
01055       .version = AST_FRAMEHOOK_INTERFACE_VERSION,
01056       .event_cb = hook_event_cb,
01057       .destroy_cb = hook_destroy_cb,
01058    };
01059    int i = 0;
01060 
01061    /* If disabled, strip any existing jitterbuffer and don't replace it. */
01062    if (!strcasecmp(jb_conf->impl, "disabled")) {
01063       int *id;
01064       ast_channel_lock(chan);
01065       if ((datastore = ast_channel_datastore_find(chan, &jb_datastore, NULL))) {
01066          id = datastore->data;
01067          ast_framehook_detach(chan, *id);
01068          ast_channel_datastore_remove(chan, datastore);
01069          ast_datastore_free(datastore);
01070       }
01071       ast_channel_unlock(chan);
01072       return;
01073    }
01074 
01075    if (!(framedata = ast_calloc(1, sizeof(*framedata)))) {
01076       return;
01077    }
01078 
01079    if (jb_framedata_init(framedata, jb_conf)) {
01080       jb_framedata_destroy(framedata);
01081       return;
01082    }
01083 
01084    interface.data = framedata;
01085 
01086    ast_channel_lock(chan);
01087    i = ast_framehook_attach(chan, &interface);
01088    if (i >= 0) {
01089       int *id;
01090       if ((datastore = ast_channel_datastore_find(chan, &jb_datastore, NULL))) {
01091          /* There is already a jitterbuffer on the channel. */
01092          if (prefer_existing) {
01093             /* We prefer the existing jitterbuffer, so remove the new one and keep the old one. */
01094             ast_framehook_detach(chan, i);
01095             ast_channel_unlock(chan);
01096             return;
01097          }
01098          /* We prefer the new jitterbuffer, so strip the old one. */
01099          id = datastore->data;
01100          ast_framehook_detach(chan, *id);
01101          ast_channel_datastore_remove(chan, datastore);
01102          ast_datastore_free(datastore);
01103       }
01104 
01105       if (!(datastore = ast_datastore_alloc(&jb_datastore, NULL))) {
01106          ast_framehook_detach(chan, i);
01107          ast_channel_unlock(chan);
01108          return;
01109       }
01110 
01111       if (!(id = ast_calloc(1, sizeof(int)))) {
01112          ast_datastore_free(datastore);
01113          ast_framehook_detach(chan, i);
01114          ast_channel_unlock(chan);
01115          return;
01116       }
01117 
01118       *id = i; /* Store off the id. The channel is still locked so it is safe to access this ptr. */
01119       datastore->data = id;
01120       ast_channel_datastore_add(chan, datastore);
01121 
01122       ast_channel_set_fd(chan, AST_JITTERBUFFER_FD, framedata->timer_fd);
01123    } else {
01124       jb_framedata_destroy(framedata);
01125       framedata = NULL;
01126    }
01127    ast_channel_unlock(chan);
01128 }

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 493 of file abstract_jb.c.

References ao2_cleanup, ast_channel_jb(), 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, JB_CREATED, ast_jb::jbobj, ast_jb::last_format, ast_jb::logfile, ast_jb_impl::name, NULL, and ast_jb_impl::remove.

Referenced by ast_channel_destructor().

00494 {
00495    struct ast_jb *jb = ast_channel_jb(chan);
00496    const struct ast_jb_impl *jbimpl = jb->impl;
00497    void *jbobj = jb->jbobj;
00498    struct ast_frame *f;
00499 
00500    if (jb->logfile) {
00501       fclose(jb->logfile);
00502       jb->logfile = NULL;
00503    }
00504 
00505    ao2_cleanup(jb->last_format);
00506 
00507    if (ast_test_flag(jb, JB_CREATED)) {
00508       /* Remove and free all frames still queued in jb */
00509       while (jbimpl->remove(jbobj, &f) == AST_JB_IMPL_OK) {
00510          ast_frfree(f);
00511       }
00512 
00513       jbimpl->destroy(jbobj);
00514       jb->jbobj = NULL;
00515 
00516       ast_clear_flag(jb, JB_CREATED);
00517 
00518       ast_verb(3, "%s jitterbuffer destroyed on channel %s\n", jbimpl->name, ast_channel_name(chan));
00519    }
00520 }

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 163 of file abstract_jb.c.

References AST_CHAN_TP_CREATESJITTER, AST_CHAN_TP_WANTSJITTER, ast_channel_jb(), ast_channel_tech(), AST_JB_ENABLED, AST_JB_FORCED, ast_set_flag, ast_test_flag, ast_jb::conf, jb_choose_impl(), JB_CREATED, JB_TIMEBASE_INITIALIZED, JB_USE, NULL, ast_channel_tech::properties, and ast_jb::timebase.

00164 {
00165    struct ast_jb *jb0 = ast_channel_jb(c0);
00166    struct ast_jb *jb1 = ast_channel_jb(c1);
00167    struct ast_jb_conf *conf0 = &jb0->conf;
00168    struct ast_jb_conf *conf1 = &jb1->conf;
00169    int c0_wants_jitter = ast_channel_tech(c0)->properties & AST_CHAN_TP_WANTSJITTER;
00170    int c0_creates_jitter = ast_channel_tech(c0)->properties & AST_CHAN_TP_CREATESJITTER;
00171    int c0_jb_enabled = ast_test_flag(conf0, AST_JB_ENABLED);
00172    int c0_force_jb = ast_test_flag(conf0, AST_JB_FORCED);
00173    int c0_jb_timebase_initialized = ast_test_flag(jb0, JB_TIMEBASE_INITIALIZED);
00174    int c0_jb_created = ast_test_flag(jb0, JB_CREATED);
00175    int c1_wants_jitter = ast_channel_tech(c1)->properties & AST_CHAN_TP_WANTSJITTER;
00176    int c1_creates_jitter = ast_channel_tech(c1)->properties & AST_CHAN_TP_CREATESJITTER;
00177    int c1_jb_enabled = ast_test_flag(conf1, AST_JB_ENABLED);
00178    int c1_force_jb = ast_test_flag(conf1, AST_JB_FORCED);
00179    int c1_jb_timebase_initialized = ast_test_flag(jb1, JB_TIMEBASE_INITIALIZED);
00180    int c1_jb_created = ast_test_flag(jb1, JB_CREATED);
00181    int inuse = 0;
00182 
00183    /* Determine whether audio going to c0 needs a jitter buffer */
00184    if (((!c0_wants_jitter && c1_creates_jitter) || (c0_force_jb && c1_creates_jitter)) && c0_jb_enabled) {
00185       ast_set_flag(jb0, JB_USE);
00186       if (!c0_jb_timebase_initialized) {
00187          if (c1_jb_timebase_initialized) {
00188             memcpy(&jb0->timebase, &jb1->timebase, sizeof(struct timeval));
00189          } else {
00190             gettimeofday(&jb0->timebase, NULL);
00191          }
00192          ast_set_flag(jb0, JB_TIMEBASE_INITIALIZED);
00193       }
00194 
00195       if (!c0_jb_created) {
00196          jb_choose_impl(c0);
00197       }
00198 
00199       inuse = 1;
00200    }
00201 
00202    /* Determine whether audio going to c1 needs a jitter buffer */
00203    if (((!c1_wants_jitter && c0_creates_jitter) || (c1_force_jb && c0_creates_jitter)) && c1_jb_enabled) {
00204       ast_set_flag(jb1, JB_USE);
00205       if (!c1_jb_timebase_initialized) {
00206          if (c0_jb_timebase_initialized) {
00207             memcpy(&jb1->timebase, &jb0->timebase, sizeof(struct timeval));
00208          } else {
00209             gettimeofday(&jb1->timebase, NULL);
00210          }
00211          ast_set_flag(jb1, JB_TIMEBASE_INITIALIZED);
00212       }
00213 
00214       if (!c1_jb_created) {
00215          jb_choose_impl(c1);
00216       }
00217 
00218       inuse = 1;
00219    }
00220 
00221    return inuse;
00222 }

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 593 of file abstract_jb.c.

References ast_channel_jb(), ast_test_flag, ast_jb_impl::empty_and_reset, ast_jb::impl, JB_CREATED, JB_USE, and ast_jb::jbobj.

00594 {
00595    struct ast_jb *jb0 = ast_channel_jb(c0);
00596    struct ast_jb *jb1 = ast_channel_jb(c1);
00597    int c0_use_jb = ast_test_flag(jb0, JB_USE);
00598    int c0_jb_is_created = ast_test_flag(jb0, JB_CREATED);
00599    int c1_use_jb = ast_test_flag(jb1, JB_USE);
00600    int c1_jb_is_created = ast_test_flag(jb1, JB_CREATED);
00601 
00602    if (c0_use_jb && c0_jb_is_created && jb0->impl->empty_and_reset) {
00603       jb0->impl->empty_and_reset(jb0->jbobj);
00604    }
00605 
00606    if (c1_use_jb && c1_jb_is_created && jb1->impl->empty_and_reset) {
00607       jb1->impl->empty_and_reset(jb1->jbobj);
00608    }
00609 }

void ast_jb_enable_for_channel ( struct ast_channel chan  ) 

Sets a jitterbuffer frame hook on the channel based on the channel's stored jitterbuffer configuration.

Since:
12.0
Parameters:
chan Which channel is being set up

Definition at line 574 of file abstract_jb.c.

References ast_channel_jb(), ast_jb_create_framehook(), AST_JB_ENABLED, ast_test_flag, and ast_jb::conf.

Referenced by bridge_channel_internal_join().

00575 {
00576    struct ast_jb_conf conf = ast_channel_jb(chan)->conf;
00577    if (ast_test_flag(&conf, AST_JB_ENABLED)) {
00578       ast_jb_create_framehook(chan, &conf, 1);
00579    }
00580 }

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 329 of file abstract_jb.c.

References ast_channel_jb(), ast_test_flag, JB_CREATED, jb_get_and_deliver(), and JB_USE.

00330 {
00331    struct ast_jb *jb0 = ast_channel_jb(c0);
00332    struct ast_jb *jb1 = ast_channel_jb(c1);
00333    int c0_use_jb = ast_test_flag(jb0, JB_USE);
00334    int c0_jb_is_created = ast_test_flag(jb0, JB_CREATED);
00335    int c1_use_jb = ast_test_flag(jb1, JB_USE);
00336    int c1_jb_is_created = ast_test_flag(jb1, JB_CREATED);
00337 
00338    if (c0_use_jb && c0_jb_is_created)
00339       jb_get_and_deliver(c0);
00340 
00341    if (c1_use_jb && c1_jb_is_created)
00342       jb_get_and_deliver(c1);
00343 }

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 588 of file abstract_jb.c.

References ast_channel_jb().

00589 {
00590    memcpy(conf, &ast_channel_jb((struct ast_channel *) chan)->conf, sizeof(*conf));
00591 }

struct ast_jb_impl* ast_jb_get_impl ( enum ast_jb_type  type  )  [read]

Definition at line 804 of file abstract_jb.c.

References ARRAY_LEN, and NULL.

Referenced by jb_framedata_init().

00805 {
00806    int i;
00807    for (i = 0; i < ARRAY_LEN(avail_impl); i++) {
00808       if (avail_impl[i].type == type) {
00809          return &avail_impl[i];
00810       }
00811    }
00812    return NULL;
00813 }

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 224 of file abstract_jb.c.

References ast_channel_jb(), ast_test_flag, get_now(), JB_CREATED, JB_USE, ast_jb::next, and NULL.

00225 {
00226    struct ast_jb *jb0 = ast_channel_jb(c0);
00227    struct ast_jb *jb1 = ast_channel_jb(c1);
00228    int c0_use_jb = ast_test_flag(jb0, JB_USE);
00229    int c0_jb_is_created = ast_test_flag(jb0, JB_CREATED);
00230    int c1_use_jb = ast_test_flag(jb1, JB_USE);
00231    int c1_jb_is_created = ast_test_flag(jb1, JB_CREATED);
00232    int wait, wait0, wait1;
00233    struct timeval tv_now;
00234 
00235    if (time_left == 0) {
00236       /* No time left - the bridge will be retried */
00237       /* TODO: Test disable this */
00238       /*return 0;*/
00239    }
00240 
00241    if (time_left < 0) {
00242       time_left = INT_MAX;
00243    }
00244 
00245    gettimeofday(&tv_now, NULL);
00246 
00247    wait0 = (c0_use_jb && c0_jb_is_created) ? jb0->next - get_now(jb0, &tv_now) : time_left;
00248    wait1 = (c1_use_jb && c1_jb_is_created) ? jb1->next - get_now(jb1, &tv_now) : time_left;
00249 
00250    wait = wait0 < wait1 ? wait0 : wait1;
00251    wait = wait < time_left ? wait : time_left;
00252 
00253    if (wait == INT_MAX) {
00254       wait = -1;
00255    } else if (wait < 1) {
00256       /* don't let wait=0, because this can cause the pbx thread to loop without any sleeping at all */
00257       wait = 1;
00258    }
00259 
00260    return wait;
00261 }

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 264 of file abstract_jb.c.

References ast_channel_jb(), 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, JB_CREATED, jb_framelog, JB_USE, ast_jb::jbobj, ast_frame::len, LOG_ERROR, LOG_WARNING, ast_jb_impl::next, ast_jb::next, NULL, ast_jb_impl::put, ast_frame::src, and ast_frame::ts.

00265 {
00266    struct ast_jb *jb = ast_channel_jb(chan);
00267    const struct ast_jb_impl *jbimpl = jb->impl;
00268    void *jbobj = jb->jbobj;
00269    struct ast_frame *frr;
00270    long now = 0;
00271 
00272    if (!ast_test_flag(jb, JB_USE))
00273       return -1;
00274 
00275    if (f->frametype != AST_FRAME_VOICE) {
00276       if (f->frametype == AST_FRAME_DTMF && ast_test_flag(jb, JB_CREATED)) {
00277          jb_framelog("JB_PUT {now=%ld}: Received DTMF frame. Force resynching jb...\n", now);
00278          jbimpl->force_resync(jbobj);
00279       }
00280 
00281       return -1;
00282    }
00283 
00284    /* We consider an enabled jitterbuffer should receive frames with valid timing info. */
00285    if (!ast_test_flag(f, AST_FRFLAG_HAS_TIMING_INFO) || f->len < 2 || f->ts < 0) {
00286       ast_log(LOG_WARNING, "%s received frame with invalid timing info: "
00287          "has_timing_info=%u, len=%ld, ts=%ld, src=%s\n",
00288          ast_channel_name(chan), ast_test_flag(f, AST_FRFLAG_HAS_TIMING_INFO), f->len, f->ts, f->src);
00289       return -1;
00290    }
00291 
00292    frr = ast_frdup(f);
00293 
00294    if (!frr) {
00295       ast_log(LOG_ERROR, "Failed to isolate frame for the jitterbuffer on channel '%s'\n", ast_channel_name(chan));
00296       return -1;
00297    }
00298 
00299    if (!ast_test_flag(jb, JB_CREATED)) {
00300       if (create_jb(chan, frr)) {
00301          ast_frfree(frr);
00302          /* Disable the jitterbuffer */
00303          ast_clear_flag(jb, JB_USE);
00304          return -1;
00305       }
00306 
00307       ast_set_flag(jb, JB_CREATED);
00308       return 0;
00309    } else {
00310       now = get_now(jb, NULL);
00311       if (jbimpl->put(jbobj, frr, now) != AST_JB_IMPL_OK) {
00312          jb_framelog("JB_PUT {now=%ld}: Dropped frame with ts=%ld and len=%ld\n", now, frr->ts, frr->len);
00313          ast_frfree(frr);
00314          /*return -1;*/
00315          /* TODO: Check this fix - should return 0 here, because the dropped frame shouldn't
00316             be delivered at all */
00317          return 0;
00318       }
00319 
00320       jb->next = jbimpl->next(jbobj);
00321 
00322       jb_framelog("JB_PUT {now=%ld}: Queued frame with ts=%ld and len=%ld\n", now, frr->ts, frr->len);
00323 
00324       return 0;
00325    }
00326 }

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 536 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, ast_jb_conf::target_extra, and tmp().

Referenced by _build_general_config(), config_parse_variables(), jb_helper(), load_module(), process_dahdi(), reload_config(), and store_config_core().

00537 {
00538    int prefixlen = sizeof(AST_JB_CONF_PREFIX) - 1;
00539    const char *name;
00540    int tmp;
00541 
00542    if (strncasecmp(AST_JB_CONF_PREFIX, varname, prefixlen)) {
00543       return -1;
00544    }
00545 
00546    name = varname + prefixlen;
00547 
00548    if (!strcasecmp(name, AST_JB_CONF_ENABLE)) {
00549       ast_set2_flag(conf, ast_true(value), AST_JB_ENABLED);
00550    } else if (!strcasecmp(name, AST_JB_CONF_FORCE)) {
00551       ast_set2_flag(conf, ast_true(value), AST_JB_FORCED);
00552    } else if (!strcasecmp(name, AST_JB_CONF_MAX_SIZE)) {
00553       if ((tmp = atoi(value)) > 0)
00554          conf->max_size = tmp;
00555    } else if (!strcasecmp(name, AST_JB_CONF_RESYNCH_THRESHOLD)) {
00556       if ((tmp = atoi(value)) > 0)
00557          conf->resync_threshold = tmp;
00558    } else if (!strcasecmp(name, AST_JB_CONF_IMPL)) {
00559       if (!ast_strlen_zero(value))
00560          snprintf(conf->impl, sizeof(conf->impl), "%s", value);
00561    } else if (!strcasecmp(name, AST_JB_CONF_TARGET_EXTRA)) {
00562       if (sscanf(value, "%30d", &tmp) == 1) {
00563          conf->target_extra = tmp;
00564       }
00565    } else if (!strcasecmp(name, AST_JB_CONF_LOG)) {
00566       ast_set2_flag(conf, ast_true(value), AST_JB_LOG);
00567    } else {
00568       return -1;
00569    }
00570 
00571    return 0;
00572 }


Generated on Thu Apr 16 06:28:07 2015 for Asterisk - The Open Source Telephony Project by  doxygen 1.5.6