FreeSWITCH API Documentation  1.7.0
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 }
 

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

Enumeration Type Documentation

Enumerator
SJB_QUEUE_ONLY 

Definition at line 36 of file switch_jitterbuffer.h.

36  {
37  SJB_QUEUE_ONLY = (1 << 0)
switch_jb_flag_t
Enumerator
SJB_VIDEO 
SJB_AUDIO 

Definition at line 40 of file switch_jitterbuffer.h.

Function Documentation

void switch_jb_clear_flag ( switch_jb_t jb,
switch_jb_flag_t  flag 
)

Definition at line 826 of file switch_jitterbuffer.c.

References switch_clear_flag.

827 {
828  switch_clear_flag(jb, flag);
829 }
#define switch_clear_flag(obj, flag)
Clear a flag on an arbitrary object while locked.
Definition: switch_utils.h:655
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 970 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, 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().

972 {
973  switch_jb_t *jb;
974  int free_pool = 0;
975 
976  if (!pool) {
978  free_pool = 1;
979  }
980 
981  jb = switch_core_alloc(pool, sizeof(*jb));
982  jb->free_pool = free_pool;
983  jb->min_frame_len = jb->frame_len = min_frame_len;
984  jb->max_frame_len = max_frame_len;
985  jb->pool = pool;
986  jb->type = type;
987  jb->highest_frame_len = jb->frame_len;
988 
989  if (jb->type == SJB_VIDEO) {
991  }
995 
996  *jbp = jb;
997 
998  return SWITCH_STATUS_SUCCESS;
999 }
switch_jb_type_t type
#define switch_core_new_memory_pool(p)
Create a new sub memory pool from the core's master pool.
Definition: switch_core.h:631
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:682
switch_status_t switch_mutex_init(switch_mutex_t **lock, unsigned int flags, switch_memory_pool_t *pool)
Definition: switch_apr.c:270
switch_mutex_t * list_mutex
uint32_t highest_frame_len
switch_memory_pool_t * pool
void switch_jb_debug_level ( switch_jb_t jb,
uint8_t  level 
)

Definition at line 841 of file switch_jitterbuffer.c.

Referenced by switch_ivr_delay_echo(), and switch_rtp_debug_jitter_buffer().

842 {
843  jb->debug_level = level;
844 }
switch_status_t switch_jb_destroy ( switch_jb_t **  jbp)

Definition at line 1001 of file switch_jitterbuffer.c.

References free_nodes(), switch_jb_s::free_pool, switch_jb_s::missing_seq_hash, switch_jb_s::node_hash, switch_jb_s::node_hash_ts, switch_jb_s::pool, SJB_VIDEO, switch_core_destroy_memory_pool, switch_core_inthash_destroy(), SWITCH_STATUS_SUCCESS, and switch_jb_s::type.

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

1002 {
1003  switch_jb_t *jb = *jbp;
1004  *jbp = NULL;
1005 
1006  if (jb->type == SJB_VIDEO) {
1008  }
1010 
1011  if (jb->node_hash_ts) {
1013  }
1014 
1015  free_nodes(jb);
1016 
1017  if (jb->free_pool) {
1019  }
1020 
1021  return SWITCH_STATUS_SUCCESS;
1022 }
switch_jb_type_t type
switch_inthash_t * node_hash
switch_inthash_t * node_hash_ts
switch_inthash_t * missing_seq_hash
#define switch_core_destroy_memory_pool(p)
Returns a subpool back to the main pool.
Definition: switch_core.h:640
switch_status_t switch_core_inthash_destroy(switch_inthash_t **hash)
static void free_nodes(switch_jb_t *jb)
switch_memory_pool_t * pool
int switch_jb_frame_count ( switch_jb_t jb)

Definition at line 836 of file switch_jitterbuffer.c.

837 {
838  return jb->complete_frames;
839 }
uint32_t complete_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 916 of file switch_jitterbuffer.c.

References switch_mutex_lock(), switch_mutex_unlock(), and SWITCH_STATUS_SUCCESS.

Referenced by switch_rtp_get_stats(), and switch_rtp_get_video_buffer_size().

917 {
918 
920 
921  if (min_frame_len) {
922  *min_frame_len = jb->min_frame_len;
923  }
924 
925  if (max_frame_len) {
926  *max_frame_len = jb->max_frame_len;
927  }
928 
929  if (cur_frame_len) {
930  *cur_frame_len = jb->frame_len;
931  }
932 
934 
935  return SWITCH_STATUS_SUCCESS;
936 }
uint32_t min_frame_len
uint32_t max_frame_len
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:290
switch_mutex_t * mutex
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:285
switch_size_t switch_jb_get_last_read_len ( switch_jb_t jb)

Definition at line 1189 of file switch_jitterbuffer.c.

Referenced by read_rtp_packet().

1190 {
1191  return jb->last_len;
1192 }
switch_size_t last_len
switch_status_t switch_jb_get_packet ( switch_jb_t jb,
switch_rtp_packet_t packet,
switch_size_t len 
)

Definition at line 1195 of file switch_jitterbuffer.c.

References switch_rtp_packet_t::body, CF_VIDEO_BITRATE_UNMANAGABLE, switch_core_session_message::from, switch_rtp_packet_t::header, hide_node(), jb_debug, jb_frame_inc, jb_next_packet(), switch_jb_node_s::len, switch_core_session_message::message_id, switch_core_session_message::numeric_arg, switch_jb_node_s::packet, PERIOD_LEN, switch_rtp_hdr_t::seq, SJB_VIDEO, switch_channel_clear_flag(), switch_channel_set_flag, switch_channel_test_flag(), switch_core_session_receive_message, switch_core_session_request_video_refresh(), switch_goto_status, switch_jb_reset(), 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_TRUE, thin_frames(), and switch_rtp_hdr_t::ts.

Referenced by read_rtp_packet(), and switch_ivr_delay_echo().

1196 {
1197  switch_jb_node_t *node = NULL;
1198  switch_status_t status;
1199  int plc = 0;
1200 
1201  switch_mutex_lock(jb->mutex);
1202 
1203  if (jb->complete_frames == 0) {
1205  }
1206 
1207  if (jb->complete_frames < jb->frame_len) {
1208  jb_debug(jb, 2, "BUFFERING %u/%u\n", jb->complete_frames , jb->frame_len);
1210  }
1211 
1212  jb_debug(jb, 2, "GET PACKET %u/%u n:%d\n", jb->complete_frames , jb->frame_len, jb->visible_nodes);
1213 
1214  if (++jb->period_count >= PERIOD_LEN) {
1215 
1216  if (jb->consec_good_count >= (PERIOD_LEN - 5)) {
1217  jb_frame_inc(jb, -1);
1218  }
1219 
1220  jb->period_count = 1;
1221  jb->period_miss_inc = 0;
1222  jb->period_miss_count = 0;
1223  jb->period_good_count = 0;
1224  jb->consec_miss_count = 0;
1225  jb->consec_good_count = 0;
1226 
1227  if (jb->type == SJB_VIDEO && jb->channel && jb->video_low_bitrate) {
1228  //switch_time_t now = switch_time_now();
1229  //int ok = (now - jb->last_bitrate_change) > 10000;
1230 
1232  jb_debug(jb, 2, "%s", "Allow BITRATE changes\n");
1234  jb->bitrate_control = 0;
1235  if (jb->session) {
1237  }
1239  switch_core_session_message_t msg = { 0 };
1240 
1242 
1244  msg.numeric_arg = jb->bitrate_control * 1024;
1245  msg.from = __FILE__;
1246 
1247  jb_debug(jb, 2, "Force BITRATE to %d\n", jb->bitrate_control);
1250  if (jb->session) {
1252  }
1253  }
1254  }
1255 
1256  }
1257 
1258  jb->period_miss_pct = ((double)jb->period_miss_count / jb->period_count) * 100;
1259 
1260  if (jb->period_miss_pct > 60.0f) {
1261  jb_debug(jb, 2, "Miss percent %02f too high, resetting buffer.\n", jb->period_miss_pct);
1262  switch_jb_reset(jb);
1263  }
1264 
1265  if ((status = jb_next_packet(jb, &node)) == SWITCH_STATUS_SUCCESS) {
1266  jb_debug(jb, 2, "Found next frame cur ts: %u seq: %u\n", htonl(node->packet.header.ts), htons(node->packet.header.seq));
1267 
1268  if (!jb->read_init || ntohs(node->packet.header.seq) > ntohs(jb->highest_read_seq) ||
1269  (ntohs(jb->highest_read_seq) > USHRT_MAX - 10 && ntohs(node->packet.header.seq) <= 10) ) {
1270  jb->highest_read_seq = node->packet.header.seq;
1271  }
1272 
1273  if (jb->read_init && htons(node->packet.header.seq) >= htons(jb->highest_read_seq) && (ntohl(node->packet.header.ts) > ntohl(jb->highest_read_ts))) {
1274  jb->complete_frames--;
1275  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);
1276  jb->highest_read_ts = node->packet.header.ts;
1277  } else if (!jb->read_init) {
1278  jb->highest_read_ts = node->packet.header.ts;
1279  }
1280 
1281  if (!jb->read_init) jb->read_init = 1;
1282  } else {
1283  if (jb->type == SJB_VIDEO) {
1284  switch_jb_reset(jb);
1285 
1286  switch(status) {
1287  case SWITCH_STATUS_RESTART:
1288  jb_debug(jb, 2, "%s", "Error encountered ask for new keyframe\n");
1291  default:
1292  jb_debug(jb, 2, "%s", "No frames found wait for more\n");
1294  }
1295  } else {
1296  switch(status) {
1297  case SWITCH_STATUS_RESTART:
1298  jb_debug(jb, 2, "%s", "Error encountered\n");
1299  switch_jb_reset(jb);
1302  default:
1303  if (jb->consec_miss_count > jb->frame_len) {
1304  switch_jb_reset(jb);
1305  jb_frame_inc(jb, 1);
1306  jb_debug(jb, 2, "%s", "Too many frames not found, RESIZE\n");
1308  } else {
1309  jb_debug(jb, 2, "%s", "Frame not found suggest PLC\n");
1310  plc = 1;
1312  }
1313  }
1314  }
1315  }
1316 
1317  if (node) {
1318  status = SWITCH_STATUS_SUCCESS;
1319 
1320  *packet = node->packet;
1321  *len = node->len;
1322  jb->last_len = *len;
1323  memcpy(packet->body, node->packet.body, node->len);
1324  hide_node(node, SWITCH_TRUE);
1325 
1326  jb_debug(jb, 1, "GET packet ts:%u seq:%u %s\n", ntohl(packet->header.ts), ntohs(packet->header.seq), packet->header.m ? " <MARK>" : "");
1327 
1328  } else {
1329  status = SWITCH_STATUS_MORE_DATA;
1330  }
1331 
1332  end:
1333 
1334  if (plc) {
1335  uint16_t seq;
1336  uint32_t ts = 0;
1337 
1338  if (jb->samples_per_frame) {
1339  seq = htons(jb->last_psuedo_seq);
1340  ts = jb->last_target_ts;
1341  } else {
1342  seq = jb->last_target_seq;
1343  }
1344 
1345  packet->header.seq = seq;
1346  packet->header.ts = ts;
1347  }
1348 
1350 
1351  if (jb->complete_frames > jb->max_frame_len) {
1352  thin_frames(jb, 8, 25);
1353  }
1354 
1355  return status;
1356 }
switch_jb_type_t type
switch_core_session_message_types_t message_id
Definition: switch_core.h:181
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:53
uint32_t highest_read_ts
uint32_t complete_frames
#define jb_debug(_jb, _level, _format,...)
#define jb_frame_inc(_jb, _i)
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:177
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:290
uint32_t bitrate_control
switch_mutex_t * mutex
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:285
switch_size_t last_len
uint32_t visible_nodes
uint32_t consec_miss_count
uint32_t period_count
static void thin_frames(switch_jb_t *jb, int freq, int max)
#define switch_core_session_receive_message(_session, _message)
Definition: switch_core.h:1217
uint32_t video_low_bitrate
uint32_t period_miss_inc
uint32_t period_good_count
uint32_t period_miss_count
switch_status_t switch_core_session_request_video_refresh(switch_core_session_t *session)
uint16_t last_psuedo_seq
switch_status_t
Common return values.
#define switch_goto_status(_status, _label)
Definition: switch_utils.h:256
char body[SWITCH_RTP_MAX_BUF_LEN+4+sizeof(char *)]
Definition: switch_rtp.h:54
#define switch_channel_set_flag(_c, _f)
switch_core_session_t * session
uint32_t last_target_seq
#define PERIOD_LEN
switch_rtp_packet_t packet
void switch_channel_clear_flag(switch_channel_t *channel, switch_channel_flag_t flag)
Clear given flag(s) from a channel.
static switch_status_t jb_next_packet(switch_jb_t *jb, switch_jb_node_t **nodep)
uint32_t samples_per_frame
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_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 1169 of file switch_jitterbuffer.c.

