Asterisk - The Open Source Telephony Project  18.5.0
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"
Include dependency graph for abstract_jb.c:

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. More...
 
#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

◆ DEFAULT_RESYNC

#define DEFAULT_RESYNC   1000

Definition at line 839 of file abstract_jb.c.

Referenced by ast_jb_conf_default().

◆ DEFAULT_SIZE

#define DEFAULT_SIZE   200

Definition at line 837 of file abstract_jb.c.

Referenced by ast_jb_conf_default().

◆ DEFAULT_TARGET_EXTRA

#define DEFAULT_TARGET_EXTRA   40

Definition at line 838 of file abstract_jb.c.

Referenced by ast_jb_conf_default().

◆ DEFAULT_TIMER_INTERVAL

#define DEFAULT_TIMER_INTERVAL   20

Definition at line 836 of file abstract_jb.c.

Referenced by jb_framedata_init().

◆ DEFAULT_TYPE

#define DEFAULT_TYPE   AST_JB_FIXED

Definition at line 840 of file abstract_jb.c.

Referenced by jb_framedata_init().

◆ jb_framelog

#define jb_framelog (   ...)

Macros for the frame log files.

Definition at line 130 of file abstract_jb.c.

Referenced by ast_jb_put(), create_jb(), and jb_get_and_deliver().

◆ MAXIMUM_EARLY_FRAME_COUNT

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

Referenced by hook_event_cb().

Enumeration Type Documentation

◆ anonymous enum

anonymous enum

Internal jb flags

Enumerator
JB_USE 
JB_TIMEBASE_INITIALIZED 
JB_CREATED 

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

◆ 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

◆ create_jb()

static int create_jb ( struct ast_channel chan,
struct ast_frame first_frame 
)
static

Definition at line 413 of file abstract_jb.c.

References ao2_bump, ast_assert, ast_channel_bridge_peer(), ast_channel_cleanup, ast_channel_jb(), AST_CHANNEL_NAME, ast_channel_name(), ast_frfree, AST_JB_IMPL_NAME_SIZE, AST_JB_LOG, ast_log, ast_test_flag, ast_verb, ast_jb::conf, ast_jb_impl::create, errno, ast_frame_subclass::format, get_now(), ast_jb::impl, jb_framelog, ast_jb::jbobj, ast_jb::last_format, ast_frame::len, LOG_ERROR, LOG_WARNING, ast_jb::logfile, ast_jb_impl::name, ast_jb_impl::next, ast_jb::next, NULL, ast_jb_impl::put_first, ast_frame::subclass, tmp(), and ast_frame::ts.

Referenced by ast_jb_put().

414 {
415  struct ast_jb *jb = ast_channel_jb(chan);
416  struct ast_jb_conf *jbconf = &jb->conf;
417  const struct ast_jb_impl *jbimpl = jb->impl;
418  void *jbobj;
419  long now;
420  char logfile_pathname[20 + AST_JB_IMPL_NAME_SIZE + 2*AST_CHANNEL_NAME + 1];
421  char name1[AST_CHANNEL_NAME], name2[AST_CHANNEL_NAME], *tmp;
422  int res;
423 
424  jbobj = jb->jbobj = jbimpl->create(jbconf);
425  if (!jbobj) {
426  ast_log(LOG_WARNING, "Failed to create jitterbuffer on channel '%s'\n", ast_channel_name(chan));
427  return -1;
428  }
429 
430  now = get_now(jb, NULL);
431  res = jbimpl->put_first(jbobj, frr, now);
432 
433  /* The result of putting the first frame should not differ from OK. However, its possible
434  some implementations (i.e. adaptive's when resynch_threshold is specified) to drop it. */
435  if (res != AST_JB_IMPL_OK) {
436  ast_log(LOG_WARNING, "Failed to put first frame in the jitterbuffer on channel '%s'\n", ast_channel_name(chan));
437  /*
438  jbimpl->destroy(jbobj);
439  return -1;
440  */
441  }
442 
443  /* Init next */
444  jb->next = jbimpl->next(jbobj);
445 
446  /* Init last format for a first time. */
447  jb->last_format = ao2_bump(frr->subclass.format);
448 
449  /* Create a frame log file */
450  if (ast_test_flag(jbconf, AST_JB_LOG)) {
451  struct ast_channel *bridged = ast_channel_bridge_peer(chan);
452  char safe_logfile[30] = "/tmp/logfile-XXXXXX";
453  int safe_fd;
454 
455  snprintf(name2, sizeof(name2), "%s", ast_channel_name(chan));
456  while ((tmp = strchr(name2, '/'))) {
457  *tmp = '#';
458  }
459 
460  /* We should always have bridged chan if a jitterbuffer is in use */
461  ast_assert(bridged != NULL);
462 
463  snprintf(name1, sizeof(name1), "%s", ast_channel_name(bridged));
464  while ((tmp = strchr(name1, '/'))) {
465  *tmp = '#';
466  }
467 
468  snprintf(logfile_pathname, sizeof(logfile_pathname),
469  "/tmp/ast_%s_jb_%s--%s.log", jbimpl->name, name1, name2);
470  unlink(logfile_pathname);
471  safe_fd = mkstemp(safe_logfile);
472  if (safe_fd < 0 || link(safe_logfile, logfile_pathname) || unlink(safe_logfile) || !(jb->logfile = fdopen(safe_fd, "w+b"))) {
473  ast_log(LOG_ERROR, "Failed to create frame log file with pathname '%s': %s\n", logfile_pathname, strerror(errno));
474  jb->logfile = NULL;
475  if (safe_fd > -1) {
476  close(safe_fd);
477  }
478  }
479 
480  if (res == AST_JB_IMPL_OK) {
481  jb_framelog("JB_PUT_FIRST {now=%ld}: Queued frame with ts=%ld and len=%ld\n",
482  now, frr->ts, frr->len);
483  } else {
484  jb_framelog("JB_PUT_FIRST {now=%ld}: Dropped frame with ts=%ld and len=%ld\n",
485  now, frr->ts, frr->len);
486  }
487 
488  ast_channel_cleanup(bridged);
489  }
490 
491  ast_verb(3, "%s jitterbuffer created on channel %s\n", jbimpl->name, ast_channel_name(chan));
492 
493  /* Free the frame if it has not been queued in the jb */
494  if (res != AST_JB_IMPL_OK) {
495  ast_frfree(frr);
496  }
497 
498  return 0;
499 }
Main Channel structure associated with a channel.
jb_next_impl next
Definition: abstract_jb.h:130
jb_create_impl create
Definition: abstract_jb.h:125
#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 LOG_WARNING
Definition: logger.h:274
static int tmp()
Definition: bt_open.c:389
#define ast_assert(a)
Definition: utils.h:695
static long get_now(struct ast_jb *jb, struct timeval *tv)
Definition: abstract_jb.c:532
struct ast_jb_conf conf
Jitterbuffer configuration.
Definition: abstract_jb.h:143
#define AST_JB_IMPL_NAME_SIZE
Definition: abstract_jb.h:64
#define NULL
Definition: resample.c:96
#define ast_verb(level,...)
Definition: logger.h:463
#define ao2_bump(obj)
Definition: astobj2.h:491
#define jb_framelog(...)
Macros for the frame log files.
Definition: abstract_jb.c:130
#define ast_log
Definition: astobj2.c:42
#define ast_channel_cleanup(c)
Cleanup a channel reference.
Definition: channel.h:2992
void * jbobj
Jitterbuffer object, passed to the implementation.
Definition: abstract_jb.h:147
#define LOG_ERROR
Definition: logger.h:285
int errno
jb_put_first_impl put_first
Definition: abstract_jb.h:127
General jitterbuffer state.
Definition: abstract_jb.h:140
#define AST_CHANNEL_NAME
Definition: channel.h:172
FILE * logfile
File for frame timestamp tracing.
Definition: abstract_jb.h:155
struct ast_jb * ast_channel_jb(struct ast_channel *chan)
char name[AST_JB_IMPL_NAME_SIZE]
Definition: abstract_jb.h:123
struct ast_channel * ast_channel_bridge_peer(struct ast_channel *chan)
Get the channel&#39;s bridge peer only if the bridge is two-party.
Definition: channel.c:10765
const char * ast_channel_name(const struct ast_channel *chan)
#define ast_frfree(fr)
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
General jitterbuffer configuration.
Definition: abstract_jb.h:69
long next
The time the next frame should be played.
Definition: abstract_jb.h:151

