Asterisk - The Open Source Telephony Project  21.4.1
Data Structures | Macros | Enumerations | Functions | Variables
abstract_jb.c File Reference

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/pbx.h"
#include "asterisk/timing.h"
#include "asterisk/rtp_engine.h"
#include "asterisk/format_cache.h"
#include "asterisk/abstract_jb.h"
#include "fixedjitterbuf.h"
#include "jitterbuf.h"

Go to the source code of this file.

Data Structures

struct  jb_framedata
 
struct  jb_stream_sync
 

Macros

#define DEFAULT_RESYNC   1000
 
#define DEFAULT_SIZE   200
 
#define DEFAULT_TARGET_EXTRA   40
 
#define DEFAULT_TIMER_INTERVAL   20
 
#define DEFAULT_TYPE   AST_JB_FIXED
 
#define jb_framelog(...)
 Macros for the frame log files.
 
#define MAXIMUM_EARLY_FRAME_COUNT   200
 

Enumerations

enum  { JB_USE = (1 << 0), JB_TIMEBASE_INITIALIZED = (1 << 1), JB_CREATED = (1 << 2) }
 

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. More...
 
void ast_jb_configure (struct ast_channel *chan, const struct ast_jb_conf *conf)
 Configures a jitterbuffer on a channel. More...
 
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. More...
 
void ast_jb_destroy (struct ast_channel *chan)
 Destroys jitterbuffer on a channel. More...
 
int ast_jb_do_usecheck (struct ast_channel *c0, struct ast_channel *c1)
 Checks the need of a jb use in a generic bridge. More...
 
void ast_jb_empty_and_reset (struct ast_channel *c0, struct ast_channel *c1)
 drops all frames from a jitterbuffer and resets it More...
 
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. More...
 
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. More...
 
void ast_jb_get_config (const struct ast_channel *chan, struct ast_jb_conf *conf)
 Copies a channel's jitterbuffer configuration. More...
 
const 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. More...
 
int ast_jb_put (struct ast_channel *chan, struct ast_frame *f)
 Puts a frame into a channel jitterbuffer. More...
 
int ast_jb_read_conf (struct ast_jb_conf *conf, const char *varname, const char *value)
 Sets jitterbuffer configuration property. More...
 
static int create_jb (struct ast_channel *chan, struct ast_frame *first_frame)
 
static void datastore_destroy_cb (void *data)
 
static long get_now (struct ast_jb *jb, struct timeval *tv)
 
static void hook_destroy_cb (void *framedata)
 
static struct ast_framehook_event_cb (struct ast_channel *chan, struct ast_frame *frame, enum ast_framehook_event event, void *data)
 
static void jb_choose_impl (struct ast_channel *chan)
 
static void * jb_create_adaptive (struct ast_jb_conf *general_config)
 
static void * jb_create_fixed (struct ast_jb_conf *general_config)
 
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 void jb_framedata_destroy (struct jb_framedata *framedata)
 
static int jb_framedata_init (struct jb_framedata *framedata, struct ast_jb_conf *jb_conf)
 
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 int jb_is_late_adaptive (void *jb, long ts)
 
static int jb_is_late_fixed (void *jb, long ts)
 
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)
 
static struct timeval jitterbuffer_frame_get_ntp_timestamp (const struct jb_stream_sync *stream_sync, const struct ast_frame *frame)
 

Variables

static const int adaptive_to_abstract_code []
 
static const struct ast_jb_impl avail_impl []
 
static int default_impl = 0
 
static const int fixed_to_abstract_code []
 
static const struct ast_datastore_info jb_datastore
 
static const char *const jb_get_actions [] = {"Delivered", "Dropped", "Interpolated", "No"}
 

Detailed Description

Common implementation-independent jitterbuffer stuff.

Author
Slav Klenov slav@.nosp@m.secu.nosp@m.rax.o.nosp@m.rg

Definition in file abstract_jb.c.

Macro Definition Documentation

#define MAXIMUM_EARLY_FRAME_COUNT   200

The maximum size we allow the early frame buffer to get

Definition at line 59 of file abstract_jb.c.

Enumeration Type Documentation

anonymous enum

Internal jb flags

Definition at line 52 of file abstract_jb.c.