References switch_rtp_packet_t::body, jb_debug, switch_jb_node_s::len, switch_jb_node_s::packet, switch_core_inthash_find(), switch_mutex_lock(), switch_mutex_unlock(), SWITCH_STATUS_NOTFOUND, and SWITCH_STATUS_SUCCESS.

Referenced by handle_nack().

1170 {
1171  switch_jb_node_t *node;
1173 
1174  switch_mutex_lock(jb->mutex);
1175  if ((node = switch_core_inthash_find(jb->node_hash, seq))) {
1176  jb_debug(jb, 2, "Found buffered seq: %u\n", ntohs(seq));
1177  *packet = node->packet;
1178  *len = node->len;
1179  memcpy(packet->body, node->packet.body, node->len);
1180  status = SWITCH_STATUS_SUCCESS;
1181  } else {
1182  jb_debug(jb, 2, "Missing buffered seq: %u\n", ntohs(seq));
1183  }
1185 
1186  return status;
1187 }
switch_inthash_t * node_hash
#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:290
switch_mutex_t * mutex
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:285
switch_status_t
Common return values.
char body[SWITCH_RTP_MAX_BUF_LEN+4+sizeof(char *)]
Definition: switch_rtp.h:54
switch_rtp_packet_t packet
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 890 of file switch_jitterbuffer.c.

