From 0a11b9b4333eb960038feca7972470f3770a5cce Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 18 Nov 2010 16:23:01 -0600 Subject: [PATCH] FS-2859 --- src/include/switch_types.h | 4 +++- src/switch_rtp.c | 49 +++++++++++++++++++++++++++++++++++++- 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/src/include/switch_types.h b/src/include/switch_types.h index c01638089f..12fac04a8b 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -471,7 +471,9 @@ typedef enum { SWITCH_VAD_FLAG_TALKING = (1 << 0), SWITCH_VAD_FLAG_EVENTS_TALK = (1 << 1), SWITCH_VAD_FLAG_EVENTS_NOTALK = (1 << 2), - SWITCH_VAD_FLAG_CNG = (1 << 3) + SWITCH_VAD_FLAG_CNG = (1 << 3), +/* added to keep track when last normal packet sent */ + SWITCH_VAD_NPACKET_SENT = (1 << 4) } switch_vad_flag_enum_t; typedef uint32_t switch_vad_flag_t; diff --git a/src/switch_rtp.c b/src/switch_rtp.c index ee1c4acf5e..e347212ad5 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -240,6 +240,7 @@ struct switch_rtp { switch_time_t send_time; switch_byte_t auto_adj_used; + int last_voicepkt; }; struct switch_rtcp_senderinfo { @@ -1356,6 +1357,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_create(switch_rtp_t **new_rtp_session rtp_session->pool = pool; rtp_session->te = 101; rtp_session->recv_te = 101; + rtp_session->last_voicepkt=0; switch_mutex_init(&rtp_session->flag_mutex, SWITCH_MUTEX_NESTED, pool); switch_mutex_init(&rtp_session->read_mutex, SWITCH_MUTEX_NESTED, pool); @@ -3155,9 +3157,12 @@ static int rtp_common_write(switch_rtp_t *rtp_session, { switch_size_t bytes, rtcp_bytes; uint8_t send = 1; + uint8_t CNdata[10] = { 0 }; + uint8_t sendCN = 0; uint32_t this_ts = 0; int ret; switch_time_t now; + CNdata[0] = 65; if (!switch_rtp_ready(rtp_session)) { return SWITCH_STATUS_FALSE; @@ -3239,9 +3244,15 @@ static int rtp_common_write(switch_rtp_t *rtp_session, rtp_session->recv_msg.header.pt = 102; } + if ( !switch_test_flag(rtp_session,SWITCH_RTP_FLAG_VAD ) ) + switch_set_flag( rtp_session,SWITCH_RTP_FLAG_VAD); + + +/* if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_VAD) && rtp_session->recv_msg.header.pt == rtp_session->vad_data.read_codec->implementation->ianacode) { - +*/ + if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_VAD)) { int16_t decoded[SWITCH_RECOMMENDED_BUFFER_SIZE / sizeof(int16_t)] = { 0 }; uint32_t rate = 0; uint32_t codec_flags = 0; @@ -3290,6 +3301,7 @@ static int rtp_common_write(switch_rtp_t *rtp_session, if (score > rtp_session->vad_data.bg_level && !switch_test_flag(&rtp_session->vad_data, SWITCH_VAD_FLAG_TALKING)) { uint32_t diff = score - rtp_session->vad_data.bg_level; + if (rtp_session->vad_data.hangover_hits) { rtp_session->vad_data.hangover_hits--; } @@ -3342,11 +3354,31 @@ static int rtp_common_write(switch_rtp_t *rtp_session, this_ts = ntohl(send_msg->header.ts); + + /* if previous normal packet is sent but this one is not scheduled to be sent, send a CN packet */ + if ( !rtp_session->last_voicepkt && send==0 ) { + send=1; + sendCN=1; + //switch_set_flag(&rtp_session->vad_data,SWITCH_VAD_NPACKET_SENT ); + rtp_session->last_voicepkt=1; + } + if (!switch_rtp_ready(rtp_session) || rtp_session->sending_dtmf || !this_ts) { send = 0; } + /* we send CN automatically. ignore other attempts */ + if ( send_msg->header.pt == rtp_session->cng_pt ){ + send = 0; + } + + + if (send) { + if ( !sendCN) + rtp_session->last_voicepkt=0; + + send_msg->header.seq = htons(++rtp_session->seq); if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_SECURE_SEND)) { @@ -3441,6 +3473,18 @@ static int rtp_common_write(switch_rtp_t *rtp_session, } } + if ( sendCN ) { + int CNdatalen = 2; + rtp_session->cn++; + memcpy(send_msg->body, CNdata, CNdatalen); + bytes = CNdatalen + rtp_header_len; + payload = rtp_session->cng_pt; + send_msg->header.pt = rtp_session->cng_pt; + send_msg->header.m = 0; + rtp_session->last_voicepkt=1; + } + + if (switch_socket_sendto(rtp_session->sock_output, rtp_session->remote_addr, 0, (void *) send_msg, &bytes) != SWITCH_STATUS_SUCCESS) { rtp_session->seq--; @@ -3523,6 +3567,9 @@ static int rtp_common_write(switch_rtp_t *rtp_session, } } + + + if (rtp_session->remote_stun_addr) { do_stun_ping(rtp_session); }