Asterisk - The Open Source Telephony Project  GIT-master-a24979a
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.

◆ AST_JB_CONF_FORCE

#define AST_JB_CONF_FORCE   "force"

Definition at line 87 of file abstract_jb.h.

◆ AST_JB_CONF_IMPL

#define AST_JB_CONF_IMPL   "impl"

Definition at line 91 of file abstract_jb.h.

◆ AST_JB_CONF_LOG

#define AST_JB_CONF_LOG   "log"

Definition at line 92 of file abstract_jb.h.

◆ AST_JB_CONF_MAX_SIZE

#define AST_JB_CONF_MAX_SIZE   "maxsize"

Definition at line 88 of file abstract_jb.h.

◆ AST_JB_CONF_PREFIX

#define AST_JB_CONF_PREFIX   "jb"

Definition at line 85 of file abstract_jb.h.

◆ AST_JB_CONF_RESYNCH_THRESHOLD

#define AST_JB_CONF_RESYNCH_THRESHOLD   "resyncthreshold"

Definition at line 89 of file abstract_jb.h.

◆ AST_JB_CONF_SYNC_VIDEO

#define AST_JB_CONF_SYNC_VIDEO   "syncvideo"

Definition at line 93 of file abstract_jb.h.

◆ AST_JB_CONF_TARGET_EXTRA

#define AST_JB_CONF_TARGET_EXTRA   "targetextra"

Definition at line 90 of file abstract_jb.h.

◆ AST_JB_IMPL_NAME_SIZE

#define AST_JB_IMPL_NAME_SIZE   12

Definition at line 64 of file abstract_jb.h.

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 };
@ AST_JB_SYNC_VIDEO
Definition: abstract_jb.h:48
@ AST_JB_FORCED
Definition: abstract_jb.h:46
@ AST_JB_LOG
Definition: abstract_jb.h:47
@ AST_JB_ENABLED
Definition: abstract_jb.h:45

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

57  {
62 };
@ AST_JB_IMPL_INTERP
Definition: abstract_jb.h:60
@ AST_JB_IMPL_OK
Definition: abstract_jb.h:58
@ AST_JB_IMPL_NOFRAME
Definition: abstract_jb.h:61
@ AST_JB_IMPL_DROP
Definition: abstract_jb.h:59

◆ ast_jb_type

Enumerator
AST_JB_FIXED 
AST_JB_ADAPTIVE 

Definition at line 51 of file abstract_jb.h.

51  {
54 };
@ AST_JB_ADAPTIVE
Definition: abstract_jb.h:53
@ AST_JB_FIXED
Definition: abstract_jb.h:52

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.

891 {
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 }
#define DEFAULT_TARGET_EXTRA
Definition: abstract_jb.c:838
#define DEFAULT_RESYNC
Definition: abstract_jb.c:839
#define DEFAULT_SIZE
Definition: abstract_jb.c:837
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:406
All configuration options for statsd client.
Definition: res_statsd.c:101
#define ast_clear_flag(p, flag)
Definition: utils.h:77
#define AST_FLAGS_ALL
Definition: utils.h:196

References ast_clear_flag, ast_copy_string(), AST_FLAGS_ALL, DEFAULT_RESYNC, DEFAULT_SIZE, and DEFAULT_TARGET_EXTRA.

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

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

References ast_channel_jb().

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

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