References switch_rtp_packet_t::body, switch_rtp_packet_t::header, switch_jb_node_s::len, switch_rtp_hdr_t::m, switch_jb_node_s::packet, switch_rtp_hdr_t::seq, switch_core_inthash_find(), SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, and switch_rtp_hdr_t::ts.

891 {
892  switch_jb_node_t *node = NULL;
893  if (seq) {
894  uint16_t want_seq = seq + peek;
895  node = switch_core_inthash_find(jb->node_hash, htons(want_seq));
896  } else if (ts && jb->samples_per_frame) {
897  uint32_t want_ts = ts + (peek * jb->samples_per_frame);
898  node = switch_core_inthash_find(jb->node_hash_ts, htonl(want_ts));
899  }
900 
901  if (node) {
902  frame->seq = ntohs(node->packet.header.seq);
903  frame->timestamp = ntohl(node->packet.header.ts);
904  frame->m = node->packet.header.m;
905  frame->datalen = node->len;
906 
907  if (frame->data && frame->buflen > node->len) {
908  memcpy(frame->data, node->packet.body, node->len);
909  }
910  return SWITCH_STATUS_SUCCESS;
911  }
912 
913  return SWITCH_STATUS_FALSE;
914 }
switch_bool_t m
Definition: switch_frame.h:72
switch_inthash_t * node_hash
switch_inthash_t * node_hash_ts
uint32_t timestamp
Definition: switch_frame.h:69
void * switch_core_inthash_find(switch_inthash_t *hash, uint32_t key)
uint16_t seq
Definition: switch_frame.h:70
uint32_t buflen
Definition: switch_frame.h:59
uint32_t datalen
Definition: switch_frame.h:57
uint32_t samples_per_frame
int switch_jb_poll ( switch_jb_t jb)

