mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-04-20 02:04:54 +00:00
FS-10088: [freeswitch-core] Backports
This commit is contained in:
parent
24973b9279
commit
48b51ffbb7
@ -774,6 +774,7 @@ typedef enum {
|
||||
SWITCH_RTP_FLAG_GEN_TS_MANUAL,
|
||||
SWITCH_RTP_FLAG_DETECT_SSRC,
|
||||
SWITCH_RTP_FLAG_OLD_FIR,
|
||||
SWITCH_RTP_FLAG_PASSTHRU,
|
||||
SWITCH_RTP_FLAG_INVALID
|
||||
} switch_rtp_flag_t;
|
||||
|
||||
@ -1577,7 +1578,8 @@ typedef enum {
|
||||
SFF_PICTURE_RESET = (1 << 14),
|
||||
SFF_SAME_IMAGE = (1 << 15),
|
||||
SFF_USE_VIDEO_TIMESTAMP = (1 << 16),
|
||||
SFF_ENCODED = (1 << 17)
|
||||
SFF_ENCODED = (1 << 17),
|
||||
SFF_EXTERNAL = (1 << 20)
|
||||
} switch_frame_flag_enum_t;
|
||||
typedef uint32_t switch_frame_flag_t;
|
||||
|
||||
|
@ -58,9 +58,10 @@ struct switch_jb_s {
|
||||
struct switch_jb_node_s *node_list;
|
||||
uint32_t last_target_seq;
|
||||
uint32_t highest_read_ts;
|
||||
uint32_t highest_dropped_ts;
|
||||
uint32_t highest_read_seq;
|
||||
uint32_t highest_wrote_ts;
|
||||
uint32_t highest_wrote_seq;
|
||||
uint16_t highest_wrote_seq;
|
||||
uint16_t target_seq;
|
||||
uint32_t target_ts;
|
||||
uint32_t last_target_ts;
|
||||
@ -104,6 +105,8 @@ struct switch_jb_s {
|
||||
switch_channel_t *channel;
|
||||
uint32_t buffer_lag;
|
||||
uint32_t flush;
|
||||
uint32_t packet_count;
|
||||
uint32_t max_packet_len;
|
||||
};
|
||||
|
||||
|
||||
@ -211,6 +214,22 @@ static inline switch_jb_node_t *new_node(switch_jb_t *jb)
|
||||
}
|
||||
|
||||
if (!np) {
|
||||
int mult = 25;
|
||||
|
||||
if (jb->type != SJB_VIDEO) {
|
||||
mult = 2;
|
||||
} else {
|
||||
if (jb->max_packet_len > mult) {
|
||||
mult = jb->max_packet_len;
|
||||
}
|
||||
}
|
||||
|
||||
if (jb->allocated_nodes > jb->max_frame_len * mult) {
|
||||
jb_debug(jb, 2, "ALLOCATED FRAMES TOO HIGH! %d\n", jb->allocated_nodes);
|
||||
switch_jb_reset(jb);
|
||||
switch_mutex_unlock(jb->list_mutex);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
np = switch_core_alloc(jb->pool, sizeof(*np));
|
||||
jb->allocated_nodes++;
|
||||
@ -279,7 +298,7 @@ static inline void hide_node(switch_jb_node_t *node, switch_bool_t pop)
|
||||
}
|
||||
|
||||
if (switch_core_inthash_delete(jb->node_hash, node->packet.header.seq)) {
|
||||
if (node->packet.header.m && jb->type == SJB_VIDEO) {
|
||||
if (node->packet.header.version == 1 && jb->type == SJB_VIDEO) {
|
||||
jb->complete_frames--;
|
||||
}
|
||||
}
|
||||
@ -573,20 +592,45 @@ static inline void drop_second_newest_frame(switch_jb_t *jb)
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline int check_seq(uint16_t a, uint16_t b)
|
||||
{
|
||||
a = ntohs(a);
|
||||
b = ntohs(b);
|
||||
|
||||
if (a >= b || (b > a && b > USHRT_MAX / 2 && a < USHRT_MAX / 2)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int check_ts(uint32_t a, uint32_t b)
|
||||
{
|
||||
a = ntohl(a);
|
||||
b = ntohl(b);
|
||||
|
||||
if (a > b || (b > a && b > UINT_MAX / 2 && a < UINT_MAX / 2)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void add_node(switch_jb_t *jb, switch_rtp_packet_t *packet, switch_size_t len)
|
||||
{
|
||||
switch_jb_node_t *node = new_node(jb);
|
||||
|
||||
if (!node) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
node->packet = *packet;
|
||||
node->len = len;
|
||||
memcpy(node->packet.body, packet->body, len);
|
||||
|
||||
switch_core_inthash_insert(jb->node_hash, node->packet.header.seq, node);
|
||||
|
||||
if (packet->header.m && jb->type == SJB_VIDEO) {
|
||||
jb->complete_frames++;
|
||||
}
|
||||
|
||||
if (jb->node_hash_ts) {
|
||||
switch_core_inthash_insert(jb->node_hash_ts, node->packet.header.ts, node);
|
||||
}
|
||||
@ -621,11 +665,23 @@ static inline void add_node(switch_jb_t *jb, switch_rtp_packet_t *packet, switch
|
||||
}
|
||||
|
||||
if (jb->type == SJB_VIDEO) {
|
||||
if (jb->write_init && ((htons(packet->header.seq) >= htons(jb->highest_wrote_seq) && (ntohl(node->packet.header.ts) > ntohl(jb->highest_wrote_ts))) ||
|
||||
(ntohl(jb->highest_wrote_ts) > (UINT_MAX - 1000) && ntohl(node->packet.header.ts) < 1000))) {
|
||||
if (!switch_test_flag(jb, SJB_QUEUE_ONLY)) {
|
||||
jb->packet_count++;
|
||||
}
|
||||
|
||||
if (jb->write_init && check_seq(packet->header.seq, jb->highest_wrote_seq) && check_ts(node->packet.header.ts, jb->highest_wrote_ts)) {
|
||||
jb_debug(jb, 2, "WRITE frame ts: %u complete=%u/%u n:%u\n", ntohl(node->packet.header.ts), jb->complete_frames , jb->frame_len, jb->visible_nodes);
|
||||
jb->highest_wrote_ts = packet->header.ts;
|
||||
//verify_oldest_frame(jb);
|
||||
jb->complete_frames++;
|
||||
|
||||
if (!switch_test_flag(jb, SJB_QUEUE_ONLY)) {
|
||||
if (jb->packet_count > jb->max_packet_len) {
|
||||
jb->max_packet_len = jb->packet_count;
|
||||
}
|
||||
|
||||
jb->packet_count = 0;
|
||||
}
|
||||
node->packet.header.version = 1;
|
||||
} else if (!jb->write_init) {
|
||||
jb->highest_wrote_ts = packet->header.ts;
|
||||
}
|
||||
@ -716,9 +772,9 @@ static inline switch_status_t jb_next_packet_by_seq(switch_jb_t *jb, switch_jb_n
|
||||
jb_frame_inc(jb, 1);
|
||||
}
|
||||
|
||||
//if (jb->session) {
|
||||
// switch_core_session_request_video_refresh(jb->session);
|
||||
//}
|
||||
if (jb->session) {
|
||||
switch_core_session_request_video_refresh(jb->session);
|
||||
}
|
||||
|
||||
for (x = 0; x < 10; x++) {
|
||||
increment_seq(jb);
|
||||
@ -729,6 +785,7 @@ static inline switch_status_t jb_next_packet_by_seq(switch_jb_t *jb, switch_jb_n
|
||||
jb_debug(jb, 2, "%s", "SAME FRAME DROPPING\n");
|
||||
jb->dropped++;
|
||||
drop_ts(jb, node->packet.header.ts);
|
||||
jb->highest_dropped_ts = ntohl(node->packet.header.ts);
|
||||
node = NULL;
|
||||
goto top;
|
||||
}
|
||||
@ -737,6 +794,7 @@ static inline switch_status_t jb_next_packet_by_seq(switch_jb_t *jb, switch_jb_n
|
||||
jb_debug(jb, 2, "MISSING incremental seq: %u\n", ntohs(jb->target_seq));
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
increment_seq(jb);
|
||||
}
|
||||
@ -816,10 +874,11 @@ SWITCH_DECLARE(void) switch_jb_set_session(switch_jb_t *jb, switch_core_session_
|
||||
jb->session = session;
|
||||
jb->channel = switch_core_session_get_channel(session);
|
||||
|
||||
if (jb->type == SJB_VIDEO && (var = switch_channel_get_variable_dup(jb->channel, "jb_video_low_bitrate", SWITCH_FALSE, -1))) {
|
||||
if (jb->type == SJB_VIDEO && !switch_test_flag(jb, SJB_QUEUE_ONLY) &&
|
||||
(var = switch_channel_get_variable_dup(jb->channel, "jb_video_low_bitrate", SWITCH_FALSE, -1))) {
|
||||
int tmp = atoi(var);
|
||||
|
||||
if (tmp > 128 && tmp < 10240) {
|
||||
if (tmp >= 128 && tmp <= 10240) {
|
||||
jb->video_low_bitrate = (uint32_t)tmp;
|
||||
}
|
||||
}
|
||||
@ -1122,6 +1181,16 @@ SWITCH_DECLARE(switch_status_t) switch_jb_put_packet(switch_jb_t *jb, switch_rtp
|
||||
|
||||
switch_mutex_lock(jb->mutex);
|
||||
|
||||
if (jb->highest_dropped_ts) {
|
||||
if (ntohl(packet->header.ts) < jb->highest_dropped_ts) {
|
||||
jb_debug(jb, 2, "%s", "TS ALREADY DROPPED, DROPPING PACKET\n");
|
||||
switch_mutex_unlock(jb->mutex);
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
jb->highest_dropped_ts = 0;
|
||||
}
|
||||
|
||||
|
||||
if (!want) want = got;
|
||||
|
||||
if (switch_test_flag(jb, SJB_QUEUE_ONLY) || jb->type == SJB_AUDIO) {
|
||||
@ -1186,6 +1255,7 @@ SWITCH_DECLARE(switch_status_t) switch_jb_get_packet_by_seq(switch_jb_t *jb, uin
|
||||
*packet = node->packet;
|
||||
*len = node->len;
|
||||
memcpy(packet->body, node->packet.body, node->len);
|
||||
packet->header.version = 2;
|
||||
status = SWITCH_STATUS_SUCCESS;
|
||||
} else {
|
||||
jb_debug(jb, 2, "Missing buffered seq: %u\n", ntohs(seq));
|
||||
@ -1200,7 +1270,6 @@ SWITCH_DECLARE(switch_size_t) switch_jb_get_last_read_len(switch_jb_t *jb)
|
||||
return jb->last_len;
|
||||
}
|
||||
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_jb_get_packet(switch_jb_t *jb, switch_rtp_packet_t *packet, switch_size_t *len)
|
||||
{
|
||||
switch_jb_node_t *node = NULL;
|
||||
@ -1250,16 +1319,17 @@ SWITCH_DECLARE(switch_status_t) switch_jb_get_packet(switch_jb_t *jb, switch_rtp
|
||||
if (jb->session) {
|
||||
switch_core_session_request_video_refresh(jb->session);
|
||||
}
|
||||
} else if (!switch_channel_test_flag(jb->channel, CF_VIDEO_BITRATE_UNMANAGABLE) && jb->frame_len > jb->min_frame_len * 2) {
|
||||
} else if (!switch_channel_test_flag(jb->channel, CF_VIDEO_BITRATE_UNMANAGABLE) && jb->frame_len > jb->max_frame_len / 2) {
|
||||
switch_core_session_message_t msg = { 0 };
|
||||
|
||||
jb->bitrate_control = jb->video_low_bitrate;
|
||||
|
||||
|
||||
msg.message_id = SWITCH_MESSAGE_INDICATE_BITRATE_REQ;
|
||||
msg.numeric_arg = jb->bitrate_control * 1024;
|
||||
msg.from = __FILE__;
|
||||
|
||||
jb_debug(jb, 2, "Force BITRATE to %d\n", jb->bitrate_control);
|
||||
|
||||
switch_core_session_receive_message(jb->session, &msg);
|
||||
switch_channel_set_flag(jb->channel, CF_VIDEO_BITRATE_UNMANAGABLE);
|
||||
if (jb->session) {
|
||||
@ -1280,15 +1350,14 @@ SWITCH_DECLARE(switch_status_t) switch_jb_get_packet(switch_jb_t *jb, switch_rtp
|
||||
if ((status = jb_next_packet(jb, &node)) == SWITCH_STATUS_SUCCESS) {
|
||||
jb_debug(jb, 2, "Found next frame cur ts: %u seq: %u\n", htonl(node->packet.header.ts), htons(node->packet.header.seq));
|
||||
|
||||
if (!jb->read_init || ntohs(node->packet.header.seq) > ntohs(jb->highest_read_seq) ||
|
||||
(ntohs(jb->highest_read_seq) > USHRT_MAX - 10 && ntohs(node->packet.header.seq) <= 10) ) {
|
||||
if (!jb->read_init || check_seq(node->packet.header.seq, jb->highest_read_seq)) {
|
||||
jb->highest_read_seq = node->packet.header.seq;
|
||||
}
|
||||
|
||||
if (jb->type == SJB_AUDIO ||
|
||||
(jb->read_init && htons(node->packet.header.seq) >= htons(jb->highest_read_seq) && (ntohl(node->packet.header.ts) > ntohl(jb->highest_read_ts)))) {
|
||||
if (jb->type != SJB_VIDEO ||
|
||||
(jb->read_init && check_seq(node->packet.header.seq, jb->highest_read_seq) && check_ts(node->packet.header.ts, jb->highest_read_ts))) {
|
||||
|
||||
if (jb->type == SJB_AUDIO) {
|
||||
if (jb->type != SJB_VIDEO) {
|
||||
jb->complete_frames--;
|
||||
}
|
||||
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);
|
||||
@ -1340,6 +1409,7 @@ SWITCH_DECLARE(switch_status_t) switch_jb_get_packet(switch_jb_t *jb, switch_rtp
|
||||
*len = node->len;
|
||||
jb->last_len = *len;
|
||||
memcpy(packet->body, node->packet.body, node->len);
|
||||
packet->header.version = 2;
|
||||
hide_node(node, SWITCH_TRUE);
|
||||
|
||||
jb_debug(jb, 1, "GET packet ts:%u seq:%u %s\n", ntohl(packet->header.ts), ntohs(packet->header.seq), packet->header.m ? " <MARK>" : "");
|
||||
|
207
src/switch_rtp.c
207
src/switch_rtp.c
@ -302,8 +302,8 @@ typedef struct ts_normalize_s {
|
||||
uint32_t last_frame;
|
||||
uint32_t ts;
|
||||
uint32_t delta;
|
||||
uint32_t delta_ct;
|
||||
uint32_t delta_ttl;
|
||||
int last_external;
|
||||
} ts_normalize_t;
|
||||
|
||||
struct switch_rtp {
|
||||
@ -453,6 +453,7 @@ struct switch_rtp {
|
||||
switch_byte_t rtcp_auto_adj_used;
|
||||
uint8_t pause_jb;
|
||||
uint16_t last_seq;
|
||||
uint16_t last_write_seq;
|
||||
switch_time_t last_read_time;
|
||||
switch_size_t last_flush_packet_count;
|
||||
uint32_t interdigit_delay;
|
||||
@ -526,7 +527,7 @@ typedef enum {
|
||||
static void do_2833(switch_rtp_t *rtp_session);
|
||||
|
||||
|
||||
#define rtp_type(rtp_session) (rtp_session->flags[SWITCH_RTP_FLAG_VIDEO] ? "video" : "audio")
|
||||
#define rtp_type(rtp_session) rtp_session->flags[SWITCH_RTP_FLAG_VIDEO] ? "video" : "audio"
|
||||
|
||||
|
||||
static void switch_rtp_change_ice_dest(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, const char *host, switch_port_t port)
|
||||
@ -1656,6 +1657,10 @@ static void check_jitter(switch_rtp_t *rtp_session)
|
||||
(rtp_session->stats.inbound.last_processed_seq + 1), lost);
|
||||
rtp_session->stats.inbound.last_loss++;
|
||||
|
||||
if (rtp_session->flags[SWITCH_RTP_FLAG_VIDEO]) {
|
||||
switch_core_session_request_video_refresh(rtp_session->session);
|
||||
}
|
||||
|
||||
if (rtp_session->stats.inbound.last_loss > 0 && rtp_session->stats.inbound.last_loss < LOST_BURST_CAPTURE) {
|
||||
rtp_session->stats.inbound.loss[rtp_session->stats.inbound.last_loss] += lost;
|
||||
}
|
||||
@ -4119,21 +4124,27 @@ SWITCH_DECLARE(switch_jb_t *) switch_rtp_get_jitter_buffer(switch_rtp_t *rtp_ses
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_rtp_pause_jitter_buffer(switch_rtp_t *rtp_session, switch_bool_t pause)
|
||||
{
|
||||
|
||||
if (!switch_rtp_ready(rtp_session) || !rtp_session->jb) {
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
if (!!pause == !!rtp_session->pause_jb) {
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
int new_val;
|
||||
|
||||
if (rtp_session->pause_jb && !pause) {
|
||||
switch_jb_reset(rtp_session->jb);
|
||||
if (rtp_session->jb) {
|
||||
switch_jb_reset(rtp_session->jb);
|
||||
}
|
||||
|
||||
if (rtp_session->vb) {
|
||||
switch_jb_reset(rtp_session->vb);
|
||||
}
|
||||
}
|
||||
|
||||
rtp_session->pause_jb = pause ? 1 : 0;
|
||||
new_val = pause ? 1 : -1;
|
||||
|
||||
if (rtp_session->pause_jb + new_val > -1) {
|
||||
rtp_session->pause_jb += new_val;
|
||||
}
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG1,
|
||||
"Jitterbuffer %s is %s\n", rtp_type(rtp_session), rtp_session->pause_jb ? "paused" : "enabled");
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@ -4730,37 +4741,7 @@ SWITCH_DECLARE(void) switch_rtp_set_flags(switch_rtp_t *rtp_session, switch_rtp_
|
||||
|
||||
for(i = 0; i < SWITCH_RTP_FLAG_INVALID; i++) {
|
||||
if (flags[i]) {
|
||||
rtp_session->flags[i] = flags[i];
|
||||
|
||||
if (i == SWITCH_RTP_FLAG_AUTOADJ) {
|
||||
rtp_session->autoadj_window = 20;
|
||||
rtp_session->autoadj_threshold = 10;
|
||||
rtp_session->autoadj_tally = 0;
|
||||
if (rtp_session->session) {
|
||||
switch_channel_t *channel = switch_core_session_get_channel(rtp_session->session);
|
||||
const char *x = switch_channel_get_variable(channel, "rtp_auto_adjust_threshold");
|
||||
if (x && *x) {
|
||||
int xn = atoi(x);
|
||||
if (xn > 0 && xn <= 65535) {
|
||||
rtp_session->autoadj_window = xn*2;
|
||||
rtp_session->autoadj_threshold = xn;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
rtp_session->flags[SWITCH_RTP_FLAG_RTCP_AUTOADJ] = 1;
|
||||
|
||||
|
||||
rtp_session->rtcp_autoadj_window = 20;
|
||||
rtp_session->rtcp_autoadj_threshold = 1;
|
||||
rtp_session->rtcp_autoadj_tally = 0;
|
||||
|
||||
|
||||
rtp_flush_read_buffer(rtp_session, SWITCH_RTP_FLUSH_ONCE);
|
||||
} else if (i == SWITCH_RTP_FLAG_NOBLOCK && rtp_session->sock_input) {
|
||||
switch_socket_opt_set(rtp_session->sock_input, SWITCH_SO_NONBLOCK, TRUE);
|
||||
}
|
||||
switch_rtp_set_flag(rtp_session, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4771,19 +4752,24 @@ SWITCH_DECLARE(void) switch_rtp_clear_flags(switch_rtp_t *rtp_session, switch_rt
|
||||
|
||||
for(i = 0; i < SWITCH_RTP_FLAG_INVALID; i++) {
|
||||
if (flags[i]) {
|
||||
rtp_session->flags[i] = 0;
|
||||
switch_rtp_clear_flag(rtp_session, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(void) switch_rtp_set_flag(switch_rtp_t *rtp_session, switch_rtp_flag_t flag)
|
||||
{
|
||||
int old_flag = rtp_session->flags[flag];
|
||||
|
||||
switch_mutex_lock(rtp_session->flag_mutex);
|
||||
rtp_session->flags[flag] = 1;
|
||||
switch_mutex_unlock(rtp_session->flag_mutex);
|
||||
|
||||
if (flag == SWITCH_RTP_FLAG_DTMF_ON) {
|
||||
if (flag == SWITCH_RTP_FLAG_PASSTHRU) {
|
||||
if (!old_flag) {
|
||||
switch_rtp_pause_jitter_buffer(rtp_session, SWITCH_TRUE);
|
||||
}
|
||||
} else if (flag == SWITCH_RTP_FLAG_DTMF_ON) {
|
||||
rtp_session->stats.inbound.last_processed_seq = 0;
|
||||
} else if (flag == SWITCH_RTP_FLAG_FLUSH) {
|
||||
reset_jitter_seq(rtp_session);
|
||||
@ -4832,12 +4818,17 @@ SWITCH_DECLARE(uint32_t) switch_rtp_test_flag(switch_rtp_t *rtp_session, switch_
|
||||
|
||||
SWITCH_DECLARE(void) switch_rtp_clear_flag(switch_rtp_t *rtp_session, switch_rtp_flag_t flag)
|
||||
{
|
||||
int old_flag = rtp_session->flags[flag];
|
||||
|
||||
switch_mutex_lock(rtp_session->flag_mutex);
|
||||
rtp_session->flags[flag] = 0;
|
||||
switch_mutex_unlock(rtp_session->flag_mutex);
|
||||
|
||||
if (flag == SWITCH_RTP_FLAG_DTMF_ON) {
|
||||
if (flag == SWITCH_RTP_FLAG_PASSTHRU) {
|
||||
if (old_flag) {
|
||||
switch_rtp_pause_jitter_buffer(rtp_session, SWITCH_FALSE);
|
||||
}
|
||||
} else if (flag == SWITCH_RTP_FLAG_DTMF_ON) {
|
||||
rtp_session->stats.inbound.last_processed_seq = 0;
|
||||
} else if (flag == SWITCH_RTP_FLAG_PAUSE) {
|
||||
reset_jitter_seq(rtp_session);
|
||||
@ -5803,7 +5794,7 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (rtp_session->vb && jb_valid(rtp_session)) {
|
||||
if (rtp_session->vb && !rtp_session->pause_jb && jb_valid(rtp_session)) {
|
||||
status = switch_jb_put_packet(rtp_session->vb, (switch_rtp_packet_t *) &rtp_session->recv_msg, *bytes);
|
||||
|
||||
if (status == SWITCH_STATUS_TOO_LATE) {
|
||||
@ -5900,7 +5891,7 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t
|
||||
}
|
||||
}
|
||||
|
||||
if (rtp_session->vb && jb_valid(rtp_session)) {
|
||||
if (rtp_session->vb && !rtp_session->pause_jb && jb_valid(rtp_session)) {
|
||||
switch_status_t vstatus = switch_jb_get_packet(rtp_session->vb, (switch_rtp_packet_t *) &rtp_session->recv_msg, bytes);
|
||||
status = vstatus;
|
||||
|
||||
@ -6687,7 +6678,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
|
||||
pt = 100000;
|
||||
}
|
||||
|
||||
if (rtp_session->vb) {
|
||||
if (rtp_session->vb && !rtp_session->pause_jb) {
|
||||
if (switch_jb_poll(rtp_session->vb)) {
|
||||
pt = 1000;
|
||||
}
|
||||
@ -6713,7 +6704,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
|
||||
}
|
||||
|
||||
if (rtp_session->flags[SWITCH_RTP_FLAG_VIDEO]) {
|
||||
got_jb = (rtp_session->vb && switch_jb_poll(rtp_session->vb));
|
||||
got_jb = (rtp_session->vb && !rtp_session->pause_jb && switch_jb_poll(rtp_session->vb));
|
||||
} else {
|
||||
got_jb = SWITCH_TRUE;
|
||||
}
|
||||
@ -6909,7 +6900,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
|
||||
process_rtcp_packet(rtp_session, &rtcp_bytes);
|
||||
ret = 1;
|
||||
|
||||
if (!rtp_session->flags[SWITCH_RTP_FLAG_USE_TIMER] && rtp_session->timer.interval) {
|
||||
if (!rtp_session->flags[SWITCH_RTP_FLAG_USE_TIMER] && rtp_session->timer.interval && !rtp_session->flags[SWITCH_RTP_FLAG_VIDEO]) {
|
||||
switch_core_timer_sync(&rtp_session->timer);
|
||||
reset_jitter_seq(rtp_session);
|
||||
}
|
||||
@ -7395,6 +7386,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_zerocopy_read_frame(switch_rtp_t *rtp
|
||||
frame->source = __FILE__;
|
||||
|
||||
switch_set_flag(frame, SFF_RAW_RTP);
|
||||
switch_set_flag(frame, SFF_EXTERNAL);
|
||||
if (frame->payload == rtp_session->recv_te) {
|
||||
switch_set_flag(frame, SFF_RFC2833);
|
||||
}
|
||||
@ -7622,59 +7614,65 @@ static int rtp_common_write(switch_rtp_t *rtp_session,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (switch_rtp_test_flag(rtp_session, SWITCH_RTP_FLAG_GEN_TS_DELTA) || switch_rtp_test_flag(rtp_session, SWITCH_RTP_FLAG_VIDEO)) {
|
||||
if (switch_rtp_test_flag(rtp_session, SWITCH_RTP_FLAG_VIDEO)) {
|
||||
int external = (*flags & SFF_EXTERNAL);
|
||||
/* Normalize the timestamps to our own base by generating a made up starting point then adding the measured deltas to that base
|
||||
so if the timestamps and ssrc of the source change, it will not break the other end's jitter bufffer / decoder etc *cough* CHROME *cough*
|
||||
*/
|
||||
|
||||
if (!rtp_session->ts_norm.ts) {
|
||||
if (switch_rtp_test_flag(rtp_session, SWITCH_RTP_FLAG_GEN_TS_DELTA)) {
|
||||
rtp_session->ts_norm.ts = (uint32_t) rand() % 1000000 + 1;
|
||||
} else {
|
||||
switch_core_timer_sync(&rtp_session->timer);
|
||||
rtp_session->ts_norm.ts = rtp_session->timer.samplecount;
|
||||
}
|
||||
rtp_session->ts_norm.ts = (uint32_t) rand() % 1000000 + 1;
|
||||
}
|
||||
|
||||
if (!rtp_session->ts_norm.last_ssrc || send_msg->header.ssrc != rtp_session->ts_norm.last_ssrc) {
|
||||
if (switch_rtp_test_flag(rtp_session, SWITCH_RTP_FLAG_GEN_TS_DELTA)) {
|
||||
if (rtp_session->ts_norm.last_ssrc) {
|
||||
rtp_session->ts_norm.delta_ct = 1;
|
||||
rtp_session->ts_norm.delta_ttl = 0;
|
||||
if (rtp_session->ts_norm.delta) {
|
||||
rtp_session->ts_norm.ts += rtp_session->ts_norm.delta;
|
||||
}
|
||||
}
|
||||
if (!rtp_session->ts_norm.last_ssrc || send_msg->header.ssrc != rtp_session->ts_norm.last_ssrc || rtp_session->ts_norm.last_external != external) {
|
||||
switch_core_session_t *other_session;
|
||||
|
||||
switch_core_session_request_video_refresh(rtp_session->session);
|
||||
switch_core_media_gen_key_frame(rtp_session->session);
|
||||
|
||||
if (switch_core_session_get_partner(rtp_session->session, &other_session) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_core_session_request_video_refresh(other_session);
|
||||
switch_core_media_gen_key_frame(other_session);
|
||||
switch_core_session_rwunlock(other_session);
|
||||
}
|
||||
|
||||
if (rtp_session->ts_norm.last_ssrc) {
|
||||
rtp_session->ts_norm.delta_ttl = 0;
|
||||
rtp_session->ts_norm.ts++;
|
||||
}
|
||||
|
||||
rtp_session->ts_norm.last_ssrc = send_msg->header.ssrc;
|
||||
rtp_session->ts_norm.last_frame = ntohl(send_msg->header.ts);
|
||||
}
|
||||
|
||||
rtp_session->ts_norm.last_external = external;
|
||||
|
||||
if (ntohl(send_msg->header.ts) != rtp_session->ts_norm.last_frame) {
|
||||
int32_t delta = (int32_t) (ntohl(send_msg->header.ts) - rtp_session->ts_norm.last_frame);
|
||||
int32_t delta;
|
||||
int64_t x, y;
|
||||
|
||||
if (switch_rtp_test_flag(rtp_session, SWITCH_RTP_FLAG_VIDEO) && delta > 0 && delta < 90000) {
|
||||
x = rtp_session->ts_norm.last_frame;
|
||||
y = ntohl(send_msg->header.ts);
|
||||
|
||||
if (x > UINT32_MAX / 2 && y < UINT32_MAX / 2) {
|
||||
x -= (int64_t)UINT32_MAX+1;
|
||||
}
|
||||
|
||||
delta = (int32_t)y-x;
|
||||
|
||||
if (delta < 0 || delta > 90000) {
|
||||
switch_core_media_gen_key_frame(rtp_session->session);
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG1,
|
||||
"Timestamp shift detected last: %d this: %d delta: %d stick with prev delta: %d\n",
|
||||
rtp_session->ts_norm.last_frame, ntohl(send_msg->header.ts), delta, rtp_session->ts_norm.delta);
|
||||
} else {
|
||||
rtp_session->ts_norm.delta = delta;
|
||||
}
|
||||
|
||||
if (switch_rtp_test_flag(rtp_session, SWITCH_RTP_FLAG_GEN_TS_DELTA)) {
|
||||
rtp_session->ts_norm.ts += rtp_session->ts_norm.delta;
|
||||
} else {
|
||||
switch_core_timer_sync(&rtp_session->timer);
|
||||
if (rtp_session->ts_norm.ts == rtp_session->timer.samplecount) {
|
||||
rtp_session->ts_norm.ts = rtp_session->timer.samplecount + 1;
|
||||
} else {
|
||||
rtp_session->ts_norm.ts = rtp_session->timer.samplecount;
|
||||
}
|
||||
if (send_msg->header.m) {
|
||||
rtp_session->ts_norm.last_frame++;
|
||||
}
|
||||
}
|
||||
}
|
||||
rtp_session->ts_norm.ts += rtp_session->ts_norm.delta;
|
||||
|
||||
}
|
||||
|
||||
rtp_session->ts_norm.last_frame = ntohl(send_msg->header.ts);
|
||||
send_msg->header.ts = htonl(rtp_session->ts_norm.ts);
|
||||
}
|
||||
@ -7817,8 +7815,27 @@ static int rtp_common_write(switch_rtp_t *rtp_session,
|
||||
}
|
||||
|
||||
if (send) {
|
||||
send_msg->header.seq = htons(++rtp_session->seq);
|
||||
int delta = 1;
|
||||
|
||||
if (rtp_session->flags[SWITCH_RTP_FLAG_VIDEO] && (*flags & SFF_EXTERNAL) && rtp_session->stats.outbound.packet_count && rtp_session->flags[SWITCH_RTP_FLAG_PASSTHRU]) {
|
||||
int32_t x;
|
||||
int32_t y;
|
||||
|
||||
x = rtp_session->last_write_seq;
|
||||
y = ntohs(send_msg->header.seq);
|
||||
|
||||
if (x > UINT16_MAX / 2 && y < UINT16_MAX / 2) {
|
||||
x -= (int32_t)UINT16_MAX+1;
|
||||
}
|
||||
|
||||
delta = y-x;
|
||||
}
|
||||
|
||||
rtp_session->seq += delta;
|
||||
|
||||
send_msg->header.seq = htons(rtp_session->seq);
|
||||
rtp_session->last_write_seq = rtp_session->seq;
|
||||
|
||||
if (rtp_session->flags[SWITCH_RTP_FLAG_BYTESWAP] && send_msg->header.pt == rtp_session->payload) {
|
||||
switch_swap_linear((int16_t *)send_msg->body, (int) datalen);
|
||||
}
|
||||
@ -7966,7 +7983,8 @@ static int rtp_common_write(switch_rtp_t *rtp_session,
|
||||
// //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "SEND %u\n", ntohs(send_msg->header.seq));
|
||||
//}
|
||||
if (switch_socket_sendto(rtp_session->sock_output, rtp_session->remote_addr, 0, (void *) send_msg, &bytes) != SWITCH_STATUS_SUCCESS) {
|
||||
rtp_session->seq--;
|
||||
rtp_session->seq -= delta;
|
||||
|
||||
ret = -1;
|
||||
goto end;
|
||||
}
|
||||
@ -8212,7 +8230,7 @@ SWITCH_DECLARE(int) switch_rtp_write_frame(switch_rtp_t *rtp_session, switch_fra
|
||||
fwd = (rtp_session->flags[SWITCH_RTP_FLAG_RAW_WRITE] &&
|
||||
(switch_test_flag(frame, SFF_RAW_RTP) || switch_test_flag(frame, SFF_RAW_RTP_PARSE_FRAME))) ? 1 : 0;
|
||||
|
||||
if (!fwd && !rtp_session->sending_dtmf && !rtp_session->queue_delay &&
|
||||
if (!fwd && !rtp_session->sending_dtmf && !rtp_session->queue_delay && !rtp_session->flags[SWITCH_RTP_FLAG_VIDEO] &&
|
||||
rtp_session->flags[SWITCH_RTP_FLAG_RAW_WRITE] && (rtp_session->rtp_bugs & RTP_BUG_GEN_ONE_GEN_ALL)) {
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_WARNING, "Generating RTP locally but timestamp passthru is configured, disabling....\n");
|
||||
@ -8243,20 +8261,6 @@ SWITCH_DECLARE(int) switch_rtp_write_frame(switch_rtp_t *rtp_session, switch_fra
|
||||
}
|
||||
|
||||
|
||||
if (switch_test_flag(frame, SFF_RTP_HEADER)) {
|
||||
switch_size_t wrote;
|
||||
|
||||
wrote = switch_rtp_write_manual(rtp_session, frame->data, frame->datalen,
|
||||
frame->m, frame->payload, (uint32_t) (frame->timestamp), &frame->flags);
|
||||
|
||||
rtp_session->stats.outbound.raw_bytes += wrote;
|
||||
rtp_session->stats.outbound.media_bytes += wrote;
|
||||
rtp_session->stats.outbound.media_packet_count++;
|
||||
rtp_session->stats.outbound.packet_count++;
|
||||
|
||||
return wrote;
|
||||
}
|
||||
|
||||
if (frame->pmap && rtp_session->pmaps && *rtp_session->pmaps) {
|
||||
payload_map_t *pmap;
|
||||
|
||||
@ -8281,6 +8285,7 @@ SWITCH_DECLARE(int) switch_rtp_write_frame(switch_rtp_t *rtp_session, switch_fra
|
||||
if (switch_test_flag(frame, SFF_RAW_RTP_PARSE_FRAME)) {
|
||||
send_msg->header.version = 2;
|
||||
send_msg->header.m = frame->m;
|
||||
|
||||
send_msg->header.ts = htonl(frame->timestamp);
|
||||
if (frame->ssrc) {
|
||||
send_msg->header.ssrc = htonl(frame->ssrc);
|
||||
|
Loading…
x
Reference in New Issue
Block a user