dramatic jitterbuffer changes
This commit is contained in:
parent
bbf1cd1f43
commit
d547096164
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -2542,6 +2542,60 @@ SWITCH_STANDARD_API(uuid_simplify_function)
|
|||
}
|
||||
|
||||
|
||||
#define JITTERBUFFER_SYNTAX "<uuid> [0|<min_msec>[:<max_msec>]]"
|
||||
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 "<uuid>"
|
||||
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 | <section> <tag> <tag_attr_name> <tag_attr_val>]");
|
||||
SWITCH_ADD_API(commands_api_interface, "xml_wrap", "Wrap another api command in xml", xml_wrap_api_function, "<command> <args>");
|
||||
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");
|
||||
|
|
|
@ -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, "<menu_name>", SAF_NONE);
|
||||
SWITCH_ADD_APP(app_interface, "redirect", "Send session redirect", "Send a redirect message to a session.", redirect_function, "<redirect_data>",
|
||||
SAF_SUPPORT_NOMEDIA);
|
||||
SWITCH_ADD_APP(app_interface, "jitterbuffer", "Send session jitterbuffer", "Send a jitterbuffer message to a session.",
|
||||
jitterbuffer_function, "<jitterbuffer_data>", SAF_SUPPORT_NOMEDIA);
|
||||
SWITCH_ADD_APP(app_interface, "send_display", "Send session a new display", "Send session a new display.", display_function, "<text>",
|
||||
SAF_SUPPORT_NOMEDIA);
|
||||
SWITCH_ADD_APP(app_interface, "respond", "Send session respond", "Send a respond message to a session.", respond_function, "<respond_data>",
|
||||
|
|
|
@ -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])) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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))) {
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue