RTS API Documentation  1.10.11
Enumerations | Functions
switch_jitterbuffer.h File Reference
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Enumerations

enum  switch_jb_flag_t { SJB_QUEUE_ONLY = (1 << 0) }
 
enum  switch_jb_type_t { SJB_VIDEO = 0, SJB_AUDIO, SJB_TEXT }
 

Functions

SWITCH_BEGIN_EXTERN_C switch_status_t switch_jb_create (switch_jb_t **jbp, switch_jb_type_t type, uint32_t min_frame_len, uint32_t max_frame_len, switch_memory_pool_t *pool)
 
switch_status_t switch_jb_set_frames (switch_jb_t *jb, uint32_t min_frame_len, uint32_t max_frame_len)
 
switch_status_t switch_jb_peek_frame (switch_jb_t *jb, uint32_t ts, uint16_t seq, int peek, switch_frame_t *frame)
 
switch_status_t switch_jb_get_frames (switch_jb_t *jb, uint32_t *min_frame_len, uint32_t *max_frame_len, uint32_t *cur_frame_len, uint32_t *highest_frame_len)
 
switch_status_t switch_jb_destroy (switch_jb_t **jbp)
 
void switch_jb_reset (switch_jb_t *jb)
 
void switch_jb_debug_level (switch_jb_t *jb, uint8_t level)
 
int switch_jb_frame_count (switch_jb_t *jb)
 
int switch_jb_poll (switch_jb_t *jb)
 
switch_status_t switch_jb_put_packet (switch_jb_t *jb, switch_rtp_packet_t *packet, switch_size_t len)
 
switch_size_t switch_jb_get_last_read_len (switch_jb_t *jb)
 
switch_status_t switch_jb_get_packet (switch_jb_t *jb, switch_rtp_packet_t *packet, switch_size_t *len)
 
uint32_t switch_jb_pop_nack (switch_jb_t *jb)
 
switch_status_t switch_jb_get_packet_by_seq (switch_jb_t *jb, uint16_t seq, switch_rtp_packet_t *packet, switch_size_t *len)
 
void switch_jb_set_session (switch_jb_t *jb, switch_core_session_t *session)
 
void switch_jb_set_jitter_estimator (switch_jb_t *jb, double *jitter, uint32_t samples_per_frame, uint32_t samples_per_second)
 
void switch_jb_ts_mode (switch_jb_t *jb, uint32_t samples_per_frame, uint32_t samples_per_second)
 
void switch_jb_set_flag (switch_jb_t *jb, switch_jb_flag_t flag)
 
void switch_jb_clear_flag (switch_jb_t *jb, switch_jb_flag_t flag)
 
uint32_t switch_jb_get_nack_success (switch_jb_t *jb)
 
uint32_t switch_jb_get_packets_per_frame (switch_jb_t *jb)
 

Enumeration Type Documentation

◆ switch_jb_flag_t

Enumerator
SJB_QUEUE_ONLY 

Definition at line 36 of file switch_jitterbuffer.h.