◆ datastore_destroy_cb()

static void datastore_destroy_cb ( void *  data)
static

Definition at line 899 of file abstract_jb.c.

References ast_debug, and ast_free.

899  {
900  ast_free(data);
901  ast_debug(1, "JITTERBUFFER datastore destroyed\n");
902 }
const char * data
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_free(a)
Definition: astmm.h:182

◆ get_now()

static long get_now ( struct ast_jb jb,
struct timeval *  tv 
)
static

Definition at line 532 of file abstract_jb.c.

References ast_tvdiff_ms(), NULL, and ast_jb::timebase.

Referenced by ast_jb_get_when_to_wakeup(), ast_jb_put(), create_jb(), and jb_get_and_deliver().

533 {
534  struct timeval now;
535 
536  if (!when) {
537  when = &now;
538  gettimeofday(when, NULL);
539  }
540 
541  return ast_tvdiff_ms(*when, jb->timebase);
542 }
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:98
#define NULL
Definition: resample.c:96
struct timeval timebase
The time the jitterbuffer was created.
Definition: abstract_jb.h:149

◆ hook_destroy_cb()

static void hook_destroy_cb ( void *  framedata)
static

Definition at line 909 of file abstract_jb.c.

References ast_debug, and jb_framedata_destroy().

Referenced by ast_jb_create_framehook().

910 {
911  ast_debug(1, "JITTERBUFFER hook destroyed\n");
912  jb_framedata_destroy((struct jb_framedata *) framedata);
913 }
static void jb_framedata_destroy(struct jb_framedata *framedata)
Definition: abstract_jb.c:867
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452

◆ hook_event_cb()

static struct ast_frame* hook_event_cb ( struct ast_channel chan,
struct ast_frame frame,
enum ast_framehook_event  event,
void *  data 
)
static

Definition at line 953 of file abstract_jb.c.

References ao2_replace, ast_channel_fdno(), AST_CONTROL_HOLD, AST_CONTROL_SRCCHANGE, AST_CONTROL_SRCUPDATE, AST_CONTROL_T38_PARAMETERS, AST_CONTROL_UNHOLD, ast_format_get_sample_rate(), AST_FRAME_CONTROL, AST_FRAME_NULL, AST_FRAME_RTCP, AST_FRAME_VIDEO, AST_FRAME_VOICE, AST_FRAMEHOOK_EVENT_ATTACHED, AST_FRAMEHOOK_EVENT_DETACHED, AST_FRAMEHOOK_EVENT_READ, AST_FRAMEHOOK_EVENT_WRITE, ast_frdup, AST_FRFLAG_HAS_TIMING_INFO, AST_FRFLAG_REQUEUED, ast_frfree, AST_FRIENDLY_OFFSET, ast_frisolate, AST_JB_IMPL_DROP, AST_JB_IMPL_INTERP, AST_JB_IMPL_NOFRAME, AST_JB_IMPL_OK, AST_JB_SYNC_VIDEO, AST_JITTERBUFFER_FD, AST_LIST_FIRST, AST_LIST_HEAD_INIT_NOLOCK, AST_LIST_HEAD_NOLOCK(), AST_LIST_INSERT_TAIL, AST_LIST_NEXT, AST_LIST_REMOVE_CURRENT, AST_LIST_REMOVE_HEAD, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_log, ast_null_frame, AST_RTP_RTCP_SR, ast_samp2tv(), ast_test_flag, ast_timer_ack(), ast_timer_set_rate(), ast_tvadd(), ast_tvdiff_ms(), ast_tvnow(), jb_framedata::audio_flowing, jb_framedata::audio_stream_id, jb_framedata::audio_stream_sync, ast_frame::data, ast_frame::delivery, jb_framedata::early_frame_count, jb_framedata::early_frames, jb_framedata::first, ast_jb_impl::force_resync, ast_frame_subclass::format, ast_frame::frametype, ast_jb_impl::get, ast_frame_subclass::integer, ast_jb_impl::is_late, jb_framedata::jb_conf, jb_framedata::jb_impl, jb_framedata::jb_obj, jitterbuffer_frame_get_ntp_timestamp(), jb_framedata::last_audio_ntp_timestamp, jb_framedata::last_format, ast_frame::len, LOG_ERROR, MAXIMUM_EARLY_FRAME_COUNT, ast_jb_impl::next, ast_frame::next, jb_stream_sync::ntp, ast_rtp_rtcp_report::ntp_timestamp, NULL, ast_frame::offset, ast_frame::ptr, ast_jb_impl::put, ast_jb_impl::put_first, ast_rtp_rtcp_report::rtp_timestamp, ast_frame::samples, ast_rtp_rtcp_report::sender_information, ast_frame::src, jb_framedata::start_tv, ast_frame::stream_num, ast_frame::subclass, jb_framedata::timer, jb_framedata::timer_interval, jb_stream_sync::timestamp, ast_frame::ts, jb_framedata::video_stream_id, and jb_framedata::video_stream_sync.

Referenced by ast_jb_create_framehook().