52  {
53  JB_USE = (1 << 0),
54  JB_TIMEBASE_INITIALIZED = (1 << 1),
55  JB_CREATED = (1 << 2)
56 };

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
confWhich jitterbuffer is being set

Definition at line 890 of file abstract_jb.c.

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

891 {
892  ast_clear_flag(conf, AST_FLAGS_ALL);
893  conf->max_size = DEFAULT_SIZE;
894  conf->resync_threshold = DEFAULT_RESYNC;
895  ast_copy_string(conf->impl, "fixed", sizeof(conf->impl));
896  conf->target_extra = DEFAULT_TARGET_EXTRA;
897 }
long resync_threshold
Resynchronization threshold of the jitterbuffer implementation.
Definition: abstract_jb.h:76
long target_extra
amount of additional jitterbuffer adjustment
Definition: abstract_jb.h:80
char impl[AST_JB_IMPL_NAME_SIZE]
Name of the jitterbuffer implementation to be used.
Definition: abstract_jb.h:78
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425
long max_size
Max size of the jitterbuffer implementation.
Definition: abstract_jb.h:74
void ast_jb_configure ( struct ast_channel chan,
const struct ast_jb_conf conf 
)

Configures a jitterbuffer on a channel.

Parameters
chanchannel to configure.
confconfiguration to apply.

Called from a channel driver when a channel is created and its jitterbuffer needs to be configured.

Definition at line 593 of file abstract_jb.c.

Referenced by ast_unreal_new_channels(), console_new(), and unistim_new().

594 {
595  memcpy(&ast_channel_jb(chan)->conf, conf, sizeof(*conf));
596 }
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
chanWhich channel the jitterbuffer is being set on
jb_confConfiguration to use for the jitterbuffer
prefer_existingIf this is true and a jitterbuffer already exists for the channel, use the existing jitterbuffer

Definition at line 1267 of file abstract_jb.c.

References ast_calloc, ast_channel_datastore_add(), ast_channel_datastore_find(), ast_channel_datastore_remove(), ast_channel_set_fd(), ast_datastore_free(), ast_framehook_attach(), ast_framehook_detach(), AST_JITTERBUFFER_FD, ast_datastore::data, ast_framehook_interface::data, ast_jb_conf::impl, and ast_framehook_interface::version.

Referenced by ast_jb_enable_for_channel().