36  {
37  SJB_QUEUE_ONLY = (1 << 0)
switch_jb_flag_t

◆ switch_jb_type_t

Enumerator
SJB_VIDEO 
SJB_AUDIO 
SJB_TEXT 

Definition at line 40 of file switch_jitterbuffer.h.

Function Documentation

◆ switch_jb_clear_flag()

void switch_jb_clear_flag ( switch_jb_t jb,
switch_jb_flag_t  flag 
)

Definition at line 1143 of file switch_jitterbuffer.c.

References switch_clear_flag.

1144 {
1145  switch_clear_flag(jb, flag);
1146 }
#define switch_clear_flag(obj, flag)
Clear a flag on an arbitrary object while locked.
Definition: switch_utils.h:724

◆ switch_jb_create()

SWITCH_BEGIN_EXTERN_C switch_status_t switch_jb_create ( switch_jb_t **  jbp,
switch_jb_type_t  type,
uint32_t  min_frame_len,
uint32_t  max_frame_len,
switch_memory_pool_t pool 
)

Definition at line 1322 of file switch_jitterbuffer.c.

References switch_jb_s::frame_len, switch_jb_s::free_pool, switch_jb_s::highest_frame_len, switch_jb_s::list_mutex, switch_jb_s::max_frame_len, switch_jb_s::min_frame_len, switch_jb_s::missing_seq_hash, switch_jb_s::mutex, switch_jb_s::node_hash, switch_jb_s::period_len, pool, switch_jb_s::pool, SJB_VIDEO, switch_core_alloc, switch_core_inthash_init(), switch_core_new_memory_pool, switch_mutex_init(), SWITCH_MUTEX_NESTED, SWITCH_STATUS_SUCCESS, and switch_jb_s::type.

Referenced by rtp_common_write(), switch_ivr_delay_echo(), switch_rtp_activate_jitter_buffer(), and switch_rtp_set_video_buffer_size().

1324 {
1325  switch_jb_t *jb;
1326  int free_pool = 0;
1327 
1328  if (!pool) {
1330  free_pool = 1;
1331  }
1332 
1333  jb = switch_core_alloc(pool, sizeof(*jb));
1334  jb->free_pool = free_pool;
1335  jb->min_frame_len = jb->frame_len = min_frame_len;
1336  jb->max_frame_len = max_frame_len;
1337  jb->pool = pool;
1338  jb->type = type;
1339  jb->highest_frame_len = jb->frame_len;
1340 
1341  if (jb->type == SJB_VIDEO) {
1343  jb->period_len = 2500;
1344  } else {
1345  jb->period_len = 250;
1346  }
1347 
1351 
1352  *jbp = jb;
1353 
1354  return SWITCH_STATUS_SUCCESS;
1355 }
switch_jb_type_t type
#define switch_core_new_memory_pool(p)
Create a new sub memory pool from the core&#39;s master pool.
Definition: switch_core.h:633
switch_status_t switch_core_inthash_init(switch_inthash_t **hash)
switch_inthash_t * node_hash
uint32_t min_frame_len
switch_inthash_t * missing_seq_hash
switch_memory_pool_t * pool
uint32_t max_frame_len
#define SWITCH_MUTEX_NESTED
Definition: switch_apr.h:318
switch_mutex_t * mutex
#define switch_core_alloc(_pool, _mem)
Allocate memory directly from a memory pool.
Definition: switch_core.h:684
switch_status_t switch_mutex_init(switch_mutex_t **lock, unsigned int flags, switch_memory_pool_t *pool)
Definition: switch_apr.c:293
switch_mutex_t * list_mutex
uint32_t highest_frame_len
switch_memory_pool_t * pool

◆ switch_jb_debug_level()

void switch_jb_debug_level ( switch_jb_t jb,
uint8_t  level 
)

Definition at line 1169 of file switch_jitterbuffer.c.

References switch_jb_s::debug_level.

Referenced by switch_ivr_delay_echo(), and switch_rtp_debug_jitter_buffer().

1170 {
1171  jb->debug_level = level;
1172 }

◆ switch_jb_destroy()

switch_status_t switch_jb_destroy ( switch_jb_t **  jbp)

Definition at line 1357 of file switch_jitterbuffer.c.

References free_nodes(), switch_jb_s::free_pool, jb_debug, switch_jb_s::missing_seq_hash, switch_jb_s::nack_didnt_save_the_day, switch_jb_s::nack_saved_the_day, switch_jb_s::node_hash, switch_jb_s::node_hash_ts, switch_jb_s::pool, SJB_QUEUE_ONLY, SJB_VIDEO, switch_core_destroy_memory_pool, switch_core_inthash_destroy(), switch_hashtable_count(), SWITCH_STATUS_SUCCESS, switch_test_flag, and switch_jb_s::type.

Referenced by read_rtp_packet(), switch_ivr_delay_echo(), and switch_rtp_destroy().

1358 {
1359  switch_jb_t *jb = *jbp;
1360  *jbp = NULL;
1361 
1362  if (jb->type == SJB_VIDEO && !switch_test_flag(jb, SJB_QUEUE_ONLY)) {
1363  jb_debug(jb, 3, "Stats: NACK saved the day: %u\n", jb->nack_saved_the_day);
1364  jb_debug(jb, 3, "Stats: NACK was late: %u\n", jb->nack_didnt_save_the_day);
1365  jb_debug(jb, 3, "Stats: Hash entrycount: missing_seq_hash %u\n", switch_hashtable_count(jb->missing_seq_hash));
1366  }
1367  if (jb->type == SJB_VIDEO) {
1369  }
1371 
1372  if (jb->node_hash_ts) {
1374  }
1375 
1376  free_nodes(jb);
1377 
1378  if (jb->free_pool) {
1380  }
1381 
1382  return SWITCH_STATUS_SUCCESS;
1383 }
switch_jb_type_t type
switch_inthash_t * node_hash
switch_inthash_t * node_hash_ts
switch_inthash_t * missing_seq_hash
uint32_t nack_saved_the_day
#define switch_core_destroy_memory_pool(p)
Returns a subpool back to the main pool.
Definition: switch_core.h:642
#define jb_debug(_jb, _level, _format,...)
switch_status_t switch_core_inthash_destroy(switch_inthash_t **hash)
uint32_t nack_didnt_save_the_day
static void free_nodes(switch_jb_t *jb)
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:693
switch_memory_pool_t * pool
unsigned int switch_hashtable_count(switch_hashtable_t *h)

◆ switch_jb_frame_count()

int switch_jb_frame_count ( switch_jb_t jb)

Definition at line 1164 of file switch_jitterbuffer.c.

References switch_jb_s::complete_frames.

1165 {
1166  return jb->complete_frames;
1167 }
uint32_t complete_frames

◆ switch_jb_get_frames()

switch_status_t switch_jb_get_frames ( switch_jb_t jb,
uint32_t *  min_frame_len,
uint32_t *  max_frame_len,
uint32_t *  cur_frame_len,
uint32_t *  highest_frame_len 
)

Definition at line 1268 of file switch_jitterbuffer.c.

References switch_jb_s::frame_len, switch_jb_s::max_frame_len, switch_jb_s::min_frame_len, switch_jb_s::mutex, switch_mutex_lock(), switch_mutex_unlock(), and SWITCH_STATUS_SUCCESS.

Referenced by switch_rtp_get_stats(), and switch_rtp_get_video_buffer_size().

1269 {
1270 
1271  switch_mutex_lock(jb->mutex);
1272 
1273  if (min_frame_len) {
1274  *min_frame_len = jb->min_frame_len;
1275  }
1276 
1277  if (max_frame_len) {
1278  *max_frame_len = jb->max_frame_len;
1279  }
1280 
1281  if (cur_frame_len) {
1282  *cur_frame_len = jb->frame_len;
1283  }
1284 
1286 
1287  return SWITCH_STATUS_SUCCESS;
1288 }
uint32_t min_frame_len
uint32_t max_frame_len
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:313
switch_mutex_t * mutex
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:308

◆ switch_jb_get_last_read_len()

switch_size_t switch_jb_get_last_read_len ( switch_jb_t jb)

Definition at line 1567 of file switch_jitterbuffer.c.

References switch_jb_s::last_len.

Referenced by read_rtp_packet().

1568 {
1569  return jb->last_len;
1570 }
switch_size_t last_len

◆ switch_jb_get_nack_success()

uint32_t switch_jb_get_nack_success ( switch_jb_t jb)

Definition at line 1224 of file switch_jitterbuffer.c.

References switch_jb_s::mutex, switch_jb_s::nack_didnt_save_the_day, switch_jb_s::nack_saved_the_day, switch_mutex_lock(), and switch_mutex_unlock().

Referenced by switch_rtp_destroy().

1225 {
1226  uint32_t nack_recovered; /*count*/
1227  switch_mutex_lock(jb->mutex);
1228  nack_recovered = jb->nack_saved_the_day + jb->nack_didnt_save_the_day;
1230  return nack_recovered;
1231 }
uint32_t nack_saved_the_day
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:313
switch_mutex_t * mutex
uint32_t nack_didnt_save_the_day
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:308

◆ switch_jb_get_packet()

switch_status_t switch_jb_get_packet ( switch_jb_t jb,
switch_rtp_packet_t packet,
switch_size_t len 
)

Definition at line 1572 of file switch_jitterbuffer.c.

References switch_jb_s::bitrate_control, switch_jb_stats_s::buffer_size_ms, CF_VIDEO_BITRATE_UNMANAGABLE, switch_jb_s::channel, check_jb_size(), check_seq(), check_ts(), switch_jb_s::complete_frames, switch_jb_s::consec_good_count, switch_jb_s::consec_miss_count, decrement_seq(), switch_jb_s::elastic, switch_jb_jitter_s::estimate, switch_jb_stats_s::estimate_ms, switch_jb_stats_s::expand, switch_jb_s::flush, switch_jb_s::frame_len, switch_core_session_message::from, switch_rtp_packet_t::header, hide_node(), switch_jb_s::highest_read_seq, switch_jb_s::highest_read_ts, jb_debug, jb_frame_inc, jb_next_packet(), switch_jb_s::jitter, switch_jb_s::last_len, switch_jb_s::last_psuedo_seq, switch_jb_s::last_target_seq, switch_jb_s::last_target_ts, switch_jb_node_s::len, switch_rtp_hdr_t::m, switch_jb_s::max_frame_len, switch_core_session_message::message_id, switch_jb_s::min_frame_len, switch_jb_s::mutex, switch_core_session_message::numeric_arg, switch_jb_node_s::packet, switch_jb_s::period_count, switch_jb_s::period_good_count, switch_jb_s::period_len, switch_jb_s::period_miss_count, switch_jb_s::period_miss_inc, switch_jb_s::period_miss_pct, switch_jb_s::read_init, switch_jb_stats_s::reset_error, switch_jb_jitter_s::samples_per_frame, switch_jb_s::samples_per_frame, switch_jb_jitter_s::samples_per_second, switch_rtp_hdr_t::seq, switch_jb_s::session, SJB_VIDEO, switch_jb_jitter_s::stats, switch_channel_clear_flag_recursive(), switch_channel_set_flag_recursive(), switch_channel_test_flag(), switch_core_session_receive_message, switch_core_session_request_video_refresh, switch_goto_status, switch_jb_poll(), switch_jb_reset(), SWITCH_LOG_INFO, SWITCH_MESSAGE_INDICATE_BITRATE_REQ, switch_mutex_lock(), switch_mutex_unlock(), SWITCH_STATUS_BREAK, SWITCH_STATUS_MORE_DATA, SWITCH_STATUS_NOTFOUND, SWITCH_STATUS_RESTART, SWITCH_STATUS_SUCCESS, SWITCH_STATUS_TIMEOUT, SWITCH_TRUE, switch_rtp_hdr_t::ts, switch_jb_s::type, switch_rtp_hdr_t::version, switch_jb_s::video_low_bitrate, and switch_jb_s::visible_nodes.

Referenced by read_rtp_packet(), and switch_ivr_delay_echo().

1573 {
1574  switch_jb_node_t *node = NULL;
1575  switch_status_t status;
1576  int plc = 0;
1577 
1578  switch_mutex_lock(jb->mutex);
1579 
1580  if (jb->complete_frames == 0) {
1581  jb->flush = 0;
1583  }
1584 
1585  if (jb->complete_frames < jb->frame_len) {
1586 
1587  switch_jb_poll(jb);
1588 
1589  if (!jb->flush) {
1590  jb_debug(jb, 2, "BUFFERING %u/%u\n", jb->complete_frames , jb->frame_len);
1592  }
1593  }
1594 
1595  jb_debug(jb, 2, "GET PACKET %u/%u n:%d\n", jb->complete_frames , jb->frame_len, jb->visible_nodes);
1596 
1597  if (++jb->period_count >= jb->period_len) {
1598 
1599  if (jb->consec_good_count >= (jb->period_len - 5)) {
1600  jb_frame_inc(jb, -1);
1601  }
1602 
1603  jb->period_count = 1;
1604  jb->period_miss_inc = 0;
1605  jb->period_miss_count = 0;
1606  jb->period_good_count = 0;
1607  jb->consec_miss_count = 0;
1608  jb->consec_good_count = 0;
1609 
1610  if (jb->type == SJB_VIDEO && jb->channel && jb->video_low_bitrate) {
1611  //switch_time_t now = switch_time_now();
1612  //int ok = (now - jb->last_bitrate_change) > 10000;
1613 
1615  jb_debug(jb, 2, "%s", "Allow BITRATE changes\n");
1617  jb->bitrate_control = 0;
1618  if (jb->session) {
1620  }
1622  switch_core_session_message_t msg = { 0 };
1623 
1625 
1627  msg.numeric_arg = jb->bitrate_control * 1024;
1628  msg.from = __FILE__;
1629 
1630  jb_debug(jb, 2, "Force BITRATE to %d\n", jb->bitrate_control);
1631 
1634  if (jb->session) {
1636  }
1637  }
1638  }
1639  }
1640 
1641 
1642  jb->period_miss_pct = ((double)jb->period_miss_count / jb->period_count) * 100;
1643 
1644  //if (jb->period_miss_pct > 60.0f) {
1645  // jb_debug(jb, 2, "Miss percent %02f too high, resetting buffer.\n", jb->period_miss_pct);
1646  // switch_jb_reset(jb);
1647  //}
1648 
1649  if ((status = jb_next_packet(jb, &node)) == SWITCH_STATUS_SUCCESS) {
1650  jb_debug(jb, 2, "Found next frame cur ts: %u seq: %u\n", htonl(node->packet.header.ts), htons(node->packet.header.seq));
1651 
1652  if (!jb->read_init || check_seq(node->packet.header.seq, jb->highest_read_seq)) {
1653  jb->highest_read_seq = node->packet.header.seq;
1654  }
1655 
1656  if (jb->type != SJB_VIDEO ||
1658 
1659  if (jb->type != SJB_VIDEO) {
1660  jb->complete_frames--;
1661  }
1662  jb_debug(jb, 2, "READ frame ts: %u complete=%u/%u n:%u\n", ntohl(node->packet.header.ts), jb->complete_frames , jb->frame_len, jb->visible_nodes);
1663  jb->highest_read_ts = node->packet.header.ts;
1664  } else if (!jb->read_init) {
1665  jb->highest_read_ts = node->packet.header.ts;
1666  }
1667 
1668  if (!jb->read_init) jb->read_init = 1;
1669  } else {
1670  if (jb->type == SJB_VIDEO) {
1671  //switch_jb_reset(jb);
1672 
1673  switch(status) {
1674  case SWITCH_STATUS_RESTART:
1675  jb_debug(jb, 2, "%s", "Error encountered ask for new keyframe\n");
1678  default:
1679  jb_debug(jb, 2, "%s", "No frames found wait for more\n");
1681  }
1682  } else {
1683  switch(status) {
1684  case SWITCH_STATUS_RESTART:
1685  jb_debug(jb, 2, "%s", "Error encountered\n");
1686  jb->jitter.stats.reset_error++;
1687  switch_jb_reset(jb);
1690  default:
1691  if (jb->consec_miss_count > jb->frame_len) {
1692  //switch_jb_reset(jb);
1693  jb_frame_inc(jb, 1);
1694  jb_debug(jb, 2, "%s", "Too many frames not found, RESIZE\n");
1696  } else {
1697  if (jb->elastic) {
1698  int visible_not_old = check_jb_size(jb);
1699 
1700  jb->jitter.stats.estimate_ms = (int)((*jb->jitter.estimate) / ((jb->jitter.samples_per_second)) * 1000);
1701  jb->jitter.stats.buffer_size_ms = (int)((visible_not_old * jb->jitter.samples_per_frame) / (jb->jitter.samples_per_second / 1000));
1702  /* When playing PLC, we take the oportunity to expand the buffer if the jitter buffer is smaller than the 3x the estimated jitter. */
1703  if (jb->jitter.stats.buffer_size_ms < (3 * jb->jitter.stats.estimate_ms)) {
1704  jb_debug(jb, SWITCH_LOG_INFO, "JITTER estimation %dms buffersize %d/%d %dms EXPAND [plc]\n",
1706  jb->jitter.stats.expand++;
1707  decrement_seq(jb);
1708  } else {
1709  jb_debug(jb, 2, "%s", "Frame not found suggest PLC\n");
1710  }
1711  } else {
1712  jb_debug(jb, 2, "%s", "Frame not found suggest PLC\n");
1713  }
1714 
1715  plc = 1;
1717  }
1718  }
1719  }
1720  }
1721 
1722  *packet = node->packet;
1723  *len = node->len;
1724  jb->last_len = *len;
1725  packet->header.version = 2;
1726  hide_node(node, SWITCH_TRUE);
1727 
1728  jb_debug(jb, 2, "GET packet ts:%u seq:%u %s\n", ntohl(packet->header.ts), ntohs(packet->header.seq), packet->header.m ? " <MARK>" : "");
1729 
1730  end:
1731 
1732  if (plc) {
1733  uint16_t seq;
1734  uint32_t ts = 0;
1735 
1736  if (jb->samples_per_frame) {
1737  seq = htons(jb->last_psuedo_seq);
1738  ts = jb->last_target_ts;
1739  } else {
1740  seq = jb->last_target_seq;
1741  }
1742 
1743  packet->header.seq = seq;
1744  packet->header.ts = ts;
1745  }
1746 
1748 
1749  if (jb->type == SJB_VIDEO) {
1750  if (jb->complete_frames > jb->max_frame_len * 2) {
1751  jb_debug(jb, 2, "JB TOO BIG (%d), RESET\n", jb->complete_frames);
1752  switch_jb_reset(jb);
1753  }
1754  } else {
1755  int too_big = (int)(jb->max_frame_len * 1.5);
1756  if (jb->visible_nodes > too_big && status == SWITCH_STATUS_SUCCESS) {
1757  status = SWITCH_STATUS_TIMEOUT;
1758  }
1759  }
1760 
1761  return status;
1762 }
switch_jb_type_t type
void switch_channel_set_flag_recursive(switch_channel_t *channel, switch_channel_flag_t flag)
switch_core_session_message_types_t message_id
Definition: switch_core.h:183
switch_jb_jitter_t jitter
uint32_t highest_read_seq
switch_channel_t * channel
uint32_t min_frame_len
uint32_t last_target_ts
switch_rtp_hdr_t header
Definition: switch_rtp.h:56
uint32_t highest_read_ts
switch_bool_t elastic
uint32_t complete_frames
#define jb_debug(_jb, _level, _format,...)
static void decrement_seq(switch_jb_t *jb)
#define jb_frame_inc(_jb, _i)
int switch_jb_poll(switch_jb_t *jb)
uint32_t switch_channel_test_flag(switch_channel_t *channel, switch_channel_flag_t flag)
Test for presence of given flag on a given channel.
uint32_t max_frame_len
A message object designed to allow unlike technologies to exchange data.
Definition: switch_core.h:179
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:313
uint32_t bitrate_control
static int check_seq(uint16_t a, uint16_t b)
switch_mutex_t * mutex
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:308
#define switch_core_session_request_video_refresh(_s)
Definition: switch_core.h:2881
switch_size_t last_len
uint32_t visible_nodes
uint32_t consec_miss_count
static int check_jb_size(switch_jb_t *jb)
#define switch_core_session_receive_message(_session, _message)
Definition: switch_core.h:1247
uint32_t video_low_bitrate
uint32_t period_miss_inc
uint32_t period_good_count
uint32_t period_miss_count
uint16_t last_psuedo_seq
switch_status_t
Common return values.
#define switch_goto_status(_status, _label)
Definition: switch_utils.h:287
switch_core_session_t * session
uint32_t last_target_seq
void switch_channel_clear_flag_recursive(switch_channel_t *channel, switch_channel_flag_t flag)
switch_jb_stats_t stats
switch_rtp_packet_t packet
static switch_status_t jb_next_packet(switch_jb_t *jb, switch_jb_node_t **nodep)
uint32_t samples_per_frame
static int check_ts(uint32_t a, uint32_t b)
static void hide_node(switch_jb_node_t *node, switch_bool_t pop)
void switch_jb_reset(switch_jb_t *jb)
uint32_t consec_good_count

◆ switch_jb_get_packet_by_seq()

switch_status_t switch_jb_get_packet_by_seq ( switch_jb_t jb,
uint16_t  seq,
switch_rtp_packet_t packet,
switch_size_t len 
)

Definition at line 1547 of file switch_jitterbuffer.c.

References switch_rtp_packet_t::header, jb_debug, switch_jb_node_s::len, switch_jb_s::mutex, switch_jb_s::node_hash, switch_jb_node_s::packet, switch_core_inthash_find(), switch_mutex_lock(), switch_mutex_unlock(), SWITCH_STATUS_NOTFOUND, SWITCH_STATUS_SUCCESS, and switch_rtp_hdr_t::version.

Referenced by handle_nack().

1548 {
1549  switch_jb_node_t *node;
1551 
1552  switch_mutex_lock(jb->mutex);
1553  if ((node = switch_core_inthash_find(jb->node_hash, seq))) {
1554  jb_debug(jb, 2, "Found buffered seq: %u\n", ntohs(seq));
1555  *packet = node->packet;
1556  *len = node->len;
1557  packet->header.version = 2;
1558  status = SWITCH_STATUS_SUCCESS;
1559  } else {
1560  jb_debug(jb, 2, "Missing buffered seq: %u\n", ntohs(seq));
1561  }
1563 
1564  return status;
1565 }
switch_inthash_t * node_hash
switch_rtp_hdr_t header
Definition: switch_rtp.h:56
#define jb_debug(_jb, _level, _format,...)
void * switch_core_inthash_find(switch_inthash_t *hash, uint32_t key)
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:313
switch_mutex_t * mutex
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:308
switch_status_t
Common return values.
switch_rtp_packet_t packet

◆ switch_jb_get_packets_per_frame()

uint32_t switch_jb_get_packets_per_frame ( switch_jb_t jb)

Definition at line 1233 of file switch_jitterbuffer.c.

References switch_jb_s::mutex, switch_jb_s::packet_count, switch_mutex_lock(), and switch_mutex_unlock().

1234 {
1235  uint32_t ppf;
1236  switch_mutex_lock(jb->mutex);
1237  ppf = jb->packet_count; /* get current packets per frame */
1239  return ppf;
1240 }
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:313
switch_mutex_t * mutex
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:308

◆ switch_jb_peek_frame()

switch_status_t switch_jb_peek_frame ( switch_jb_t jb,
uint32_t  ts,
uint16_t  seq,
int  peek,
switch_frame_t frame 
)

Definition at line 1242 of file switch_jitterbuffer.c.

References switch_rtp_packet_t::body, switch_frame::buflen, switch_frame::data, switch_frame::datalen, switch_rtp_packet_t::header, switch_jb_node_s::len, switch_frame::m, switch_rtp_hdr_t::m, switch_jb_s::node_hash, switch_jb_s::node_hash_ts, switch_jb_node_s::packet, switch_jb_s::samples_per_frame, switch_frame::seq, switch_rtp_hdr_t::seq, switch_core_inthash_find(), SWITCH_RTP_HEADER_LEN, SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, switch_frame::timestamp, and switch_rtp_hdr_t::ts.

Referenced by switch_core_media_read_frame().

1243 {
1244  switch_jb_node_t *node = NULL;
1245  if (seq) {
1246  uint16_t want_seq = seq + peek;
1247  node = switch_core_inthash_find(jb->node_hash, htons(want_seq));
1248  } else if (ts && jb->samples_per_frame) {
1249  uint32_t want_ts = ts + (peek * jb->samples_per_frame);
1250  node = switch_core_inthash_find(jb->node_hash_ts, htonl(want_ts));
1251  }
1252 
1253  if (node) {
1254  frame->seq = ntohs(node->packet.header.seq);
1255  frame->timestamp = ntohl(node->packet.header.ts);
1256  frame->m = node->packet.header.m;
1257  frame->datalen = node->len - SWITCH_RTP_HEADER_LEN;
1258 
1259  if (frame->data && frame->buflen > node->len - SWITCH_RTP_HEADER_LEN) {
1260  memcpy(frame->data, node->packet.body, node->len - SWITCH_RTP_HEADER_LEN);
1261  }
1262  return SWITCH_STATUS_SUCCESS;
1263  }
1264 
1265  return SWITCH_STATUS_FALSE;
1266 }
switch_bool_t m
Definition: switch_frame.h:83
switch_inthash_t * node_hash
switch_inthash_t * node_hash_ts
uint32_t timestamp
Definition: switch_frame.h:80
void * switch_core_inthash_find(switch_inthash_t *hash, uint32_t key)
uint16_t seq
Definition: switch_frame.h:81
uint32_t buflen
Definition: switch_frame.h:70
uint32_t datalen
Definition: switch_frame.h:68
#define SWITCH_RTP_HEADER_LEN
Definition: switch_rtp.h:44
uint32_t samples_per_frame

◆ switch_jb_poll()

int switch_jb_poll ( switch_jb_t jb)

Definition at line 1148 of file switch_jitterbuffer.c.

References switch_jb_s::buffer_lag, switch_jb_s::complete_frames, switch_jb_s::flush, switch_jb_s::frame_len, SJB_TEXT, and switch_jb_s::type.

Referenced by rtp_common_read(), and switch_jb_get_packet().

1149 {
1150  if (jb->type == SJB_TEXT) {
1151  if (jb->complete_frames < jb->frame_len) {
1152  if (jb->complete_frames && !jb->buffer_lag) {
1153  jb->buffer_lag = 10;
1154  }
1155  if (jb->buffer_lag && --jb->buffer_lag == 0) {
1156  jb->flush = 1;
1157  }
1158  }
1159  }
1160 
1161  return (jb->complete_frames >= jb->frame_len) || jb->flush;
1162 }
switch_jb_type_t type
uint32_t complete_frames

◆ switch_jb_pop_nack()

uint32_t switch_jb_pop_nack ( switch_jb_t jb)

Definition at line 1385 of file switch_jitterbuffer.c.

References switch_jb_s::frame_len, jb_debug, switch_jb_s::missing_seq_hash, switch_jb_s::mutex, RENACK_TIME, SJB_VIDEO, switch_core_hash_first_iter(), switch_core_hash_next(), switch_core_hash_this(), switch_core_inthash_delete(), switch_core_inthash_insert(), switch_mutex_lock(), switch_mutex_unlock(), switch_safe_free, switch_time_now(), switch_jb_s::target_seq, and switch_jb_s::type.

Referenced by check_rtcp_and_ice().

1386 {
1387  switch_hash_index_t *hi = NULL;
1388  uint32_t nack = 0;
1389  uint16_t blp = 0;
1390  uint16_t least = 0;
1391  int i = 0;
1392  void *val;
1393  const void *var;
1394 
1395  if (jb->type != SJB_VIDEO) {
1396  return 0;
1397  }
1398 
1399  switch_mutex_lock(jb->mutex);
1400 
1401  top:
1402 
1403  for (hi = switch_core_hash_first_iter(jb->missing_seq_hash, hi); hi; hi = switch_core_hash_next(&hi)) {
1404  uint16_t seq;
1405  //const char *token;
1406  switch_time_t then = 0;
1407 
1408  switch_core_hash_this(hi, &var, NULL, &val);
1409  //token = (const char *) val;
1410 
1411  //if (token == TOKEN_2) {
1412  //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "SKIP %u %s\n", ntohs(*((uint16_t *) var)), token);
1413  //printf("WTf\n");
1414  // continue;
1415  //}
1416 
1417  seq = ntohs(*((uint16_t *) var));
1418  then = (intptr_t) val;
1419 
1420  if (then != 1 && ((uint32_t)(switch_time_now() - then)) < RENACK_TIME) {
1421  jb_debug(jb, 3, "NACKABLE seq %u too soon to repeat\n", seq);
1422  continue;
1423  }
1424 
1425  //if (then != 1) {
1426  // jb_debug(jb, 3, "NACKABLE seq %u not too soon to repeat %lu\n", seq, switch_time_now() - then);
1427  //}
1428 
1429  if (seq < ntohs(jb->target_seq) - jb->frame_len) {
1430  jb_debug(jb, 3, "NACKABLE seq %u expired\n", seq);
1431  switch_core_inthash_delete(jb->missing_seq_hash, (uint32_t)htons(seq));
1432  goto top;
1433  }
1434 
1435  if (!least || seq < least) {
1436  least = seq;
1437  }
1438  }
1439 
1440  switch_safe_free(hi);
1441 
1442  if (least && switch_core_inthash_delete(jb->missing_seq_hash, (uint32_t)htons(least))) {
1443  jb_debug(jb, 3, "Found NACKABLE seq %u\n", least);
1444  nack = (uint32_t) htons(least);
1445  switch_core_inthash_insert(jb->missing_seq_hash, nack, (void *) (intptr_t)switch_time_now());
1446 
1447  for(i = 0; i < 16; i++) {
1448  if (switch_core_inthash_delete(jb->missing_seq_hash, (uint32_t)htons(least + i + 1))) {
1449  switch_core_inthash_insert(jb->missing_seq_hash, (uint32_t)htons(least + i + 1), (void *)(intptr_t)switch_time_now());
1450  jb_debug(jb, 3, "Found addtl NACKABLE seq %u\n", least + i + 1);
1451  blp |= (1 << i);
1452  }
1453  }
1454 
1455  blp = htons(blp);
1456  nack |= (uint32_t) blp << 16;
1457 
1458  //jb_frame_inc(jb, 1);
1459  }
1460 
1462 
1463 
1464  return nack;
1465 }
switch_jb_type_t type
switch_inthash_t * missing_seq_hash
#define jb_debug(_jb, _level, _format,...)
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:313
int64_t switch_time_t
Definition: switch_apr.h:188
switch_mutex_t * mutex
void * switch_core_inthash_delete(switch_inthash_t *hash, uint32_t key)
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:308
switch_status_t switch_core_inthash_insert(switch_inthash_t *hash, uint32_t key, const void *data)
#define switch_safe_free(it)
Free a pointer and set it to NULL unless it already is NULL.
Definition: switch_utils.h:885
#define RENACK_TIME
void switch_core_hash_this(_In_ switch_hash_index_t *hi, _Out_opt_ptrdiff_cap_(klen) const void **key, _Out_opt_ switch_ssize_t *klen, _Out_ void **val)
Gets the key and value of the current hash element.
switch_hash_index_t * switch_core_hash_next(_In_ switch_hash_index_t **hi)
Gets the next element of a hashtable.
switch_time_t switch_time_now(void)
Definition: switch_apr.c:325
switch_hash_index_t * switch_core_hash_first_iter(_In_ switch_hash_t *hash, switch_hash_index_t *hi)
Gets the first element of a hashtable.

◆ switch_jb_put_packet()

switch_status_t switch_jb_put_packet ( switch_jb_t jb,
switch_rtp_packet_t packet,
switch_size_t  len 
)

Definition at line 1467 of file switch_jitterbuffer.c.

References add_node(), switch_jb_s::allocated_nodes, drop_oldest_frame(), switch_jb_s::frame_len, switch_rtp_packet_t::header, switch_jb_s::highest_dropped_ts, jb_debug, jb_frame_inc, switch_jb_s::jitter, switch_jb_s::max_frame_len, switch_jb_s::max_packet_len, switch_jb_s::missing_seq_hash, switch_jb_s::mutex, switch_jb_s::nack_didnt_save_the_day, switch_jb_s::nack_saved_the_day, switch_jb_s::next_seq, switch_jb_stats_s::reset_missing_frames, switch_rtp_hdr_t::seq, SJB_AUDIO, SJB_QUEUE_ONLY, SJB_TEXT, SJB_VIDEO, switch_jb_jitter_s::stats, SWITCH_CHANNEL_LOG, switch_core_inthash_delete(), switch_core_inthash_insert(), switch_jb_reset(), switch_log_printf(), SWITCH_LOG_WARNING, switch_mutex_lock(), switch_mutex_unlock(), SWITCH_RTP_MAX_PACKET_LEN, SWITCH_SIZE_T_FMT, SWITCH_STATUS_SUCCESS, switch_test_flag, switch_jb_s::target_seq, switch_rtp_hdr_t::ts, switch_jb_s::type, and switch_jb_s::visible_nodes.

Referenced by read_bundle_rtp_packet(), read_rtp_packet(), rtp_common_write(), and switch_ivr_delay_echo().

1468 {
1469  uint32_t i;
1470  uint16_t want = ntohs(jb->next_seq), got = ntohs(packet->header.seq);
1471 
1472  if (len >= SWITCH_RTP_MAX_PACKET_LEN) {
1473  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "trying to put %" SWITCH_SIZE_T_FMT " bytes exceeding buffer, truncate to %" SWITCH_SIZE_T_FMT "\n", len, SWITCH_RTP_MAX_PACKET_LEN);
1475  }
1476 
1477  switch_mutex_lock(jb->mutex);
1478 
1479  if (jb->highest_dropped_ts) {
1480  if (ntohl(packet->header.ts) < jb->highest_dropped_ts) {
1481  jb_debug(jb, 2, "%s", "TS ALREADY DROPPED, DROPPING PACKET\n");
1483  return SWITCH_STATUS_SUCCESS;
1484  }
1485  jb->highest_dropped_ts = 0;
1486  }
1487 
1488 
1489  if (!want) want = got;
1490 
1491  if (switch_test_flag(jb, SJB_QUEUE_ONLY) || jb->type == SJB_AUDIO || jb->type == SJB_TEXT) {
1492  jb->next_seq = htons(got + 1);
1493  } else {
1494 
1495  if (switch_core_inthash_delete(jb->missing_seq_hash, (uint32_t)htons(got))) {
1496  if (got < ntohs(jb->target_seq)) {
1497  jb_debug(jb, 2, "got nacked seq %u too late\n", got);
1498  jb_frame_inc(jb, 1);
1500  } else {
1501  jb_debug(jb, 2, "got nacked %u saved the day!\n", got);
1502  jb->nack_saved_the_day++;
1503  }
1504  }
1505 
1506  if (got > want) {
1507  if (got - want > jb->max_frame_len && got - want > 17) {
1508  jb_debug(jb, 2, "Missing %u frames, Resetting\n", got - want);
1510  switch_jb_reset(jb);
1511  } else {
1512  if (jb->type != SJB_VIDEO && jb->frame_len < got - want) {
1513  jb_frame_inc(jb, 1);
1514  }
1515 
1516  jb_debug(jb, 2, "GOT %u WANTED %u; MARK SEQS MISSING %u - %u\n", got, want, want, got - 1);
1517 
1518  for (i = want; i < got; i++) {
1519  jb_debug(jb, 2, "MARK MISSING %u ts:%u\n", i, ntohl(packet->header.ts));
1520  switch_core_inthash_insert(jb->missing_seq_hash, (uint32_t)htons(i), (void *)(intptr_t)1);
1521  }
1522  }
1523  }
1524 
1525  if (got >= want || (want - got) > 1000) {
1526  jb->next_seq = htons(got + 1);
1527  }
1528  }
1529 
1530  add_node(jb, packet, len);
1531 
1532  if (switch_test_flag(jb, SJB_QUEUE_ONLY) && jb->max_packet_len && jb->max_frame_len * 2 > jb->max_packet_len &&
1533  jb->allocated_nodes > jb->max_frame_len * 2 - 1) {
1534  while ((jb->max_frame_len * 2 - jb->visible_nodes) < jb->max_packet_len) {
1535  drop_oldest_frame(jb);
1536  }
1537  } else if (switch_test_flag(jb, SJB_QUEUE_ONLY) && jb->max_packet_len && jb->max_frame_len * 2 < jb->max_packet_len) {
1538  /* rtp_nack_buffer_size less than initial max_packet_len */
1539  drop_oldest_frame(jb);
1540  }
1541 
1543 
1544  return SWITCH_STATUS_SUCCESS;
1545 }
switch_jb_type_t type
#define SWITCH_CHANNEL_LOG
switch_jb_jitter_t jitter
switch_rtp_hdr_t header
Definition: switch_rtp.h:56
switch_inthash_t * missing_seq_hash
uint32_t nack_saved_the_day
#define jb_debug(_jb, _level, _format,...)
#define jb_frame_inc(_jb, _i)
uint32_t highest_dropped_ts
uint32_t max_frame_len
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:313
static void drop_oldest_frame(switch_jb_t *jb)
uint32_t max_packet_len
static void add_node(switch_jb_t *jb, switch_rtp_packet_t *packet, switch_size_t len)
switch_mutex_t * mutex
void * switch_core_inthash_delete(switch_inthash_t *hash, uint32_t key)
uint32_t nack_didnt_save_the_day
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:308
switch_status_t switch_core_inthash_insert(switch_inthash_t *hash, uint32_t key, const void *data)
uint32_t visible_nodes
#define SWITCH_SIZE_T_FMT
uint32_t allocated_nodes
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:693
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
switch_jb_stats_t stats
#define SWITCH_RTP_MAX_PACKET_LEN
Definition: switch_rtp.h:48
void switch_jb_reset(switch_jb_t *jb)

