diff --git a/src/include/private/switch_core_pvt.h b/src/include/private/switch_core_pvt.h index 13410a00ae..a565299fae 100644 --- a/src/include/private/switch_core_pvt.h +++ b/src/include/private/switch_core_pvt.h @@ -31,7 +31,7 @@ * this file does not exist!!!! * */ - +#include "spandsp.h" #include "switch_profile.h" #ifndef WIN32 @@ -169,6 +169,7 @@ struct switch_core_session { switch_log_level_t loglevel; uint32_t soft_lock; switch_ivr_dmachine_t *dmachine; + plc_state_t *plc; }; struct switch_media_bug { diff --git a/src/include/switch_rtp.h b/src/include/switch_rtp.h index 7269a2b8d9..e3e9f665a3 100644 --- a/src/include/switch_rtp.h +++ b/src/include/switch_rtp.h @@ -229,7 +229,12 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_activate_rtcp(switch_rtp_t *rtp_sessi \param queue_frames the number of frames to delay \return SWITCH_STATUS_SUCCESS */ -SWITCH_DECLARE(switch_status_t) switch_rtp_activate_jitter_buffer(switch_rtp_t *rtp_session, uint32_t queue_frames); +SWITCH_DECLARE(switch_status_t) switch_rtp_activate_jitter_buffer(switch_rtp_t *rtp_session, + uint32_t queue_frames, + uint32_t max_queue_frames, + uint32_t samples_per_packet, uint32_t samples_per_second); + +SWITCH_DECLARE(switch_status_t) switch_rtp_deactivate_jitter_buffer(switch_rtp_t *rtp_session); /*! \brief Set an RTP Flag diff --git a/src/include/switch_types.h b/src/include/switch_types.h index c01638089f..d020775d48 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -790,6 +790,7 @@ typedef enum { SWITCH_MESSAGE_INDICATE_T38_DESCRIPTION, SWITCH_MESSAGE_INDICATE_UDPTL_MODE, SWITCH_MESSAGE_INDICATE_CLEAR_PROGRESS, + SWITCH_MESSAGE_INDICATE_JITTER_BUFFER, SWITCH_MESSAGE_INVALID } switch_core_session_message_types_t; @@ -1093,6 +1094,7 @@ typedef enum { CF_PASSTHRU_PTIME_MISMATCH, CF_BRIDGE_NOWRITE, CF_RECOVERED, + CF_JITTERBUFFER, /* WARNING: DO NOT ADD ANY FLAGS BELOW THIS LINE */ CF_FLAG_MAX } switch_channel_flag_t; diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index 9d6920e6cd..dba86e3103 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -2542,6 +2542,60 @@ SWITCH_STANDARD_API(uuid_simplify_function) } +#define JITTERBUFFER_SYNTAX " [0|[:]]" +SWITCH_STANDARD_API(uuid_jitterbuffer_function) +{ + char *mydata = NULL, *argv[2] = { 0 }; + int argc = 0; + + switch_status_t status = SWITCH_STATUS_FALSE; + + if (zstr(cmd)) { + goto error; + } + + mydata = strdup(cmd); + switch_assert(mydata); + + argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); + + if (argc < 2) { + goto error; + } + if (argv[1]) { + switch_core_session_message_t msg = { 0 }; + switch_core_session_t *lsession = NULL; + + msg.message_id = SWITCH_MESSAGE_INDICATE_JITTER_BUFFER; + msg.string_arg = argv[1]; + msg.from = __FILE__; + + if ((lsession = switch_core_session_locate(argv[0]))) { + status = switch_core_session_receive_message(lsession, &msg); + switch_core_session_rwunlock(lsession); + } + goto ok; + } else { + goto error; + } + + error: + stream->write_function(stream, "-USAGE: %s\n", JITTERBUFFER_SYNTAX); + switch_safe_free(mydata); + return SWITCH_STATUS_SUCCESS; + ok: + switch_safe_free(mydata); + + if (status == SWITCH_STATUS_SUCCESS) { + stream->write_function(stream, "+OK Success\n"); + } else { + stream->write_function(stream, "-ERR Operation Failed\n"); + } + + return SWITCH_STATUS_SUCCESS; +} + + #define PHONE_EVENT_SYNTAX "" SWITCH_STANDARD_API(uuid_phone_event_function) { @@ -4770,6 +4824,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load) SWITCH_ADD_API(commands_api_interface, "uuid_transfer", "Transfer a session", transfer_function, TRANSFER_SYNTAX); SWITCH_ADD_API(commands_api_interface, "uuid_dual_transfer", "Transfer a session and its partner", dual_transfer_function, DUAL_TRANSFER_SYNTAX); SWITCH_ADD_API(commands_api_interface, "uuid_simplify", "Try to cut out of a call path / attended xfer", uuid_simplify_function, SIMPLIFY_SYNTAX); + SWITCH_ADD_API(commands_api_interface, "uuid_jitterbuffer", "Try to cut out of a call path / attended xfer", + uuid_jitterbuffer_function, JITTERBUFFER_SYNTAX); SWITCH_ADD_API(commands_api_interface, "xml_locate", "find some xml", xml_locate_function, "[root |
]"); SWITCH_ADD_API(commands_api_interface, "xml_wrap", "Wrap another api command in xml", xml_wrap_api_function, " "); switch_console_set_complete("add alias add"); @@ -4866,6 +4922,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load) switch_console_set_complete("add uuid_flush_dtmf ::console::list_uuid"); switch_console_set_complete("add uuid_getvar ::console::list_uuid"); switch_console_set_complete("add uuid_hold ::console::list_uuid"); + switch_console_set_complete("add uuid_jitterbuffer ::console::list_uuid"); switch_console_set_complete("add uuid_kill ::console::list_uuid"); switch_console_set_complete("add uuid_limit_release ::console::list_uuid"); switch_console_set_complete("add uuid_loglevel ::console::list_uuid console"); diff --git a/src/mod/applications/mod_dptools/mod_dptools.c b/src/mod/applications/mod_dptools/mod_dptools.c index eaff5b9364..e508486380 100755 --- a/src/mod/applications/mod_dptools/mod_dptools.c +++ b/src/mod/applications/mod_dptools/mod_dptools.c @@ -957,6 +957,17 @@ SWITCH_STANDARD_APP(redirect_function) switch_core_session_receive_message(session, &msg); } +SWITCH_STANDARD_APP(jitterbuffer_function) +{ + switch_core_session_message_t msg = { 0 }; + + /* Tell the channel to change the jitter buffer */ + msg.from = __FILE__; + msg.string_arg = data; + msg.message_id = SWITCH_MESSAGE_INDICATE_JITTER_BUFFER; + switch_core_session_receive_message(session, &msg); +} + SWITCH_STANDARD_APP(display_function) { switch_core_session_message_t msg = { 0 }; @@ -1303,13 +1314,22 @@ SWITCH_STANDARD_API(strftime_api_function) char date[80] = ""; switch_time_t thetime; char *p; - if (!zstr(cmd) && (p = strchr(cmd, '|'))) { - thetime = switch_time_make(atoi(cmd), 0); + char *mycmd = NULL; + + if (!zstr(cmd)) { + mycmd = strdup(cmd); + } + + if (!zstr(mycmd) && (p = strchr(cmd, '|'))) { + *p++ = '\0'; + + thetime = switch_time_make(atol(cmd), 0); cmd = p + 1; } else { thetime = switch_micro_time_now(); } switch_time_exp_lt(&tm, thetime); + if (zstr(cmd)) { switch_strftime_nocheck(date, &retsize, sizeof(date), "%Y-%m-%d %T", &tm); } else { @@ -3513,6 +3533,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load) SWITCH_ADD_APP(app_interface, "ivr", "Run an ivr menu", "Run an ivr menu.", ivr_application_function, "", SAF_NONE); SWITCH_ADD_APP(app_interface, "redirect", "Send session redirect", "Send a redirect message to a session.", redirect_function, "", SAF_SUPPORT_NOMEDIA); + SWITCH_ADD_APP(app_interface, "jitterbuffer", "Send session jitterbuffer", "Send a jitterbuffer message to a session.", + jitterbuffer_function, "", SAF_SUPPORT_NOMEDIA); SWITCH_ADD_APP(app_interface, "send_display", "Send session a new display", "Send session a new display.", display_function, "", SAF_SUPPORT_NOMEDIA); SWITCH_ADD_APP(app_interface, "respond", "Send session respond", "Send a respond message to a session.", respond_function, "", diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 74c4c0897e..0e64d54a0a 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -906,7 +906,7 @@ static switch_status_t sofia_read_frame(switch_core_session_t *session, switch_f tech_pvt->read_frame.flags = SFF_NONE; status = switch_rtp_zerocopy_read_frame(tech_pvt->rtp_session, &tech_pvt->read_frame, flags); - + if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_BREAK) { if (status == SWITCH_STATUS_TIMEOUT) { @@ -1332,6 +1332,49 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi } } break; + case SWITCH_MESSAGE_INDICATE_JITTER_BUFFER: + { + if (switch_rtp_ready(tech_pvt->rtp_session)) { + int len, maxlen = 0, qlen = 0, maxqlen = 50; + + if (msg->string_arg) { + char *p; + + if ((len = atoi(msg->string_arg))) { + qlen = len / (tech_pvt->read_impl.microseconds_per_packet / 1000); + } + + if (qlen) { + if ((p = strchr(msg->string_arg, ':'))) { + p++; + maxlen = atol(p); + } + } + + + if (maxlen) { + maxqlen = maxlen / (tech_pvt->read_impl.microseconds_per_packet / 1000); + } + } + + if (qlen) { + if (switch_rtp_activate_jitter_buffer(tech_pvt->rtp_session, qlen, maxqlen, + tech_pvt->read_impl.samples_per_packet, + tech_pvt->read_impl.samples_per_second) == SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), + SWITCH_LOG_DEBUG, "Setting Jitterbuffer to %dms (%d frames) (%d max frames)\n", len, qlen, maxqlen); + switch_channel_set_flag(tech_pvt->channel, CF_JITTERBUFFER); + } else { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), + SWITCH_LOG_WARNING, "Error Setting Jitterbuffer to %dms (%d frames)\n", len, qlen); + } + + } else { + switch_rtp_deactivate_jitter_buffer(tech_pvt->rtp_session); + } + } + } + break; case SWITCH_MESSAGE_INDICATE_DEBUG_AUDIO: { if (switch_rtp_ready(tech_pvt->rtp_session) && !zstr(msg->string_array_arg[0]) && !zstr(msg->string_array_arg[1])) { diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index 6416778ab0..74f5d3d764 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -3153,18 +3153,37 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f if ((val = switch_channel_get_variable(tech_pvt->channel, "jitterbuffer_msec"))) { int len = atoi(val); + int maxlen = 50; + char *p; - if (len < 100 || len > 1000) { + if ((p = strchr(val, ':'))) { + p++; + maxlen = atoi(val); + } + + if (len < 20 || len > 10000) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_ERROR, - "Invalid Jitterbuffer spec [%d] must be between 100 and 1000\n", len); + "Invalid Jitterbuffer spec [%d] must be between 20 and 10000\n", len); } else { - int qlen; - + int qlen, maxqlen = 0; + qlen = len / (tech_pvt->read_impl.microseconds_per_packet / 1000); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "Setting Jitterbuffer to %dms (%d frames)\n", len, - qlen); - switch_rtp_activate_jitter_buffer(tech_pvt->rtp_session, qlen); + if (maxlen) { + maxqlen = maxlen / (tech_pvt->read_impl.microseconds_per_packet / 1000); + } + + if (switch_rtp_activate_jitter_buffer(tech_pvt->rtp_session, qlen, maxqlen, + tech_pvt->read_impl.samples_per_packet, + tech_pvt->read_impl.samples_per_second) == SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), + SWITCH_LOG_DEBUG, "Setting Jitterbuffer to %dms (%d frames)\n", len, qlen); + switch_channel_set_flag(tech_pvt->channel, CF_JITTERBUFFER); + } else { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), + SWITCH_LOG_WARNING, "Error Setting Jitterbuffer to %dms (%d frames)\n", len, qlen); + } + } } diff --git a/src/switch_core_io.c b/src/switch_core_io.c index 6f3e65a9f4..a2df79d1bc 100644 --- a/src/switch_core_io.c +++ b/src/switch_core_io.c @@ -235,7 +235,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi if (switch_test_flag(*frame, SFF_CNG)) { status = SWITCH_STATUS_SUCCESS; - if (!session->bugs) { + if (!session->bugs && !session->plc) { goto done; } is_cng = 1; @@ -303,7 +303,13 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi session->raw_read_frame.datalen = session->raw_read_frame.buflen; if (is_cng) { - memset(session->raw_read_frame.data, 255, read_frame->codec->implementation->decoded_bytes_per_packet); + if (session->plc) { + plc_fillin(session->plc, session->raw_read_frame.data, read_frame->codec->implementation->decoded_bytes_per_packet / 2); + is_cng = 0; + flag &= !SFF_CNG; + } else { + memset(session->raw_read_frame.data, 255, read_frame->codec->implementation->decoded_bytes_per_packet); + } session->raw_read_frame.datalen = read_frame->codec->implementation->decoded_bytes_per_packet; session->raw_read_frame.samples = session->raw_read_frame.datalen / sizeof(int16_t); read_frame = &session->raw_read_frame; @@ -326,6 +332,23 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi session->read_impl.actual_samples_per_second, session->raw_read_frame.data, &session->raw_read_frame.datalen, &session->raw_read_frame.rate, &read_frame->flags); + + if (status == SWITCH_STATUS_SUCCESS) { + if (switch_channel_test_flag(session->channel, CF_JITTERBUFFER) && !session->plc) { + session->plc = plc_init(NULL); + } + + if (session->plc) { + if (switch_test_flag(read_frame, SFF_PLC)) { + plc_fillin(session->plc, session->raw_read_frame.data, session->raw_read_frame.datalen / 2); + switch_clear_flag(read_frame, SFF_PLC); + } else { + plc_rx(session->plc, session->raw_read_frame.data, session->raw_read_frame.datalen / 2); + } + } + } + + } if (do_resample && ((status == SWITCH_STATUS_SUCCESS) || is_cng)) { @@ -361,6 +384,10 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi session->raw_read_frame.seq = read_frame->seq; session->raw_read_frame.m = read_frame->m; session->raw_read_frame.payload = read_frame->payload; + session->raw_read_frame.flags = 0; + if (switch_test_flag(read_frame, SFF_PLC)) { + session->raw_read_frame.flags |= SFF_PLC; + } read_frame = &session->raw_read_frame; break; case SWITCH_STATUS_NOOP: @@ -383,6 +410,11 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi session->raw_read_frame.seq = read_frame->seq; session->raw_read_frame.m = read_frame->m; session->raw_read_frame.payload = read_frame->payload; + session->raw_read_frame.flags = 0; + if (switch_test_flag(read_frame, SFF_PLC)) { + session->raw_read_frame.flags |= SFF_PLC; + } + read_frame = &session->raw_read_frame; status = SWITCH_STATUS_SUCCESS; break; @@ -462,7 +494,6 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi read_frame->datalen = session->read_resampler->to_len * 2; read_frame->rate = session->read_resampler->to_rate; switch_mutex_unlock(session->resample_mutex); - } if (read_frame->datalen == session->read_impl.decoded_bytes_per_packet) { @@ -481,7 +512,6 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi } } - if (perfect || switch_buffer_inuse(session->raw_read_buffer) >= session->read_impl.decoded_bytes_per_packet) { if (perfect) { enc_frame = read_frame; @@ -810,6 +840,11 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess session->raw_write_frame.ssrc = frame->ssrc; session->raw_write_frame.seq = frame->seq; session->raw_write_frame.payload = frame->payload; + session->raw_write_frame.flags = 0; + if (switch_test_flag(frame, SFF_PLC)) { + session->raw_write_frame.flags |= SFF_PLC; + } + write_frame = &session->raw_write_frame; break; case SWITCH_STATUS_BREAK: diff --git a/src/switch_ivr.c b/src/switch_ivr.c index 46ba4e6659..6e2aeaf637 100644 --- a/src/switch_ivr.c +++ b/src/switch_ivr.c @@ -2290,7 +2290,7 @@ SWITCH_DECLARE(void) switch_ivr_delay_echo(switch_core_session_t *session, uint3 qlen = delay_ms / (interval); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Setting delay to %dms (%d frames)\n", delay_ms, qlen); - jb = stfu_n_init(qlen, 0); + jb = stfu_n_init(qlen, qlen, read_impl.samples_per_packet, read_impl.samples_per_second); write_frame.codec = switch_core_session_get_read_codec(session); @@ -2300,7 +2300,7 @@ SWITCH_DECLARE(void) switch_ivr_delay_echo(switch_core_session_t *session, uint3 break; } - stfu_n_eat(jb, ts, read_frame->payload, read_frame->data, read_frame->datalen); + stfu_n_eat(jb, ts, 0, read_frame->payload, read_frame->data, read_frame->datalen); ts += interval; if ((jb_frame = stfu_n_read_a_frame(jb))) { diff --git a/src/switch_rtp.c b/src/switch_rtp.c index ee1c4acf5e..aba14b2d0a 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -1618,12 +1618,65 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_activate_stun_ping(switch_rtp_t *rtp_ return SWITCH_STATUS_SUCCESS; } -SWITCH_DECLARE(switch_status_t) switch_rtp_activate_jitter_buffer(switch_rtp_t *rtp_session, uint32_t queue_frames) +static void jb_callback(stfu_instance_t *i, void *udata) +{ + switch_core_session_t *session = (switch_core_session_t *) udata; + stfu_report_t r = { 0 }; + + stfu_n_report(i, &r); + + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, + "%s JB REPORT:\nlen: %u\nin: %u\nclean: %u\ngood: %u\nbad: %u\n", + switch_core_session_get_name(session), + r.qlen, + r.packet_in_count, + r.clean_count, + r.consecutive_good_count, + r.consecutive_bad_count + ); + +} + +SWITCH_DECLARE(switch_status_t) switch_rtp_deactivate_jitter_buffer(switch_rtp_t *rtp_session) +{ + + if (!switch_rtp_ready(rtp_session) || !rtp_session->jb) { + return SWITCH_STATUS_FALSE; + } + + READ_INC(rtp_session); + stfu_n_destroy(&rtp_session->jb); + READ_DEC(rtp_session); + + return SWITCH_STATUS_SUCCESS; +} + +SWITCH_DECLARE(switch_status_t) switch_rtp_activate_jitter_buffer(switch_rtp_t *rtp_session, + uint32_t queue_frames, + uint32_t max_queue_frames, + uint32_t samples_per_packet, + uint32_t samples_per_second) { - rtp_session->jb = stfu_n_init(queue_frames, 0); + if (!switch_rtp_ready(rtp_session)) { + return SWITCH_STATUS_FALSE; + } - return SWITCH_STATUS_SUCCESS; + READ_INC(rtp_session); + if (rtp_session->jb) { + stfu_n_resize(rtp_session->jb, queue_frames); + } else { + rtp_session->jb = stfu_n_init(queue_frames, max_queue_frames || 50, samples_per_packet, samples_per_second); + } + READ_DEC(rtp_session); + + if (rtp_session->jb) { + switch_core_session_t *session = switch_core_memory_pool_get_data(rtp_session->pool, "__session"); + stfu_n_call_me(rtp_session->jb, jb_callback, session); + return SWITCH_STATUS_SUCCESS; + } + + return SWITCH_STATUS_FALSE; } SWITCH_DECLARE(switch_status_t) switch_rtp_activate_rtcp(switch_rtp_t *rtp_session, int send_rate, switch_port_t remote_port) @@ -2016,14 +2069,18 @@ static void do_flush(switch_rtp_t *rtp_session) switch_size_t bytes; switch_status_t status; - if (!switch_rtp_ready(rtp_session) || switch_test_flag(rtp_session, SWITCH_RTP_FLAG_PROXY_MEDIA)) { + if (!switch_rtp_ready(rtp_session) || + switch_test_flag(rtp_session, SWITCH_RTP_FLAG_PROXY_MEDIA) || + switch_test_flag(rtp_session, SWITCH_RTP_FLAG_VIDEO) + ) { return; } READ_INC(rtp_session); if (switch_rtp_ready(rtp_session)) { - + uint32_t flushed = 0; + if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_DEBUG_RTP_READ)) { switch_core_session_t *session = switch_core_memory_pool_get_data(rtp_session->pool, "__session"); if (!session) { @@ -2047,6 +2104,16 @@ static void do_flush(switch_rtp_t *rtp_session) bytes = sizeof(rtp_msg_t); status = switch_socket_recvfrom(rtp_session->from_addr, rtp_session->sock_input, 0, (void *) &rtp_session->recv_msg, &bytes); if (bytes) { + + flushed++; + + if (rtp_session->jb) { + stfu_n_eat(rtp_session->jb, ntohl(rtp_session->recv_msg.header.ts), + ntohs((uint16_t) rtp_session->recv_msg.header.seq), + rtp_session->recv_msg.header.pt, + rtp_session->recv_msg.body, bytes - rtp_header_len); + } + rtp_session->stats.inbound.raw_bytes += bytes; rtp_session->stats.inbound.flush_packet_count++; rtp_session->stats.inbound.packet_count++; @@ -2056,6 +2123,10 @@ static void do_flush(switch_rtp_t *rtp_session) } } while (bytes > 0); + if (rtp_session->jb && flushed) { + stfu_n_sync(rtp_session->jb, flushed); + } + if (was_blocking && switch_rtp_ready(rtp_session)) { switch_clear_flag_locked(rtp_session, SWITCH_RTP_FLAG_NOBLOCK); switch_socket_opt_set(rtp_session->sock_input, SWITCH_SO_NONBLOCK, FALSE); @@ -2104,7 +2175,9 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t stfu_n_reset(rtp_session->jb); } - stfu_n_eat(rtp_session->jb, ntohl(rtp_session->recv_msg.header.ts), rtp_session->recv_msg.header.pt, + stfu_n_eat(rtp_session->jb, ntohl(rtp_session->recv_msg.header.ts), + ntohs((uint16_t) rtp_session->recv_msg.header.seq), + rtp_session->recv_msg.header.pt, rtp_session->recv_msg.body, *bytes - rtp_header_len); *bytes = 0; status = SWITCH_STATUS_FALSE; @@ -2114,14 +2187,14 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t if ((jb_frame = stfu_n_read_a_frame(rtp_session->jb))) { memcpy(rtp_session->recv_msg.body, jb_frame->data, jb_frame->dlen); if (jb_frame->plc) { - *flags |= SFF_PLC; + (*flags) |= SFF_PLC; } else { rtp_session->stats.inbound.jb_packet_count++; } *bytes = jb_frame->dlen + rtp_header_len; rtp_session->recv_msg.header.ts = htonl(jb_frame->ts); rtp_session->recv_msg.header.pt = jb_frame->pt; - + rtp_session->recv_msg.header.seq = htons((uint16_t)jb_frame->seq); status = SWITCH_STATUS_SUCCESS; } } @@ -2824,7 +2897,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ if ((poll_status = switch_poll(rtp_session->read_pollfd, 1, &fdr, 0)) == SWITCH_STATUS_SUCCESS) { goto recvfrom; } - + memset(data, 0, 2); data[0] = 65; rtp_session->recv_msg.header.pt = (uint32_t) rtp_session->cng_pt ? rtp_session->cng_pt : SWITCH_RTP_CNG_PAYLOAD; @@ -3053,6 +3126,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_zerocopy_read_frame(switch_rtp_t *rtp frame->packet = &rtp_session->recv_msg; frame->packetlen = bytes; frame->source = __FILE__; + switch_set_flag(frame, SFF_RAW_RTP); if (frame->payload == rtp_session->recv_te) { switch_set_flag(frame, SFF_RFC2833);