1268 {
1269  struct jb_framedata *framedata;
1270  struct ast_datastore *datastore = NULL;
1271  struct ast_framehook_interface interface = {
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 }
static void jb_framedata_destroy(struct jb_framedata *framedata)
Definition: abstract_jb.c:867
static const struct ast_datastore_info jb_datastore
Definition: abstract_jb.c:904
static void hook_destroy_cb(void *framedata)
Definition: abstract_jb.c:909
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 int jb_framedata_init(struct jb_framedata *framedata, struct ast_jb_conf *jb_conf)
Definition: abstract_jb.c:1227
enum queue_result id
Definition: app_queue.c:1640
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
Definition: channel.c:2384
int ast_channel_datastore_remove(struct ast_channel *chan, struct ast_datastore *datastore)
Remove a datastore from a channel.
Definition: channel.c:2393
#define ast_channel_lock(chan)
Definition: channel.h:2922
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:2398
void ast_channel_set_fd(struct ast_channel *chan, int which, int fd)
Definition: channel.c:2425
#define AST_JITTERBUFFER_FD
Definition: channel.h:204
#define ast_channel_unlock(chan)
Definition: channel.h:2923
#define ast_datastore_alloc(info, uid)
Definition: datastore.h:85
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
int ast_framehook_detach(struct ast_channel *chan, int framehook_id)
Detach an framehook from a channel.
Definition: framehook.c:177
#define AST_FRAMEHOOK_INTERFACE_VERSION
Definition: framehook.h:227
#define NULL
Definition: resample.c:96
Structure for a data store object.
Definition: datastore.h:64
void * data
Definition: datastore.h:66

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, jb_datastore, jb_framedata_destroy(), jb_framedata_init(), NULL, jb_framedata::timer_fd, and ast_framehook_interface::version.

Referenced by ast_jb_enable_for_channel().

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

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 }
@ JB_CREATED
Definition: abstract_jb.c:55
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
const char * ast_channel_name(const struct ast_channel *chan)
#define ast_frfree(fr)
#define ast_verb(level,...)
Data structure associated with a single frame of data.
Jitterbuffer implementation struct.
Definition: abstract_jb.h:122
jb_destroy_impl destroy
Definition: abstract_jb.h:126
char name[AST_JB_IMPL_NAME_SIZE]
Definition: abstract_jb.h:123
jb_remove_impl remove
Definition: abstract_jb.h:131
General jitterbuffer state.
Definition: abstract_jb.h:141
void * jbobj
Jitterbuffer object, passed to the implementation.
Definition: abstract_jb.h:147
struct ast_format * last_format
Voice format of the last frame in.
Definition: abstract_jb.h:153
FILE * logfile
File for frame timestamp tracing.
Definition: abstract_jb.h:155
const struct ast_jb_impl * impl
Jitterbuffer implementation to be used.
Definition: abstract_jb.h:145
#define ast_test_flag(p, flag)
Definition: utils.h:63

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

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

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 }
@ JB_USE
Definition: abstract_jb.c:53
@ JB_TIMEBASE_INITIALIZED
Definition: abstract_jb.c:54
static void jb_choose_impl(struct ast_channel *chan)
Definition: abstract_jb.c:148
@ AST_CHAN_TP_WANTSJITTER
Channels have this property if they can accept input with jitter; i.e. most VoIP channels.
Definition: channel.h:960
@ AST_CHAN_TP_CREATESJITTER
Channels have this property if they can create jitter; i.e. most VoIP channels.
Definition: channel.h:965
const struct ast_channel_tech * ast_channel_tech(const struct ast_channel *chan)
General jitterbuffer configuration.
Definition: abstract_jb.h:70
struct ast_jb_conf conf
Jitterbuffer configuration.
Definition: abstract_jb.h:143
struct timeval timebase
The time the jitterbuffer was created.
Definition: abstract_jb.h:149
#define ast_set_flag(p, flag)
Definition: utils.h:70

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.

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

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 }
jb_empty_and_reset_impl empty_and_reset
Definition: abstract_jb.h:133

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

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

586 {
587  struct ast_jb_conf conf = ast_channel_jb(chan)->conf;
589  ast_jb_create_framehook(chan, &conf, 1);
590  }
591 }
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

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

Referenced by bridge_channel_internal_join().

◆ 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 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 }
static void jb_get_and_deliver(struct ast_channel *chan)
Definition: abstract_jb.c:353

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

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

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

References ast_channel_jb().

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

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 struct ast_jb_impl avail_impl[]
Definition: abstract_jb.c:87
static const char type[]
Definition: chan_ooh323.c:109
#define ARRAY_LEN(a)
Definition: utils.h:661

References ARRAY_LEN, avail_impl, NULL, and type.

Referenced by jb_framedata_init().

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

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 }
static long get_now(struct ast_jb *jb, struct timeval *tv)
Definition: abstract_jb.c:532
long next
The time the next frame should be played.
Definition: abstract_jb.h:151

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

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

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 }
static int create_jb(struct ast_channel *chan, struct ast_frame *first_frame)
Definition: abstract_jb.c:413
#define jb_framelog(...)
Macros for the frame log files.
Definition: abstract_jb.c:130
#define ast_log
Definition: astobj2.c:42
@ AST_FRFLAG_HAS_TIMING_INFO
#define AST_FRAME_DTMF
#define ast_frdup(fr)
Copies a frame.
@ AST_FRAME_VOICE
#define LOG_ERROR
#define LOG_WARNING
enum ast_frame_type frametype
const char * src
jb_next_impl next
Definition: abstract_jb.h:130
jb_put_impl put
Definition: abstract_jb.h:128
jb_force_resynch_impl force_resync
Definition: abstract_jb.h:132

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.

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

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_ENABLE
Definition: abstract_jb.h:86
#define AST_JB_CONF_RESYNCH_THRESHOLD
Definition: abstract_jb.h:89
#define AST_JB_CONF_IMPL
Definition: abstract_jb.h:91
#define AST_JB_CONF_LOG
Definition: abstract_jb.h:92
#define AST_JB_CONF_SYNC_VIDEO
Definition: abstract_jb.h:93
#define AST_JB_CONF_FORCE
Definition: abstract_jb.h:87
#define AST_JB_CONF_MAX_SIZE
Definition: abstract_jb.h:88
#define AST_JB_CONF_TARGET_EXTRA
Definition: abstract_jb.h:90
#define AST_JB_CONF_PREFIX
Definition: abstract_jb.h:85
static int tmp()
Definition: bt_open.c:389
static const char name[]
Definition: format_mp3.c:68
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true"....
Definition: main/utils.c:2097
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
int value
Definition: syslog.c:37
#define ast_set2_flag(p, value, flag)
Definition: utils.h:94

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(), name, tmp(), and value.

Referenced by config_parse_variables(), process_dahdi(), reload_config(), and store_config_core().