954 {
955  struct jb_framedata *framedata = data;
956  struct timeval now_tv;
957  unsigned long now;
958  int putframe = 0; /* signifies if audio frame was placed into the buffer or not */
959 
960  switch (event) {
962  break;
966  return frame;
967  }
968 
969  if (ast_channel_fdno(chan) == AST_JITTERBUFFER_FD && framedata->timer) {
970  if (ast_timer_ack(framedata->timer, 1) < 0) {
971  ast_log(LOG_ERROR, "Failed to acknowledge timer in jitter buffer\n");
972  return frame;
973  }
974  }
975 
976  /*
977  * If the frame has been requeued (for instance when the translate core returns
978  * more than one frame) then if the frame is late we want to immediately return
979  * it. Otherwise attempt to insert it into the jitterbuffer.
980  *
981  * If the frame is requeued and late then in all likely hood it's a frame that
982  * that was previously retrieved from the jitterbuffer, passed to the translate
983  * core, and then put back into the channel read queue. Even if it had not been
984  * in the jitterbuffer prior to now it needs to be the next frame "out".
985  *
986  * However late arriving frames that have not been requeued (i.e. regular frames)
987  * need to be passed to the jitterbuffer so they can be appropriately dropped. As
988  * well any requeued frames that are not late should be put into the jitterbuffer.
989  */
990  if (!frame || (ast_test_flag(frame, AST_FRFLAG_REQUEUED) &&
991  framedata->jb_impl->is_late(framedata->jb_obj, frame->ts))) {
992  return frame;
993  }
994 
995  if (ast_test_flag(&framedata->jb_conf, AST_JB_SYNC_VIDEO)) {
996  if (frame->frametype == AST_FRAME_VOICE) {
997  /* Store the stream identifier for the audio stream so we can associate the incoming RTCP SR
998  * with the correct stream sync structure.
999  */
1000  framedata->audio_stream_id = frame->stream_num;
1001  } else if (frame->frametype == AST_FRAME_RTCP && frame->subclass.integer == AST_RTP_RTCP_SR) {
1002  struct ast_rtp_rtcp_report *rtcp_report = frame->data.ptr;
1003  struct jb_stream_sync *stream_sync = NULL;
1004 
1005  /* Determine which stream this RTCP is in regards to */
1006  if (framedata->audio_stream_id == frame->stream_num) {
1007  stream_sync = &framedata->audio_stream_sync;
1008  } else if (framedata->video_stream_id == frame->stream_num) {
1009  stream_sync = &framedata->video_stream_sync;
1010  }
1011 
1012  if (stream_sync) {
1013  /* Store the RTP and NTP timestamp mapping so we can derive an NTP timestamp for each frame */
1014  stream_sync->timestamp = rtcp_report->sender_information.rtp_timestamp;
1015  stream_sync->ntp = rtcp_report->sender_information.ntp_timestamp;
1016  }
1017  } else if (frame->frametype == AST_FRAME_VIDEO) {
1018  /* If a video frame is late according to the audio timestamp don't stash it away, just return it.
1019  * If however it is ahead then we keep it until such time as the audio catches up.
1020  */
1021  struct ast_frame *jbframe;
1022 
1023  framedata->video_stream_id = frame->stream_num;
1024 
1025  /* If no timing information is available we can't store this away, so just let it through now */
1027  return frame;
1028  }
1029 
1030  /* To ensure that the video starts when the audio starts we only start allowing frames through once
1031  * audio starts flowing.
1032  */
1033  if (framedata->audio_flowing) {
1034  struct timeval video_timestamp;
1035 
1036  video_timestamp = jitterbuffer_frame_get_ntp_timestamp(&framedata->video_stream_sync, frame);
1037  if (ast_tvdiff_ms(framedata->last_audio_ntp_timestamp, video_timestamp) >= 0) {
1038  return frame;
1039  }
1040  }
1041 
1042  /* To prevent the early frame buffer from growing uncontrolled we impose a maximum count that it can
1043  * get to. If this is reached then we drop a video frame, which should cause the receiver to ask for a
1044  * new key frame.
1045  */
1046  if (framedata->early_frame_count == MAXIMUM_EARLY_FRAME_COUNT) {
1047  jbframe = AST_LIST_REMOVE_HEAD(&framedata->early_frames, frame_list);
1048  framedata->early_frame_count--;
1049  ast_frfree(jbframe);
1050  }
1051 
1052  jbframe = ast_frisolate(frame);
1053  if (!jbframe) {
1054  /* If we can't isolate the frame the safest thing we can do is return it, even if the A/V sync
1055  * may be off.
1056  */
1057  return frame;
1058  }
1059 
1060  AST_LIST_INSERT_TAIL(&framedata->early_frames, jbframe, frame_list);
1061  framedata->early_frame_count++;
1062  return &ast_null_frame;
1063  }
1064  }
1065 
1066  now_tv = ast_tvnow();
1067  now = ast_tvdiff_ms(now_tv, framedata->start_tv);
1068 
1069  if (frame->frametype == AST_FRAME_VOICE) {
1070  int res;
1071  struct ast_frame *jbframe;
1072 
1073  if (!ast_test_flag(frame, AST_FRFLAG_HAS_TIMING_INFO) || frame->len < 2 || frame->ts < 0) {
1074  /* only frames with timing info can enter the jitterbuffer */
1075  return frame;
1076  }
1077 
1078  jbframe = ast_frisolate(frame);
1079  ao2_replace(framedata->last_format, frame->subclass.format);
1080 
1081  if (frame->len && (frame->len != framedata->timer_interval)) {
1082  framedata->timer_interval = frame->len;
1083  ast_timer_set_rate(framedata->timer, 1000 / framedata->timer_interval);
1084  }
1085  if (!framedata->first) {
1086  framedata->first = 1;
1087  res = framedata->jb_impl->put_first(framedata->jb_obj, jbframe, now);
1088  } else {
1089  res = framedata->jb_impl->put(framedata->jb_obj, jbframe, now);
1090  }
1091 
1092  if (res == AST_JB_IMPL_OK) {
1093  if (jbframe != frame) {
1094  ast_frfree(frame);
1095  }
1096  frame = &ast_null_frame;
1097  } else if (jbframe != frame) {
1098  ast_frfree(jbframe);
1099  }
1100  putframe = 1;
1101  }
1102 
1103  if (frame->frametype == AST_FRAME_NULL) {
1104  int res;
1105  long next = framedata->jb_impl->next(framedata->jb_obj);
1106 
1107  /* If now is earlier than the next expected output frame
1108  * from the jitterbuffer we may choose to pass on retrieving
1109  * a frame during this read iteration. The only exception
1110  * to this rule is when an audio frame is placed into the buffer
1111  * and the time for the next frame to come out of the buffer is
1112  * at least within the timer_interval of the next output frame. By
1113  * doing this we are able to feed off the timing of the input frames
1114  * and only rely on our jitterbuffer timer when frames are dropped.
1115  * During testing, this hybrid form of timing gave more reliable results. */
1116  if (now < next) {
1117  long int diff = next - now;
1118  if (!putframe) {
1119  return frame;
1120  } else if (diff >= framedata->timer_interval) {
1121  return frame;
1122  }
1123  }
1124 
1125  ast_frfree(frame);
1126  frame = &ast_null_frame;
1127  res = framedata->jb_impl->get(framedata->jb_obj, &frame, now, framedata->timer_interval);
1128  switch (res) {
1129  case AST_JB_IMPL_OK:
1130  /* got it, and pass it through */
1131  break;
1132  case AST_JB_IMPL_DROP:
1133  ast_frfree(frame);
1134  frame = &ast_null_frame;
1135  break;
1136  case AST_JB_IMPL_INTERP:
1137  if (framedata->last_format) {
1138  struct ast_frame tmp = { 0, };
1139 
1140  tmp.frametype = AST_FRAME_VOICE;
1141  tmp.subclass.format = framedata->last_format;
1142  /* example: 8000hz / (1000 / 20ms) = 160 samples */
1143  tmp.samples = ast_format_get_sample_rate(framedata->last_format) / (1000 / framedata->timer_interval);
1144  tmp.delivery = ast_tvadd(framedata->start_tv, ast_samp2tv(next, 1000));
1146  tmp.src = "func_jitterbuffer interpolation";
1147  ast_frfree(frame);
1148  frame = ast_frdup(&tmp);
1149  break;
1150  }
1151  /* else fall through */
1152  case AST_JB_IMPL_NOFRAME:
1153  ast_frfree(frame);
1154  frame = &ast_null_frame;
1155  break;
1156  }
1157  }
1158 
1159  if (frame->frametype == AST_FRAME_CONTROL) {
1160  struct ast_frame *early_frame;
1161 
1162  switch(frame->subclass.integer) {
1163  case AST_CONTROL_HOLD:
1164  case AST_CONTROL_UNHOLD:
1166  case AST_CONTROL_SRCUPDATE:
1167  case AST_CONTROL_SRCCHANGE:
1168  framedata->jb_impl->force_resync(framedata->jb_obj);
1169  /* Since we are resyncing go ahead and clear out the video frames too */
1170  while ((early_frame = AST_LIST_REMOVE_HEAD(&framedata->early_frames, frame_list))) {
1171  ast_frfree(early_frame);
1172  }
1173  framedata->audio_flowing = 0;
1174  framedata->early_frame_count = 0;
1175  break;
1176  default:
1177  break;
1178  }
1179  }
1180 
1181  /* If a voice frame is being passed through see if we need to add any additional frames to it */
1182  if (ast_test_flag(&framedata->jb_conf, AST_JB_SYNC_VIDEO) && frame->frametype == AST_FRAME_VOICE) {
1183  AST_LIST_HEAD_NOLOCK(, ast_frame) additional_frames;
1184  struct ast_frame *early_frame;
1185 
1186  /* We store the last NTP timestamp for the audio given to the core so that subsequents frames which
1187  * are late can be passed immediately through (this will occur for video frames which are returned here)
1188  */
1190  framedata->audio_flowing = 1;
1191 
1192  AST_LIST_HEAD_INIT_NOLOCK(&additional_frames);
1193 
1194  AST_LIST_TRAVERSE_SAFE_BEGIN(&framedata->early_frames, early_frame, frame_list) {
1195  struct timeval early_timestamp = jitterbuffer_frame_get_ntp_timestamp(&framedata->video_stream_sync, early_frame);
1196  int diff = ast_tvdiff_ms(framedata->last_audio_ntp_timestamp, early_timestamp);
1197 
1198  /* If this frame is from the past we need to include it with the audio frame that is going
1199  * out.
1200  */
1201  if (diff >= 0) {
1203  framedata->early_frame_count--;
1204  AST_LIST_INSERT_TAIL(&additional_frames, early_frame, frame_list);
1205  }
1206  }
1208 
1209  /* Append any additional frames we may want to include (such as video) */
1210  AST_LIST_NEXT(frame, frame_list) = AST_LIST_FIRST(&additional_frames);
1211  }
1212 
1213  return frame;
1214 }
An object that represents data sent during a SR/RR RTCP report.
Definition: rtp_engine.h:331
#define ast_frdup(fr)
Copies a frame.
struct jb_stream_sync video_stream_sync
Definition: abstract_jb.c:859
#define AST_LIST_FIRST(head)
Returns the first entry contained in a list.
Definition: linkedlists.h:420
struct timeval ntp
Definition: abstract_jb.c:844
#define MAXIMUM_EARLY_FRAME_COUNT
Definition: abstract_jb.c:59
void * jb_obj
Definition: abstract_jb.c:864
jb_next_impl next
Definition: abstract_jb.h:130
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct ast_format * last_format
Definition: abstract_jb.c:851
struct jb_framedata::@332 early_frames
static int tmp()
Definition: bt_open.c:389
static struct timeval jitterbuffer_frame_get_ntp_timestamp(const struct jb_stream_sync *stream_sync, const struct ast_frame *frame)
Definition: abstract_jb.c:915
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
Definition: linkedlists.h:438
jb_get_impl get
Definition: abstract_jb.h:129
Definition: astman.c:222
struct jb_stream_sync audio_stream_sync
Definition: abstract_jb.c:857
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:98
#define NULL
Definition: resample.c:96
unsigned int rtp_timestamp
Definition: rtp_engine.h:337
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:614
struct ast_rtp_rtcp_report::@315 sender_information
struct ast_frame_subclass subclass
#define ast_log
Definition: astobj2.c:42
jb_put_impl put
Definition: abstract_jb.h:128
#define AST_FRIENDLY_OFFSET
Offset into a frame&#39;s data buffer.
const char * src
struct timeval last_audio_ntp_timestamp
Definition: abstract_jb.c:862
int video_stream_id
Definition: abstract_jb.c:858
jb_force_resynch_impl force_resync
Definition: abstract_jb.h:132
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:556
struct timeval ast_samp2tv(unsigned int _nsamp, unsigned int _rate)
Returns a timeval corresponding to the duration of n samples at rate r. Useful to convert samples to ...
Definition: time.h:238
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:832
AST_LIST_HEAD_NOLOCK(contactliststruct, contact)
struct ast_timer * timer
Definition: abstract_jb.c:852
unsigned int timestamp
Definition: abstract_jb.c:843
int audio_stream_id
Definition: abstract_jb.c:856
int ast_channel_fdno(const struct ast_channel *chan)
int ast_timer_ack(const struct ast_timer *handle, unsigned int quantity)
Acknowledge a timer event.
Definition: timing.c:171
#define LOG_ERROR
Definition: logger.h:285
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:730
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
Definition: extconf.c:2283
jb_put_first_impl put_first
Definition: abstract_jb.h:127
int timer_interval
Definition: abstract_jb.c:853
struct ast_jb_conf jb_conf
Definition: abstract_jb.c:849
#define ast_frisolate(fr)
Makes a frame independent of any static storage.
int ast_timer_set_rate(const struct ast_timer *handle, unsigned int rate)
Set the timing tick rate.
Definition: timing.c:166
struct timeval delivery
struct ast_frame ast_null_frame
Definition: main/frame.c:79
#define AST_LIST_HEAD_INIT_NOLOCK(head)
Initializes a list head structure.
Definition: linkedlists.h:680
#define ao2_replace(dst, src)
Definition: astobj2.h:517
struct ast_frame * next
#define AST_RTP_RTCP_SR
Definition: rtp_engine.h:293
unsigned int ast_format_get_sample_rate(const struct ast_format *format)
Get the sample rate of a media format.
Definition: format.c:379
#define ast_frfree(fr)
Data structure associated with a single frame of data.
#define AST_JITTERBUFFER_FD
Definition: channel.h:205
unsigned int early_frame_count
Definition: abstract_jb.c:861
union ast_frame::@263 data
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:528
enum ast_frame_type frametype
struct timeval start_tv
Definition: abstract_jb.c:850
struct ast_format * format
struct timeval ntp_timestamp
Definition: rtp_engine.h:336
const struct ast_jb_impl * jb_impl
Definition: abstract_jb.c:848
jb_is_late_impl is_late
Definition: abstract_jb.h:134

