From 3249dbf8ced563c1d605a377bc716a3f80f9c3c1 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 19 Nov 2008 20:12:20 +0000 Subject: [PATCH] update git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@10465 d0543943-73ff-0310-b7d9-9358b9ac24b2 --- src/include/switch_types.h | 3 +- src/switch_core_codec.c | 10 ++++++ src/switch_core_io.c | 63 +++++++++++++++++++++++--------------- src/switch_ivr_bridge.c | 12 +++++--- 4 files changed, 57 insertions(+), 31 deletions(-) diff --git a/src/include/switch_types.h b/src/include/switch_types.h index ade6b66408..bc8a8d1273 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -784,7 +784,8 @@ typedef enum { CF_PROXY_MEDIA = (1 << 27), CF_INNER_BRIDGE = (1 << 28), CF_REQ_MEDIA = (1 << 29), - CF_VERBOSE_EVENTS = (1 << 30) + CF_VERBOSE_EVENTS = (1 << 30), + CF_MASTER = (1 << 31) } switch_channel_flag_enum_t; typedef uint32_t switch_channel_flag_t; diff --git a/src/switch_core_codec.c b/src/switch_core_codec.c index 236f86b5c8..d1709049fd 100644 --- a/src/switch_core_codec.c +++ b/src/switch_core_codec.c @@ -44,16 +44,26 @@ SWITCH_DECLARE(uint32_t) switch_core_codec_next_id(void) SWITCH_DECLARE(void) switch_core_session_unset_read_codec(switch_core_session_t *session) { + switch_mutex_t *mutex = NULL; + + if (session->read_codec) mutex = session->read_codec->mutex; + if (mutex) switch_mutex_lock(mutex); session->real_read_codec = session->read_codec = NULL; session->raw_read_frame.codec = session->read_codec; session->raw_write_frame.codec = session->read_codec; session->enc_read_frame.codec = session->read_codec; session->enc_write_frame.codec = session->read_codec; + if (mutex) switch_mutex_unlock(mutex); } SWITCH_DECLARE(void) switch_core_session_unset_write_codec(switch_core_session_t *session) { + switch_mutex_t *mutex = NULL; + + if (session->write_codec) mutex = session->write_codec->mutex; + if (mutex) switch_mutex_lock(mutex); session->real_write_codec = session->write_codec = NULL; + if (mutex) switch_mutex_unlock(mutex); } diff --git a/src/switch_core_io.c b/src/switch_core_io.c index a8d803229b..52b8c31011 100644 --- a/src/switch_core_io.c +++ b/src/switch_core_io.c @@ -103,17 +103,24 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi int stream_id) { switch_io_event_hook_read_frame_t *ptr; - switch_status_t status; + switch_status_t status = SWITCH_STATUS_FALSE; int need_codec, perfect, do_bugs = 0, do_resample = 0, is_cng = 0; unsigned int flag = 0; switch_assert(session != NULL); + if (!(session->read_codec && session->read_codec->implementation)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s has no read codec.\n", switch_channel_get_name(session->channel)); + return SWITCH_STATUS_FALSE; + } + + switch_mutex_lock(session->read_codec->mutex); + top: if (switch_channel_get_state(session->channel) >= CS_HANGUP) { *frame = NULL; - return SWITCH_STATUS_FALSE; + status = SWITCH_STATUS_FALSE; goto even_more_done; } @@ -178,10 +185,6 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi switch_assert((*frame)->codec != NULL); - if (!(session->read_codec && session->read_codec->implementation)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s has no read codec.\n", switch_channel_get_name(session->channel)); - return SWITCH_STATUS_FALSE; - } if (((*frame)->codec && session->read_codec->implementation != (*frame)->codec->implementation)) { need_codec = TRUE; @@ -517,6 +520,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi *frame = &runtime.dummy_cng_frame; } + switch_mutex_unlock(session->read_codec->mutex); + return status; } @@ -578,6 +583,12 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess switch_assert(frame->codec != NULL); switch_assert(frame->codec->implementation != NULL); + if (!(session->write_codec && frame->codec)) { + return SWITCH_STATUS_FALSE; + } + switch_mutex_lock(session->write_codec->mutex); + switch_mutex_lock(frame->codec->mutex); + if ((session->write_codec && frame->codec && session->write_codec->implementation != frame->codec->implementation)) { need_codec = TRUE; if (session->write_codec->implementation->codec_id == frame->codec->implementation->codec_id) { @@ -589,10 +600,6 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess need_codec = TRUE; } - if (!session->write_codec && frame->codec) { - return SWITCH_STATUS_FALSE; - } - if (session->bugs && !need_codec) { do_bugs = TRUE; need_codec = TRUE; @@ -655,7 +662,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess write_frame = &session->raw_write_frame; break; case SWITCH_STATUS_BREAK: - return SWITCH_STATUS_SUCCESS; + status = SWITCH_STATUS_SUCCESS; goto error; case SWITCH_STATUS_NOOP: if (session->write_resampler) { switch_mutex_lock(session->resample_mutex); @@ -669,15 +676,15 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess default: if (status == SWITCH_STATUS_NOT_INITALIZED) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Codec init error!\n"); - return status; + goto error; } if (ptime_mismatch) { status = perform_write(session, frame, flags, stream_id); - return SWITCH_STATUS_SUCCESS; + status = SWITCH_STATUS_SUCCESS; goto error; } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Codec %s decoder error!\n", frame->codec->codec_interface->interface_name); - return status; + goto error; } } @@ -775,13 +782,13 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess bytes * SWITCH_BUFFER_BLOCK_FRAMES, bytes * SWITCH_BUFFER_START_FRAMES, 0)) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Write Buffer Failed!\n"); - return status; + goto error; } } if (!(switch_buffer_write(session->raw_write_buffer, write_frame->data, write_frame->datalen))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Write Buffer %u bytes Failed!\n", write_frame->datalen); - return SWITCH_STATUS_MEMERR; + status = SWITCH_STATUS_MEMERR; goto error; } } @@ -827,18 +834,18 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess case SWITCH_STATUS_NOT_INITALIZED: switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Codec init error!\n"); write_frame = NULL; - return status; + goto error; default: switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Codec %s encoder error!\n", session->read_codec->codec_interface->interface_name); write_frame = NULL; - return status; + goto error; } if (flag & SFF_CNG) { switch_set_flag(write_frame, SFF_CNG); } status = perform_write(session, write_frame, flags, stream_id); - return status; + goto error; } else { switch_size_t used = switch_buffer_inuse(session->raw_write_buffer); uint32_t bytes = session->write_codec->implementation->decoded_bytes_per_packet; @@ -846,7 +853,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess status = SWITCH_STATUS_SUCCESS; if (!frames) { - return status; + goto error; } else { switch_size_t x; for (x = 0; x < frames; x++) { @@ -918,12 +925,12 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess case SWITCH_STATUS_NOT_INITALIZED: switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Codec init error!\n"); write_frame = NULL; - return status; + goto error; default: switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Codec %s encoder error %d!\n", session->read_codec->codec_interface->interface_name, status); write_frame = NULL; - return status; + goto error; } if (session->read_resampler) { @@ -952,7 +959,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess } } } - return status; + goto error; } } } @@ -960,11 +967,17 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess do_write = TRUE; } - done: + done: if (do_write) { - return perform_write(session, frame, flags, stream_id); + status = perform_write(session, frame, flags, stream_id); } + + error: + + switch_mutex_unlock(session->write_codec->mutex); + switch_mutex_unlock(frame->codec->mutex); + return status; } diff --git a/src/switch_ivr_bridge.c b/src/switch_ivr_bridge.c index da51fc9ed1..a428582c44 100644 --- a/src/switch_ivr_bridge.c +++ b/src/switch_ivr_bridge.c @@ -529,7 +529,7 @@ static switch_status_t uuid_bridge_on_reset(switch_core_session_t *session) switch_channel_clear_flag(channel, CF_TRANSFER); switch_channel_clear_flag(channel, CF_ORIGINATING); - if (switch_channel_test_flag(channel, CF_ORIGINATOR)) { + if (switch_channel_test_flag(channel, CF_MASTER)) { switch_channel_set_state(channel, CS_SOFT_EXECUTE); } @@ -547,10 +547,12 @@ static switch_status_t uuid_bridge_on_soft_execute(switch_core_session_t *sessio switch_channel_clear_flag(channel, CF_TRANSFER); - if (!switch_channel_test_flag(channel, CF_ORIGINATOR)) { + if (!switch_channel_test_flag(channel, CF_MASTER)) { return SWITCH_STATUS_SUCCESS; } + switch_channel_clear_flag(channel, CF_MASTER); + if ((other_uuid = switch_channel_get_variable(channel, SWITCH_UUID_BRIDGE)) && (other_session = switch_core_session_locate(other_uuid))) { switch_channel_t *other_channel = switch_core_session_get_channel(other_session); switch_event_t *event; @@ -724,7 +726,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_signal_bridge(switch_core_session_t * switch_channel_set_variable(caller_channel, SWITCH_SIGNAL_BRIDGE_VARIABLE, switch_core_session_get_uuid(peer_session)); switch_channel_set_variable(peer_channel, SWITCH_SIGNAL_BRIDGE_VARIABLE, switch_core_session_get_uuid(session)); - switch_channel_set_state_flag(caller_channel, CF_ORIGINATOR); + switch_channel_set_flag(caller_channel, CF_ORIGINATOR); switch_channel_clear_state_handler(caller_channel, NULL); switch_channel_clear_state_handler(peer_channel, NULL); @@ -1033,8 +1035,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_uuid_bridge(const char *originator_uu switch_channel_clear_state_handler(originator_channel, NULL); switch_channel_clear_state_handler(originatee_channel, NULL); - switch_channel_set_state_flag(originator_channel, CF_ORIGINATOR); - switch_channel_clear_flag(originatee_channel, CF_ORIGINATOR); + switch_channel_set_state_flag(originator_channel, CF_MASTER); + switch_channel_clear_flag(originatee_channel, CF_MASTER); switch_channel_add_state_handler(originator_channel, &uuid_bridge_state_handlers); switch_channel_add_state_handler(originatee_channel, &uuid_bridge_state_handlers); switch_channel_set_variable(originator_channel, SWITCH_UUID_BRIDGE, switch_core_session_get_uuid(originatee_session));