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;
}
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;
*frame = &runtime.dummy_cng_frame;
}
+ switch_mutex_unlock(session->read_codec->mutex);
+
return status;
}
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) {
need_codec = TRUE;
}
- if (!session->write_codec && frame->codec) {
- return SWITCH_STATUS_FALSE;
- }
-
if (session->bugs && !need_codec) {
do_bugs = TRUE;
need_codec = TRUE;
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);
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;
}
}
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;
}
}
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;
status = SWITCH_STATUS_SUCCESS;
if (!frames) {
- return status;
+ goto error;
} else {
switch_size_t x;
for (x = 0; x < frames; x++) {
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) {
}
}
}
- return status;
+ goto error;
}
}
}
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;
}
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);
}
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;
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);
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));