1268 {
1269  struct jb_framedata *framedata;
1270  struct ast_datastore *datastore = NULL;
1271  struct ast_framehook_interface interface = {
1272  .version = AST_FRAMEHOOK_INTERFACE_VERSION,
1273  .event_cb = hook_event_cb,
1274  .destroy_cb = hook_destroy_cb,
1275  };
1276  int i = 0;
1277 
1278  /* If disabled, strip any existing jitterbuffer and don't replace it. */
1279  if (!strcasecmp(jb_conf->impl, "disabled")) {
1280  int *id;
1281  ast_channel_lock(chan);
1282  if ((datastore = ast_channel_datastore_find(chan, &jb_datastore, NULL))) {
1283  id = datastore->data;
1284  ast_framehook_detach(chan, *id);
1285  ast_channel_datastore_remove(chan, datastore);
1286  ast_datastore_free(datastore);
1287  }
1288  ast_channel_unlock(chan);
1289  return;
1290  }
1291 
1292  if (!(framedata = ast_calloc(1, sizeof(*framedata)))) {
1293  return;
1294  }
1295 
1296  if (jb_framedata_init(framedata, jb_conf)) {
1297  jb_framedata_destroy(framedata);
1298  return;
1299  }
1300 
1301  interface.data = framedata;
1302 
1303  ast_channel_lock(chan);
1304  i = ast_framehook_attach(chan, &interface);
1305  if (i >= 0) {
1306  int *id;
1307  if ((datastore = ast_channel_datastore_find(chan, &jb_datastore, NULL))) {
1308  /* There is already a jitterbuffer on the channel. */
1309  if (prefer_existing) {
1310  /* We prefer the existing jitterbuffer, so remove the new one and keep the old one. */
1311  ast_framehook_detach(chan, i);
1312  ast_channel_unlock(chan);
1313  return;
1314  }
1315  /* We prefer the new jitterbuffer, so strip the old one. */
1316  id = datastore->data;
1317  ast_framehook_detach(chan, *id);
1318  ast_channel_datastore_remove(chan, datastore);
1319  ast_datastore_free(datastore);
1320  }
1321 
1322  if (!(datastore = ast_datastore_alloc(&jb_datastore, NULL))) {
1323  ast_framehook_detach(chan, i);
1324  ast_channel_unlock(chan);
1325  return;
1326  }
1327 
1328  if (!(id = ast_calloc(1, sizeof(int)))) {
1329  ast_datastore_free(datastore);
1330  ast_framehook_detach(chan, i);
1331  ast_channel_unlock(chan);
1332  return;
1333  }
1334 
1335  *id = i; /* Store off the id. The channel is still locked so it is safe to access this ptr. */
1336  datastore->data = id;
1337  ast_channel_datastore_add(chan, datastore);
1338 
1339  ast_channel_set_fd(chan, AST_JITTERBUFFER_FD, framedata->timer_fd);
1340  } else {
1341  jb_framedata_destroy(framedata);
1342  framedata = NULL;
1343  }
1344  ast_channel_unlock(chan);
1345 }
int ast_framehook_detach(struct ast_channel *chan, int framehook_id)
Detach an framehook from a channel.
Definition: framehook.c:177
Structure for a data store object.
Definition: datastore.h:64
struct ast_datastore * ast_channel_datastore_find(struct ast_channel *chan, const struct ast_datastore_info *info, const char *uid)
Find a datastore on a channel.
Definition: channel.c:2399
int ast_datastore_free(struct ast_datastore *datastore)
Free a data store object.
Definition: datastore.c:68
int ast_framehook_attach(struct ast_channel *chan, struct ast_framehook_interface *i)
Attach an framehook onto a channel for frame interception.
Definition: framehook.c:132
char impl[AST_JB_IMPL_NAME_SIZE]
Name of the jitterbuffer implementation to be used.
Definition: abstract_jb.h:78
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
void ast_channel_set_fd(struct ast_channel *chan, int which, int fd)
Definition: channel.c:2426
void * data
Definition: datastore.h:66
#define AST_JITTERBUFFER_FD
Definition: channel.h:204
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
Definition: channel.c:2385
int ast_channel_datastore_remove(struct ast_channel *chan, struct ast_datastore *datastore)
Remove a datastore from a channel.
Definition: channel.c:2394
void ast_jb_destroy ( struct ast_channel chan)

Destroys jitterbuffer on a channel.

Parameters
chanchannel.

Called from ast_channel_free() when a channel is destroyed.

Definition at line 502 of file abstract_jb.c.

References ast_jb::impl, ast_jb::jbobj, ast_jb::last_format, and ast_jb::logfile.

Referenced by ast_channel_destructor().

503 {
504  struct ast_jb *jb = ast_channel_jb(chan);
505  const struct ast_jb_impl *jbimpl = jb->impl;
506  void *jbobj = jb->jbobj;
507  struct ast_frame *f;
508 
509  if (jb->logfile) {
510  fclose(jb->logfile);
511  jb->logfile = NULL;
512  }
513 
514  ao2_cleanup(jb->last_format);
515 
516  if (ast_test_flag(jb, JB_CREATED)) {
517  /* Remove and free all frames still queued in jb */
518  while (jbimpl->remove(jbobj, &f) == AST_JB_IMPL_OK) {
519  ast_frfree(f);
520  }
521 
522  jbimpl->destroy(jbobj);
523  jb->jbobj = NULL;
524 
525  ast_clear_flag(jb, JB_CREATED);
526 
527  ast_verb(3, "%s jitterbuffer destroyed on channel %s\n", jbimpl->name, ast_channel_name(chan));
528  }
529 }
const struct ast_jb_impl * impl
Jitterbuffer implementation to be used.
Definition: abstract_jb.h:145
void * jbobj
Jitterbuffer object, passed to the implementation.
Definition: abstract_jb.h:147
General jitterbuffer state.
Definition: abstract_jb.h:140
FILE * logfile
File for frame timestamp tracing.
Definition: abstract_jb.h:155
Data structure associated with a single frame of data.
struct ast_format * last_format
Voice format of the last frame in.
Definition: abstract_jb.h:153
Jitterbuffer implementation struct.
Definition: abstract_jb.h:121
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
c0first bridged channel.
c1second 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
zeroif there are no jitter buffers in use
non-zeroif there are

