59 #define MAXIMUM_EARLY_FRAME_COUNT 200 127 static const char *
const jb_get_actions[] = {
"Delivered",
"Dropped",
"Interpolated",
"No"};
130 #define jb_framelog(...) do { \ 132 fprintf(jb->logfile, __VA_ARGS__); \ 133 fflush(jb->logfile); \ 153 int i, avail_impl_count =
ARRAY_LEN(avail_impl);
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;
191 if (((!c0_wants_jitter && c1_creates_jitter) || (c0_force_jb && c1_creates_jitter)) && c0_jb_enabled) {
193 if (!c0_jb_timebase_initialized) {
194 if (c1_jb_timebase_initialized) {
202 if (!c0_jb_created) {
210 if (((!c1_wants_jitter && c0_creates_jitter) || (c1_force_jb && c0_creates_jitter)) && c1_jb_enabled) {
212 if (!c1_jb_timebase_initialized) {
213 if (c0_jb_timebase_initialized) {
221 if (!c1_jb_created) {
239 int wait, wait0, wait1;
240 struct timeval tv_now;
242 if (time_left == 0) {
252 gettimeofday(&tv_now,
NULL);
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;
257 wait = wait0 < wait1 ? wait0 : wait1;
258 wait = wait < time_left ? wait : time_left;
260 if (wait == INT_MAX) {
262 }
else if (wait < 1) {
275 void *jbobj = jb->
jbobj;
284 jb_framelog(
"JB_PUT {now=%ld}: Received DTMF frame. Force resynching jb...\n", now);
294 "has_timing_info=%u, len=%ld, ts=%ld, src=%s\n",
319 jb_framelog(
"JB_PUT {now=%ld}: Dropped frame with ts=%ld and len=%ld\n", now, frr->
ts, frr->
len);
329 jb_framelog(
"JB_PUT {now=%ld}: Queued frame with ts=%ld and len=%ld\n", now, frr->
ts, frr->
len);
345 if (c0_use_jb && c0_jb_is_created)
348 if (c1_use_jb && c1_jb_is_created)
357 void *jbobj = jb->
jbobj;
360 int interpolation_len, res;
364 if (now < jb->
next) {
369 while (now >= jb->
next) {
372 res = jbimpl->
get(jbobj, &f, now, interpolation_len);
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);
388 f->
samples = interpolation_len * 8;
389 f->
src =
"JB interpolation";
394 jb_framelog(
"\tJB_GET {now=%ld}: Interpolated frame with len=%d\n", now, interpolation_len);
398 "AST_JB_IMPL_NOFRAME is returned from the %s jb when now=%ld >= next=%ld, jbnext=%ld!\n",
400 jb_framelog(
"\tJB_GET {now=%ld}: No frame for now!?\n", now);
431 res = jbimpl->
put_first(jbobj, frr, now);
435 if (res != AST_JB_IMPL_OK) {
452 char safe_logfile[30] =
"/tmp/logfile-XXXXXX";
456 while ((tmp = strchr(name2,
'/'))) {
464 while ((tmp = strchr(name1,
'/'))) {
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));
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);
484 jb_framelog(
"JB_PUT_FIRST {now=%ld}: Dropped frame with ts=%ld and len=%ld\n",
485 now, frr->
ts, frr->
len);
494 if (res != AST_JB_IMPL_OK) {
506 void *jbobj = jb->
jbobj;
538 gettimeofday(when,
NULL);
555 name = varname + prefixlen;
562 if ((tmp = atoi(value)) > 0)
565 if ((tmp = atoi(value)) > 0)
569 snprintf(conf->
impl,
sizeof(conf->
impl),
"%s", value);
571 if (sscanf(value,
"%30d", &tmp) == 1) {
654 return fixed_to_abstract_code[res];
665 return fixed_to_abstract_code[res];
678 return fixed_to_abstract_code[res];
699 return fixed_to_abstract_code[res];
766 return adaptive_to_abstract_code[res];
776 res =
jb_get(adaptivejb, &frame, now, interpl);
779 return adaptive_to_abstract_code[res];
800 return adaptive_to_abstract_code[res];
823 for (i = 0; i <
ARRAY_LEN(avail_impl); i++) {
824 if (avail_impl[i].type == type) {
825 return &avail_impl[i];
836 #define DEFAULT_TIMER_INTERVAL 20 837 #define DEFAULT_SIZE 200 838 #define DEFAULT_TARGET_EXTRA 40 839 #define DEFAULT_RESYNC 1000 840 #define DEFAULT_TYPE AST_JB_FIXED 850 struct timeval start_tv;
862 struct timeval last_audio_ntp_timestamp;
871 if (framedata->
timer) {
901 ast_debug(1,
"JITTERBUFFER datastore destroyed\n");
905 .
type =
"jitterbuffer",
911 ast_debug(1,
"JITTERBUFFER hook destroyed\n");
934 timestamp_diff = (frame->ts * (rate / 1000)) - stream_sync->timestamp;
940 timestamp_diff = frame->ts - stream_sync->timestamp;
943 if (timestamp_diff < 0) {
956 struct timeval now_tv;
1034 struct timeval video_timestamp;
1085 if (!framedata->
first) {
1086 framedata->
first = 1;
1092 if (res == AST_JB_IMPL_OK) {
1093 if (jbframe != frame) {
1097 }
else if (jbframe != frame) {
1117 long int diff = next - now;
1146 tmp.
src =
"func_jitterbuffer interpolation";
1222 memcpy(&framedata->
jb_conf, jb_conf,
sizeof(*jb_conf));
1226 if (!strcasecmp(jb_conf->
impl,
"fixed")) {
1228 }
else if (!strcasecmp(jb_conf->
impl,
"adaptive")) {
1269 if (!strcasecmp(jb_conf->
impl,
"disabled")) {
1273 id = datastore->
data;
1282 if (!(framedata =
ast_calloc(1,
sizeof(*framedata)))) {
1291 interface.
data = framedata;
1299 if (prefer_existing) {
1306 id = datastore->
data;
An object that represents data sent during a SR/RR RTCP report.
#define ast_channel_lock(chan)
Main Channel structure associated with a channel.
#define ast_frdup(fr)
Copies a frame.
Asterisk main include file. File version handling, generic pbx functions.
struct jb_stream_sync video_stream_sync
#define AST_LIST_FIRST(head)
Returns the first entry contained in a list.
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.
#define MAXIMUM_EARLY_FRAME_COUNT
private fixed_jb structure
static void jb_framedata_destroy(struct jb_framedata *framedata)
Channels have this property if they can accept input with jitter; i.e. most VoIP channels.
#define ast_set2_flag(p, value, flag)
#define ast_test_flag(p, flag)
int ast_jb_read_conf(struct ast_jb_conf *conf, const char *varname, const char *value)
Sets jitterbuffer configuration property.
#define AST_JB_CONF_ENABLE
struct ast_format * last_format
int fixed_jb_remove(struct fixed_jb *jb, struct fixed_jb_frame *frameout)
static void jb_force_resynch_fixed(void *jb)
struct jb_framedata::@332 early_frames
const struct ast_jb_impl * impl
Jitterbuffer implementation to be used.
#define ast_set_flag(p, flag)
void ast_jb_destroy(struct ast_channel *chan)
Destroys jitterbuffer on a channel.
ast_framehook_event
These are the types of events that the framehook's event callback can receive.
void ast_jb_empty_and_reset(struct ast_channel *c0, struct ast_channel *c1)
drops all frames from a jitterbuffer and resets it
int ast_framehook_detach(struct ast_channel *chan, int framehook_id)
Detach an framehook from a channel.
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
int ast_tvzero(const struct timeval t)
Returns true if the argument is 0,0.
static struct timeval jitterbuffer_frame_get_ntp_timestamp(const struct jb_stream_sync *stream_sync, const struct ast_frame *frame)
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
void ast_timer_close(struct ast_timer *handle)
Close an opened timing handle.
static int create_jb(struct ast_channel *chan, struct ast_frame *first_frame)
static void jb_destroy_fixed(void *jb)
Structure for a data store type.
struct ast_timer * ast_timer_open(void)
Open a timer.
struct jb_stream_sync audio_stream_sync
#define DEFAULT_TIMER_INTERVAL
static const char *const jb_get_actions[]
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
static int jb_remove_adaptive(void *jb, struct ast_frame **fout)
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Structure for a data store object.
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.
static long get_now(struct ast_jb *jb, struct timeval *tv)
struct ast_jb_conf conf
Jitterbuffer configuration.
#define AST_JB_IMPL_NAME_SIZE
enum jb_return_code jb_get(jitterbuf *jb, jb_frame *frame, long now, long interpl)
get a frame for time now (receiver's time) return value is one of JB_OK: You've got frame! JB_DROP: H...
static long jb_next_fixed(void *jb)
Common implementation-independent jitterbuffer stuff.
unsigned int rtp_timestamp
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
#define ast_verb(level,...)
struct ast_rtp_rtcp_report::@315 sender_information
int ast_datastore_free(struct ast_datastore *datastore)
Free a data store object.
struct ast_frame_subclass subclass
static void jb_choose_impl(struct ast_channel *chan)
#define ast_strlen_zero(foo)
All configuration options for statsd client.
static int jb_put_fixed(void *jb, struct ast_frame *fin, long now)
jitterbuf * jb_new(void)
new jitterbuf
long resync_threshold
Resynchronization threshold of the jitterbuffer implementation.
static void jb_force_resynch_adaptive(void *jb)
int ast_framehook_attach(struct ast_channel *chan, struct ast_framehook_interface *i)
Attach an framehook onto a channel for frame interception.
static int jb_is_late_fixed(void *jb, long ts)
#define jb_framelog(...)
Macros for the frame log files.
static const struct ast_datastore_info jb_datastore
#define ast_debug(level,...)
Log a DEBUG message.
long jb_next(jitterbuf *jb)
when is the next frame due out, in receiver's time (0=EMPTY) This value may change as frames are adde...
void ast_jb_conf_default(struct ast_jb_conf *conf)
Sets the contents of an ast_jb_conf struct to the default jitterbuffer settings.
int ast_jb_do_usecheck(struct ast_channel *c0, struct ast_channel *c1)
Checks the need of a jb use in a generic bridge.
General Asterisk PBX channel definitions.
#define DEFAULT_TARGET_EXTRA
#define AST_FRIENDLY_OFFSET
Offset into a frame's data buffer.
static void jb_destroy_adaptive(void *jb)
struct timeval last_audio_ntp_timestamp
#define AST_JB_CONF_PREFIX
int jb_is_late(jitterbuf *jb, long ts)
Checks if the given time stamp is late.
jb_force_resynch_impl force_resync
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
#define ast_channel_cleanup(c)
Cleanup a channel reference.
Asterisk internal frame definitions.
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 ...
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 configuratio...
static int jb_get_adaptive(void *jb, struct ast_frame **fout, long now, long interpl)
void * jbobj
Jitterbuffer object, passed to the implementation.
long target_extra
amount of additional jitterbuffer adjustment
static void datastore_destroy_cb(void *data)
static const struct ast_jb_impl avail_impl[]
int fixed_jb_get(struct fixed_jb *jb, struct fixed_jb_frame *frame, long now, long interpl)
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
AST_LIST_HEAD_NOLOCK(contactliststruct, contact)
#define AST_JB_CONF_TARGET_EXTRA
char impl[AST_JB_IMPL_NAME_SIZE]
Name of the jitterbuffer implementation to be used.
Core PBX routines and definitions.
int ast_rtp_get_rate(const struct ast_format *format)
Retrieve the sample rate of a format according to RTP specifications.
jitterbuf: an application-independent jitterbuffer jitterbuf.c
static void jb_empty_and_reset_fixed(void *jb)
int ast_channel_fdno(const struct ast_channel *chan)
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.
static const int fixed_to_abstract_code[]
void fixed_jb_destroy(struct fixed_jb *jb)
int ast_timer_ack(const struct ast_timer *handle, unsigned int quantity)
Acknowledge a timer event.
static int jb_put_first_fixed(void *jb, struct ast_frame *fin, long now)
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
const struct ast_jb_impl * ast_jb_get_impl(enum ast_jb_type type)
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".
static struct ast_frame * hook_event_cb(struct ast_channel *chan, struct ast_frame *frame, enum ast_framehook_event event, void *data)
static void hook_destroy_cb(void *framedata)
enum jb_return_code jb_setconf(jitterbuf *jb, jb_conf *conf)
set jitterbuf conf
int ast_jb_put(struct ast_channel *chan, struct ast_frame *f)
Puts a frame into a channel jitterbuffer.
#define AST_FRAMEHOOK_INTERFACE_VERSION
int fixed_jb_put_first(struct fixed_jb *jb, void *data, long ms, long ts, long now)
static const int adaptive_to_abstract_code[]
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
void ast_jb_get_config(const struct ast_channel *chan, struct ast_jb_conf *conf)
Copies a channel's jitterbuffer configuration.
static long jb_next_adaptive(void *jb)
#define AST_JB_CONF_FORCE
jb_put_first_impl put_first
General jitterbuffer state.
static int jb_remove_fixed(void *jb, struct ast_frame **fout)
long fixed_jb_next(struct fixed_jb *jb)
#define ast_channel_unlock(chan)
#define ast_calloc(num, len)
A wrapper for calloc()
FILE * logfile
File for frame timestamp tracing.
static int jb_is_late_adaptive(void *jb, long ts)
static void * jb_create_adaptive(struct ast_jb_conf *general_config)
struct ast_jb_conf jb_conf
void ast_jb_configure(struct ast_channel *chan, const struct ast_jb_conf *conf)
Configures a jitterbuffer on a channel.
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.
#define ast_frisolate(fr)
Makes a frame independent of any static storage.
int ast_timer_fd(const struct ast_timer *handle)
Get a poll()-able file descriptor for a timer.
int ast_timer_set_rate(const struct ast_timer *handle, unsigned int rate)
Set the timing tick rate.
struct ast_jb * ast_channel_jb(struct ast_channel *chan)
Jitterbuffering algorithm.
#define ast_clear_flag(p, flag)
void ast_channel_set_fd(struct ast_channel *chan, int which, int fd)
char name[AST_JB_IMPL_NAME_SIZE]
struct ast_frame ast_null_frame
void fixed_jb_set_force_resynch(struct fixed_jb *jb)
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.
#define AST_LIST_HEAD_INIT_NOLOCK(head)
Initializes a list head structure.
jb_empty_and_reset_impl empty_and_reset
#define ao2_replace(dst, src)
static void * jb_create_fixed(struct ast_jb_conf *general_config)
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
struct timeval ast_tv(ast_time_t sec, ast_suseconds_t usec)
Returns a timeval from sec, usec.
struct ast_channel * ast_channel_bridge_peer(struct ast_channel *chan)
Get the channel's bridge peer only if the bridge is two-party.
const char * ast_channel_name(const struct ast_channel *chan)
struct fixed_jb * fixed_jb_new(struct fixed_jb_conf *conf)
int fixed_jb_put(struct fixed_jb *jb, void *data, long ms, long ts, long now)
Data structure associated with a single frame of data.
int fixed_jb_is_late(struct fixed_jb *jb, long ts)
Checks if the given time stamp is late.
struct ast_format * last_format
Voice format of the last frame in.
static int jb_put_adaptive(void *jb, struct ast_frame *fin, long now)
#define AST_JITTERBUFFER_FD
static int jb_framedata_init(struct jb_framedata *framedata, struct ast_jb_conf *jb_conf)
unsigned int early_frame_count
Handy terminal functions for vt* terms.
struct timeval ast_tvsub(struct timeval a, struct timeval b)
Returns the difference of two timevals a - b.
#define ast_datastore_alloc(info, uid)
union ast_frame::@263 data
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
enum ast_frame_type frametype
void jb_destroy(jitterbuf *jb)
destroy jitterbuf
struct ast_format * format
#define AST_JB_CONF_MAX_SIZE
struct timeval timebase
The time the jitterbuffer was created.
struct timeval ntp_timestamp
const struct ast_jb_impl * jb_impl
#define AST_JB_CONF_SYNC_VIDEO
Pluggable RTP Architecture.
enum jb_return_code jb_getall(jitterbuf *jb, jb_frame *frameout)
unconditionally get frames from jitterbuf until empty
#define AST_JB_CONF_RESYNCH_THRESHOLD
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
long max_size
Max size of the jitterbuffer implementation.
static void jb_get_and_deliver(struct ast_channel *chan)
Jitterbuffer implementation struct.
const struct ast_channel_tech * ast_channel_tech(const struct ast_channel *chan)
General jitterbuffer configuration.
int ast_channel_datastore_remove(struct ast_channel *chan, struct ast_datastore *datastore)
Remove a datastore from a channel.
static void jb_empty_and_reset_adaptive(void *jb)
Timing source management.
static int jb_put_first_adaptive(void *jb, struct ast_frame *fin, long now)
long next
The time the next frame should be played.
void jb_reset(jitterbuf *jb)
reset jitterbuf
Channels have this property if they can create jitter; i.e. most VoIP channels.
static int jb_get_fixed(void *jb, struct ast_frame **fout, long now, long interpl)