◆ switch_jb_reset()

void switch_jb_reset ( switch_jb_t jb)

Definition at line 1174 of file switch_jitterbuffer.c.

References switch_jb_s::channel, switch_jb_s::complete_frames, switch_jb_s::consec_good_count, switch_jb_s::consec_miss_count, switch_jb_s::drop_flag, hide_nodes(), switch_jb_s::highest_read_seq, switch_jb_s::highest_read_ts, switch_jb_s::highest_wrote_seq, switch_jb_s::highest_wrote_ts, jb_debug, switch_jb_s::jitter, switch_jb_s::last_target_seq, switch_jb_s::last_target_ts, switch_jb_s::missing_seq_hash, switch_jb_s::mutex, switch_jb_s::next_seq, switch_jb_s::period_count, switch_jb_s::period_good_count, switch_jb_s::period_miss_count, switch_jb_s::period_miss_inc, switch_jb_s::period_miss_pct, switch_jb_s::read_init, switch_jb_stats_s::reset, switch_jb_stats_s::reset_error, switch_jb_stats_s::reset_missing_frames, switch_jb_stats_s::reset_too_big, switch_jb_stats_s::reset_ts_jump, switch_jb_s::session, SJB_VIDEO, switch_jb_jitter_s::stats, switch_channel_set_variable_printf(), switch_core_inthash_destroy(), switch_core_inthash_init(), switch_core_session_request_video_refresh, switch_mutex_lock(), switch_mutex_unlock(), switch_jb_s::target_seq, switch_jb_s::target_ts, switch_jb_s::type, and switch_jb_s::write_init.