Definition at line 170 of file abstract_jb.c.

References AST_CHAN_TP_CREATESJITTER, AST_CHAN_TP_WANTSJITTER, ast_jb::conf, ast_channel_tech::properties, and ast_jb::timebase.

171 {
172  struct ast_jb *jb0 = ast_channel_jb(c0);
173  struct ast_jb *jb1 = ast_channel_jb(c1);
174  struct ast_jb_conf *conf0 = &jb0->conf;
175  struct ast_jb_conf *conf1 = &jb1->conf;
176  int c0_wants_jitter = ast_channel_tech(c0)->properties & AST_CHAN_TP_WANTSJITTER;
177  int c0_creates_jitter = ast_channel_tech(c0)->properties & AST_CHAN_TP_CREATESJITTER;
178  int c0_jb_enabled = ast_test_flag(conf0, AST_JB_ENABLED);
179  int c0_force_jb = ast_test_flag(conf0, AST_JB_FORCED);
180  int c0_jb_timebase_initialized = ast_test_flag(jb0, JB_TIMEBASE_INITIALIZED);
181  int c0_jb_created = ast_test_flag(jb0, JB_CREATED);
182  int c1_wants_jitter = ast_channel_tech(c1)->properties & AST_CHAN_TP_WANTSJITTER;
183  int c1_creates_jitter = ast_channel_tech(c1)->properties & AST_CHAN_TP_CREATESJITTER;
184  int c1_jb_enabled = ast_test_flag(conf1, AST_JB_ENABLED);
185  int c1_force_jb = ast_test_flag(conf1, AST_JB_FORCED);
186  int c1_jb_timebase_initialized = ast_test_flag(jb1, JB_TIMEBASE_INITIALIZED);
187  int c1_jb_created = ast_test_flag(jb1, JB_CREATED);
188  int inuse = 0;
189 
190  /* Determine whether audio going to c0 needs a jitter buffer */
191  if (((!c0_wants_jitter && c1_creates_jitter) || (c0_force_jb && c1_creates_jitter)) && c0_jb_enabled) {
192  ast_set_flag(jb0, JB_USE);
193  if (!c0_jb_timebase_initialized) {
194  if (c1_jb_timebase_initialized) {
195  memcpy(&jb0->timebase, &jb1->timebase, sizeof(struct timeval));
196  } else {
197  gettimeofday(&jb0->timebase, NULL);
198  }
199  ast_set_flag(jb0, JB_TIMEBASE_INITIALIZED);
200  }
201 
202  if (!c0_jb_created) {
203  jb_choose_impl(c0);
204  }
205 
206  inuse = 1;
207  }
208 
209  /* Determine whether audio going to c1 needs a jitter buffer */
210  if (((!c1_wants_jitter && c0_creates_jitter) || (c1_force_jb && c0_creates_jitter)) && c1_jb_enabled) {
211  ast_set_flag(jb1, JB_USE);
212  if (!c1_jb_timebase_initialized) {
213  if (c0_jb_timebase_initialized) {
214  memcpy(&jb1->timebase, &jb0->timebase, sizeof(struct timeval));
215  } else {
216  gettimeofday(&jb1->timebase, NULL);
217  }
218  ast_set_flag(jb1, JB_TIMEBASE_INITIALIZED);
219  }
220 
221  if (!c1_jb_created) {
222  jb_choose_impl(c1);
223  }
224 
225  inuse = 1;
226  }
227 
228  return inuse;
229 }
struct ast_jb_conf conf
Jitterbuffer configuration.
Definition: abstract_jb.h:143
Structure to describe a channel "technology", ie a channel driver See for examples: ...
Definition: channel.h:628
General jitterbuffer state.
Definition: abstract_jb.h:140
Channels have this property if they can accept input with jitter; i.e. most VoIP channels.
Definition: channel.h:960
Channels have this property if they can create jitter; i.e. most VoIP channels.
Definition: channel.h:965
struct timeval timebase
The time the jitterbuffer was created.
Definition: abstract_jb.h:149
General jitterbuffer configuration.
Definition: abstract_jb.h:69
void ast_jb_empty_and_reset ( struct ast_channel c0,
struct ast_channel c1 
)

drops all frames from a jitterbuffer and resets it