Definition at line 831 of file switch_jitterbuffer.c.

Referenced by rtp_common_read().

832 {
833  return (jb->complete_frames >= jb->frame_len);
834 }
uint32_t complete_frames
uint32_t switch_jb_pop_nack ( switch_jb_t jb)

Definition at line 1024 of file switch_jitterbuffer.c.

References jb_debug, RENACK_TIME, SJB_VIDEO, switch_core_hash_first, switch_core_hash_next(), switch_core_hash_this(), switch_core_inthash_delete(), switch_core_inthash_insert(), switch_mutex_lock(), switch_mutex_unlock(), and switch_time_now().

Referenced by check_rtcp_and_ice().

1025 {
1026  switch_hash_index_t *hi = NULL;
1027  uint32_t nack = 0;
1028  uint16_t blp = 0;
1029  uint16_t least = 0;
1030  int i = 0;
1031  void *val;
1032  const void *var;
1033 
1034  if (jb->type != SJB_VIDEO) {
1035  return 0;
1036  }
1037 
1038  switch_mutex_lock(jb->mutex);
1039 
1040  top:
1041 
1042  for (hi = switch_core_hash_first(jb->missing_seq_hash); hi; hi = switch_core_hash_next(&hi)) {
1043  uint16_t seq;
1044  //const char *token;
1045  switch_time_t then = 0;
1046 
1047  switch_core_hash_this(hi, &var, NULL, &val);
1048  //token = (const char *) val;
1049 
1050  //if (token == TOKEN_2) {
1051  //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "SKIP %u %s\n", ntohs(*((uint16_t *) var)), token);
1052  //printf("WTf\n");
1053  // continue;
1054  //}
1055 
1056  seq = ntohs(*((uint16_t *) var));
1057  then = (intptr_t) val;
1058 
1059  if (then != 1 && switch_time_now() - then < RENACK_TIME) {
1060  //jb_debug(jb, 3, "NACKABLE seq %u too soon to repeat\n", seq);
1061  continue;
1062  }
1063 
1064  //if (then != 1) {
1065  // jb_debug(jb, 3, "NACKABLE seq %u not too soon to repeat %lu\n", seq, switch_time_now() - then);
1066  //}
1067 
1068  if (seq < ntohs(jb->target_seq) - jb->frame_len) {
1069  jb_debug(jb, 3, "NACKABLE seq %u expired\n", seq);
1070  switch_core_inthash_delete(jb->missing_seq_hash, (uint32_t)htons(seq));
1071  goto top;
1072  }
1073 
1074  if (!least || seq < least) {
1075  least = seq;
1076  }
1077  }
1078 
1079  if (least && switch_core_inthash_delete(jb->missing_seq_hash, (uint32_t)htons(least))) {
1080  jb_debug(jb, 3, "Found NACKABLE seq %u\n", least);
1081  nack = (uint32_t) htons(least);
1082  switch_core_inthash_insert(jb->missing_seq_hash, nack, (void *) (intptr_t)switch_time_now());
1083 
1084  for(i = 0; i < 16; i++) {
1085  if (switch_core_inthash_delete(jb->missing_seq_hash, (uint32_t)htons(least + i + 1))) {
1086  switch_core_inthash_insert(jb->missing_seq_hash, (uint32_t)htons(least + i + 1), (void *)(intptr_t)switch_time_now());
1087  jb_debug(jb, 3, "Found addtl NACKABLE seq %u\n", least + i + 1);
1088  blp |= (1 << i);
1089  }
1090  }
1091 
1092  blp = htons(blp);
1093  nack |= (uint32_t) blp << 16;
1094 
1095  //jb_frame_inc(jb, 1);
1096  }
1097 
1099 
1100 
1101  return nack;
1102 }
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:290
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:285
switch_status_t switch_core_inthash_insert(switch_inthash_t *hash, uint32_t key, const void *data)
#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:302
#define switch_core_hash_first(_h)
Definition: switch_core.h:1501
switch_status_t switch_jb_put_packet ( switch_jb_t jb,
switch_rtp_packet_t packet,
switch_size_t  len 
)