Referenced by add_node(), do_flush(), handle_rfc2833(), new_node(), read_rtp_packet(), switch_jb_get_packet(), switch_jb_put_packet(), switch_rtp_del_dtls(), switch_rtp_pause_jitter_buffer(), switch_rtp_reset_jb(), switch_rtp_reset_vb(), and switch_rtp_set_flag().

1175 {
1176  jb->jitter.stats.reset++;
1177  if (jb->channel) {
1178  switch_channel_set_variable_printf(jb->channel, "rtp_jb_reset_count", "%u", jb->jitter.stats.reset);
1179  switch_channel_set_variable_printf(jb->channel, "rtp_jb_reset_too_big", "%u", jb->jitter.stats.reset_too_big);
1180  switch_channel_set_variable_printf(jb->channel, "rtp_jb_reset_missing_frames", "%u", jb->jitter.stats.reset_missing_frames);
1181  switch_channel_set_variable_printf(jb->channel, "rtp_jb_reset_ts_jump", "%u", jb->jitter.stats.reset_ts_jump);
1182  switch_channel_set_variable_printf(jb->channel, "rtp_jb_reset_error", "%u", jb->jitter.stats.reset_error);
1183  }
1184 
1185  if (jb->type == SJB_VIDEO) {
1186  switch_mutex_lock(jb->mutex);
1190 
1191  if (jb->session) {
1193  }
1194  }
1195 
1196  jb_debug(jb, 2, "%s", "RESET BUFFER\n");
1197 
1198  switch_mutex_lock(jb->mutex);
1199  hide_nodes(jb);
1201 
1202  jb->drop_flag = 0;
1203  jb->last_target_seq = 0;
1204  jb->target_seq = 0;
1205  jb->write_init = 0;
1206  jb->highest_wrote_seq = 0;
1207  jb->highest_wrote_ts = 0;
1208  jb->next_seq = 0;
1209  jb->highest_read_ts = 0;
1210  jb->highest_read_seq = 0;
1211  jb->read_init = 0;
1212  jb->complete_frames = 0;
1213  jb->period_miss_count = 0;
1214  jb->consec_miss_count = 0;
1215  jb->period_miss_pct = 0;
1216  jb->period_good_count = 0;
1217  jb->consec_good_count = 0;
1218  jb->period_count = 0;
1219  jb->period_miss_inc = 0;
1220  jb->target_ts = 0;
1221  jb->last_target_ts = 0;
1222 }
switch_status_t switch_channel_set_variable_printf(switch_channel_t *channel, const char *varname, const char *fmt,...)
uint32_t highest_wrote_ts
switch_jb_type_t type
switch_status_t switch_core_inthash_init(switch_inthash_t **hash)
switch_jb_jitter_t jitter
uint32_t highest_read_seq
switch_channel_t * channel
uint32_t last_target_ts
switch_inthash_t * missing_seq_hash
static void hide_nodes(switch_jb_t *jb)
uint32_t highest_read_ts
uint32_t complete_frames
#define jb_debug(_jb, _level, _format,...)
uint16_t highest_wrote_seq
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:313
switch_status_t switch_core_inthash_destroy(switch_inthash_t **hash)
switch_mutex_t * mutex
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:308
#define switch_core_session_request_video_refresh(_s)
Definition: switch_core.h:2881
uint32_t consec_miss_count
uint32_t period_miss_inc
uint32_t period_good_count
uint32_t period_miss_count
switch_core_session_t * session
uint32_t last_target_seq
switch_jb_stats_t stats
uint32_t consec_good_count

