mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-06-28 20:22:41 +00:00
FS-10088: [freeswitch-core] Backports #resolve
This commit is contained in:
parent
70f4c41184
commit
fa33b30267
@ -231,8 +231,8 @@ SWITCH_BEGIN_EXTERN_C
|
|||||||
#define SWITCH_MAX_TRANS 2000
|
#define SWITCH_MAX_TRANS 2000
|
||||||
#define SWITCH_CORE_SESSION_MAX_PRIVATES 2
|
#define SWITCH_CORE_SESSION_MAX_PRIVATES 2
|
||||||
#define SWITCH_DEFAULT_VIDEO_SIZE 1200
|
#define SWITCH_DEFAULT_VIDEO_SIZE 1200
|
||||||
#define SWITCH_RTCP_AUDIO_INTERVAL_MSEC "5000"
|
#define SWITCH_RTCP_AUDIO_INTERVAL_MSEC "1000"
|
||||||
#define SWITCH_RTCP_VIDEO_INTERVAL_MSEC "2000"
|
#define SWITCH_RTCP_VIDEO_INTERVAL_MSEC "1000"
|
||||||
|
|
||||||
#define MAX_FMTP_LEN 256
|
#define MAX_FMTP_LEN 256
|
||||||
|
|
||||||
@ -773,6 +773,7 @@ typedef enum {
|
|||||||
SWITCH_RTP_FLAG_GEN_TS_DELTA,
|
SWITCH_RTP_FLAG_GEN_TS_DELTA,
|
||||||
SWITCH_RTP_FLAG_GEN_TS_MANUAL,
|
SWITCH_RTP_FLAG_GEN_TS_MANUAL,
|
||||||
SWITCH_RTP_FLAG_DETECT_SSRC,
|
SWITCH_RTP_FLAG_DETECT_SSRC,
|
||||||
|
SWITCH_RTP_FLAG_OLD_FIR,
|
||||||
SWITCH_RTP_FLAG_INVALID
|
SWITCH_RTP_FLAG_INVALID
|
||||||
} switch_rtp_flag_t;
|
} switch_rtp_flag_t;
|
||||||
|
|
||||||
|
@ -3554,6 +3554,8 @@ static switch_status_t check_ice(switch_media_handle_t *smh, switch_media_type_t
|
|||||||
|
|
||||||
if (engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_addr && engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_port) {
|
if (engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_addr && engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_port) {
|
||||||
char tmp[80] = "";
|
char tmp[80] = "";
|
||||||
|
const char *media_varname = NULL, *port_varname = NULL;
|
||||||
|
|
||||||
engine->cur_payload_map->remote_sdp_ip = switch_core_session_strdup(smh->session, (char *) engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_addr);
|
engine->cur_payload_map->remote_sdp_ip = switch_core_session_strdup(smh->session, (char *) engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_addr);
|
||||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_DEBUG,
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_DEBUG,
|
||||||
"setting remote %s ice addr to index %d %s:%d based on candidate\n", type2str(type), engine->ice_in.chosen[0],
|
"setting remote %s ice addr to index %d %s:%d based on candidate\n", type2str(type), engine->ice_in.chosen[0],
|
||||||
@ -3570,12 +3572,23 @@ static switch_status_t check_ice(switch_media_handle_t *smh, switch_media_type_t
|
|||||||
smh->mparams->remote_ip = engine->cur_payload_map->remote_sdp_ip;
|
smh->mparams->remote_ip = engine->cur_payload_map->remote_sdp_ip;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (engine->type == SWITCH_MEDIA_TYPE_VIDEO) {
|
||||||
|
media_varname = "remote_video_rtp_ip";
|
||||||
|
port_varname = "remote_video_rtp_port";
|
||||||
|
} else if (engine->type == SWITCH_MEDIA_TYPE_AUDIO) {
|
||||||
|
media_varname = "remote_audio_rtp_ip";
|
||||||
|
port_varname = "remote_audio_rtp_port";
|
||||||
|
}
|
||||||
|
|
||||||
switch_snprintf(tmp, sizeof(tmp), "%d", engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_port);
|
switch_snprintf(tmp, sizeof(tmp), "%d", engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_port);
|
||||||
switch_channel_set_variable(smh->session->channel, SWITCH_REMOTE_MEDIA_IP_VARIABLE, engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_addr);
|
switch_channel_set_variable(smh->session->channel, media_varname, engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_addr);
|
||||||
switch_channel_set_variable(smh->session->channel, SWITCH_REMOTE_MEDIA_PORT_VARIABLE, tmp);
|
switch_channel_set_variable(smh->session->channel, port_varname, tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (engine->ice_in.cands[engine->ice_in.chosen[1]][1].con_port) {
|
if (engine->ice_in.cands[engine->ice_in.chosen[1]][1].con_port) {
|
||||||
|
char tmp[80] = "";
|
||||||
|
const char *media_varname = NULL, *port_varname = NULL;
|
||||||
|
|
||||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_DEBUG,
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_DEBUG,
|
||||||
"Setting remote rtcp %s addr to %s:%d based on candidate\n", type2str(type),
|
"Setting remote rtcp %s addr to %s:%d based on candidate\n", type2str(type),
|
||||||
engine->ice_in.cands[engine->ice_in.chosen[1]][1].con_addr, engine->ice_in.cands[engine->ice_in.chosen[1]][1].con_port);
|
engine->ice_in.cands[engine->ice_in.chosen[1]][1].con_addr, engine->ice_in.cands[engine->ice_in.chosen[1]][1].con_port);
|
||||||
@ -3583,6 +3596,20 @@ static switch_status_t check_ice(switch_media_handle_t *smh, switch_media_type_t
|
|||||||
engine->remote_rtcp_ice_addr = switch_core_session_strdup(smh->session, engine->ice_in.cands[engine->ice_in.chosen[1]][1].con_addr);
|
engine->remote_rtcp_ice_addr = switch_core_session_strdup(smh->session, engine->ice_in.cands[engine->ice_in.chosen[1]][1].con_addr);
|
||||||
|
|
||||||
engine->remote_rtcp_port = engine->ice_in.cands[engine->ice_in.chosen[1]][1].con_port;
|
engine->remote_rtcp_port = engine->ice_in.cands[engine->ice_in.chosen[1]][1].con_port;
|
||||||
|
|
||||||
|
|
||||||
|
if (engine->type == SWITCH_MEDIA_TYPE_VIDEO) {
|
||||||
|
media_varname = "remote_video_rtcp_ip";
|
||||||
|
port_varname = "remote_video_rtcp_port";
|
||||||
|
} else if (engine->type == SWITCH_MEDIA_TYPE_AUDIO) {
|
||||||
|
media_varname = "remote_audio_rtcp_ip";
|
||||||
|
port_varname = "remote_audio_rtcp_port";
|
||||||
|
}
|
||||||
|
|
||||||
|
switch_snprintf(tmp, sizeof(tmp), "%d", engine->ice_in.cands[engine->ice_in.chosen[1]][1].con_port);
|
||||||
|
switch_channel_set_variable(smh->session->channel, media_varname, engine->ice_in.cands[engine->ice_in.chosen[1]][1].con_addr);
|
||||||
|
switch_channel_set_variable(smh->session->channel, port_varname, tmp);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -5094,6 +5121,32 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
|
|||||||
|
|
||||||
t38_done:
|
t38_done:
|
||||||
|
|
||||||
|
if (v_engine->rtp_session) {
|
||||||
|
if (v_engine->fir) {
|
||||||
|
switch_rtp_set_flag(v_engine->rtp_session, SWITCH_RTP_FLAG_FIR);
|
||||||
|
} else {
|
||||||
|
switch_rtp_clear_flag(v_engine->rtp_session, SWITCH_RTP_FLAG_FIR);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (v_engine->pli) {
|
||||||
|
switch_rtp_set_flag(v_engine->rtp_session, SWITCH_RTP_FLAG_PLI);
|
||||||
|
} else {
|
||||||
|
switch_rtp_clear_flag(v_engine->rtp_session, SWITCH_RTP_FLAG_PLI);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (v_engine->nack) {
|
||||||
|
switch_rtp_set_flag(v_engine->rtp_session, SWITCH_RTP_FLAG_NACK);
|
||||||
|
} else {
|
||||||
|
switch_rtp_clear_flag(v_engine->rtp_session, SWITCH_RTP_FLAG_NACK);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (v_engine->tmmbr) {
|
||||||
|
switch_rtp_set_flag(v_engine->rtp_session, SWITCH_RTP_FLAG_TMMBR);
|
||||||
|
} else {
|
||||||
|
switch_rtp_clear_flag(v_engine->rtp_session, SWITCH_RTP_FLAG_TMMBR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (parser) {
|
if (parser) {
|
||||||
sdp_parser_free(parser);
|
sdp_parser_free(parser);
|
||||||
}
|
}
|
||||||
|
@ -101,6 +101,8 @@ struct switch_jb_s {
|
|||||||
switch_jb_type_t type;
|
switch_jb_type_t type;
|
||||||
switch_core_session_t *session;
|
switch_core_session_t *session;
|
||||||
switch_channel_t *channel;
|
switch_channel_t *channel;
|
||||||
|
uint32_t buffer_lag;
|
||||||
|
uint32_t flush;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -600,7 +602,7 @@ static inline void add_node(switch_jb_t *jb, switch_rtp_packet_t *packet, switch
|
|||||||
ts_diff = abs((int)((int64_t)ntohl(node->packet.header.ts) - (int64_t)ntohl(jb->highest_wrote_ts)));
|
ts_diff = abs((int)((int64_t)ntohl(node->packet.header.ts) - (int64_t)ntohl(jb->highest_wrote_ts)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (((seq_diff >= jb->max_frame_len) || (ts_diff > (900000 * 5)))) {
|
if (((seq_diff >= 100) || (ts_diff > (900000 * 5)))) {
|
||||||
jb_debug(jb, 2, "CHANGE DETECTED, PUNT %u\n", abs(((int)ntohs(packet->header.seq) - ntohs(jb->highest_wrote_seq))));
|
jb_debug(jb, 2, "CHANGE DETECTED, PUNT %u\n", abs(((int)ntohs(packet->header.seq) - ntohs(jb->highest_wrote_seq))));
|
||||||
switch_jb_reset(jb);
|
switch_jb_reset(jb);
|
||||||
}
|
}
|
||||||
@ -622,7 +624,7 @@ static inline void add_node(switch_jb_t *jb, switch_rtp_packet_t *packet, switch
|
|||||||
jb->highest_wrote_ts = packet->header.ts;
|
jb->highest_wrote_ts = packet->header.ts;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (jb->write_init) {
|
if (jb->write_init || jb->type == SJB_AUDIO) {
|
||||||
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_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->complete_frames++;
|
jb->complete_frames++;
|
||||||
} else {
|
} else {
|
||||||
@ -830,7 +832,7 @@ SWITCH_DECLARE(void) switch_jb_clear_flag(switch_jb_t *jb, switch_jb_flag_t flag
|
|||||||
|
|
||||||
SWITCH_DECLARE(int) switch_jb_poll(switch_jb_t *jb)
|
SWITCH_DECLARE(int) switch_jb_poll(switch_jb_t *jb)
|
||||||
{
|
{
|
||||||
return (jb->complete_frames >= jb->frame_len);
|
return (jb->complete_frames >= jb->frame_len) || jb->flush;
|
||||||
}
|
}
|
||||||
|
|
||||||
SWITCH_DECLARE(int) switch_jb_frame_count(switch_jb_t *jb)
|
SWITCH_DECLARE(int) switch_jb_frame_count(switch_jb_t *jb)
|
||||||
@ -1203,12 +1205,18 @@ SWITCH_DECLARE(switch_status_t) switch_jb_get_packet(switch_jb_t *jb, switch_rtp
|
|||||||
switch_mutex_lock(jb->mutex);
|
switch_mutex_lock(jb->mutex);
|
||||||
|
|
||||||
if (jb->complete_frames == 0) {
|
if (jb->complete_frames == 0) {
|
||||||
|
jb->flush = 0;
|
||||||
switch_goto_status(SWITCH_STATUS_BREAK, end);
|
switch_goto_status(SWITCH_STATUS_BREAK, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (jb->complete_frames < jb->frame_len) {
|
if (jb->complete_frames < jb->frame_len) {
|
||||||
jb_debug(jb, 2, "BUFFERING %u/%u\n", jb->complete_frames , jb->frame_len);
|
|
||||||
switch_goto_status(SWITCH_STATUS_MORE_DATA, end);
|
switch_jb_poll(jb);
|
||||||
|
|
||||||
|
if (!jb->flush) {
|
||||||
|
jb_debug(jb, 2, "BUFFERING %u/%u\n", jb->complete_frames , jb->frame_len);
|
||||||
|
switch_goto_status(SWITCH_STATUS_MORE_DATA, end);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
jb_debug(jb, 2, "GET PACKET %u/%u n:%d\n", jb->complete_frames , jb->frame_len, jb->visible_nodes);
|
jb_debug(jb, 2, "GET PACKET %u/%u n:%d\n", jb->complete_frames , jb->frame_len, jb->visible_nodes);
|
||||||
@ -1254,9 +1262,9 @@ SWITCH_DECLARE(switch_status_t) switch_jb_get_packet(switch_jb_t *jb, switch_rtp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
jb->period_miss_pct = ((double)jb->period_miss_count / jb->period_count) * 100;
|
jb->period_miss_pct = ((double)jb->period_miss_count / jb->period_count) * 100;
|
||||||
|
|
||||||
if (jb->period_miss_pct > 60.0f) {
|
if (jb->period_miss_pct > 60.0f) {
|
||||||
@ -1272,7 +1280,8 @@ SWITCH_DECLARE(switch_status_t) switch_jb_get_packet(switch_jb_t *jb, switch_rtp
|
|||||||
jb->highest_read_seq = node->packet.header.seq;
|
jb->highest_read_seq = node->packet.header.seq;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (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_AUDIO ||
|
||||||
|
(jb->read_init && htons(node->packet.header.seq) >= htons(jb->highest_read_seq) && (ntohl(node->packet.header.ts) > ntohl(jb->highest_read_ts)))) {
|
||||||
jb->complete_frames--;
|
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);
|
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);
|
||||||
jb->highest_read_ts = node->packet.header.ts;
|
jb->highest_read_ts = node->packet.header.ts;
|
||||||
|
447
src/switch_rtp.c
447
src/switch_rtp.c
@ -322,6 +322,7 @@ struct switch_rtp {
|
|||||||
rtcp_msg_t rtcp_send_msg;
|
rtcp_msg_t rtcp_send_msg;
|
||||||
switch_rtcp_frame_t rtcp_frame;
|
switch_rtcp_frame_t rtcp_frame;
|
||||||
|
|
||||||
|
uint8_t send_rr;
|
||||||
uint8_t fir_seq;
|
uint8_t fir_seq;
|
||||||
uint16_t fir_count;
|
uint16_t fir_count;
|
||||||
uint16_t pli_count;
|
uint16_t pli_count;
|
||||||
@ -525,7 +526,7 @@ typedef enum {
|
|||||||
static void do_2833(switch_rtp_t *rtp_session);
|
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)
|
static void switch_rtp_change_ice_dest(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, const char *host, switch_port_t port)
|
||||||
@ -1030,7 +1031,6 @@ static void handle_ice(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, void *d
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((ice->type & ICE_VANILLA)) {
|
if ((ice->type & ICE_VANILLA)) {
|
||||||
char foo1[13] = "", foo2[13] = "";
|
|
||||||
if (!ok) ok = !memcmp(packet->header.id, ice->last_sent_id, 12);
|
if (!ok) ok = !memcmp(packet->header.id, ice->last_sent_id, 12);
|
||||||
|
|
||||||
if (packet->header.type == SWITCH_STUN_BINDING_RESPONSE) {
|
if (packet->header.type == SWITCH_STUN_BINDING_RESPONSE) {
|
||||||
@ -1049,9 +1049,6 @@ static void handle_ice(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, void *d
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(foo1, packet->header.id, 12);
|
|
||||||
memcpy(foo2, ice->last_sent_id, 12);
|
|
||||||
|
|
||||||
if (!ok && ice == &rtp_session->ice && rtp_session->rtcp_ice.ice_params && pri &&
|
if (!ok && ice == &rtp_session->ice && rtp_session->rtcp_ice.ice_params && pri &&
|
||||||
*pri == rtp_session->rtcp_ice.ice_params->cands[rtp_session->rtcp_ice.ice_params->chosen[1]][1].priority) {
|
*pri == rtp_session->rtcp_ice.ice_params->cands[rtp_session->rtcp_ice.ice_params->chosen[1]][1].priority) {
|
||||||
ice = &rtp_session->rtcp_ice;
|
ice = &rtp_session->rtcp_ice;
|
||||||
@ -1295,7 +1292,7 @@ static void handle_ice(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, void *d
|
|||||||
msg.message_id = SWITCH_MESSAGE_INDICATE_STUN_ERROR;
|
msg.message_id = SWITCH_MESSAGE_INDICATE_STUN_ERROR;
|
||||||
switch_core_session_receive_message(rtp_session->session, &msg);
|
switch_core_session_receive_message(rtp_session->session, &msg);
|
||||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG,
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG,
|
||||||
"STUN/ICE binding error received on %s channel\n", rtp_session->flags[SWITCH_RTP_FLAG_VIDEO] ? "video" : "audio");
|
"STUN/ICE binding error received on %s channel\n", rtp_type(rtp_session));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1766,7 +1763,7 @@ static void rtcp_generate_sender_info(switch_rtp_t *rtp_session, struct switch_r
|
|||||||
switch_time_t now;
|
switch_time_t now;
|
||||||
uint32_t sec, ntp_sec, ntp_usec;
|
uint32_t sec, ntp_sec, ntp_usec;
|
||||||
switch_time_exp_t now_hr;
|
switch_time_exp_t now_hr;
|
||||||
now = switch_time_now();
|
now = switch_micro_time_now();
|
||||||
sec = (uint32_t)(now/1000000); /* convert to seconds */
|
sec = (uint32_t)(now/1000000); /* convert to seconds */
|
||||||
ntp_sec = sec+NTP_TIME_OFFSET; /* convert to NTP seconds */
|
ntp_sec = sec+NTP_TIME_OFFSET; /* convert to NTP seconds */
|
||||||
sr->ntp_msw = htonl(ntp_sec); /* store result in "most significant word" */
|
sr->ntp_msw = htonl(ntp_sec); /* store result in "most significant word" */
|
||||||
@ -1795,7 +1792,7 @@ static void rtcp_generate_report_block(switch_rtp_t *rtp_session, struct switch_
|
|||||||
uint32_t expected_pkt, dlsr;
|
uint32_t expected_pkt, dlsr;
|
||||||
int32_t pkt_lost;
|
int32_t pkt_lost;
|
||||||
uint32_t ntp_sec, ntp_usec, lsr_now, sec;
|
uint32_t ntp_sec, ntp_usec, lsr_now, sec;
|
||||||
now = switch_time_now();
|
now = switch_micro_time_now();
|
||||||
sec = (uint32_t)(now/1000000); /* convert to seconds */
|
sec = (uint32_t)(now/1000000); /* convert to seconds */
|
||||||
ntp_sec = sec+NTP_TIME_OFFSET; /* convert to NTP seconds */
|
ntp_sec = sec+NTP_TIME_OFFSET; /* convert to NTP seconds */
|
||||||
ntp_usec = (uint32_t)(now - (sec*1000000)); /* remove seconds to keep only the microseconds */
|
ntp_usec = (uint32_t)(now - (sec*1000000)); /* remove seconds to keep only the microseconds */
|
||||||
@ -2007,7 +2004,7 @@ static int using_ice(switch_rtp_t *rtp_session)
|
|||||||
static int check_rtcp_and_ice(switch_rtp_t *rtp_session)
|
static int check_rtcp_and_ice(switch_rtp_t *rtp_session)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
int rtcp_ok = 0, rtcp_fb = 0;
|
int rtcp_ok = 0, rtcp_fb = 0, send_rr = 0;
|
||||||
switch_time_t now = switch_micro_time_now();
|
switch_time_t now = switch_micro_time_now();
|
||||||
int rate = 0, nack_ttl = 0;
|
int rate = 0, nack_ttl = 0;
|
||||||
uint32_t cur_nack[MAX_NACK] = { 0 };
|
uint32_t cur_nack[MAX_NACK] = { 0 };
|
||||||
@ -2057,6 +2054,12 @@ static int check_rtcp_and_ice(switch_rtp_t *rtp_session)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rtp_session->send_rr) {
|
||||||
|
rtp_session->send_rr = 0;
|
||||||
|
rtcp_ok = 1;
|
||||||
|
send_rr = 1;
|
||||||
|
}
|
||||||
|
|
||||||
//switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_ERROR, "TIME CHECK %d > %d\n", (int)((now - rtp_session->rtcp_last_sent) / 1000), rate);
|
//switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_ERROR, "TIME CHECK %d > %d\n", (int)((now - rtp_session->rtcp_last_sent) / 1000), rate);
|
||||||
|
|
||||||
if (!rtcp_ok && (!rtp_session->rtcp_last_sent || (int)((now - rtp_session->rtcp_last_sent) / 1000) > rate)) {
|
if (!rtcp_ok && (!rtp_session->rtcp_last_sent || (int)((now - rtp_session->rtcp_last_sent) / 1000) > rate)) {
|
||||||
@ -2100,7 +2103,7 @@ static int check_rtcp_and_ice(switch_rtp_t *rtp_session)
|
|||||||
rtp_session->rtcp_send_msg.header.count = 1;
|
rtp_session->rtcp_send_msg.header.count = 1;
|
||||||
|
|
||||||
|
|
||||||
if (!rtp_session->stats.rtcp.sent_pkt_count) {
|
if (!rtp_session->stats.rtcp.sent_pkt_count || send_rr) {
|
||||||
rtp_session->rtcp_send_msg.header.type = _RTCP_PT_RR; /* Receiver report */
|
rtp_session->rtcp_send_msg.header.type = _RTCP_PT_RR; /* Receiver report */
|
||||||
rr=(struct switch_rtcp_receiver_report*) rtp_session->rtcp_send_msg.body;
|
rr=(struct switch_rtcp_receiver_report*) rtp_session->rtcp_send_msg.body;
|
||||||
rr->ssrc = htonl(rtp_session->ssrc);
|
rr->ssrc = htonl(rtp_session->ssrc);
|
||||||
@ -2177,6 +2180,16 @@ static int check_rtcp_and_ice(switch_rtp_t *rtp_session)
|
|||||||
switch_rtcp_ext_hdr_t *ext_hdr;
|
switch_rtcp_ext_hdr_t *ext_hdr;
|
||||||
rtcp_fir_t *fir;
|
rtcp_fir_t *fir;
|
||||||
|
|
||||||
|
if (switch_rtp_test_flag(rtp_session, SWITCH_RTP_FLAG_OLD_FIR)) {
|
||||||
|
p = (uint8_t *) (&rtp_session->rtcp_send_msg) + rtcp_bytes;
|
||||||
|
ext_hdr = (switch_rtcp_ext_hdr_t *) p;
|
||||||
|
|
||||||
|
ext_hdr->version = 2;
|
||||||
|
ext_hdr->pt = _RTCP_PT_FIR;
|
||||||
|
rtcp_bytes += sizeof(switch_rtcp_ext_hdr_t);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
p = (uint8_t *) (&rtp_session->rtcp_send_msg) + rtcp_bytes;
|
p = (uint8_t *) (&rtp_session->rtcp_send_msg) + rtcp_bytes;
|
||||||
ext_hdr = (switch_rtcp_ext_hdr_t *) p;
|
ext_hdr = (switch_rtcp_ext_hdr_t *) p;
|
||||||
|
|
||||||
@ -2682,10 +2695,10 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_set_local_address(switch_rtp_t *rtp_s
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rtp_session->flags[SWITCH_RTP_FLAG_VIDEO]) {
|
//if (rtp_session->flags[SWITCH_RTP_FLAG_VIDEO]) {
|
||||||
switch_socket_opt_set(new_sock, SWITCH_SO_RCVBUF, 1572864);
|
//switch_socket_opt_set(new_sock, SWITCH_SO_RCVBUF, 1572864);
|
||||||
switch_socket_opt_set(new_sock, SWITCH_SO_SNDBUF, 1572864);
|
//switch_socket_opt_set(new_sock, SWITCH_SO_SNDBUF, 1572864);
|
||||||
}
|
//}
|
||||||
|
|
||||||
if (switch_socket_bind(new_sock, rtp_session->local_addr) != SWITCH_STATUS_SUCCESS) {
|
if (switch_socket_bind(new_sock, rtp_session->local_addr) != SWITCH_STATUS_SUCCESS) {
|
||||||
char *em = switch_core_sprintf(rtp_session->pool, "Bind Error! %s:%d", host, port);
|
char *em = switch_core_sprintf(rtp_session->pool, "Bind Error! %s:%d", host, port);
|
||||||
@ -3666,7 +3679,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_add_crypto_key(switch_rtp_t *rtp_sess
|
|||||||
|
|
||||||
if (status == SWITCH_STATUS_SUCCESS) {
|
if (status == SWITCH_STATUS_SUCCESS) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_INFO, "Activating %s Secure %s RECV\n",
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_INFO, "Activating %s Secure %s RECV\n",
|
||||||
rtp_session->flags[SWITCH_RTP_FLAG_VIDEO] ? "Video" : "Audio", idx ? "RTCP" : "RTP");
|
rtp_type(rtp_session), idx ? "RTCP" : "RTP");
|
||||||
rtp_session->flags[SWITCH_RTP_FLAG_SECURE_RECV] = 1;
|
rtp_session->flags[SWITCH_RTP_FLAG_SECURE_RECV] = 1;
|
||||||
} else {
|
} else {
|
||||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_ERROR, "Error allocating srtp [%d]\n", stat);
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_ERROR, "Error allocating srtp [%d]\n", stat);
|
||||||
@ -3688,7 +3701,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_add_crypto_key(switch_rtp_t *rtp_sess
|
|||||||
|
|
||||||
if (status == SWITCH_STATUS_SUCCESS) {
|
if (status == SWITCH_STATUS_SUCCESS) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_INFO, "Activating %s Secure %s SEND\n",
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_INFO, "Activating %s Secure %s SEND\n",
|
||||||
rtp_session->flags[SWITCH_RTP_FLAG_VIDEO] ? "Video" : "Audio", idx ? "RTCP" : "RTP");
|
rtp_type(rtp_session), idx ? "RTCP" : "RTP");
|
||||||
rtp_session->flags[SWITCH_RTP_FLAG_SECURE_SEND] = 1;
|
rtp_session->flags[SWITCH_RTP_FLAG_SECURE_SEND] = 1;
|
||||||
} else {
|
} else {
|
||||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_ERROR, "Error allocating SRTP [%d]\n", stat);
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_ERROR, "Error allocating SRTP [%d]\n", stat);
|
||||||
@ -3974,7 +3987,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_create(switch_rtp_t **new_rtp_session
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Jitter */
|
/* Jitter */
|
||||||
rtp_session->stats.inbound.last_proc_time = switch_time_now() / 1000;
|
rtp_session->stats.inbound.last_proc_time = switch_micro_time_now() / 1000;
|
||||||
rtp_session->stats.inbound.jitter_n = 0;
|
rtp_session->stats.inbound.jitter_n = 0;
|
||||||
rtp_session->stats.inbound.jitter_add = 0;
|
rtp_session->stats.inbound.jitter_add = 0;
|
||||||
rtp_session->stats.inbound.jitter_addsq = 0;
|
rtp_session->stats.inbound.jitter_addsq = 0;
|
||||||
@ -4097,11 +4110,11 @@ SWITCH_DECLARE(switch_timer_t *) switch_rtp_get_media_timer(switch_rtp_t *rtp_se
|
|||||||
|
|
||||||
SWITCH_DECLARE(switch_jb_t *) switch_rtp_get_jitter_buffer(switch_rtp_t *rtp_session)
|
SWITCH_DECLARE(switch_jb_t *) switch_rtp_get_jitter_buffer(switch_rtp_t *rtp_session)
|
||||||
{
|
{
|
||||||
if (!switch_rtp_ready(rtp_session) || !rtp_session->jb) {
|
if (!switch_rtp_ready(rtp_session)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return rtp_session->jb;
|
return rtp_session->jb ? rtp_session->jb : rtp_session->vb;
|
||||||
}
|
}
|
||||||
|
|
||||||
SWITCH_DECLARE(switch_status_t) switch_rtp_pause_jitter_buffer(switch_rtp_t *rtp_session, switch_bool_t pause)
|
SWITCH_DECLARE(switch_status_t) switch_rtp_pause_jitter_buffer(switch_rtp_t *rtp_session, switch_bool_t pause)
|
||||||
@ -4127,7 +4140,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_pause_jitter_buffer(switch_rtp_t *rtp
|
|||||||
SWITCH_DECLARE(switch_status_t) switch_rtp_deactivate_jitter_buffer(switch_rtp_t *rtp_session)
|
SWITCH_DECLARE(switch_status_t) switch_rtp_deactivate_jitter_buffer(switch_rtp_t *rtp_session)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (!switch_rtp_ready(rtp_session) || !rtp_session->jb) {
|
if (!switch_rtp_ready(rtp_session)) {
|
||||||
return SWITCH_STATUS_FALSE;
|
return SWITCH_STATUS_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4420,7 +4433,7 @@ SWITCH_DECLARE(void) switch_rtp_video_refresh(switch_rtp_t *rtp_session)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rtp_session->flags[SWITCH_RTP_FLAG_VIDEO] && (rtp_session->ice.ice_user || rtp_session->flags[SWITCH_RTP_FLAG_FIR])) {
|
if (rtp_session->flags[SWITCH_RTP_FLAG_VIDEO] && (rtp_session->ice.ice_user || rtp_session->flags[SWITCH_RTP_FLAG_FIR] || rtp_session->flags[SWITCH_RTP_FLAG_OLD_FIR])) {
|
||||||
rtp_session->fir_count = 1;
|
rtp_session->fir_count = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5906,6 +5919,7 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t
|
|||||||
|
|
||||||
if (vstatus == SWITCH_STATUS_SUCCESS) {
|
if (vstatus == SWITCH_STATUS_SUCCESS) {
|
||||||
rtp_session->last_rtp_hdr = rtp_session->recv_msg.header;
|
rtp_session->last_rtp_hdr = rtp_session->recv_msg.header;
|
||||||
|
|
||||||
if (!xcheck_jitter) {
|
if (!xcheck_jitter) {
|
||||||
check_jitter(rtp_session);
|
check_jitter(rtp_session);
|
||||||
xcheck_jitter = *bytes;
|
xcheck_jitter = *bytes;
|
||||||
@ -5979,6 +5993,7 @@ static void handle_nack(switch_rtp_t *rtp_session, uint32_t nack)
|
|||||||
|
|
||||||
}
|
}
|
||||||
//switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "RE----SEND %u\n", ntohs(send_msg->header.seq));
|
//switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "RE----SEND %u\n", ntohs(send_msg->header.seq));
|
||||||
|
|
||||||
switch_rtp_write_raw(rtp_session, (void *) &send_msg, &bytes, SWITCH_FALSE);
|
switch_rtp_write_raw(rtp_session, (void *) &send_msg, &bytes, SWITCH_FALSE);
|
||||||
} else {
|
} else {
|
||||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG1, "Cannot send NACK for seq %u\n", ntohs(seq) + i);
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG1, "Cannot send NACK for seq %u\n", ntohs(seq) + i);
|
||||||
@ -6009,6 +6024,11 @@ static switch_status_t process_rtcp_report(switch_rtp_t *rtp_session, rtcp_msg_t
|
|||||||
|
|
||||||
if (msg->header.type == _RTCP_PT_FIR) {
|
if (msg->header.type == _RTCP_PT_FIR) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_WARNING, "Ancient FIR Received. Hello from 1996!\n");
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_WARNING, "Ancient FIR Received. Hello from 1996!\n");
|
||||||
|
|
||||||
|
if (!switch_rtp_test_flag(rtp_session, SWITCH_RTP_FLAG_OLD_FIR)) {
|
||||||
|
switch_rtp_set_flag(rtp_session, SWITCH_RTP_FLAG_OLD_FIR);
|
||||||
|
switch_core_session_request_video_refresh(rtp_session->session);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
switch_core_media_gen_key_frame(rtp_session->session);
|
switch_core_media_gen_key_frame(rtp_session->session);
|
||||||
if (rtp_session->vbw) {
|
if (rtp_session->vbw) {
|
||||||
@ -6033,7 +6053,8 @@ static switch_status_t process_rtcp_report(switch_rtp_t *rtp_session, rtcp_msg_t
|
|||||||
switch_core_media_gen_key_frame(rtp_session->session);
|
switch_core_media_gen_key_frame(rtp_session->session);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else
|
} else {
|
||||||
|
struct switch_rtcp_report_block *report;
|
||||||
|
|
||||||
if (msg->header.type == _RTCP_PT_SR || msg->header.type == _RTCP_PT_RR) {
|
if (msg->header.type == _RTCP_PT_SR || msg->header.type == _RTCP_PT_RR) {
|
||||||
switch_time_t now;
|
switch_time_t now;
|
||||||
@ -6044,7 +6065,11 @@ static switch_status_t process_rtcp_report(switch_rtp_t *rtp_session, rtcp_msg_t
|
|||||||
double rtt_now = 0;
|
double rtt_now = 0;
|
||||||
int rtt_increase = 0, packet_loss_increase=0;
|
int rtt_increase = 0, packet_loss_increase=0;
|
||||||
|
|
||||||
now = switch_time_now(); /* number of microseconds since 00:00:00 january 1, 1970 UTC */
|
if (msg->header.type == _RTCP_PT_SR && rtp_session->ice.ice_user) {
|
||||||
|
rtp_session->send_rr = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
now = switch_micro_time_now(); /* number of microseconds since 00:00:00 january 1, 1970 UTC */
|
||||||
sec = (uint32_t)(now/1000000); /* converted to second (NTP most significant bits) */
|
sec = (uint32_t)(now/1000000); /* converted to second (NTP most significant bits) */
|
||||||
ntp_sec = sec+NTP_TIME_OFFSET; /* 32bits most significant */
|
ntp_sec = sec+NTP_TIME_OFFSET; /* 32bits most significant */
|
||||||
ntp_usec = (uint32_t)(now - (sec*1000000)); /* micro seconds */
|
ntp_usec = (uint32_t)(now - (sec*1000000)); /* micro seconds */
|
||||||
@ -6060,7 +6085,7 @@ static switch_status_t process_rtcp_report(switch_rtp_t *rtp_session, rtcp_msg_t
|
|||||||
lsr = (ntohl(sr->sender_info.ntp_lsw)&0xffff0000)>>16 | (ntohl(sr->sender_info.ntp_msw)&0x0000ffff)<<16; /* The middle 32 bits out of 64 in the NTP timestamp */
|
lsr = (ntohl(sr->sender_info.ntp_lsw)&0xffff0000)>>16 | (ntohl(sr->sender_info.ntp_msw)&0x0000ffff)<<16; /* The middle 32 bits out of 64 in the NTP timestamp */
|
||||||
rtp_session->stats.rtcp.last_recv_lsr_peer = htonl(lsr); /* Save it include it in the next SR */
|
rtp_session->stats.rtcp.last_recv_lsr_peer = htonl(lsr); /* Save it include it in the next SR */
|
||||||
rtp_session->stats.rtcp.last_recv_lsr_local = lsr_now; /* Save it to calculate DLSR when generating next SR */
|
rtp_session->stats.rtcp.last_recv_lsr_local = lsr_now; /* Save it to calculate DLSR when generating next SR */
|
||||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG10,"Received a SR with %d report blocks, " \
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG3,"Received a SR with %d report blocks, " \
|
||||||
"length in words = %d, " \
|
"length in words = %d, " \
|
||||||
"SSRC = 0x%X, " \
|
"SSRC = 0x%X, " \
|
||||||
"NTP MSW = %u, " \
|
"NTP MSW = %u, " \
|
||||||
@ -6086,172 +6111,188 @@ static switch_status_t process_rtcp_report(switch_rtp_t *rtp_session, rtcp_msg_t
|
|||||||
rtp_session->rtcp_frame.packet_count = ntohl(sr->sender_info.pc);
|
rtp_session->rtcp_frame.packet_count = ntohl(sr->sender_info.pc);
|
||||||
rtp_session->rtcp_frame.octect_count = ntohl(sr->sender_info.oc);
|
rtp_session->rtcp_frame.octect_count = ntohl(sr->sender_info.oc);
|
||||||
|
|
||||||
for (i = 0; i < (int)msg->header.count && i < MAX_REPORT_BLOCKS ; i++) {
|
report = &sr->report_block;
|
||||||
struct switch_rtcp_report_block *report = (struct switch_rtcp_report_block *) (msg->body + (sizeof(struct switch_rtcp_sr_head) + (i * sizeof(struct switch_rtcp_report_block))));
|
|
||||||
uint32_t old_avg = rtp_session->rtcp_frame.reports[i].loss_avg;
|
|
||||||
uint8_t percent_fraction = (uint8_t)report->fraction * 100 / 256 ;
|
|
||||||
if (!rtp_session->rtcp_frame.reports[i].loss_avg) {
|
|
||||||
rtp_session->rtcp_frame.reports[i].loss_avg = (uint8_t)percent_fraction;
|
|
||||||
} else {
|
|
||||||
rtp_session->rtcp_frame.reports[i].loss_avg = (uint32_t)(((float)rtp_session->rtcp_frame.reports[i].loss_avg * .7) +
|
|
||||||
((float)(uint8_t)percent_fraction * .3));
|
|
||||||
}
|
|
||||||
|
|
||||||
rtp_session->rtcp_frame.reports[i].ssrc = ntohl(report->ssrc);
|
|
||||||
rtp_session->rtcp_frame.reports[i].fraction = (uint8_t)report->fraction;
|
|
||||||
rtp_session->rtcp_frame.reports[i].lost = ntohl(report->lost);
|
|
||||||
rtp_session->rtcp_frame.reports[i].highest_sequence_number_received = ntohl(report->highest_sequence_number_received);
|
|
||||||
rtp_session->rtcp_frame.reports[i].jitter = ntohl(report->jitter);
|
|
||||||
rtp_session->rtcp_frame.reports[i].lsr = ntohl(report->lsr);
|
|
||||||
rtp_session->rtcp_frame.reports[i].dlsr = ntohl(report->dlsr);
|
|
||||||
if (rtp_session->rtcp_frame.reports[i].lsr && !rtp_session->flags[SWITCH_RTP_FLAG_RTCP_PASSTHRU]) {
|
|
||||||
switch_time_exp_gmt(&now_hr,now);
|
|
||||||
/* Calculating RTT = A - DLSR - LSR */
|
|
||||||
rtt_now = (double)(lsr_now - rtp_session->rtcp_frame.reports[i].dlsr - rtp_session->rtcp_frame.reports[i].lsr)/65536;
|
|
||||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG3,
|
|
||||||
"Receiving an RTCP packet\n[%04d-%02d-%02d %02d:%02d:%02d.%d] SSRC[0x%x]\n"
|
|
||||||
"RTT[%f] = A[%u] - DLSR[%u] - LSR[%u]\n",
|
|
||||||
1900 + now_hr.tm_year, now_hr.tm_mday, now_hr.tm_mon, now_hr.tm_hour, now_hr.tm_min, now_hr.tm_sec, now_hr.tm_usec,
|
|
||||||
rtp_session->rtcp_frame.reports[i].ssrc, rtt_now,
|
|
||||||
lsr_now, rtp_session->rtcp_frame.reports[i].dlsr, rtp_session->rtcp_frame.reports[i].lsr);
|
|
||||||
if (!rtp_session->rtcp_frame.reports[i].rtt_avg) {
|
|
||||||
rtp_session->rtcp_frame.reports[i].rtt_avg = rtt_now;
|
|
||||||
} else {
|
|
||||||
rtp_session->rtcp_frame.reports[i].rtt_avg = (double)((rtp_session->rtcp_frame.reports[i].rtt_avg * .7) + (rtt_now * .3 ));
|
|
||||||
}
|
|
||||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG3, "RTT average %f\n",
|
|
||||||
rtp_session->rtcp_frame.reports[i].rtt_avg);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rtp_session->flags[SWITCH_RTP_FLAG_ADJ_BITRATE_CAP] && rtp_session->flags[SWITCH_RTP_FLAG_ESTIMATORS] && !rtp_session->flags[SWITCH_RTP_FLAG_VIDEO]) {
|
|
||||||
|
|
||||||
/* SWITCH_RTP_FLAG_ADJ_BITRATE_CAP : Can the codec change its bitrate on the fly per API command ? */
|
|
||||||
#ifdef DEBUG_ESTIMATORS_
|
|
||||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG3, "Current packet loss: [%d %%] Current RTT: [%f ms]\n", percent_fraction, rtt_now);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
switch_kalman_estimate(rtp_session->estimators[EST_RTT], rtt_now, EST_RTT);
|
|
||||||
|
|
||||||
if (switch_kalman_cusum_detect_change(rtp_session->detectors[EST_RTT], rtt_now, rtp_session->estimators[EST_RTT]->val_estimate_last)) {
|
|
||||||
/* sudden change in the mean value of RTT */
|
|
||||||
#ifdef DEBUG_ESTIMATORS_
|
|
||||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG3,"Sudden change in the mean value of RTT !\n");
|
|
||||||
#endif
|
|
||||||
rtt_increase = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch_kalman_estimate(rtp_session->estimators[EST_LOSS], percent_fraction, EST_LOSS);
|
|
||||||
|
|
||||||
if (switch_kalman_cusum_detect_change(rtp_session->detectors[EST_LOSS], percent_fraction, rtp_session->estimators[EST_LOSS]->val_estimate_last)){
|
|
||||||
/* sudden change in the mean value of packet loss */
|
|
||||||
#ifdef DEBUG_ESTIMATORS_
|
|
||||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG3,"Sudden change in the mean value of packet loss!\n");
|
|
||||||
#endif
|
|
||||||
packet_loss_increase = 1;
|
|
||||||
}
|
|
||||||
#ifdef DEBUG_ESTIMATORS_
|
|
||||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG3, "ESTIMATORS: Packet loss will be: [%f] RTT will be: [%f ms]\n",
|
|
||||||
rtp_session->estimators[EST_LOSS]->val_estimate_last, rtp_session->estimators[EST_RTT]->val_estimate_last);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (rtp_session->rtcp_frame.reports[i].loss_avg != old_avg) {
|
|
||||||
/*getting bad*/
|
|
||||||
if (switch_kalman_is_slow_link(rtp_session->estimators[EST_LOSS],
|
|
||||||
rtp_session->estimators[EST_RTT])) {
|
|
||||||
/* going to minimum bitrate */
|
|
||||||
#ifdef DEBUG_ESTIMATORS_
|
|
||||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG3, "Slow link conditions: Loss average: [%d %%], Previous loss: [%d %%]. \
|
|
||||||
Going to minimum bitrate!",rtp_session->rtcp_frame.reports[i].loss_avg, old_avg);
|
|
||||||
#endif
|
|
||||||
switch_core_media_codec_control(rtp_session->session, SWITCH_MEDIA_TYPE_AUDIO,
|
|
||||||
SWITCH_IO_WRITE, SCC_AUDIO_ADJUST_BITRATE, SCCT_STRING, "minimum", SCCT_NONE, NULL, NULL, NULL);
|
|
||||||
/* if after going to minimum bitrate we still have packet loss then we increase ptime. TODO */
|
|
||||||
|
|
||||||
} else if (packet_loss_increase && (rtp_session->estimators[EST_LOSS]->val_estimate_last >= 5)) {
|
|
||||||
/* sudden change in the mean value of packet loss percentage */
|
|
||||||
switch_core_media_codec_control(rtp_session->session, SWITCH_MEDIA_TYPE_AUDIO,
|
|
||||||
SWITCH_IO_WRITE, SCC_AUDIO_ADJUST_BITRATE,
|
|
||||||
SCCT_STRING, "decrease",
|
|
||||||
SCCT_NONE, NULL, NULL, NULL);
|
|
||||||
#ifdef DEBUG_ESTIMATORS_
|
|
||||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG3,"Sudden change in the mean value of packet loss percentage !\n");
|
|
||||||
#endif
|
|
||||||
switch_core_media_codec_control(rtp_session->session, SWITCH_MEDIA_TYPE_AUDIO,
|
|
||||||
SWITCH_IO_WRITE, SCC_AUDIO_PACKET_LOSS, SCCT_INT,
|
|
||||||
(void *)&rtp_session->rtcp_frame.reports[i].loss_avg,
|
|
||||||
SCCT_NONE, NULL, NULL, NULL);
|
|
||||||
|
|
||||||
} else if (!rtt_increase && rtp_session->estimators[EST_LOSS]->val_estimate_last >= rtp_session->rtcp_frame.reports[i].loss_avg ) {
|
|
||||||
/* lossy because of congestion (queues full somewhere -> some packets are dropped , but RTT is good ), packet loss with many small gaps */
|
|
||||||
#ifdef DEBUG_ESTIMATORS_
|
|
||||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG3, "packet loss, but RTT is not bad\n");
|
|
||||||
#endif
|
|
||||||
switch_core_media_codec_control(rtp_session->session, SWITCH_MEDIA_TYPE_AUDIO,
|
|
||||||
SWITCH_IO_WRITE, SCC_AUDIO_PACKET_LOSS, SCCT_INT,
|
|
||||||
(void *)&rtp_session->rtcp_frame.reports[i].loss_avg,
|
|
||||||
SCCT_NONE, NULL, NULL, NULL);
|
|
||||||
|
|
||||||
} else if ((rtp_session->estimators[EST_LOSS]->val_estimate_last < 1) && packet_loss_increase) {
|
|
||||||
#ifdef DEBUG_ESTIMATORS_
|
|
||||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG3, "small packet loss average\n");
|
|
||||||
#endif
|
|
||||||
/*small loss_avg*/
|
|
||||||
switch_core_media_codec_control(rtp_session->session, SWITCH_MEDIA_TYPE_AUDIO,
|
|
||||||
SWITCH_IO_WRITE, SCC_AUDIO_ADJUST_BITRATE,
|
|
||||||
SCCT_STRING, "default",
|
|
||||||
SCCT_NONE, NULL, NULL, NULL);
|
|
||||||
|
|
||||||
switch_core_media_codec_control(rtp_session->session, SWITCH_MEDIA_TYPE_AUDIO,
|
|
||||||
SWITCH_IO_WRITE, SCC_AUDIO_PACKET_LOSS, SCCT_INT,
|
|
||||||
(void *)&rtp_session->rtcp_frame.reports[i].loss_avg,
|
|
||||||
SCCT_NONE, NULL, NULL, NULL);
|
|
||||||
|
|
||||||
} else if ((rtp_session->estimators[EST_LOSS]->val_estimate_last < 5) &&
|
|
||||||
(rtp_session->rtcp_frame.reports[i].rtt_avg < rtp_session->estimators[EST_RTT]->val_estimate_last)) {
|
|
||||||
|
|
||||||
/* estimate that packet loss will decrease, we can increase the bitrate */
|
|
||||||
switch_core_media_codec_control(rtp_session->session, SWITCH_MEDIA_TYPE_AUDIO,
|
|
||||||
SWITCH_IO_WRITE, SCC_AUDIO_ADJUST_BITRATE,
|
|
||||||
SCCT_STRING, "increase",
|
|
||||||
SCCT_NONE, NULL, NULL, NULL);
|
|
||||||
|
|
||||||
switch_core_media_codec_control(rtp_session->session, SWITCH_MEDIA_TYPE_AUDIO,
|
|
||||||
SWITCH_IO_WRITE, SCC_AUDIO_PACKET_LOSS, SCCT_INT,
|
|
||||||
(void *)&rtp_session->rtcp_frame.reports[i].loss_avg,
|
|
||||||
SCCT_NONE, NULL, NULL, NULL);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
/* *do nothing about bitrate, just pass the packet loss to the codec */
|
|
||||||
#ifdef DEBUG_ESTIMATORS_
|
|
||||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG3,"do nothing about bitrate, just pass the packet loss to the codec\n");
|
|
||||||
#endif
|
|
||||||
switch_core_media_codec_control(rtp_session->session, SWITCH_MEDIA_TYPE_AUDIO,
|
|
||||||
SWITCH_IO_WRITE, SCC_AUDIO_PACKET_LOSS, SCCT_INT,
|
|
||||||
(void *)&rtp_session->rtcp_frame.reports[i].loss_avg,
|
|
||||||
SCCT_NONE, NULL, NULL, NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (!rtp_session->flags[SWITCH_RTP_FLAG_VIDEO] && rtp_session->rtcp_frame.reports[i].loss_avg != old_avg) {
|
|
||||||
switch_core_media_codec_control(rtp_session->session, SWITCH_MEDIA_TYPE_AUDIO,
|
|
||||||
SWITCH_IO_WRITE, SCC_AUDIO_PACKET_LOSS, SCCT_INT,
|
|
||||||
(void *)&rtp_session->rtcp_frame.reports[i].loss_avg,
|
|
||||||
SCCT_NONE, NULL, NULL, NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rtp_session->rtcp_frame.report_count = (uint16_t)i;
|
|
||||||
|
|
||||||
} else { /* Receiver report */
|
} else { /* Receiver report */
|
||||||
struct switch_rtcp_receiver_report* rr = (struct switch_rtcp_receiver_report*)msg->body;
|
struct switch_rtcp_receiver_report* rr = (struct switch_rtcp_receiver_report*)msg->body;
|
||||||
packet_ssrc = rr->ssrc;
|
packet_ssrc = rr->ssrc;
|
||||||
memset(&rtp_session->rtcp_frame, 0, sizeof(rtp_session->rtcp_frame));
|
//memset(&rtp_session->rtcp_frame, 0, sizeof(rtp_session->rtcp_frame));
|
||||||
|
report = &rr->report_block;
|
||||||
|
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG3,"Received a RR with %d report blocks, " \
|
||||||
|
"length in words = %d, " \
|
||||||
|
"SSRC = 0x%X, ",
|
||||||
|
msg->header.count,
|
||||||
|
ntohs((uint16_t)msg->header.length),
|
||||||
|
ntohl(rr->ssrc));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for (i = 0; i < (int)msg->header.count && i < MAX_REPORT_BLOCKS ; i++) {
|
||||||
|
uint32_t old_avg = rtp_session->rtcp_frame.reports[i].loss_avg;
|
||||||
|
uint8_t percent_fraction = (uint8_t)report->fraction * 100 / 256 ;
|
||||||
|
if (!rtp_session->rtcp_frame.reports[i].loss_avg) {
|
||||||
|
rtp_session->rtcp_frame.reports[i].loss_avg = (uint8_t)percent_fraction;
|
||||||
|
} else {
|
||||||
|
rtp_session->rtcp_frame.reports[i].loss_avg = (uint32_t)(((float)rtp_session->rtcp_frame.reports[i].loss_avg * .7) +
|
||||||
|
((float)(uint8_t)percent_fraction * .3));
|
||||||
|
}
|
||||||
|
|
||||||
|
rtp_session->rtcp_frame.reports[i].ssrc = ntohl(report->ssrc);
|
||||||
|
rtp_session->rtcp_frame.reports[i].fraction = (uint8_t)report->fraction;
|
||||||
|
rtp_session->rtcp_frame.reports[i].lost = ntohl(report->lost);
|
||||||
|
rtp_session->rtcp_frame.reports[i].highest_sequence_number_received = ntohl(report->highest_sequence_number_received);
|
||||||
|
rtp_session->rtcp_frame.reports[i].jitter = ntohl(report->jitter);
|
||||||
|
rtp_session->rtcp_frame.reports[i].lsr = ntohl(report->lsr);
|
||||||
|
rtp_session->rtcp_frame.reports[i].dlsr = ntohl(report->dlsr);
|
||||||
|
if (rtp_session->rtcp_frame.reports[i].lsr && !rtp_session->flags[SWITCH_RTP_FLAG_RTCP_PASSTHRU]) {
|
||||||
|
switch_time_exp_gmt(&now_hr,now);
|
||||||
|
/* Calculating RTT = A - DLSR - LSR */
|
||||||
|
rtt_now = (double)(lsr_now - rtp_session->rtcp_frame.reports[i].dlsr - rtp_session->rtcp_frame.reports[i].lsr)/65536;
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG3,
|
||||||
|
"Receiving an RTCP packet\n[%04d-%02d-%02d %02d:%02d:%02d.%d] SSRC[0x%x]\n"
|
||||||
|
"RTT[%f] = A[%u] - DLSR[%u] - LSR[%u]\n",
|
||||||
|
1900 + now_hr.tm_year, now_hr.tm_mday, now_hr.tm_mon, now_hr.tm_hour, now_hr.tm_min, now_hr.tm_sec, now_hr.tm_usec,
|
||||||
|
rtp_session->rtcp_frame.reports[i].ssrc, rtt_now,
|
||||||
|
lsr_now, rtp_session->rtcp_frame.reports[i].dlsr, rtp_session->rtcp_frame.reports[i].lsr);
|
||||||
|
if (!rtp_session->rtcp_frame.reports[i].rtt_avg) {
|
||||||
|
rtp_session->rtcp_frame.reports[i].rtt_avg = rtt_now;
|
||||||
|
} else {
|
||||||
|
rtp_session->rtcp_frame.reports[i].rtt_avg = (double)((rtp_session->rtcp_frame.reports[i].rtt_avg * .7) + (rtt_now * .3 ));
|
||||||
|
}
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG3, "RTT average %f\n",
|
||||||
|
rtp_session->rtcp_frame.reports[i].rtt_avg);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rtp_session->flags[SWITCH_RTP_FLAG_ADJ_BITRATE_CAP] && rtp_session->flags[SWITCH_RTP_FLAG_ESTIMATORS] && !rtp_session->flags[SWITCH_RTP_FLAG_VIDEO]) {
|
||||||
|
|
||||||
|
/* SWITCH_RTP_FLAG_ADJ_BITRATE_CAP : Can the codec change its bitrate on the fly per API command ? */
|
||||||
|
#ifdef DEBUG_ESTIMATORS_
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG3, "Current packet loss: [%d %%] Current RTT: [%f ms]\n", percent_fraction, rtt_now);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
switch_kalman_estimate(rtp_session->estimators[EST_RTT], rtt_now, EST_RTT);
|
||||||
|
|
||||||
|
if (switch_kalman_cusum_detect_change(rtp_session->detectors[EST_RTT], rtt_now, rtp_session->estimators[EST_RTT]->val_estimate_last)) {
|
||||||
|
/* sudden change in the mean value of RTT */
|
||||||
|
#ifdef DEBUG_ESTIMATORS_
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG3,"Sudden change in the mean value of RTT !\n");
|
||||||
|
#endif
|
||||||
|
rtt_increase = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch_kalman_estimate(rtp_session->estimators[EST_LOSS], percent_fraction, EST_LOSS);
|
||||||
|
|
||||||
|
if (switch_kalman_cusum_detect_change(rtp_session->detectors[EST_LOSS], percent_fraction, rtp_session->estimators[EST_LOSS]->val_estimate_last)){
|
||||||
|
/* sudden change in the mean value of packet loss */
|
||||||
|
#ifdef DEBUG_ESTIMATORS_
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG3,"Sudden change in the mean value of packet loss!\n");
|
||||||
|
#endif
|
||||||
|
packet_loss_increase = 1;
|
||||||
|
}
|
||||||
|
#ifdef DEBUG_ESTIMATORS_
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG3, "ESTIMATORS: Packet loss will be: [%f] RTT will be: [%f ms]\n",
|
||||||
|
rtp_session->estimators[EST_LOSS]->val_estimate_last, rtp_session->estimators[EST_RTT]->val_estimate_last);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (rtp_session->rtcp_frame.reports[i].loss_avg != old_avg) {
|
||||||
|
/*getting bad*/
|
||||||
|
if (switch_kalman_is_slow_link(rtp_session->estimators[EST_LOSS],
|
||||||
|
rtp_session->estimators[EST_RTT])) {
|
||||||
|
/* going to minimum bitrate */
|
||||||
|
#ifdef DEBUG_ESTIMATORS_
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG3, "Slow link conditions: Loss average: [%d %%], Previous loss: [%d %%]. \
|
||||||
|
Going to minimum bitrate!",rtp_session->rtcp_frame.reports[i].loss_avg, old_avg);
|
||||||
|
#endif
|
||||||
|
switch_core_media_codec_control(rtp_session->session, SWITCH_MEDIA_TYPE_AUDIO,
|
||||||
|
SWITCH_IO_WRITE, SCC_AUDIO_ADJUST_BITRATE, SCCT_STRING, "minimum", SCCT_NONE, NULL, NULL, NULL);
|
||||||
|
/* if after going to minimum bitrate we still have packet loss then we increase ptime. TODO */
|
||||||
|
|
||||||
|
} else if (packet_loss_increase && (rtp_session->estimators[EST_LOSS]->val_estimate_last >= 5)) {
|
||||||
|
/* sudden change in the mean value of packet loss percentage */
|
||||||
|
switch_core_media_codec_control(rtp_session->session, SWITCH_MEDIA_TYPE_AUDIO,
|
||||||
|
SWITCH_IO_WRITE, SCC_AUDIO_ADJUST_BITRATE,
|
||||||
|
SCCT_STRING, "decrease",
|
||||||
|
SCCT_NONE, NULL, NULL, NULL);
|
||||||
|
#ifdef DEBUG_ESTIMATORS_
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG3,"Sudden change in the mean value of packet loss percentage !\n");
|
||||||
|
#endif
|
||||||
|
switch_core_media_codec_control(rtp_session->session, SWITCH_MEDIA_TYPE_AUDIO,
|
||||||
|
SWITCH_IO_WRITE, SCC_AUDIO_PACKET_LOSS, SCCT_INT,
|
||||||
|
(void *)&rtp_session->rtcp_frame.reports[i].loss_avg,
|
||||||
|
SCCT_NONE, NULL, NULL, NULL);
|
||||||
|
|
||||||
|
} else if (!rtt_increase && rtp_session->estimators[EST_LOSS]->val_estimate_last >= rtp_session->rtcp_frame.reports[i].loss_avg ) {
|
||||||
|
/* lossy because of congestion (queues full somewhere -> some packets are dropped , but RTT is good ), packet loss with many small gaps */
|
||||||
|
#ifdef DEBUG_ESTIMATORS_
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG3, "packet loss, but RTT is not bad\n");
|
||||||
|
#endif
|
||||||
|
switch_core_media_codec_control(rtp_session->session, SWITCH_MEDIA_TYPE_AUDIO,
|
||||||
|
SWITCH_IO_WRITE, SCC_AUDIO_PACKET_LOSS, SCCT_INT,
|
||||||
|
(void *)&rtp_session->rtcp_frame.reports[i].loss_avg,
|
||||||
|
SCCT_NONE, NULL, NULL, NULL);
|
||||||
|
|
||||||
|
} else if ((rtp_session->estimators[EST_LOSS]->val_estimate_last < 1) && packet_loss_increase) {
|
||||||
|
#ifdef DEBUG_ESTIMATORS_
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG3, "small packet loss average\n");
|
||||||
|
#endif
|
||||||
|
/*small loss_avg*/
|
||||||
|
switch_core_media_codec_control(rtp_session->session, SWITCH_MEDIA_TYPE_AUDIO,
|
||||||
|
SWITCH_IO_WRITE, SCC_AUDIO_ADJUST_BITRATE,
|
||||||
|
SCCT_STRING, "default",
|
||||||
|
SCCT_NONE, NULL, NULL, NULL);
|
||||||
|
|
||||||
|
switch_core_media_codec_control(rtp_session->session, SWITCH_MEDIA_TYPE_AUDIO,
|
||||||
|
SWITCH_IO_WRITE, SCC_AUDIO_PACKET_LOSS, SCCT_INT,
|
||||||
|
(void *)&rtp_session->rtcp_frame.reports[i].loss_avg,
|
||||||
|
SCCT_NONE, NULL, NULL, NULL);
|
||||||
|
|
||||||
|
} else if ((rtp_session->estimators[EST_LOSS]->val_estimate_last < 5) &&
|
||||||
|
(rtp_session->rtcp_frame.reports[i].rtt_avg < rtp_session->estimators[EST_RTT]->val_estimate_last)) {
|
||||||
|
|
||||||
|
/* estimate that packet loss will decrease, we can increase the bitrate */
|
||||||
|
switch_core_media_codec_control(rtp_session->session, SWITCH_MEDIA_TYPE_AUDIO,
|
||||||
|
SWITCH_IO_WRITE, SCC_AUDIO_ADJUST_BITRATE,
|
||||||
|
SCCT_STRING, "increase",
|
||||||
|
SCCT_NONE, NULL, NULL, NULL);
|
||||||
|
|
||||||
|
switch_core_media_codec_control(rtp_session->session, SWITCH_MEDIA_TYPE_AUDIO,
|
||||||
|
SWITCH_IO_WRITE, SCC_AUDIO_PACKET_LOSS, SCCT_INT,
|
||||||
|
(void *)&rtp_session->rtcp_frame.reports[i].loss_avg,
|
||||||
|
SCCT_NONE, NULL, NULL, NULL);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
/* *do nothing about bitrate, just pass the packet loss to the codec */
|
||||||
|
#ifdef DEBUG_ESTIMATORS_
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG3,"do nothing about bitrate, just pass the packet loss to the codec\n");
|
||||||
|
#endif
|
||||||
|
switch_core_media_codec_control(rtp_session->session, SWITCH_MEDIA_TYPE_AUDIO,
|
||||||
|
SWITCH_IO_WRITE, SCC_AUDIO_PACKET_LOSS, SCCT_INT,
|
||||||
|
(void *)&rtp_session->rtcp_frame.reports[i].loss_avg,
|
||||||
|
SCCT_NONE, NULL, NULL, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!rtp_session->flags[SWITCH_RTP_FLAG_VIDEO] && rtp_session->rtcp_frame.reports[i].loss_avg != old_avg) {
|
||||||
|
switch_core_media_codec_control(rtp_session->session, SWITCH_MEDIA_TYPE_AUDIO,
|
||||||
|
SWITCH_IO_WRITE, SCC_AUDIO_PACKET_LOSS, SCCT_INT,
|
||||||
|
(void *)&rtp_session->rtcp_frame.reports[i].loss_avg,
|
||||||
|
SCCT_NONE, NULL, NULL, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
report++;
|
||||||
|
}
|
||||||
|
rtp_session->rtcp_frame.report_count = (uint16_t)i;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
rtp_session->rtcp_fresh_frame = 1;
|
rtp_session->rtcp_fresh_frame = 1;
|
||||||
rtp_session->stats.rtcp.peer_ssrc = ntohl(packet_ssrc);
|
rtp_session->stats.rtcp.peer_ssrc = ntohl(packet_ssrc);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (msg->header.type > 194 && msg->header.type < 255) {
|
if (msg->header.type > 194 && msg->header.type < 255) {
|
||||||
status = SWITCH_STATUS_SUCCESS;
|
status = SWITCH_STATUS_SUCCESS;
|
||||||
@ -6478,6 +6519,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
|
|||||||
int hot_socket = 0;
|
int hot_socket = 0;
|
||||||
int read_loops = 0;
|
int read_loops = 0;
|
||||||
int slept = 0;
|
int slept = 0;
|
||||||
|
switch_bool_t got_jb = SWITCH_FALSE;
|
||||||
|
|
||||||
if (!switch_rtp_ready(rtp_session)) {
|
if (!switch_rtp_ready(rtp_session)) {
|
||||||
return -1;
|
return -1;
|
||||||
@ -6642,12 +6684,12 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (rtp_session->flags[SWITCH_RTP_FLAG_VIDEO] && !rtp_session->flags[SWITCH_RTP_FLAG_PROXY_MEDIA]) {
|
if (rtp_session->flags[SWITCH_RTP_FLAG_VIDEO] && !rtp_session->flags[SWITCH_RTP_FLAG_PROXY_MEDIA]) {
|
||||||
pt = 200000;
|
pt = 100000;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rtp_session->vb) {
|
if (rtp_session->vb) {
|
||||||
if (switch_jb_poll(rtp_session->vb)) {
|
if (switch_jb_poll(rtp_session->vb)) {
|
||||||
pt = 0;
|
pt = 1000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6657,11 +6699,6 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
|
|||||||
|
|
||||||
poll_status = switch_poll(rtp_session->read_pollfd, 1, &fdr, pt);
|
poll_status = switch_poll(rtp_session->read_pollfd, 1, &fdr, pt);
|
||||||
|
|
||||||
|
|
||||||
//if (rtp_session->flags[SWITCH_RTP_FLAG_VIDEO]) {
|
|
||||||
// switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_WARNING, "WTF Poll %d\n", poll_status);
|
|
||||||
//}
|
|
||||||
|
|
||||||
if (!rtp_session->flags[SWITCH_RTP_FLAG_VIDEO] && rtp_session->dtmf_data.out_digit_dur > 0) {
|
if (!rtp_session->flags[SWITCH_RTP_FLAG_VIDEO] && rtp_session->dtmf_data.out_digit_dur > 0) {
|
||||||
return_cng_frame();
|
return_cng_frame();
|
||||||
}
|
}
|
||||||
@ -6675,15 +6712,22 @@ 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));
|
||||||
|
} else {
|
||||||
|
got_jb = SWITCH_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
if (poll_status == SWITCH_STATUS_SUCCESS || (rtp_session->vb && switch_jb_poll(rtp_session->vb))) {
|
if (poll_status == SWITCH_STATUS_SUCCESS || got_jb) {
|
||||||
|
|
||||||
got_rtp_poll = 1;
|
got_rtp_poll = 1;
|
||||||
|
|
||||||
if (read_pretriggered) {
|
if (read_pretriggered) {
|
||||||
read_pretriggered = 0;
|
read_pretriggered = 0;
|
||||||
} else {
|
} else {
|
||||||
status = read_rtp_packet(rtp_session, &bytes, flags, pmapP, poll_status, SWITCH_TRUE);
|
|
||||||
|
|
||||||
|
status = read_rtp_packet(rtp_session, &bytes, flags, pmapP, poll_status, got_jb);
|
||||||
|
|
||||||
if (status == SWITCH_STATUS_GENERR) {
|
if (status == SWITCH_STATUS_GENERR) {
|
||||||
ret = -1;
|
ret = -1;
|
||||||
@ -6919,7 +6963,6 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
|
|||||||
rtp_flush_read_buffer(rtp_session, SWITCH_RTP_FLUSH_ONCE);
|
rtp_flush_read_buffer(rtp_session, SWITCH_RTP_FLUSH_ONCE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (rtp_session->last_rtp_hdr.pt == rtp_session->cng_pt || rtp_session->last_rtp_hdr.pt == 13) {
|
if (rtp_session->last_rtp_hdr.pt == rtp_session->cng_pt || rtp_session->last_rtp_hdr.pt == 13) {
|
||||||
*flags |= SFF_NOT_AUDIO;
|
*flags |= SFF_NOT_AUDIO;
|
||||||
} else {
|
} else {
|
||||||
@ -7156,7 +7199,10 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
|
|||||||
do_continue:
|
do_continue:
|
||||||
|
|
||||||
if (!bytes && !rtp_session->flags[SWITCH_RTP_FLAG_USE_TIMER]) {
|
if (!bytes && !rtp_session->flags[SWITCH_RTP_FLAG_USE_TIMER]) {
|
||||||
switch_yield(sleep_mss);
|
|
||||||
|
if (sleep_mss) {
|
||||||
|
switch_yield(sleep_mss);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -7698,7 +7744,7 @@ static int rtp_common_write(switch_rtp_t *rtp_session,
|
|||||||
|
|
||||||
switch_set_flag(&rtp_session->vad_data, SWITCH_VAD_FLAG_TALKING);
|
switch_set_flag(&rtp_session->vad_data, SWITCH_VAD_FLAG_TALKING);
|
||||||
|
|
||||||
rtp_session->vad_data.start_talking = switch_time_now();
|
rtp_session->vad_data.start_talking = switch_micro_time_now();
|
||||||
|
|
||||||
if (!(rtp_session->rtp_bugs & RTP_BUG_NEVER_SEND_MARKER)) {
|
if (!(rtp_session->rtp_bugs & RTP_BUG_NEVER_SEND_MARKER)) {
|
||||||
send_msg->header.m = 1;
|
send_msg->header.m = 1;
|
||||||
@ -7721,7 +7767,7 @@ static int rtp_common_write(switch_rtp_t *rtp_session,
|
|||||||
}
|
}
|
||||||
if (switch_test_flag(&rtp_session->vad_data, SWITCH_VAD_FLAG_TALKING)) {
|
if (switch_test_flag(&rtp_session->vad_data, SWITCH_VAD_FLAG_TALKING)) {
|
||||||
if (++rtp_session->vad_data.hangover_hits >= rtp_session->vad_data.hangover) {
|
if (++rtp_session->vad_data.hangover_hits >= rtp_session->vad_data.hangover) {
|
||||||
rtp_session->vad_data.stop_talking = switch_time_now();
|
rtp_session->vad_data.stop_talking = switch_micro_time_now();
|
||||||
rtp_session->vad_data.total_talk_time += (rtp_session->vad_data.stop_talking - rtp_session->vad_data.start_talking);
|
rtp_session->vad_data.total_talk_time += (rtp_session->vad_data.stop_talking - rtp_session->vad_data.start_talking);
|
||||||
|
|
||||||
switch_clear_flag(&rtp_session->vad_data, SWITCH_VAD_FLAG_TALKING);
|
switch_clear_flag(&rtp_session->vad_data, SWITCH_VAD_FLAG_TALKING);
|
||||||
@ -8028,7 +8074,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_enable_vad(switch_rtp_t *rtp_session,
|
|||||||
rtp_session->vad_data.next_scan = switch_epoch_time_now(NULL);
|
rtp_session->vad_data.next_scan = switch_epoch_time_now(NULL);
|
||||||
rtp_session->vad_data.scan_freq = 0;
|
rtp_session->vad_data.scan_freq = 0;
|
||||||
if (switch_test_flag(&rtp_session->vad_data, SWITCH_VAD_FLAG_TALKING)) {
|
if (switch_test_flag(&rtp_session->vad_data, SWITCH_VAD_FLAG_TALKING)) {
|
||||||
rtp_session->vad_data.start_talking = switch_time_now();
|
rtp_session->vad_data.start_talking = switch_micro_time_now();
|
||||||
}
|
}
|
||||||
switch_rtp_set_flag(rtp_session, SWITCH_RTP_FLAG_VAD);
|
switch_rtp_set_flag(rtp_session, SWITCH_RTP_FLAG_VAD);
|
||||||
switch_set_flag(&rtp_session->vad_data, SWITCH_VAD_FLAG_CNG);
|
switch_set_flag(&rtp_session->vad_data, SWITCH_VAD_FLAG_CNG);
|
||||||
@ -8196,14 +8242,19 @@ SWITCH_DECLARE(int) switch_rtp_write_frame(switch_rtp_t *rtp_session, switch_fra
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (switch_test_flag(frame, SFF_RTP_HEADER)) {
|
if (switch_test_flag(frame, SFF_RTP_HEADER)) {
|
||||||
switch_size_t wrote = switch_rtp_write_manual(rtp_session, frame->data, frame->datalen,
|
switch_size_t wrote;
|
||||||
frame->m, frame->payload, (uint32_t) (frame->timestamp), &frame->flags);
|
|
||||||
|
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.raw_bytes += wrote;
|
||||||
rtp_session->stats.outbound.media_bytes += wrote;
|
rtp_session->stats.outbound.media_bytes += wrote;
|
||||||
rtp_session->stats.outbound.media_packet_count++;
|
rtp_session->stats.outbound.media_packet_count++;
|
||||||
rtp_session->stats.outbound.packet_count++;
|
rtp_session->stats.outbound.packet_count++;
|
||||||
|
|
||||||
|
return wrote;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (frame->pmap && rtp_session->pmaps && *rtp_session->pmaps) {
|
if (frame->pmap && rtp_session->pmaps && *rtp_session->pmaps) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user