Definition at line 1104 of file switch_jitterbuffer.c.

References add_node(), drop_oldest_frame(), jb_debug, jb_frame_inc, SJB_AUDIO, SJB_QUEUE_ONLY, SWITCH_CHANNEL_LOG, switch_core_inthash_delete(), switch_core_inthash_insert(), switch_core_session_request_video_refresh(), switch_jb_reset(), switch_log_printf(), SWITCH_LOG_WARNING, switch_mutex_lock(), switch_mutex_unlock(), SWITCH_SIZE_T_FMT, SWITCH_STATUS_SUCCESS, and switch_test_flag.

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

1105 {
1106  uint32_t i;
1107  uint16_t want = ntohs(jb->next_seq), got = ntohs(packet->header.seq);
1108 
1109  if (len >= sizeof(switch_rtp_packet_t)) {
1110  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, sizeof(switch_rtp_packet_t));
1111  len = sizeof(switch_rtp_packet_t);
1112  }
1113 
1114  switch_mutex_lock(jb->mutex);
1115 
1116  if (!want) want = got;
1117 
1118  if (switch_test_flag(jb, SJB_QUEUE_ONLY) || jb->type == SJB_AUDIO) {
1119  jb->next_seq = htons(got + 1);
1120  } else {
1121 
1122  if (switch_core_inthash_delete(jb->missing_seq_hash, (uint32_t)htons(got))) {
1123  if (got < ntohs(jb->target_seq)) {
1124  jb_debug(jb, 2, "got nacked seq %u too late\n", got);
1125  jb_frame_inc(jb, 1);
1126  } else {
1127  jb_debug(jb, 2, "got nacked %u saved the day!\n", got);
1128  }
1129  }
1130 
1131  if (got > want) {
1132  if (got - want > jb->max_frame_len && got - want > 17) {
1133  jb_debug(jb, 2, "Missing %u frames, Resetting\n", got - want);
1134  switch_jb_reset(jb);
1135  if (jb->session) {
1137  }
1138  } else {
1139 
1140  if (jb->frame_len < got - want) {
1141  jb_frame_inc(jb, 1);
1142  }
1143 
1144  jb_debug(jb, 2, "GOT %u WANTED %u; MARK SEQS MISSING %u - %u\n", got, want, want, got - 1);
1145 
1146  for (i = want; i < got; i++) {
1147  jb_debug(jb, 2, "MARK MISSING %u ts:%u\n", i, ntohl(packet->header.ts));
1148  switch_core_inthash_insert(jb->missing_seq_hash, (uint32_t)htons(i), (void *)(intptr_t)1);
1149  }
1150  }
1151  }
1152 
1153  if (got >= want || (want - got) > 1000) {
1154  jb->next_seq = htons(got + 1);
1155  }
1156  }
1157 
1158  add_node(jb, packet, len);
1159 
1161  drop_oldest_frame(jb);
1162  }
1163 
1165 
1166  return SWITCH_STATUS_SUCCESS;
1167 }
switch_jb_type_t type
#define SWITCH_CHANNEL_LOG
switch_rtp_hdr_t header
Definition: switch_rtp.h:53
switch_inthash_t * missing_seq_hash
uint32_t complete_frames
#define jb_debug(_jb, _level, _format,...)
#define jb_frame_inc(_jb, _i)
uint32_t max_frame_len
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:290
static void drop_oldest_frame(switch_jb_t *jb)
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)
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:285
switch_status_t switch_core_inthash_insert(switch_inthash_t *hash, uint32_t key, const void *data)
switch_status_t switch_core_session_request_video_refresh(switch_core_session_t *session)
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:624
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.
#define SWITCH_SIZE_T_FMT
void switch_jb_reset(switch_jb_t *jb)
void switch_jb_reset ( switch_jb_t jb)