◆ switch_jb_set_flag()

void switch_jb_set_flag ( switch_jb_t jb,
switch_jb_flag_t  flag 
)

Definition at line 1138 of file switch_jitterbuffer.c.

References switch_set_flag.

Referenced by rtp_common_write().

1139 {
1140  switch_set_flag(jb, flag);
1141 }
#define switch_set_flag(obj, flag)
Set a flag on an arbitrary object.
Definition: switch_utils.h:700

◆ switch_jb_set_frames()

switch_status_t switch_jb_set_frames ( switch_jb_t jb,
uint32_t  min_frame_len,
uint32_t  max_frame_len 
)

Definition at line 1290 of file switch_jitterbuffer.c.

References switch_jb_s::frame_len, switch_jb_s::highest_frame_len, switch_jb_s::max_frame_len, switch_jb_s::min_frame_len, switch_jb_s::mutex, switch_mutex_lock(), switch_mutex_unlock(), and SWITCH_STATUS_SUCCESS.

Referenced by switch_rtp_activate_jitter_buffer(), and switch_rtp_set_video_buffer_size().

1291 {
1292  int lowest = 0;
1293 
1294  switch_mutex_lock(jb->mutex);
1295 
1296  if (jb->frame_len == jb->min_frame_len) lowest = 1;
1297 
1298  jb->min_frame_len = min_frame_len;
1299  jb->max_frame_len = max_frame_len;
1300 
1301  if (jb->frame_len > jb->max_frame_len) {
1302  jb->frame_len = jb->max_frame_len;
1303  }
1304 
1305  if (jb->frame_len < jb->min_frame_len) {
1306  jb->frame_len = jb->min_frame_len;
1307  }
1308 
1309  if (jb->frame_len > jb->highest_frame_len) {
1310  jb->highest_frame_len = jb->frame_len;
1311  }
1312 
1313  if (lowest) {
1314  jb->frame_len = jb->min_frame_len;
1315  }
1316 
1318 
1319  return SWITCH_STATUS_SUCCESS;
1320 }
uint32_t min_frame_len
uint32_t max_frame_len
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:313
switch_mutex_t * mutex
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:308
uint32_t highest_frame_len