◆ jb_choose_impl()

static void jb_choose_impl ( struct ast_channel chan)
static

Definition at line 148 of file abstract_jb.c.

References ARRAY_LEN, ast_channel_jb(), ast_strlen_zero, ast_jb::conf, default_impl, ast_jb_conf::impl, ast_jb::impl, and ast_jb_impl::name.

Referenced by ast_jb_do_usecheck().

149 {
150  struct ast_jb *jb = ast_channel_jb(chan);
151  struct ast_jb_conf *jbconf = &jb->conf;
152  const struct ast_jb_impl *test_impl;
153  int i, avail_impl_count = ARRAY_LEN(avail_impl);
154 
155  jb->impl = &avail_impl[default_impl];
156 
157  if (ast_strlen_zero(jbconf->impl)) {
158  return;
159  }
160 
161  for (i = 0; i < avail_impl_count; i++) {
162  test_impl = &avail_impl[i];
163  if (!strcasecmp(jbconf->impl, test_impl->name)) {
164  jb->impl = test_impl;
165  return;
166  }
167  }
168 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
const struct ast_jb_impl * impl
Jitterbuffer implementation to be used.
Definition: abstract_jb.h:145
struct ast_jb_conf conf
Jitterbuffer configuration.
Definition: abstract_jb.h:143
#define ast_strlen_zero(foo)
Definition: strings.h:52
static const struct ast_jb_impl avail_impl[]
Definition: abstract_jb.c:87
char impl[AST_JB_IMPL_NAME_SIZE]
Name of the jitterbuffer implementation to be used.
Definition: abstract_jb.h:78
static int default_impl
Definition: abstract_jb.c:118
General jitterbuffer state.
Definition: abstract_jb.h:140
struct ast_jb * ast_channel_jb(struct ast_channel *chan)
char name[AST_JB_IMPL_NAME_SIZE]
Definition: abstract_jb.h:123
Jitterbuffer implementation struct.
Definition: abstract_jb.h:121
General jitterbuffer configuration.
Definition: abstract_jb.h:69

◆ jb_create_adaptive()

static void * jb_create_adaptive ( struct ast_jb_conf general_config)
static

Definition at line 727 of file abstract_jb.c.

References jb_new(), jb_setconf(), jb_conf::max_contig_interp, jb_conf::max_jitterbuf, ast_jb_conf::max_size, jb_conf::resync_threshold, ast_jb_conf::resync_threshold, jb_conf::target_extra, and ast_jb_conf::target_extra.

728 {
729  jb_conf jbconf;
730  jitterbuf *adaptivejb;
731 
732  adaptivejb = jb_new();
733  if (adaptivejb) {
734  jbconf.max_jitterbuf = general_config->max_size;
735  jbconf.resync_threshold = general_config->resync_threshold;
736  jbconf.max_contig_interp = 10;
737  jbconf.target_extra = general_config->target_extra;
738  jb_setconf(adaptivejb, &jbconf);
739  }
740 
741  return adaptivejb;
742 }
long max_jitterbuf
Definition: jitterbuf.h:67
jitterbuf * jb_new(void)
new jitterbuf
Definition: jitterbuf.c:86
long resync_threshold
Resynchronization threshold of the jitterbuffer implementation.
Definition: abstract_jb.h:76
long resync_threshold
Definition: jitterbuf.h:68
long target_extra
amount of additional jitterbuffer adjustment
Definition: abstract_jb.h:80
long target_extra
Definition: jitterbuf.h:70
enum jb_return_code jb_setconf(jitterbuf *jb, jb_conf *conf)
set jitterbuf conf
Definition: jitterbuf.c:825
long max_size
Max size of the jitterbuffer implementation.
Definition: abstract_jb.h:74
long max_contig_interp
Definition: jitterbuf.h:69

◆ jb_create_fixed()

static void * jb_create_fixed ( struct ast_jb_conf general_config)
static

Definition at line 625 of file abstract_jb.c.

References fixed_jb_new(), fixed_jb_conf::jbsize, ast_jb_conf::max_size, fixed_jb_conf::resync_threshold, and ast_jb_conf::resync_threshold.

626 {
627  struct fixed_jb_conf conf;
628 
629  conf.jbsize = general_config->max_size;
630  conf.resync_threshold = general_config->resync_threshold;
631 
632  return fixed_jb_new(&conf);
633 }
All configuration options for statsd client.
Definition: res_statsd.c:95
long resync_threshold
Resynchronization threshold of the jitterbuffer implementation.
Definition: abstract_jb.h:76
struct fixed_jb * fixed_jb_new(struct fixed_jb_conf *conf)
long max_size
Max size of the jitterbuffer implementation.
Definition: abstract_jb.h:74

◆ jb_destroy_adaptive()

static void jb_destroy_adaptive ( void *  jb)
static

Definition at line 745 of file abstract_jb.c.

References jb_destroy().

746 {
747  jitterbuf *adaptivejb = (jitterbuf *) jb;
748 
749  jb_destroy(adaptivejb);
750 }
void jb_destroy(jitterbuf *jb)
destroy jitterbuf
Definition: jitterbuf.c:99

◆ jb_destroy_fixed()

static void jb_destroy_fixed ( void *  jb)
static

Definition at line 635 of file abstract_jb.c.

References fixed_jb_destroy(), and jb_empty_and_reset_fixed().

636 {
637  struct fixed_jb *fixedjb = (struct fixed_jb *) jb;
638 
639  /* Ensure the fixed jb is empty - otherwise it will raise an ASSERT */
641 
642  /* destroy the jb */
643  fixed_jb_destroy(fixedjb);
644 }
private fixed_jb structure
static void jb_empty_and_reset_fixed(void *jb)
Definition: abstract_jb.c:710
void fixed_jb_destroy(struct fixed_jb *jb)

◆ jb_empty_and_reset_adaptive()

static void jb_empty_and_reset_adaptive ( void *  jb)
static

Definition at line 808 of file abstract_jb.c.

References ast_frfree, jb_frame::data, jb_getall(), JB_OK, and jb_reset().

809 {
810  jitterbuf *adaptivejb = jb;
811  jb_frame f;
812 
813  while (jb_getall(adaptivejb, &f) == JB_OK) {
814  ast_frfree(f.data);
815  }
816 
817  jb_reset(adaptivejb);
818 }
void * data
Definition: jitterbuf.h:100
#define ast_frfree(fr)
enum jb_return_code jb_getall(jitterbuf *jb, jb_frame *frameout)
unconditionally get frames from jitterbuf until empty
Definition: jitterbuf.c:801
void jb_reset(jitterbuf *jb)
reset jitterbuf
Definition: jitterbuf.c:72

◆ jb_empty_and_reset_fixed()

static void jb_empty_and_reset_fixed ( void *  jb)
static

Definition at line 710 of file abstract_jb.c.

References ast_frfree, fixed_jb_frame::data, FIXED_JB_OK, and fixed_jb_remove().

Referenced by jb_destroy_fixed().

711 {
712  struct fixed_jb *fixedjb = jb;
713  struct fixed_jb_frame f;
714 
715  while (fixed_jb_remove(fixedjb, &f) == FIXED_JB_OK) {
716  ast_frfree(f.data);
717  }
718 }
private fixed_jb structure
int fixed_jb_remove(struct fixed_jb *jb, struct fixed_jb_frame *frameout)
#define ast_frfree(fr)

◆ jb_force_resynch_adaptive()

static void jb_force_resynch_adaptive ( void *  jb)
static

Definition at line 804 of file abstract_jb.c.

805 {
806 }

◆ jb_force_resynch_fixed()

static void jb_force_resynch_fixed ( void *  jb)
static

Definition at line 703 of file abstract_jb.c.

References fixed_jb_set_force_resynch().

704 {
705  struct fixed_jb *fixedjb = (struct fixed_jb *) jb;
706 
708 }
private fixed_jb structure
void fixed_jb_set_force_resynch(struct fixed_jb *jb)

◆ jb_framedata_destroy()

static void jb_framedata_destroy ( struct jb_framedata framedata)
static

Definition at line 867 of file abstract_jb.c.

References ao2_cleanup, ast_free, ast_frfree, AST_JB_IMPL_OK, AST_LIST_REMOVE_HEAD, ast_timer_close(), ast_jb_impl::destroy, jb_framedata::early_frames, jb_framedata::jb_impl, jb_framedata::jb_obj, jb_framedata::last_format, NULL, ast_jb_impl::remove, and jb_framedata::timer.

Referenced by ast_jb_create_framehook(), and hook_destroy_cb().

868 {
869  struct ast_frame *frame;
870 
871  if (framedata->timer) {
872  ast_timer_close(framedata->timer);
873  framedata->timer = NULL;
874  }
875  if (framedata->jb_impl && framedata->jb_obj) {
876  struct ast_frame *f;
877  while (framedata->jb_impl->remove(framedata->jb_obj, &f) == AST_JB_IMPL_OK) {
878  ast_frfree(f);
879  }
880  framedata->jb_impl->destroy(framedata->jb_obj);
881  framedata->jb_obj = NULL;
882  }
883  ao2_cleanup(framedata->last_format);
884  while ((frame = AST_LIST_REMOVE_HEAD(&framedata->early_frames, frame_list))) {
885  ast_frfree(frame);
886  }
887  ast_free(framedata);
888 }
void * jb_obj
Definition: abstract_jb.c:864
struct ast_format * last_format
Definition: abstract_jb.c:851
struct jb_framedata::@332 early_frames
jb_destroy_impl destroy
Definition: abstract_jb.h:126
void ast_timer_close(struct ast_timer *handle)
Close an opened timing handle.
Definition: timing.c:154
jb_remove_impl remove
Definition: abstract_jb.h:131
#define NULL
Definition: resample.c:96
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:832
struct ast_timer * timer
Definition: abstract_jb.c:852
#define ast_free(a)
Definition: astmm.h:182
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
#define ast_frfree(fr)
Data structure associated with a single frame of data.
const struct ast_jb_impl * jb_impl
Definition: abstract_jb.c:848

◆ jb_framedata_init()

static int jb_framedata_init ( struct jb_framedata framedata,
struct ast_jb_conf jb_conf 
)
static

Definition at line 1217 of file abstract_jb.c.

References AST_JB_ADAPTIVE, AST_JB_FIXED, ast_jb_get_impl(), AST_LIST_HEAD_INIT_NOLOCK, ast_log, ast_strlen_zero, ast_timer_fd(), ast_timer_open(), ast_timer_set_rate(), ast_tvnow(), jb_framedata::audio_stream_id, ast_jb_impl::create, DEFAULT_TIMER_INTERVAL, DEFAULT_TYPE, jb_framedata::early_frames, ast_jb_conf::impl, jb_framedata::jb_conf, jb_framedata::jb_impl, jb_framedata::jb_obj, LOG_WARNING, jb_framedata::start_tv, jb_framedata::timer, jb_framedata::timer_fd, jb_framedata::timer_interval, and jb_framedata::video_stream_id.

Referenced by ast_jb_create_framehook().

1218 {
1219  int jb_impl_type = DEFAULT_TYPE;
1220  /* Initialize defaults */
1221  framedata->timer_fd = -1;
1222  memcpy(&framedata->jb_conf, jb_conf, sizeof(*jb_conf));
1223 
1224  /* Figure out implementation type from the configuration implementation string */
1225  if (!ast_strlen_zero(jb_conf->impl)) {
1226  if (!strcasecmp(jb_conf->impl, "fixed")) {
1227  jb_impl_type = AST_JB_FIXED;
1228  } else if (!strcasecmp(jb_conf->impl, "adaptive")) {
1229  jb_impl_type = AST_JB_ADAPTIVE;
1230  } else {
1231  ast_log(LOG_WARNING, "Unknown Jitterbuffer type %s. Failed to create jitterbuffer.\n", jb_conf->impl);
1232  return -1;
1233  }
1234  }
1235 
1236  if (!(framedata->jb_impl = ast_jb_get_impl(jb_impl_type))) {
1237  return -1;
1238  }
1239 
1240  if (!(framedata->timer = ast_timer_open())) {
1241  return -1;
1242  }
1243 
1244  framedata->audio_stream_id = -1;
1245  framedata->video_stream_id = -1;
1247  framedata->timer_fd = ast_timer_fd(framedata->timer);
1249  ast_timer_set_rate(framedata->timer, 1000 / framedata->timer_interval);
1250  framedata->start_tv = ast_tvnow();
1251 
1252  framedata->jb_obj = framedata->jb_impl->create(&framedata->jb_conf);
1253  return 0;
1254 }
void * jb_obj
Definition: abstract_jb.c:864
jb_create_impl create
Definition: abstract_jb.h:125
struct jb_framedata::@332 early_frames
#define LOG_WARNING
Definition: logger.h:274
struct ast_timer * ast_timer_open(void)
Open a timer.
Definition: timing.c:122
#define DEFAULT_TIMER_INTERVAL
Definition: abstract_jb.c:836
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
int video_stream_id
Definition: abstract_jb.c:858
struct ast_timer * timer
Definition: abstract_jb.c:852
int audio_stream_id
Definition: abstract_jb.c:856
char impl[AST_JB_IMPL_NAME_SIZE]
Name of the jitterbuffer implementation to be used.
Definition: abstract_jb.h:78
const struct ast_jb_impl * ast_jb_get_impl(enum ast_jb_type type)
Definition: abstract_jb.c:820
int timer_interval
Definition: abstract_jb.c:853
struct ast_jb_conf jb_conf
Definition: abstract_jb.c:849
int ast_timer_fd(const struct ast_timer *handle)
Get a poll()-able file descriptor for a timer.
Definition: timing.c:161
int ast_timer_set_rate(const struct ast_timer *handle, unsigned int rate)
Set the timing tick rate.
Definition: timing.c:166
#define AST_LIST_HEAD_INIT_NOLOCK(head)
Initializes a list head structure.
Definition: linkedlists.h:680
struct timeval start_tv
Definition: abstract_jb.c:850
#define DEFAULT_TYPE
Definition: abstract_jb.c:840
const struct ast_jb_impl * jb_impl
Definition: abstract_jb.c:848

◆ jb_get_adaptive()

static int jb_get_adaptive ( void *  jb,
struct ast_frame **  fout,
long  now,
long  interpl 
)
static

Definition at line 770 of file abstract_jb.c.

References ast_null_frame, jb_frame::data, and jb_get().

771 {
772  jitterbuf *adaptivejb = (jitterbuf *) jb;
773  jb_frame frame = { .data = &ast_null_frame };
774  int res;
775 
776  res = jb_get(adaptivejb, &frame, now, interpl);
777  *fout = frame.data;
778 
779  return adaptive_to_abstract_code[res];
780 }
enum jb_return_code jb_get(jitterbuf *jb, jb_frame *frame, long now, long interpl)
get a frame for time now (receiver&#39;s time) return value is one of JB_OK: You&#39;ve got frame! JB_DROP: H...
Definition: jitterbuf.c:785
void * data
Definition: jitterbuf.h:100
static const int adaptive_to_abstract_code[]
Definition: abstract_jb.c:123
struct ast_frame ast_null_frame
Definition: main/frame.c:79

◆ jb_get_and_deliver()

static void jb_get_and_deliver ( struct ast_channel chan)
static

Definition at line 353 of file abstract_jb.c.

References ao2_replace, ast_assert, ast_channel_jb(), ast_format_get_default_ms(), AST_FRAME_VOICE, ast_frfree, AST_FRIENDLY_OFFSET, AST_JB_IMPL_DROP, AST_JB_IMPL_INTERP, AST_JB_IMPL_NOFRAME, AST_JB_IMPL_OK, ast_log, ast_samp2tv(), ast_tvadd(), ast_write(), ast_frame::delivery, ast_frame_subclass::format, ast_frame::frametype, ast_jb_impl::get, get_now(), ast_jb::impl, jb_framelog, ast_jb::jbobj, ast_jb::last_format, ast_frame::len, LOG_ERROR, LOG_WARNING, ast_jb_impl::name, ast_jb_impl::next, ast_jb::next, ast_frame::next, NULL, ast_frame::offset, ast_frame::samples, ast_frame::src, ast_frame::subclass, ast_jb::timebase, and ast_frame::ts.

Referenced by ast_jb_get_and_deliver().

354 {
355  struct ast_jb *jb = ast_channel_jb(chan);
356  const struct ast_jb_impl *jbimpl = jb->impl;
357  void *jbobj = jb->jbobj;
358  struct ast_frame *f, finterp = { .frametype = AST_FRAME_VOICE, };
359  long now;
360  int interpolation_len, res;
361 
362  now = get_now(jb, NULL);
363  jb->next = jbimpl->next(jbobj);
364  if (now < jb->next) {
365  jb_framelog("\tJB_GET {now=%ld}: now < next=%ld\n", now, jb->next);
366  return;
367  }
368 
369  while (now >= jb->next) {
370  interpolation_len = ast_format_get_default_ms(jb->last_format);
371 
372  res = jbimpl->get(jbobj, &f, now, interpolation_len);
373 
374  switch (res) {
375  case AST_JB_IMPL_OK:
376  /* deliver the frame */
377  ast_write(chan, f);
378  case AST_JB_IMPL_DROP:
379  jb_framelog("\tJB_GET {now=%ld}: %s frame with ts=%ld and len=%ld\n",
380  now, jb_get_actions[res], f->ts, f->len);
382  ast_frfree(f);
383  break;
384  case AST_JB_IMPL_INTERP:
385  /* interpolate a frame */
386  f = &finterp;
387  f->subclass.format = jb->last_format;
388  f->samples = interpolation_len * 8;
389  f->src = "JB interpolation";
390  f->delivery = ast_tvadd(jb->timebase, ast_samp2tv(jb->next, 1000));
392  /* deliver the interpolated frame */
393  ast_write(chan, f);
394  jb_framelog("\tJB_GET {now=%ld}: Interpolated frame with len=%d\n", now, interpolation_len);
395  break;
396  case AST_JB_IMPL_NOFRAME:
398  "AST_JB_IMPL_NOFRAME is returned from the %s jb when now=%ld >= next=%ld, jbnext=%ld!\n",
399  jbimpl->name, now, jb->next, jbimpl->next(jbobj));
400  jb_framelog("\tJB_GET {now=%ld}: No frame for now!?\n", now);
401  return;
402  default:
403  ast_log(LOG_ERROR, "This should never happen!\n");
404  ast_assert("JB type unknown" == NULL);
405  break;
406  }
407 
408  jb->next = jbimpl->next(jbobj);
409  }
410 }
jb_next_impl next
Definition: abstract_jb.h:130
const struct ast_jb_impl * impl
Jitterbuffer implementation to be used.
Definition: abstract_jb.h:145
#define LOG_WARNING
Definition: logger.h:274
jb_get_impl get
Definition: abstract_jb.h:129
static const char *const jb_get_actions[]
Definition: abstract_jb.c:127
#define ast_assert(a)
Definition: utils.h:695
static long get_now(struct ast_jb *jb, struct timeval *tv)
Definition: abstract_jb.c:532
#define NULL
Definition: resample.c:96
struct ast_frame_subclass subclass
#define jb_framelog(...)
Macros for the frame log files.
Definition: abstract_jb.c:130
#define ast_log
Definition: astobj2.c:42
#define AST_FRIENDLY_OFFSET
Offset into a frame&#39;s data buffer.
const char * src
struct timeval ast_samp2tv(unsigned int _nsamp, unsigned int _rate)
Returns a timeval corresponding to the duration of n samples at rate r. Useful to convert samples to ...
Definition: time.h:238
void * jbobj
Jitterbuffer object, passed to the implementation.
Definition: abstract_jb.h:147
#define LOG_ERROR
Definition: logger.h:285
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
Definition: extconf.c:2283
General jitterbuffer state.
Definition: abstract_jb.h:140
unsigned int ast_format_get_default_ms(const struct ast_format *format)
Get the default framing size (in milliseconds) for a format.
Definition: format.c:359
int ast_write(struct ast_channel *chan, struct ast_frame *frame)
Write a frame to a channel This function writes the given frame to the indicated channel.
Definition: channel.c:5189
struct ast_jb * ast_channel_jb(struct ast_channel *chan)
struct timeval delivery
char name[AST_JB_IMPL_NAME_SIZE]
Definition: abstract_jb.h:123
#define ao2_replace(dst, src)
Definition: astobj2.h:517
struct ast_frame * next
#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
enum ast_frame_type frametype
struct ast_format * format
struct timeval timebase
The time the jitterbuffer was created.
Definition: abstract_jb.h:149
Jitterbuffer implementation struct.
Definition: abstract_jb.h:121
long next
The time the next frame should be played.
Definition: abstract_jb.h:151

◆ jb_get_fixed()

static int jb_get_fixed ( void *  jb,
struct ast_frame **  fout,
long  now,
long  interpl 
)
static

Definition at line 669 of file abstract_jb.c.

References ast_null_frame, fixed_jb_frame::data, and fixed_jb_get().

670 {
671  struct fixed_jb *fixedjb = (struct fixed_jb *) jb;
672  struct fixed_jb_frame frame = { .data = &ast_null_frame };
673  int res;
674 
675  res = fixed_jb_get(fixedjb, &frame, now, interpl);
676  *fout = frame.data;
677 
678  return fixed_to_abstract_code[res];
679 }
private fixed_jb structure
int fixed_jb_get(struct fixed_jb *jb, struct fixed_jb_frame *frame, long now, long interpl)
static const int fixed_to_abstract_code[]
Definition: abstract_jb.c:121
struct ast_frame ast_null_frame
Definition: main/frame.c:79

◆ jb_is_late_adaptive()

static int jb_is_late_adaptive ( void *  jb,
long  ts 
)
static

Definition at line 831 of file abstract_jb.c.

References jb_is_late().

832 {
833  return jb_is_late(jb, ts);
834 }
int jb_is_late(jitterbuf *jb, long ts)
Checks if the given time stamp is late.
Definition: jitterbuf.c:846

◆ jb_is_late_fixed()

static int jb_is_late_fixed ( void *  jb,
long  ts 
)
static

Definition at line 720 of file abstract_jb.c.

References fixed_jb_is_late().

721 {
722  return fixed_jb_is_late(jb, ts);
723 }
int fixed_jb_is_late(struct fixed_jb *jb, long ts)
Checks if the given time stamp is late.

◆ jb_next_adaptive()

static long jb_next_adaptive ( void *  jb)
static

Definition at line 783 of file abstract_jb.c.

References jb_next().

784 {
785  jitterbuf *adaptivejb = (jitterbuf *) jb;
786 
787  return jb_next(adaptivejb);
788 }
long jb_next(jitterbuf *jb)
when is the next frame due out, in receiver&#39;s time (0=EMPTY) This value may change as frames are adde...
Definition: jitterbuf.c:767

◆ jb_next_fixed()

static long jb_next_fixed ( void *  jb)
static

Definition at line 682 of file abstract_jb.c.

References fixed_jb_next().

683 {
684  struct fixed_jb *fixedjb = (struct fixed_jb *) jb;
685 
686  return fixed_jb_next(fixedjb);
687 }
private fixed_jb structure
long fixed_jb_next(struct fixed_jb *jb)

◆ jb_put_adaptive()

static int jb_put_adaptive ( void *  jb,
struct ast_frame fin,
long  now 
)
static

Definition at line 759 of file abstract_jb.c.

References jb_put(), JB_TYPE_VOICE, ast_frame::len, and ast_frame::ts.

Referenced by jb_put_first_adaptive().

760 {
761  jitterbuf *adaptivejb = (jitterbuf *) jb;
762  int res;
763 
764  res = jb_put(adaptivejb, fin, JB_TYPE_VOICE, fin->len, fin->ts, now);
765 
766  return adaptive_to_abstract_code[res];
767 }
enum jb_return_code jb_put(jitterbuf *jb, void *data, const enum jb_frame_type type, long ms, long ts, long now)
queue a frame
Definition: jitterbuf.c:525
static const int adaptive_to_abstract_code[]
Definition: abstract_jb.c:123

◆ jb_put_first_adaptive()

static int jb_put_first_adaptive ( void *  jb,
struct ast_frame fin,
long  now 
)
static

Definition at line 753 of file abstract_jb.c.

References jb_put_adaptive().

754 {
755  return jb_put_adaptive(jb, fin, now);
756 }
static int jb_put_adaptive(void *jb, struct ast_frame *fin, long now)
Definition: abstract_jb.c:759

◆ jb_put_first_fixed()

static int jb_put_first_fixed ( void *  jb,
struct ast_frame fin,
long  now 
)
static

Definition at line 647 of file abstract_jb.c.

References fixed_jb_put_first(), ast_frame::len, and ast_frame::ts.

648 {
649  struct fixed_jb *fixedjb = (struct fixed_jb *) jb;
650  int res;
651 
652  res = fixed_jb_put_first(fixedjb, fin, fin->len, fin->ts, now);
653 
654  return fixed_to_abstract_code[res];
655 }
private fixed_jb structure
static const int fixed_to_abstract_code[]
Definition: abstract_jb.c:121
int fixed_jb_put_first(struct fixed_jb *jb, void *data, long ms, long ts, long now)

◆ jb_put_fixed()

static int jb_put_fixed ( void *  jb,
struct ast_frame fin,
long  now 
)
static

Definition at line 658 of file abstract_jb.c.

References fixed_jb_put(), ast_frame::len, and ast_frame::ts.

659 {
660  struct fixed_jb *fixedjb = (struct fixed_jb *) jb;
661  int res;
662 
663  res = fixed_jb_put(fixedjb, fin, fin->len, fin->ts, now);
664 
665  return fixed_to_abstract_code[res];
666 }
private fixed_jb structure
static const int fixed_to_abstract_code[]
Definition: abstract_jb.c:121
int fixed_jb_put(struct fixed_jb *jb, void *data, long ms, long ts, long now)

◆ jb_remove_adaptive()

static int jb_remove_adaptive ( void *  jb,
struct ast_frame **  fout 
)
static

Definition at line 791 of file abstract_jb.c.

References jb_frame::data, and jb_getall().

792 {
793  jitterbuf *adaptivejb = (jitterbuf *) jb;
794  jb_frame frame;
795  int res;
796 
797  res = jb_getall(adaptivejb, &frame);
798  *fout = frame.data;
799 
800  return adaptive_to_abstract_code[res];
801 }
void * data
Definition: jitterbuf.h:100
static const int adaptive_to_abstract_code[]
Definition: abstract_jb.c:123
enum jb_return_code jb_getall(jitterbuf *jb, jb_frame *frameout)
unconditionally get frames from jitterbuf until empty
Definition: jitterbuf.c:801

◆ jb_remove_fixed()

static int jb_remove_fixed ( void *  jb,
struct ast_frame **  fout 
)
static

Definition at line 690 of file abstract_jb.c.

References fixed_jb_frame::data, and fixed_jb_remove().

691 {
692  struct fixed_jb *fixedjb = (struct fixed_jb *) jb;
693  struct fixed_jb_frame frame;
694  int res;
695 
696  res = fixed_jb_remove(fixedjb, &frame);
697  *fout = frame.data;
698 
699  return fixed_to_abstract_code[res];
700 }
private fixed_jb structure
int fixed_jb_remove(struct fixed_jb *jb, struct fixed_jb_frame *frameout)
static const int fixed_to_abstract_code[]
Definition: abstract_jb.c:121
union ast_frame::@263 data

◆ jitterbuffer_frame_get_ntp_timestamp()

static struct timeval jitterbuffer_frame_get_ntp_timestamp ( const struct jb_stream_sync stream_sync,
const struct ast_frame frame 
)
static

Definition at line 915 of file abstract_jb.c.

References abs, AST_FRAME_VOICE, ast_rtp_get_rate(), ast_samp2tv(), ast_tv(), ast_tvadd(), ast_tvsub(), and ast_tvzero().

Referenced by hook_event_cb().

916 {
917  int timestamp_diff;
918  unsigned int rate;
919 
920  /* It's possible for us to receive frames before we receive the information allowing
921  * us to do NTP/RTP timestamp calculations. Since the information isn't available we
922  * can't generate one and give an empty timestamp.
923  */
924  if (ast_tvzero(stream_sync->ntp)) {
925  return ast_tv(0, 0);
926  }
927 
928  /* Convert the Asterisk timestamp into an RTP timestamp, and then based on the difference we can
929  * determine how many samples are in the frame and how long has elapsed since the synchronization
930  * RTP and NTP timestamps were received giving us the NTP timestamp for this frame.
931  */
932  if (frame->frametype == AST_FRAME_VOICE) {
933  rate = ast_rtp_get_rate(frame->subclass.format);
934  timestamp_diff = (frame->ts * (rate / 1000)) - stream_sync->timestamp;
935  } else {
936  /* Video is special - internally we reference it as 1000 to preserve the RTP timestamp but
937  * it is actualy 90000, this is why we can just directly subtract the timestamp.
938  */
939  rate = 90000;
940  timestamp_diff = frame->ts - stream_sync->timestamp;
941  }
942 
943  if (timestamp_diff < 0) {
944  /* It's possible for us to be asked for an NTP timestamp from before our latest
945  * RTCP SR report. To handle this we subtract so we go back in time.
946  */
947  return ast_tvsub(stream_sync->ntp, ast_samp2tv(abs(timestamp_diff), rate));
948  } else {
949  return ast_tvadd(stream_sync->ntp, ast_samp2tv(timestamp_diff, rate));
950  }
951 }
struct timeval ntp
Definition: abstract_jb.c:844
int ast_tvzero(const struct timeval t)
Returns true if the argument is 0,0.
Definition: time.h:108
struct ast_frame_subclass subclass
struct timeval ast_samp2tv(unsigned int _nsamp, unsigned int _rate)
Returns a timeval corresponding to the duration of n samples at rate r. Useful to convert samples to ...
Definition: time.h:238
unsigned int timestamp
Definition: abstract_jb.c:843
int ast_rtp_get_rate(const struct ast_format *format)
Retrieve the sample rate of a format according to RTP specifications.
Definition: rtp_engine.c:4030
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
Definition: extconf.c:2283
#define abs(x)
Definition: f2c.h:195
struct timeval ast_tv(ast_time_t sec, ast_suseconds_t usec)
Returns a timeval from sec, usec.
Definition: time.h:226
struct timeval ast_tvsub(struct timeval a, struct timeval b)
Returns the difference of two timevals a - b.
Definition: extconf.c:2298
enum ast_frame_type frametype
struct ast_format * format

Variable Documentation

◆ adaptive_to_abstract_code

const int adaptive_to_abstract_code[]
static

◆ avail_impl

const struct ast_jb_impl avail_impl[]
static

Definition at line 87 of file abstract_jb.c.

◆ default_impl

int default_impl = 0
static

Definition at line 118 of file abstract_jb.c.

Referenced by jb_choose_impl().

◆ fixed_to_abstract_code

const int fixed_to_abstract_code[]
static

◆ jb_datastore

const struct ast_datastore_info jb_datastore
static
Initial value:
= {
.type = "jitterbuffer",
}
static void datastore_destroy_cb(void *data)
Definition: abstract_jb.c:899

Definition at line 904 of file abstract_jb.c.

◆ jb_get_actions

const char* const jb_get_actions[] = {"Delivered", "Dropped", "Interpolated", "No"}
static

Definition at line 127 of file abstract_jb.c.