Parameters
c0one channel of a bridge
c1the other channel of the bridge

Definition at line 604 of file abstract_jb.c.

References ast_jb::impl, and ast_jb::jbobj.

605 {
606  struct ast_jb *jb0 = ast_channel_jb(c0);
607  struct ast_jb *jb1 = ast_channel_jb(c1);
608  int c0_use_jb = ast_test_flag(jb0, JB_USE);
609  int c0_jb_is_created = ast_test_flag(jb0, JB_CREATED);
610  int c1_use_jb = ast_test_flag(jb1, JB_USE);
611  int c1_jb_is_created = ast_test_flag(jb1, JB_CREATED);
612 
613  if (c0_use_jb && c0_jb_is_created && jb0->impl->empty_and_reset) {
614  jb0->impl->empty_and_reset(jb0->jbobj);
615  }
616 
617  if (c1_use_jb && c1_jb_is_created && jb1->impl->empty_and_reset) {
618  jb1->impl->empty_and_reset(jb1->jbobj);
619  }
620 }
const struct ast_jb_impl * impl
Jitterbuffer implementation to be used.
Definition: abstract_jb.h:145
void * jbobj
Jitterbuffer object, passed to the implementation.
Definition: abstract_jb.h:147
General jitterbuffer state.
Definition: abstract_jb.h:140
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
chanWhich channel is being set up

Definition at line 585 of file abstract_jb.c.

References ast_jb_create_framehook(), and ast_jb::conf.

586 {
587  struct ast_jb_conf conf = ast_channel_jb(chan)->conf;
588  if (ast_test_flag(&conf, AST_JB_ENABLED)) {
589  ast_jb_create_framehook(chan, &conf, 1);
590  }
591 }
struct ast_jb_conf conf
Jitterbuffer configuration.
Definition: abstract_jb.h:143
All configuration options for http media cache.
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.
Definition: abstract_jb.c:1267
General jitterbuffer configuration.
Definition: abstract_jb.h:69
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
c0first bridged channel.
c1second 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 using ast_write() each of the channels.

Definition at line 336 of file abstract_jb.c.

337 {
338  struct ast_jb *jb0 = ast_channel_jb(c0);
339  struct ast_jb *jb1 = ast_channel_jb(c1);
340  int c0_use_jb = ast_test_flag(jb0, JB_USE);
341  int c0_jb_is_created = ast_test_flag(jb0, JB_CREATED);
342  int c1_use_jb = ast_test_flag(jb1, JB_USE);
343  int c1_jb_is_created = ast_test_flag(jb1, JB_CREATED);
344 
345  if (c0_use_jb && c0_jb_is_created)
346  jb_get_and_deliver(c0);
347 
348  if (c1_use_jb && c1_jb_is_created)
349  jb_get_and_deliver(c1);
350 }
General jitterbuffer state.
Definition: abstract_jb.h:140
void ast_jb_get_config ( const struct ast_channel chan,
struct ast_jb_conf conf 
)

Copies a channel's jitterbuffer configuration.

Parameters
chanchannel.
confdestination.

Definition at line 599 of file abstract_jb.c.

600 {
601  memcpy(conf, &ast_channel_jb((struct ast_channel *) chan)->conf, sizeof(*conf));
602 }
Main Channel structure associated with a channel.
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
c0first bridged channel.
c1second bridged channel.
time_leftbridge 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 231 of file abstract_jb.c.

References ast_jb::next.

