Asterisk - The Open Source Telephony Project  18.5.0
Data Structures | Macros | Typedefs | Enumerations | Functions
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...
 

Macros

#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_SYNC_VIDEO   "syncvideo"
 
#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. More...
 
typedef void(* jb_destroy_impl) (void *jb)
 Destroy. More...
 
typedef void(* jb_empty_and_reset_impl) (void *jb)
 Empty and reset jb. More...
 
typedef void(* jb_force_resynch_impl) (void *jb)
 Force resynch. More...
 
typedef int(* jb_get_impl) (void *jb, struct ast_frame **fout, long now, long interpl)
 Get frame for now. More...
 
typedef int(* jb_is_late_impl) (void *jb, long ts)
 Check if late. More...
 
typedef long(* jb_next_impl) (void *jb)
 Get next. More...
 
typedef int(* jb_put_first_impl) (void *jb, struct ast_frame *fin, long now)
 Put first frame. More...
 
typedef int(* jb_put_impl) (void *jb, struct ast_frame *fin, long now)
 Put frame. More...
 
typedef int(* jb_remove_impl) (void *jb, struct ast_frame **fout)
 Remove first frame. More...
 

Enumerations

enum  { AST_JB_ENABLED = (1 << 0), AST_JB_FORCED = (1 << 1), AST_JB_LOG = (1 << 2), AST_JB_SYNC_VIDEO = (1 << 3) }
 
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. 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...
 

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.h.

Macro Definition Documentation

◆ AST_JB_CONF_ENABLE

#define AST_JB_CONF_ENABLE   "enable"

Definition at line 86 of file abstract_jb.h.

Referenced by ast_jb_read_conf().

◆ AST_JB_CONF_FORCE

#define AST_JB_CONF_FORCE   "force"

Definition at line 87 of file abstract_jb.h.

Referenced by ast_jb_read_conf().

◆ AST_JB_CONF_IMPL

#define AST_JB_CONF_IMPL   "impl"

Definition at line 91 of file abstract_jb.h.

Referenced by ast_jb_read_conf().

◆ AST_JB_CONF_LOG

#define AST_JB_CONF_LOG   "log"

Definition at line 92 of file abstract_jb.h.

Referenced by ast_jb_read_conf().

◆ AST_JB_CONF_MAX_SIZE

#define AST_JB_CONF_MAX_SIZE   "maxsize"

Definition at line 88 of file abstract_jb.h.

Referenced by ast_jb_read_conf().

◆ AST_JB_CONF_PREFIX

#define AST_JB_CONF_PREFIX   "jb"

Definition at line 85 of file abstract_jb.h.

Referenced by ast_jb_read_conf().

◆ AST_JB_CONF_RESYNCH_THRESHOLD

#define AST_JB_CONF_RESYNCH_THRESHOLD   "resyncthreshold"

Definition at line 89 of file abstract_jb.h.

Referenced by ast_jb_read_conf().

◆ AST_JB_CONF_SYNC_VIDEO

#define AST_JB_CONF_SYNC_VIDEO   "syncvideo"

Definition at line 93 of file abstract_jb.h.

Referenced by ast_jb_read_conf().

◆ AST_JB_CONF_TARGET_EXTRA

#define AST_JB_CONF_TARGET_EXTRA   "targetextra"

Definition at line 90 of file abstract_jb.h.

Referenced by ast_jb_read_conf().

◆ AST_JB_IMPL_NAME_SIZE

#define AST_JB_IMPL_NAME_SIZE   12

Definition at line 64 of file abstract_jb.h.

Referenced by create_jb().

Typedef Documentation

◆ jb_create_impl

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

Create.

Definition at line 97 of file abstract_jb.h.

◆ jb_destroy_impl

typedef void(* jb_destroy_impl) (void *jb)

Destroy.

Definition at line 99 of file abstract_jb.h.

◆ jb_empty_and_reset_impl

typedef void(* jb_empty_and_reset_impl) (void *jb)

Empty and reset jb.

Definition at line 113 of file abstract_jb.h.