Definition at line 846 of file switch_jitterbuffer.c.

References hide_nodes(), jb_debug, SJB_VIDEO, switch_core_inthash_destroy(), switch_core_inthash_init(), switch_core_session_request_video_refresh(), switch_mutex_lock(), and switch_mutex_unlock().

Referenced by add_node(), do_flush(), handle_rfc2833(), process_rtcp_report(), 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().

847 {
848 
849  if (jb->type == SJB_VIDEO) {
854 
855  if (jb->session) {
857  }
858  }
859 
860  jb_debug(jb, 2, "%s", "RESET BUFFER\n");
861 
862  jb->drop_flag = 0;
863  jb->last_target_seq = 0;
864  jb->target_seq = 0;
865  jb->write_init = 0;
866  jb->highest_wrote_seq = 0;
867  jb->highest_wrote_ts = 0;
868  jb->next_seq = 0;
869  jb->highest_read_ts = 0;
870  jb->highest_read_seq = 0;
871  jb->complete_frames = 0;
872  jb->read_init = 0;
873  jb->next_seq = 0;
874  jb->complete_frames = 0;
875  jb->period_miss_count = 0;
876  jb->consec_miss_count = 0;
877  jb->period_miss_pct = 0;
878  jb->period_good_count = 0;
879  jb->consec_good_count = 0;
880  jb->period_count = 0;
881  jb->period_miss_inc = 0;
882  jb->target_ts = 0;
883  jb->last_target_ts = 0;
884 
886  hide_nodes(jb);
888 }
uint32_t highest_wrote_ts
switch_jb_type_t type
switch_status_t switch_core_inthash_init(switch_inthash_t **hash)
uint32_t highest_read_seq
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,...)
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:290
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:285
uint32_t consec_miss_count
uint32_t period_count
uint32_t period_miss_inc
uint32_t period_good_count
uint32_t period_miss_count
switch_status_t switch_core_session_request_video_refresh(switch_core_session_t *session)
switch_core_session_t * session
uint32_t last_target_seq
uint32_t highest_wrote_seq
uint32_t consec_good_count
void switch_jb_set_flag ( switch_jb_t jb,
switch_jb_flag_t  flag 
)