232 {
233  struct ast_jb *jb0 = ast_channel_jb(c0);
234  struct ast_jb *jb1 = ast_channel_jb(c1);
235  int c0_use_jb = ast_test_flag(jb0, JB_USE);
236  int c0_jb_is_created = ast_test_flag(jb0, JB_CREATED);
237  int c1_use_jb = ast_test_flag(jb1, JB_USE);
238  int c1_jb_is_created = ast_test_flag(jb1, JB_CREATED);
239  int wait, wait0, wait1;
240  struct timeval tv_now;
241 
242  if (time_left == 0) {
243  /* No time left - the bridge will be retried */
244  /* TODO: Test disable this */
245  /*return 0;*/
246  }
247 
248  if (time_left < 0) {
249  time_left = INT_MAX;
250  }
251 
252  gettimeofday(&tv_now, NULL);
253 
254  wait0 = (c0_use_jb && c0_jb_is_created) ? jb0->next - get_now(jb0, &tv_now) : time_left;
255  wait1 = (c1_use_jb && c1_jb_is_created) ? jb1->next - get_now(jb1, &tv_now) : time_left;
256 
257  wait = wait0 < wait1 ? wait0 : wait1;
258  wait = wait < time_left ? wait : time_left;
259 
260  if (wait == INT_MAX) {
261  wait = -1;
262  } else if (wait < 1) {
263  /* don't let wait=0, because this can cause the pbx thread to loop without any sleeping at all */
264  wait = 1;
265  }
266 
267  return wait;
268 }
General jitterbuffer state.
Definition: abstract_jb.h:140
long next
The time the next frame should be played.
Definition: abstract_jb.h:151
int ast_jb_put ( struct ast_channel chan,
struct ast_frame f 
)

Puts a frame into a channel jitterbuffer.

Parameters
chanchannel.
fframe.

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
0if the frame was queued
-1if not

Definition at line 271 of file abstract_jb.c.

References AST_FRAME_VOICE, ast_frdup, AST_FRFLAG_HAS_TIMING_INFO, ast_frame::frametype, ast_jb::impl, jb_framelog, ast_jb::jbobj, ast_frame::len, ast_jb::next, ast_frame::src, and ast_frame::ts.

272 {
273  struct ast_jb *jb = ast_channel_jb(chan);
274  const struct ast_jb_impl *jbimpl = jb->impl;
275  void *jbobj = jb->jbobj;
276  struct ast_frame *frr;
277  long now = 0;
278 
279  if (!ast_test_flag(jb, JB_USE))
280  return -1;
281 
282  if (f->frametype != AST_FRAME_VOICE) {
283  if (f->frametype == AST_FRAME_DTMF && ast_test_flag(jb, JB_CREATED)) {
284  jb_framelog("JB_PUT {now=%ld}: Received DTMF frame. Force resynching jb...\n", now);
285  jbimpl->force_resync(jbobj);
286  }
287 
288  return -1;
289  }
290 
291  /* We consider an enabled jitterbuffer should receive frames with valid timing info. */
292  if (!ast_test_flag(f, AST_FRFLAG_HAS_TIMING_INFO) || f->len < 2 || f->ts < 0) {
293  ast_log(LOG_WARNING, "%s received frame with invalid timing info: "
294  "has_timing_info=%u, len=%ld, ts=%ld, src=%s\n",
295  ast_channel_name(chan), ast_test_flag(f, AST_FRFLAG_HAS_TIMING_INFO), f->len, f->ts, f->src);
296  return -1;
297  }
298 
299  frr = ast_frdup(f);
300 
301  if (!frr) {
302  ast_log(LOG_ERROR, "Failed to isolate frame for the jitterbuffer on channel '%s'\n", ast_channel_name(chan));
303  return -1;
304  }
305 
306  if (!ast_test_flag(jb, JB_CREATED)) {
307  if (create_jb(chan, frr)) {
308  ast_frfree(frr);
309  /* Disable the jitterbuffer */
310  ast_clear_flag(jb, JB_USE);
311  return -1;
312  }
313 
314  ast_set_flag(jb, JB_CREATED);
315  return 0;
316  } else {
317  now = get_now(jb, NULL);
318  if (jbimpl->put(jbobj, frr, now) != AST_JB_IMPL_OK) {
319  jb_framelog("JB_PUT {now=%ld}: Dropped frame with ts=%ld and len=%ld\n", now, frr->ts, frr->len);
320  ast_frfree(frr);
321  /*return -1;*/
322  /* TODO: Check this fix - should return 0 here, because the dropped frame shouldn't
323  be delivered at all */
324  return 0;
325  }
326 
327  jb->next = jbimpl->next(jbobj);
328 
329  jb_framelog("JB_PUT {now=%ld}: Queued frame with ts=%ld and len=%ld\n", now, frr->ts, frr->len);
330 
331  return 0;
332  }
333 }
#define ast_frdup(fr)
Copies a frame.
const struct ast_jb_impl * impl
Jitterbuffer implementation to be used.
Definition: abstract_jb.h:145
#define jb_framelog(...)
Macros for the frame log files.
Definition: abstract_jb.c:130
const char * src
void * jbobj
Jitterbuffer object, passed to the implementation.
Definition: abstract_jb.h:147
General jitterbuffer state.
Definition: abstract_jb.h:140
Data structure associated with a single frame of data.
enum ast_frame_type frametype
Jitterbuffer implementation struct.
Definition: abstract_jb.h:121
long next
The time the next frame should be played.
Definition: abstract_jb.h:151
int ast_jb_read_conf ( struct ast_jb_conf conf,
const char *  varname,
const char *  value 
)

Sets jitterbuffer configuration property.

Parameters
confconfiguration to store the property in.
varnameproperty name.
valueproperty 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 545 of file abstract_jb.c.

References ast_true(), ast_jb_conf::impl, ast_jb_conf::max_size, ast_jb_conf::resync_threshold, and ast_jb_conf::target_extra.

Referenced by store_config_core().

546 {
547  int prefixlen = sizeof(AST_JB_CONF_PREFIX) - 1;
548  const char *name;
549  int tmp;
550 
551  if (strncasecmp(AST_JB_CONF_PREFIX, varname, prefixlen)) {
552  return -1;
553  }
554 
555  name = varname + prefixlen;
556 
557  if (!strcasecmp(name, AST_JB_CONF_ENABLE)) {
558  ast_set2_flag(conf, ast_true(value), AST_JB_ENABLED);
559  } else if (!strcasecmp(name, AST_JB_CONF_FORCE)) {
560  ast_set2_flag(conf, ast_true(value), AST_JB_FORCED);
561  } else if (!strcasecmp(name, AST_JB_CONF_MAX_SIZE)) {
562  if ((tmp = atoi(value)) > 0)
563  conf->max_size = tmp;
564  } else if (!strcasecmp(name, AST_JB_CONF_RESYNCH_THRESHOLD)) {
565  if ((tmp = atoi(value)) > 0)
566  conf->resync_threshold = tmp;
567  } else if (!strcasecmp(name, AST_JB_CONF_IMPL)) {
568  if (!ast_strlen_zero(value))
569  snprintf(conf->impl, sizeof(conf->impl), "%s", value);
570  } else if (!strcasecmp(name, AST_JB_CONF_TARGET_EXTRA)) {
571  if (sscanf(value, "%30d", &tmp) == 1) {
572  conf->target_extra = tmp;
573  }
574  } else if (!strcasecmp(name, AST_JB_CONF_LOG)) {
575  ast_set2_flag(conf, ast_true(value), AST_JB_LOG);
576  } else if (!strcasecmp(name, AST_JB_CONF_SYNC_VIDEO)) {
577  ast_set2_flag(conf, ast_true(value), AST_JB_SYNC_VIDEO);
578  } else {
579  return -1;
580  }
581 
582  return 0;
583 }
long resync_threshold
Resynchronization threshold of the jitterbuffer implementation.
Definition: abstract_jb.h:76
long target_extra
amount of additional jitterbuffer adjustment
Definition: abstract_jb.h:80
char impl[AST_JB_IMPL_NAME_SIZE]
Name of the jitterbuffer implementation to be used.
Definition: abstract_jb.h:78
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true". This function checks to see whether a string passed to it is an indication of an "true" value. It checks to see if the string is "yes", "true", "y", "t", "on" or "1".
Definition: utils.c:2199
long max_size
Max size of the jitterbuffer implementation.
Definition: abstract_jb.h:74

Variable Documentation

const int adaptive_to_abstract_code[]
static
Initial value:
=
{AST_JB_IMPL_OK, AST_JB_IMPL_NOFRAME, AST_JB_IMPL_NOFRAME, AST_JB_IMPL_INTERP, AST_JB_IMPL_DROP, AST_JB_IMPL_OK}

Definition at line 123 of file abstract_jb.c.

const int fixed_to_abstract_code[]
static
Initial value:
=
{AST_JB_IMPL_OK, AST_JB_IMPL_DROP, AST_JB_IMPL_INTERP, AST_JB_IMPL_NOFRAME}

Definition at line 121 of file abstract_jb.c.

const struct ast_datastore_info jb_datastore
static
Initial value:
= {
.type = "jitterbuffer",
.destroy = datastore_destroy_cb
}

Definition at line 904 of file abstract_jb.c.