◆ jb_force_resynch_impl

typedef void(* jb_force_resynch_impl) (void *jb)

Force resynch.

Definition at line 111 of file abstract_jb.h.

◆ jb_get_impl

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

Get frame for now.

Definition at line 105 of file abstract_jb.h.

◆ jb_is_late_impl

typedef int(* jb_is_late_impl) (void *jb, long ts)

Check if late.

Definition at line 115 of file abstract_jb.h.

◆ jb_next_impl

typedef long(* jb_next_impl) (void *jb)

Get next.

Definition at line 107 of file abstract_jb.h.

◆ jb_put_first_impl

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

Put first frame.

Definition at line 101 of file abstract_jb.h.

◆ jb_put_impl

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

Put frame.

Definition at line 103 of file abstract_jb.h.

◆ jb_remove_impl

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

Remove first frame.

Definition at line 109 of file abstract_jb.h.

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Enumerator
AST_JB_ENABLED 
AST_JB_FORCED 
AST_JB_LOG 
AST_JB_SYNC_VIDEO 

Definition at line 44 of file abstract_jb.h.

44  {
45  AST_JB_ENABLED = (1 << 0),
46  AST_JB_FORCED = (1 << 1),
47  AST_JB_LOG = (1 << 2),
48  AST_JB_SYNC_VIDEO = (1 << 3)
49 };

◆ anonymous enum

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

◆ ast_jb_type

Enumerator
AST_JB_FIXED 
AST_JB_ADAPTIVE 

Definition at line 51 of file abstract_jb.h.

Function Documentation

◆ ast_jb_conf_default()

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_clear_flag, ast_copy_string(), AST_FLAGS_ALL, 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().

891 {
893  conf->max_size = DEFAULT_SIZE;
895  ast_copy_string(conf->impl, "fixed", sizeof(conf->impl));
897 }
long resync_threshold
Resynchronization threshold of the jitterbuffer implementation.
Definition: abstract_jb.h:76
#define DEFAULT_SIZE
Definition: abstract_jb.c:837
#define DEFAULT_TARGET_EXTRA
Definition: abstract_jb.c:838
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
#define DEFAULT_RESYNC
Definition: abstract_jb.c:839
#define AST_FLAGS_ALL
Definition: utils.h:196
#define ast_clear_flag(p, flag)
Definition: utils.h:77
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
long max_size
Max size of the jitterbuffer implementation.
Definition: abstract_jb.h:74

◆ ast_jb_configure()

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.

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().

594 {
595  memcpy(&ast_channel_jb(chan)->conf, conf, sizeof(*conf));
596 }
struct ast_jb * ast_channel_jb(struct ast_channel *chan)

◆ ast_jb_create_framehook()

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 1257 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_datastore::data, ast_framehook_interface::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().