◆ switch_jb_set_jitter_estimator()

void switch_jb_set_jitter_estimator ( switch_jb_t jb,
double *  jitter,
uint32_t  samples_per_frame,
uint32_t  samples_per_second 
)

Definition at line 1079 of file switch_jitterbuffer.c.

References switch_jb_s::channel, switch_jb_jitter_s::drop_gap, switch_jb_jitter_s::estimate, switch_jb_s::jitter, memset(), switch_jb_jitter_s::samples_per_frame, switch_jb_jitter_s::samples_per_second, and switch_channel_set_variable_printf().

Referenced by switch_rtp_activate_jitter_buffer().

1080 {
1081  if (jb && jitter) {
1082  memset(&jb->jitter, 0, sizeof(switch_jb_jitter_t));
1083  if (jb->channel) {
1084  switch_channel_set_variable_printf(jb->channel, "rtp_jb_max_ms", "%u", 0);
1085  switch_channel_set_variable_printf(jb->channel, "rtp_jb_size_ms", "%u", 0);
1086  switch_channel_set_variable_printf(jb->channel, "rtp_jb_acceleration_ms", "%u", 0);
1087  switch_channel_set_variable_printf(jb->channel, "rtp_jb_expand_ms", "%u", 0);
1088  switch_channel_set_variable_printf(jb->channel, "rtp_jb_jitter_max_ms", "%u", 0);
1089  switch_channel_set_variable_printf(jb->channel, "rtp_jb_jitter_ms", "%u", 0);
1090  switch_channel_set_variable_printf(jb->channel, "rtp_jb_reset_count", "%u", 0);
1091  switch_channel_set_variable_printf(jb->channel, "rtp_jb_reset_too_big", "%u", 0);
1092  switch_channel_set_variable_printf(jb->channel, "rtp_jb_reset_missing_frames", "%u", 0);
1093  switch_channel_set_variable_printf(jb->channel, "rtp_jb_reset_ts_jump", "%u", 0);
1094  switch_channel_set_variable_printf(jb->channel, "rtp_jb_reset_error", "%u", 0);
1095  }
1096 
1097  jb->jitter.estimate = jitter;
1098  jb->jitter.samples_per_frame = samples_per_frame;
1099  jb->jitter.samples_per_second = samples_per_second;
1100  jb->jitter.drop_gap = 5;
1101  }
1102 }
switch_status_t switch_channel_set_variable_printf(switch_channel_t *channel, const char *varname, const char *fmt,...)
switch_jb_jitter_t jitter
switch_channel_t * channel
memset(buf, 0, buflen)

