diff --git a/src/include/switch.h b/src/include/switch.h index 4adc41cb3f..fed34cf994 100644 --- a/src/include/switch.h +++ b/src/include/switch.h @@ -41,6 +41,7 @@ extern "C" { #include #include #include +#include #include #include #include @@ -49,7 +50,6 @@ extern "C" { #include #include #include - #include //#include diff --git a/src/include/switch_core.h b/src/include/switch_core.h index 997bc962df..6caa84fa83 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -116,6 +116,7 @@ SWITCH_DECLARE(switch_status) switch_core_codec_destroy(switch_codec *codec); SWITCH_DECLARE(switch_status) switch_core_session_set_read_codec(switch_core_session *session, switch_codec *codec); SWITCH_DECLARE(switch_status) switch_core_session_set_write_codec(switch_core_session *session, switch_codec *codec); SWITCH_DECLARE(switch_memory_pool *) switch_core_session_get_pool(switch_core_session *session); +SWITCH_DECLARE(void) pbx_core_session_signal_state_change(switch_core_session *session); #ifdef __cplusplus } diff --git a/src/include/switch_module_interfaces.h b/src/include/switch_module_interfaces.h index f837e286c8..2fa9dea4b8 100644 --- a/src/include/switch_module_interfaces.h +++ b/src/include/switch_module_interfaces.h @@ -199,7 +199,7 @@ struct switch_codec { struct switch_codec_implementation { int samples_per_second; int bits_per_second; - int nanoseconds_per_frame; + int microseconds_per_frame; int samples_per_frame; int bytes_per_frame; int encoded_bytes_per_frame; diff --git a/src/include/switch_types.h b/src/include/switch_types.h index 952a0b3807..fa4d355b99 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -178,6 +178,7 @@ typedef apr_socket_t switch_socket_t; typedef apr_pollfd_t switch_pollfd_t; typedef apr_pollset_t switch_pollset_t; typedef apr_file_t switch_file_t; +typedef apr_thread_cond_t switch_thread_cond_t; #define SWITCH_UNSPEC APR_UNSPEC #define SWITCH_POLLIN APR_POLLIN @@ -189,6 +190,14 @@ typedef apr_file_t switch_file_t; #define SWITCH_READ APR_READ #define SWITCH_FPROT_UREAD APR_FPROT_UREAD #define SWITCH_FPROT_GREAD APR_FPROT_GREAD + +#define switch_thread_cond_create apr_thread_cond_create +#define switch_thread_cond_wait apr_thread_cond_wait +#define switch_thread_cond_timedwait apr_thread_cond_timedwait +#define switch_thread_cond_signal apr_thread_cond_signal +#define switch_thread_cond_broadcast apr_thread_cond_broadcast +#define switch_thread_cond_destroy apr_thread_cond_destroy + #define switch_poll_setup apr_poll_setup #define switch_pollset_create apr_pollset_create #define switch_pollset_add apr_pollset_add @@ -243,21 +252,21 @@ typedef apr_file_t switch_file_t; #define switch_file_read apr_file_read #define switch_file_write apr_file_write -#define SWITCH_FOPEN_READ APR_FOPEN_READ -#define SWITCH_FOPEN_WRITE APR_FOPEN_WRITE -#define SWITCH_FOPEN_CREATE APR_FOPEN_CREATE -#define SWITCH_FOPEN_APPEND APR_FOPEN_APPEND -#define SWITCH_FOPEN_TRUNCATE APR_FOPEN_TRUNCATE -#define SWITCH_FOPEN_BINARY APR_FOPEN_BINARY -#define SWITCH_FOPEN_EXCL APR_FOPEN_EXCL -#define SWITCH_FOPEN_BUFFERED APR_FOPEN_BUFFERED -#define SWITCH_FOPEN_DELONCLOSE APR_FOPEN_DELONCLOSE -#define SWITCH_FOPEN_XTHREAD APR_FOPEN_XTHREAD -#define SWITCH_FOPEN_SHARELOCK APR_FOPEN_SHARELOCK -#define SWITCH_FOPEN_NOCLEANUP APR_FOPEN_NOCLEANUP -#define SWITCH_FOPEN_SENDFILE_ENABLED APR_FOPEN_SENDFILE_ENABLED -#define SWITCH_FOPEN_LARGEFILE APR_FOPEN_LARGEFILE - +#define SWITCH_FOPEN_READ APR_FOPEN_READ +#define SWITCH_FOPEN_WRITE APR_FOPEN_WRITE +#define SWITCH_FOPEN_CREATE APR_FOPEN_CREATE +#define SWITCH_FOPEN_APPEND APR_FOPEN_APPEND +#define SWITCH_FOPEN_TRUNCATE APR_FOPEN_TRUNCATE +#define SWITCH_FOPEN_BINARY APR_FOPEN_BINARY +#define SWITCH_FOPEN_EXCL APR_FOPEN_EXCL +#define SWITCH_FOPEN_BUFFERED APR_FOPEN_BUFFERED +#define SWITCH_FOPEN_DELONCLOSE APR_FOPEN_DELONCLOSE +#define SWITCH_FOPEN_XTHREAD APR_FOPEN_XTHREAD +#define SWITCH_FOPEN_SHARELOCK APR_FOPEN_SHARELOCK +#define SWITCH_FOPEN_NOCLEANUP APR_FOPEN_NOCLEANUP +#define SWITCH_FOPEN_SENDFILE_ENABLED APR_FOPEN_SENDFILE_ENABLED +#define SWITCH_FOPEN_LARGEFILE APR_FOPEN_LARGEFILE + #define SWITCH_FPROT_USETID APR_FPROT_USETID diff --git a/src/mod/mod_bridgecall/mod_bridgecall.c b/src/mod/mod_bridgecall/mod_bridgecall.c index 148b56bda0..e1c14c342b 100644 --- a/src/mod/mod_bridgecall/mod_bridgecall.c +++ b/src/mod/mod_bridgecall/mod_bridgecall.c @@ -76,7 +76,7 @@ static void *audio_bridge_thread(switch_thread *thread, void *obj) data->running = -1; } } else { - switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Bad Frame.... %d Bubye!\n", read_frame->datalen); + switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Bad Frame....Bubye!\n"); data->running = -1; } switch_yield(100); diff --git a/src/mod/mod_exosip/mod_exosip.c b/src/mod/mod_exosip/mod_exosip.c index 00dad1cda4..695ff8ec7a 100644 --- a/src/mod/mod_exosip/mod_exosip.c +++ b/src/mod/mod_exosip/mod_exosip.c @@ -111,7 +111,7 @@ struct private_object { int local_sdp_audio_port; char call_id[50]; int ssrc; - //switch_mutex_t *rtp_lock; + switch_mutex_t *rtp_lock; }; @@ -373,7 +373,7 @@ static switch_status exosip_outgoing_channel(switch_core_session *session, switc memset(tech_pvt, 0, sizeof(*tech_pvt)); channel = switch_core_session_get_channel(*new_session); switch_core_session_set_private(*new_session, tech_pvt); - //switch_mutex_init(&tech_pvt->rtp_lock, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(*new_session)); + switch_mutex_init(&tech_pvt->rtp_lock, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(*new_session)); tech_pvt->session = *new_session; } else { switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Hey where is my memory pool?\n"); @@ -418,7 +418,7 @@ static void deactivate_rtp(struct private_object *tech_pvt) { int loops = 0; if (tech_pvt->rtp_session) { - //switch_mutex_lock(tech_pvt->rtp_lock); + switch_mutex_lock(tech_pvt->rtp_lock); while(loops < 10 && (switch_test_flag(tech_pvt, TFLAG_READING) || switch_test_flag(tech_pvt, TFLAG_WRITING))) { switch_yield(10000); @@ -427,7 +427,7 @@ static void deactivate_rtp(struct private_object *tech_pvt) ccrtp4c_destroy(&tech_pvt->rtp_session); tech_pvt->rtp_session = NULL; - //switch_mutex_unlock(tech_pvt->rtp_lock); + switch_mutex_unlock(tech_pvt->rtp_lock); } } @@ -443,10 +443,10 @@ static void activate_rtp(struct private_object *tech_pvt) - //switch_mutex_lock(tech_pvt->rtp_lock); + switch_mutex_lock(tech_pvt->rtp_lock); if (switch_test_flag(tech_pvt, TFLAG_USING_CODEC)) { bw = tech_pvt->read_codec.implementation->bits_per_second; - ms = tech_pvt->read_codec.implementation->nanoseconds_per_frame; + ms = tech_pvt->read_codec.implementation->microseconds_per_frame; } else { switch_channel_get_raw_mode(channel, NULL, NULL, NULL, &ms, &bw); bw *= 8; @@ -470,8 +470,8 @@ static void activate_rtp(struct private_object *tech_pvt) tech_pvt->remote_sdp_audio_ip, tech_pvt->remote_sdp_audio_port, tech_pvt->read_codec.codec_interface->ianacode, - ms, - ms * 15); + ms , + ms * 20); if (tech_pvt->rtp_session) { tech_pvt->ssrc = ccrtp4c_get_ssrc(tech_pvt->rtp_session); @@ -481,7 +481,7 @@ static void activate_rtp(struct private_object *tech_pvt) switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Oh oh?\n"); } - //switch_mutex_unlock(tech_pvt->rtp_lock); + switch_mutex_unlock(tech_pvt->rtp_lock); } static switch_status exosip_answer_channel(switch_core_session *session) @@ -521,6 +521,8 @@ static switch_status exosip_read_frame(switch_core_session *session, switch_fram struct private_object *tech_pvt = NULL; size_t bytes = 0, samples = 0, frames=0, ms=0; switch_channel *channel = NULL; + switch_time_t reference, now; + int mult = 2; channel = switch_core_session_get_channel(session); assert(channel != NULL); @@ -534,6 +536,7 @@ static switch_status exosip_read_frame(switch_core_session *session, switch_fram if (switch_test_flag(tech_pvt, TFLAG_USING_CODEC)) { bytes = tech_pvt->read_codec.implementation->encoded_bytes_per_frame; samples = tech_pvt->read_codec.implementation->samples_per_frame; + ms = tech_pvt->read_codec.implementation->microseconds_per_frame; } else { assert(0); } @@ -546,6 +549,8 @@ static switch_status exosip_read_frame(switch_core_session *session, switch_fram assert(tech_pvt->rtp_session != NULL); tech_pvt->read_frame.datalen = 0; + reference = switch_time_now(); + reference += (ms * mult); while(!switch_test_flag(tech_pvt, TFLAG_BYE) && switch_test_flag(tech_pvt, TFLAG_IO) && tech_pvt->read_frame.datalen == 0) { if ((tech_pvt->read_frame.datalen = ccrtp4c_read(tech_pvt->rtp_session, @@ -555,10 +560,21 @@ static switch_status exosip_read_frame(switch_core_session *session, switch_fram bytes = tech_pvt->read_codec.implementation->encoded_bytes_per_frame; frames = (tech_pvt->read_frame.datalen / bytes); samples = frames * tech_pvt->read_codec.implementation->samples_per_frame; - ms = frames * tech_pvt->read_codec.implementation->nanoseconds_per_frame / 1000; + ms = frames * tech_pvt->read_codec.implementation->microseconds_per_frame; tech_pvt->timestamp_recv += samples; break; } + + now = switch_time_now(); + if (now >= reference) { + printf("TO\n"); + //memset(tech_pvt->read_buf, 0, bytes *2); + //tech_pvt->timestamp_recv += (samples * mult); + //reference += (ms * mult); + //tech_pvt->read_frame.datalen = bytes *2; + //break; + } + switch_yield(100); } @@ -601,6 +617,7 @@ static switch_status exosip_write_frame(switch_core_session *session, switch_fra if (!switch_test_flag(tech_pvt, TFLAG_RTP)) { activate_rtp(tech_pvt); + //return SWITCH_STATUS_SUCCESS; } if (!switch_test_flag(tech_pvt, TFLAG_IO)) { @@ -619,7 +636,7 @@ static switch_status exosip_write_frame(switch_core_session *session, switch_fra bytes = tech_pvt->read_codec.implementation->encoded_bytes_per_frame; frames = (frame->datalen / bytes); samples = frames * tech_pvt->read_codec.implementation->samples_per_frame; - ms = frames * tech_pvt->read_codec.implementation->nanoseconds_per_frame / 1000; + ms = frames * tech_pvt->read_codec.implementation->microseconds_per_frame / 1000; } else { assert(0); } @@ -777,7 +794,7 @@ static switch_status exosip_create_call(eXosip_event_t *event) channel = switch_core_session_get_channel(session); switch_core_session_set_private(session, tech_pvt); tech_pvt->session = session; - //switch_mutex_init(&tech_pvt->rtp_lock, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session)); + switch_mutex_init(&tech_pvt->rtp_lock, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session)); } else { switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Hey where is my memory pool?\n"); switch_core_session_destroy(&session); @@ -898,7 +915,7 @@ static switch_status exosip_create_call(eXosip_event_t *event) } else { int ms; switch_set_flag(tech_pvt, TFLAG_USING_CODEC); - ms = tech_pvt->write_codec.implementation->nanoseconds_per_frame / 1000; + ms = tech_pvt->write_codec.implementation->microseconds_per_frame / 1000; switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Activate Inbound Codec %s/%d %d ms\n", dname, rate, ms); tech_pvt->read_frame.codec = &tech_pvt->read_codec; switch_core_session_set_read_codec(session, &tech_pvt->read_codec); @@ -1043,7 +1060,7 @@ static void handle_answer(eXosip_event_t *event) } else { int ms; switch_set_flag(tech_pvt, TFLAG_USING_CODEC); - ms = tech_pvt->write_codec.implementation->nanoseconds_per_frame / 1000; + ms = tech_pvt->write_codec.implementation->microseconds_per_frame / 1000; switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Activate Outbound Codec %s/%d %d ms\n", dname, rate, ms); tech_pvt->read_frame.codec = &tech_pvt->read_codec; switch_core_session_set_read_codec(tech_pvt->session, &tech_pvt->read_codec); diff --git a/src/mod/mod_g711codec/mod_g711codec.c b/src/mod/mod_g711codec/mod_g711codec.c index a58c20d4ca..c9fca24574 100644 --- a/src/mod/mod_g711codec/mod_g711codec.c +++ b/src/mod/mod_g711codec/mod_g711codec.c @@ -189,7 +189,7 @@ static switch_status switch_g711a_destroy(switch_codec *codec) static const switch_codec_implementation g711u_8k_60ms_implementation = { /*.samples_per_second*/ 8000, /*.bits_per_second*/ 19200, - /*.nanoseconds_per_frame*/ 60000, + /*.microseconds_per_frame*/ 60000, /*.samples_per_frame*/ 480, /*.bytes_per_frame*/ 960, /*.encoded_bytes_per_frame*/ 480, @@ -205,7 +205,7 @@ static const switch_codec_implementation g711u_8k_60ms_implementation = { static const switch_codec_implementation g711u_8k_30ms_implementation = { /*.samples_per_second*/ 8000, /*.bits_per_second*/ 96000, - /*.nanoseconds_per_frame*/ 30000, + /*.microseconds_per_frame*/ 30000, /*.samples_per_frame*/ 240, /*.bytes_per_frame*/ 480, /*.encoded_bytes_per_frame*/ 240, @@ -222,7 +222,7 @@ static const switch_codec_implementation g711u_8k_30ms_implementation = { static const switch_codec_implementation g711u_8k_implementation = { /*.samples_per_second*/ 8000, /*.bits_per_second*/ 64000, - /*.nanoseconds_per_frame*/ 20000, + /*.microseconds_per_frame*/ 20000, /*.samples_per_frame*/ 160, /*.bytes_per_frame*/ 320, /*.encoded_bytes_per_frame*/ 160, @@ -240,7 +240,7 @@ static const switch_codec_implementation g711u_8k_implementation = { static const switch_codec_implementation g711a_8k_implementation = { /*.samples_per_second*/ 8000, /*.bits_per_second*/ 64000, - /*.nanoseconds_per_frame*/ 20000, + /*.microseconds_per_frame*/ 20000, /*.samples_per_frame*/ 160, /*.bytes_per_frame*/ 320, /*.encoded_bytes_per_frame*/ 160, diff --git a/src/mod/mod_playback/mod_playback.c b/src/mod/mod_playback/mod_playback.c index 3fdc036398..d88e30125c 100644 --- a/src/mod/mod_playback/mod_playback.c +++ b/src/mod/mod_playback/mod_playback.c @@ -124,7 +124,7 @@ void playback_function(switch_core_session *session, char *data) switch_core_codec_destroy(&codec); - switch_channel_set_state(channel, CS_HANGUP); + switch_channel_hangup(channel); } static const switch_application_interface playback_application_interface = { diff --git a/src/mod/mod_rawaudio/mod_rawaudio.c b/src/mod/mod_rawaudio/mod_rawaudio.c index f22800741e..fa9e5cb2df 100644 --- a/src/mod/mod_rawaudio/mod_rawaudio.c +++ b/src/mod/mod_rawaudio/mod_rawaudio.c @@ -90,7 +90,7 @@ static const switch_codec_implementation raw_32k_implementation = { /*.samples_per_frame = */ 640, /*.bytes_per_frame = */ 1280, /*.encoded_bytes_per_frame = */ 1280, - /*.nanoseconds_per_frame = */ 20000, + /*.microseconds_per_frame = */ 20000, /*.number_of_channels = */ 1, /*.pref_frames_per_packet = */ 1, /*.max_frames_per_packet = */ 1, @@ -103,7 +103,7 @@ static const switch_codec_implementation raw_32k_implementation = { static const switch_codec_implementation raw_16k_implementation = { /*.samples_per_second = */ 16000, /*.bits_per_second = */ 256000, - /*.nanoseconds_per_frame = */ 20000, + /*.microseconds_per_frame = */ 20000, /*.samples_per_frame = */ 320, /*.bytes_per_frame = */ 640, /*.encoded_bytes_per_frame = */ 640, @@ -120,7 +120,7 @@ static const switch_codec_implementation raw_16k_implementation = { static const switch_codec_implementation raw_8k_implementation = { /*.samples_per_second = */ 8000, /*.bits_per_second = */ 128000, - /*.nanoseconds_per_frame = */ 20000, + /*.microseconds_per_frame = */ 20000, /*.samples_per_frame = */ 160, /*.bytes_per_frame = */ 320, /*.encoded_bytes_per_frame = */ 320, @@ -138,7 +138,7 @@ static const switch_codec_implementation raw_8k_implementation = { static const switch_codec_implementation raw_8k_30ms_implementation = { /*.samples_per_second*/ 8000, /*.bits_per_second*/ 128000, - /*.nanoseconds_per_frame*/ 30000, + /*.microseconds_per_frame*/ 30000, /*.samples_per_frame*/ 240, /*.bytes_per_frame*/ 480, /*.encoded_bytes_per_frame*/ 480, diff --git a/src/switch_channel.c b/src/switch_channel.c index b9f5f72686..f7028c0cc4 100644 --- a/src/switch_channel.c +++ b/src/switch_channel.c @@ -347,8 +347,10 @@ SWITCH_DECLARE(switch_channel_state) switch_channel_set_state(switch_channel *ch if (ok) { switch_console_printf(SWITCH_CHANNEL_CONSOLE, "%s State Change %s -> %s\n", channel->name, state_names[last_state], state_names[state]); channel->state = state; + pbx_core_session_signal_state_change(channel->session); } else { switch_console_printf(SWITCH_CHANNEL_CONSOLE, "%s Invalid State Change %s -> %s\n", channel->name, state_names[last_state], state_names[state]); + //we won't tolerate an invalid state change so we can make sure we are as robust as a nice cup of dark coffee! assert(0); } return channel->state; @@ -410,8 +412,8 @@ SWITCH_DECLARE(switch_status) switch_channel_hangup(switch_channel *channel) assert(channel != NULL); if (channel->state < CS_HANGUP) { channel->state = CS_HANGUP; + pbx_core_session_signal_state_change(channel->session); } - return channel->state; } diff --git a/src/switch_core.c b/src/switch_core.c index 949af4a73a..2c733f6faf 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -66,6 +66,9 @@ struct switch_core_session { unsigned char *raw_read_buf[3200]; unsigned char *enc_read_buf[3200]; + switch_mutex_t *mutex; + switch_thread_cond_t *cond; + void *private; }; @@ -168,7 +171,7 @@ SWITCH_DECLARE(switch_status) switch_core_codec_init(switch_codec *codec, char * } for(iptr = codec_interface->implementations; iptr; iptr = iptr->next) { - if ((!rate || rate == iptr->samples_per_second) && (!ms || ms == (iptr->nanoseconds_per_frame / 1000))) { + if ((!rate || rate == iptr->samples_per_second) && (!ms || ms == (iptr->microseconds_per_frame / 1000))) { implementation = iptr; break; } @@ -339,9 +342,12 @@ SWITCH_DECLARE(void) switch_core_thread_session_end(switch_core_thread_session * switch_core_session_kill_channel(session, SWITCH_SIG_KILL); - thread_session->running = -1; - while(thread_session->running) { - switch_yield(100); + if (thread_session->running > 0) { + thread_session->running = -1; + + while(thread_session->running) { + switch_yield(1000); + } } } @@ -1074,6 +1080,11 @@ static void switch_core_standard_on_transmit(switch_core_session *session) } +SWITCH_DECLARE(void) pbx_core_session_signal_state_change(switch_core_session *session) +{ + switch_thread_cond_signal(session->cond); +} + SWITCH_DECLARE(void) switch_core_session_run(switch_core_session *session) { switch_channel_state state = CS_NEW, laststate = CS_HANGUP; @@ -1105,6 +1116,8 @@ SWITCH_DECLARE(void) switch_core_session_run(switch_core_session *session) driver_event_handlers = endpoint_interface->event_handlers; assert(driver_event_handlers != NULL); + switch_mutex_lock(session->mutex); + while ((state = switch_channel_get_state(session->channel)) != CS_DONE) { if (state != laststate) { switch ( state ) { @@ -1190,10 +1203,11 @@ SWITCH_DECLARE(void) switch_core_session_run(switch_core_session *session) } laststate = state; } - //I should fall asleep here if possible!!! - switch_yield(1000); - } + if (state < CS_DONE) { + switch_thread_cond_wait(session->cond, session->mutex); + } + } } SWITCH_DECLARE(void) switch_core_session_destroy(switch_core_session **session) @@ -1373,6 +1387,9 @@ SWITCH_DECLARE(switch_core_session *) switch_core_session_request(const switch_e session->enc_write_frame.data = session->enc_write_buf; session->enc_read_frame.data = session->enc_read_buf; + switch_mutex_init(&session->mutex, SWITCH_MUTEX_NESTED ,session->pool); + switch_thread_cond_create(&session->cond, session->pool); + return session; } diff --git a/src/switch_loadable_module.c b/src/switch_loadable_module.c index e5e87ccdbb..ec208d65d0 100644 --- a/src/switch_loadable_module.c +++ b/src/switch_loadable_module.c @@ -244,7 +244,7 @@ SWITCH_DECLARE(switch_status) switch_loadable_module_init() ptr->iananame, ptr->interface_name, impl->samples_per_second, - impl->nanoseconds_per_frame / 1000); + impl->microseconds_per_frame / 1000); } switch_core_hash_insert(loadable_modules.codec_hash,