1258 {
1259  struct jb_framedata *framedata;
1260  struct ast_datastore *datastore = NULL;
1261  struct ast_framehook_interface interface = {
1263  .event_cb = hook_event_cb,
1264  .destroy_cb = hook_destroy_cb,
1265  };
1266  int i = 0;
1267 
1268  /* If disabled, strip any existing jitterbuffer and don't replace it. */
1269  if (!strcasecmp(jb_conf->impl, "disabled")) {
1270  int *id;
1271  ast_channel_lock(chan);
1272  if ((datastore = ast_channel_datastore_find(chan, &jb_datastore, NULL))) {
1273  id = datastore->data;
1274  ast_framehook_detach(chan, *id);
1275  ast_channel_datastore_remove(chan, datastore);
1276  ast_datastore_free(datastore);
1277  }
1278  ast_channel_unlock(chan);
1279  return;
1280  }
1281 
1282  if (!(framedata = ast_calloc(1, sizeof(*framedata)))) {
1283  return;
1284  }
1285 
1286  if (jb_framedata_init(framedata, jb_conf)) {
1287  jb_framedata_destroy(framedata);
1288  return;
1289  }
1290 
1291  interface.data = framedata;
1292 
1293  ast_channel_lock(chan);
1294  i = ast_framehook_attach(chan, &interface);
1295  if (i >= 0) {
1296  int *id;
1297  if ((datastore = ast_channel_datastore_find(chan, &jb_datastore, NULL))) {
1298  /* There is already a jitterbuffer on the channel. */
1299  if (prefer_existing) {
1300  /* We prefer the existing jitterbuffer, so remove the new one and keep the old one. */
1301  ast_framehook_detach(chan, i);
1302  ast_channel_unlock(chan);
1303  return;
1304  }
1305  /* We prefer the new jitterbuffer, so strip the old one. */
1306  id = datastore->data;
1307  ast_framehook_detach(chan, *id);
1308  ast_channel_datastore_remove(chan, datastore);
1309  ast_datastore_free(datastore);
1310  }
1311 
1312  if (!(datastore = ast_datastore_alloc(&jb_datastore, NULL))) {
1313  ast_framehook_detach(chan, i);
1314  ast_channel_unlock(chan);
1315  return;
1316  }
1317 
1318  if (!(id = ast_calloc(1, sizeof(int)))) {
1319  ast_datastore_free(datastore);
1320  ast_framehook_detach(chan, i);
1321  ast_channel_unlock(chan);
1322  return;
1323  }
1324 
1325  *id = i; /* Store off the id. The channel is still locked so it is safe to access this ptr. */
1326  datastore->data = id;
1327  ast_channel_datastore_add(chan, datastore);
1328 
1329  ast_channel_set_fd(chan, AST_JITTERBUFFER_FD, framedata->timer_fd);
1330  } else {
1331  jb_framedata_destroy(framedata);
1332  framedata = NULL;
1333  }
1334  ast_channel_unlock(chan);
1335 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
static void jb_framedata_destroy(struct jb_framedata *framedata)
Definition: abstract_jb.c:867
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:68
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:2404
#define NULL
Definition: resample.c:96
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
static const struct ast_datastore_info jb_datastore
Definition: abstract_jb.c:904
char impl[AST_JB_IMPL_NAME_SIZE]
Name of the jitterbuffer implementation to be used.
Definition: abstract_jb.h:78
static struct ast_frame * hook_event_cb(struct ast_channel *chan, struct ast_frame *frame, enum ast_framehook_event event, void *data)
Definition: abstract_jb.c:953
static void hook_destroy_cb(void *framedata)
Definition: abstract_jb.c:909
#define AST_FRAMEHOOK_INTERFACE_VERSION
Definition: framehook.h:227
#define ast_channel_unlock(chan)
Definition: channel.h:2946
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
void ast_channel_set_fd(struct ast_channel *chan, int which, int fd)
Definition: channel.c:2431
void * data
Definition: datastore.h:70
#define AST_JITTERBUFFER_FD
Definition: channel.h:205
static int jb_framedata_init(struct jb_framedata *framedata, struct ast_jb_conf *jb_conf)
Definition: abstract_jb.c:1217
#define ast_datastore_alloc(info, uid)
Definition: datastore.h:89
enum queue_result id
Definition: app_queue.c:1507
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
Definition: channel.c:2390
int ast_channel_datastore_remove(struct ast_channel *chan, struct ast_datastore *datastore)
Remove a datastore from a channel.
Definition: channel.c:2399

◆ ast_jb_destroy()

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 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, 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().

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 
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 
526 
527  ast_verb(3, "%s jitterbuffer destroyed on channel %s\n", jbimpl->name, ast_channel_name(chan));
528  }
529 }
#define ast_test_flag(p, flag)
Definition: utils.h:63
const struct ast_jb_impl * impl
Jitterbuffer implementation to be used.
Definition: abstract_jb.h:145
jb_destroy_impl destroy
Definition: abstract_jb.h:126
jb_remove_impl remove
Definition: abstract_jb.h:131
#define NULL
Definition: resample.c:96
#define ast_verb(level,...)
Definition: logger.h:463
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
struct ast_jb * ast_channel_jb(struct ast_channel *chan)
#define ast_clear_flag(p, flag)
Definition: utils.h:77
char name[AST_JB_IMPL_NAME_SIZE]
Definition: abstract_jb.h:123
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
const char * ast_channel_name(const struct ast_channel *chan)
#define ast_frfree(fr)
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

◆ ast_jb_do_usecheck()

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_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.

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  }
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  }
219  }
220 
221  if (!c1_jb_created) {
222  jb_choose_impl(c1);
223  }
224 
225  inuse = 1;
226  }
227 
228  return inuse;
229 }
Channels have this property if they can accept input with jitter; i.e. most VoIP channels.
Definition: channel.h:961
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define ast_set_flag(p, flag)
Definition: utils.h:70
struct ast_jb_conf conf
Jitterbuffer configuration.
Definition: abstract_jb.h:143
#define NULL
Definition: resample.c:96
static void jb_choose_impl(struct ast_channel *chan)
Definition: abstract_jb.c:148
General jitterbuffer state.
Definition: abstract_jb.h:140
struct ast_jb * ast_channel_jb(struct ast_channel *chan)
struct timeval timebase
The time the jitterbuffer was created.
Definition: abstract_jb.h:149
const struct ast_channel_tech * ast_channel_tech(const struct ast_channel *chan)
General jitterbuffer configuration.
Definition: abstract_jb.h:69
Channels have this property if they can create jitter; i.e. most VoIP channels.
Definition: channel.h:966

◆ ast_jb_empty_and_reset()

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_channel_jb(), ast_test_flag, ast_jb_impl::empty_and_reset, ast_jb::impl, JB_CREATED, JB_USE, 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 }
#define ast_test_flag(p, flag)
Definition: utils.h:63
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
struct ast_jb * ast_channel_jb(struct ast_channel *chan)
jb_empty_and_reset_impl empty_and_reset
Definition: abstract_jb.h:133

◆ ast_jb_enable_for_channel()

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_channel_jb(), ast_jb_create_framehook(), AST_JB_ENABLED, ast_test_flag, and ast_jb::conf.

Referenced by bridge_channel_internal_join().

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 }
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct ast_jb_conf conf
Jitterbuffer configuration.
Definition: abstract_jb.h:143
All configuration options for statsd client.
Definition: res_statsd.c:95
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:1257
struct ast_jb * ast_channel_jb(struct ast_channel *chan)
General jitterbuffer configuration.
Definition: abstract_jb.h:69

◆ ast_jb_get_and_deliver()

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 usig ast_write() each of the channels.

Definition at line 336 of file abstract_jb.c.

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

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 }
#define ast_test_flag(p, flag)
Definition: utils.h:63
General jitterbuffer state.
Definition: abstract_jb.h:140
struct ast_jb * ast_channel_jb(struct ast_channel *chan)
static void jb_get_and_deliver(struct ast_channel *chan)
Definition: abstract_jb.c:353

◆ ast_jb_get_config()

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.

References ast_channel_jb().

600 {
601  memcpy(conf, &ast_channel_jb((struct ast_channel *) chan)->conf, sizeof(*conf));
602 }
Main Channel structure associated with a channel.
struct ast_jb * ast_channel_jb(struct ast_channel *chan)

◆ ast_jb_get_impl()

const struct ast_jb_impl* ast_jb_get_impl ( enum ast_jb_type  type)

Definition at line 820 of file abstract_jb.c.

References ARRAY_LEN, and NULL.

Referenced by jb_framedata_init().

821 {
822  int i;
823  for (i = 0; i < ARRAY_LEN(avail_impl); i++) {
824  if (avail_impl[i].type == type) {
825  return &avail_impl[i];
826  }
827  }
828  return NULL;
829 }
static const char type[]
Definition: chan_ooh323.c:109
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
#define NULL
Definition: resample.c:96
static const struct ast_jb_impl avail_impl[]
Definition: abstract_jb.c:87