Definition at line 821 of file switch_jitterbuffer.c.

References switch_set_flag.

Referenced by rtp_common_write().

822 {
823  switch_set_flag(jb, flag);
824 }
#define switch_set_flag(obj, flag)
Set a flag on an arbitrary object.
Definition: switch_utils.h:631
switch_status_t switch_jb_set_frames ( switch_jb_t jb,
uint32_t  min_frame_len,
uint32_t  max_frame_len 
)

Definition at line 938 of file switch_jitterbuffer.c.

References switch_mutex_lock(), switch_mutex_unlock(), and SWITCH_STATUS_SUCCESS.

Referenced by switch_rtp_activate_jitter_buffer(), and switch_rtp_set_video_buffer_size().

939 {
940  int lowest = 0;
941 
943 
944  if (jb->frame_len == jb->min_frame_len) lowest = 1;
945 
946  jb->min_frame_len = min_frame_len;
947  jb->max_frame_len = max_frame_len;
948 
949  if (jb->frame_len > jb->max_frame_len) {
950  jb->frame_len = jb->max_frame_len;
951  }
952 
953  if (jb->frame_len < jb->min_frame_len) {
954  jb->frame_len = jb->min_frame_len;
955  }
956 
957  if (jb->frame_len > jb->highest_frame_len) {
958  jb->highest_frame_len = jb->frame_len;
959  }
960 
961  if (lowest) {
962  jb->frame_len = jb->min_frame_len;
963  }
964 
966 
967  return SWITCH_STATUS_SUCCESS;
968 }
uint32_t min_frame_len
uint32_t max_frame_len
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:290
switch_mutex_t * mutex
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:285
uint32_t highest_frame_len
void switch_jb_set_session ( switch_jb_t jb,
switch_core_session_t session 
)

Definition at line 804 of file switch_jitterbuffer.c.

References SJB_VIDEO, switch_channel_get_variable_dup(), switch_core_session_get_channel(), and SWITCH_FALSE.

Referenced by switch_rtp_activate_jitter_buffer(), and switch_rtp_set_video_buffer_size().

805 {
806  const char *var;
807 
808  jb->session = session;
810 
811  if (jb->type == SJB_VIDEO && (var = switch_channel_get_variable_dup(jb->channel, "jb_video_low_bitrate", SWITCH_FALSE, -1))) {
812  int tmp = atoi(var);
813 
814  if (tmp > 128 && tmp < 10240) {
815  jb->video_low_bitrate = (uint32_t)tmp;
816  }
817  }
818 
819 }
switch_jb_type_t type
switch_channel_t * channel
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.
_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.
switch_core_session_t * session
uint32_t video_low_bitrate
switch_core_session_t * session
void switch_jb_ts_mode ( switch_jb_t jb,
uint32_t  samples_per_frame,
uint32_t  samples_per_second 
)

Definition at line 797 of file switch_jitterbuffer.c.

References switch_core_inthash_init().

Referenced by switch_rtp_activate_jitter_buffer().

798 {
799  jb->samples_per_frame = samples_per_frame;
800  jb->samples_per_second = samples_per_second;
802 }
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