◆ switch_jb_set_session()

void switch_jb_set_session ( switch_jb_t jb,
switch_core_session_t session 
)

Definition at line 1104 of file switch_jitterbuffer.c.

References switch_jb_s::channel, switch_jb_s::codec, switch_jb_s::elastic, switch_codec_implementation::iananame, switch_codec::implementation, switch_jb_s::session, SJB_AUDIO, SJB_QUEUE_ONLY, SJB_VIDEO, switch_channel_get_variable_dup(), SWITCH_CHANNEL_SESSION_LOG, switch_channel_var_true(), switch_core_session_get_channel(), switch_core_session_get_read_codec(), SWITCH_FALSE, SWITCH_LOG_DEBUG, SWITCH_LOG_DEBUG1, switch_log_printf(), switch_test_flag, SWITCH_TRUE, switch_jb_s::type, and switch_jb_s::video_low_bitrate.

Referenced by switch_rtp_activate_jitter_buffer(), and switch_rtp_set_video_buffer_size().

1105 {
1106  const char *var;
1107 
1108  if (session) {
1110  jb->session = session;
1112  if (jb->type == SJB_AUDIO) {
1113  if (!strcmp(jb->codec->implementation->iananame, "opus")) {
1114  if (switch_channel_var_true(jb->channel, "rtp_jitter_buffer_accelerate")) {
1115  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "audio codec is %s, accelerate on\n", jb->codec->implementation->iananame);
1116  jb->elastic = SWITCH_TRUE;
1117  } else {
1118  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "audio codec is %s, accelerate off\n", jb->codec->implementation->iananame);
1119  jb->elastic = SWITCH_FALSE;
1120  }
1121  } else {
1122  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "audio codec is not Opus: %s\n", jb->codec->implementation->iananame);
1123  jb->elastic = SWITCH_FALSE;
1124  }
1125  }
1126 
1127  if (jb->type == SJB_VIDEO && !switch_test_flag(jb, SJB_QUEUE_ONLY) &&
1128  (var = switch_channel_get_variable_dup(jb->channel, "jb_video_low_bitrate", SWITCH_FALSE, -1))) {
1129  int tmp = atoi(var);
1130 
1131  if (tmp >= 128 && tmp <= 10240) {
1132  jb->video_low_bitrate = (uint32_t)tmp;
1133  }
1134  }
1135  }
1136 }
switch_jb_type_t type
#define SWITCH_CHANNEL_SESSION_LOG(x)
switch_channel_t * channel
switch_bool_t elastic
const char * switch_channel_get_variable_dup(switch_channel_t *channel, const char *varname, switch_bool_t dup, int idx)
Retrieve a variable from a given channel.
switch_codec_t * switch_core_session_get_read_codec(_In_ switch_core_session_t *session)
Retrieve the read codec from a given session.
_Ret_ switch_channel_t * switch_core_session_get_channel(_In_ switch_core_session_t *session)
Retrieve a pointer to the channel object associated with a given session.
const switch_codec_implementation_t * implementation
switch_core_session_t * session
static int switch_channel_var_true(switch_channel_t *channel, const char *variable)
uint32_t video_low_bitrate
switch_core_session_t * session
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:693
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
switch_codec_t * codec

◆ switch_jb_ts_mode()

void switch_jb_ts_mode ( switch_jb_t jb,
uint32_t  samples_per_frame,
uint32_t  samples_per_second 
)

Definition at line 1072 of file switch_jitterbuffer.c.

References switch_jb_s::node_hash_ts, switch_jb_s::samples_per_frame, switch_jb_s::samples_per_second, and switch_core_inthash_init().

Referenced by switch_rtp_activate_jitter_buffer().

1073 {
1074  jb->samples_per_frame = samples_per_frame;
1075  jb->samples_per_second = samples_per_second;
1077 }
switch_status_t switch_core_inthash_init(switch_inthash_t **hash)
switch_inthash_t * node_hash_ts
uint32_t samples_per_second
uint32_t samples_per_frame