◆ ast_jb_get_when_to_wakeup()

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_channel_jb(), ast_test_flag, get_now(), JB_CREATED, JB_USE, ast_jb::next, and NULL.

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 }
#define ast_test_flag(p, flag)
Definition: utils.h:63
static long get_now(struct ast_jb *jb, struct timeval *tv)
Definition: abstract_jb.c:532
#define NULL
Definition: resample.c:96
General jitterbuffer state.
Definition: abstract_jb.h:140
struct ast_jb * ast_channel_jb(struct ast_channel *chan)
long next
The time the next frame should be played.
Definition: abstract_jb.h:151

◆ ast_jb_put()

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_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.

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",
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 
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.
jb_next_impl next
Definition: abstract_jb.h:130
#define ast_test_flag(p, flag)
Definition: utils.h:63
const struct ast_jb_impl * impl
Jitterbuffer implementation to be used.
Definition: abstract_jb.h:145
#define ast_set_flag(p, flag)
Definition: utils.h:70
#define LOG_WARNING
Definition: logger.h:274
static int create_jb(struct ast_channel *chan, struct ast_frame *first_frame)
Definition: abstract_jb.c:413
static long get_now(struct ast_jb *jb, struct timeval *tv)
Definition: abstract_jb.c:532
#define NULL
Definition: resample.c:96
#define AST_FRAME_DTMF
#define jb_framelog(...)
Macros for the frame log files.
Definition: abstract_jb.c:130
#define ast_log
Definition: astobj2.c:42
jb_put_impl put
Definition: abstract_jb.h:128
const char * src
jb_force_resynch_impl force_resync
Definition: abstract_jb.h:132
void * jbobj
Jitterbuffer object, passed to the implementation.
Definition: abstract_jb.h:147
#define LOG_ERROR
Definition: logger.h:285
General jitterbuffer state.
Definition: abstract_jb.h:140
struct ast_jb * ast_channel_jb(struct ast_channel *chan)
#define ast_clear_flag(p, flag)
Definition: utils.h:77
const char * ast_channel_name(const struct ast_channel *chan)
#define ast_frfree(fr)
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

◆ ast_jb_read_conf()

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_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_SYNC_VIDEO, AST_JB_CONF_TARGET_EXTRA, AST_JB_ENABLED, AST_JB_FORCED, AST_JB_LOG, AST_JB_SYNC_VIDEO, 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().

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)) {
559  } else if (!strcasecmp(name, AST_JB_CONF_FORCE)) {
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)) {
576  } else if (!strcasecmp(name, AST_JB_CONF_SYNC_VIDEO)) {
578  } else {
579  return -1;
580  }
581 
582  return 0;
583 }
#define AST_JB_CONF_IMPL
Definition: abstract_jb.h:91
#define ast_set2_flag(p, value, flag)
Definition: utils.h:94
#define AST_JB_CONF_ENABLE
Definition: abstract_jb.h:86
static int tmp()
Definition: bt_open.c:389
#define AST_JB_CONF_LOG
Definition: abstract_jb.h:92
int value
Definition: syslog.c:37
#define ast_strlen_zero(foo)
Definition: strings.h:52
long resync_threshold
Resynchronization threshold of the jitterbuffer implementation.
Definition: abstract_jb.h:76
#define AST_JB_CONF_PREFIX
Definition: abstract_jb.h:85
long target_extra
amount of additional jitterbuffer adjustment
Definition: abstract_jb.h:80
#define AST_JB_CONF_TARGET_EXTRA
Definition: abstract_jb.h:90
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: main/utils.c:1951
#define AST_JB_CONF_FORCE
Definition: abstract_jb.h:87
static const char name[]
Definition: cdr_mysql.c:74
#define AST_JB_CONF_MAX_SIZE
Definition: abstract_jb.h:88
#define AST_JB_CONF_SYNC_VIDEO
Definition: abstract_jb.h:93
#define AST_JB_CONF_RESYNCH_THRESHOLD
Definition: abstract_jb.h:89
long max_size
Max size of the jitterbuffer implementation.
Definition: abstract_jb.h:74