SWITCH_MESSAGE_ANSWER_EVENT,
SWITCH_MESSAGE_PROGRESS_EVENT,
SWITCH_MESSAGE_RING_EVENT,
+ SWITCH_MESSAGE_RESAMPLE_EVENT,
SWITCH_MESSAGE_INVALID
} switch_core_session_message_types_t;
CF_VIDEO_PAUSE,
CF_BYPASS_MEDIA_AFTER_HOLD,
CF_HANGUP_HELD,
+ CF_CONFERENCE_RESET_MEDIA,
/* WARNING: DO NOT ADD ANY FLAGS BELOW THIS LINE */
/* IF YOU ADD NEW ONES CHECK IF THEY SHOULD PERSIST OR ZERO THEM IN switch_core_session.c switch_core_session_request_xml() */
CF_FLAG_MAX
switch_thread_t *input_thread;
cJSON *json;
cJSON *status_field;
+ uint8_t loop_loop;
};
typedef enum {
switch_frame_t *read_frame = NULL;
uint32_t hangover = 40, hangunder = 5, hangover_hits = 0, hangunder_hits = 0, diff_level = 400;
switch_core_session_t *session = member->session;
- uint32_t flush_len;
+ uint32_t flush_len, loops = 0;
if (switch_core_session_read_lock(session) != SWITCH_STATUS_SUCCESS) {
goto end;
member->last_score = member->score;
}
+ if (switch_channel_test_flag(member->channel, CF_CONFERENCE_RESET_MEDIA)) {
+ switch_channel_clear_flag(member->channel, CF_CONFERENCE_RESET_MEDIA);
+ if (++loops > 500) {
+ member->loop_loop = 1;
+
+ if (setup_media(member, member->conference)) {
+ break;
+ }
+ }
+
+ }
+
/* skip frames that are not actual media or when we are muted or silent */
if ((switch_test_flag(member, MFLAG_TALKING) || member->energy_level == 0 || switch_test_flag(member->conference, CFLAG_AUDIO_ALWAYS))
&& switch_test_flag(member, MFLAG_CAN_SPEAK) && !switch_test_flag(member->conference, CFLAG_WAIT_MOD)
{
switch_threadattr_t *thd_attr = NULL;
- if (member == NULL)
+ if (member == NULL || member->input_thread)
return;
switch_threadattr_create(&thd_attr, pool);
call_list = NULL;
cp = NULL;
-
+ member->loop_loop = 0;
switch_assert(member->conference != NULL);
/* Fair WARNING, If you expect the caller to hear anything or for digit handling to be processed, */
/* you better not block this thread loop for more than the duration of member->conference->timer_name! */
- while (switch_test_flag(member, MFLAG_RUNNING) && switch_test_flag(member, MFLAG_ITHREAD)
+ while (!member->loop_loop && switch_test_flag(member, MFLAG_RUNNING) && switch_test_flag(member, MFLAG_ITHREAD)
&& switch_channel_ready(channel)) {
switch_event_t *event;
int use_timer = 0;
end:
- switch_clear_flag_locked(member, MFLAG_RUNNING);
+ if (!member->loop_loop) {
+ switch_clear_flag_locked(member, MFLAG_RUNNING);
- /* Wait for the input thread to end */
- if (member->input_thread) {
- switch_thread_join(&st, member->input_thread);
+ /* Wait for the input thread to end */
+ if (member->input_thread) {
+ switch_thread_join(&st, member->input_thread);
+ }
}
switch_core_timer_destroy(&timer);
+ if (member->loop_loop) {
+ return;
+ }
+
switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "Channel leaving conference, cause: %s\n",
switch_channel_cause2str(switch_channel_get_cause(channel)));
switch_codec_implementation_t read_impl = { 0 };
switch_core_session_get_read_impl(member->session, &read_impl);
- switch_core_session_reset(member->session, SWITCH_TRUE, SWITCH_FALSE);
-
if (switch_core_codec_ready(&member->read_codec)) {
switch_core_codec_destroy(&member->read_codec);
+ memset(&member->read_codec, 0, sizeof(&member->read_codec));
+ }
+
+ if (switch_core_codec_ready(&member->write_codec)) {
+ switch_core_codec_destroy(&member->write_codec);
+ memset(&member->write_codec, 0, sizeof(&member->write_codec));
}
if (member->read_resampler) {
switch_core_session_receive_message(session, &msg);
/* Run the conference loop */
- conference_loop_output(&member);
+ do {
+ conference_loop_output(&member);
+ } while (member.loop_loop);
+
switch_channel_set_private(channel, "_conference_autocall_list_", NULL);
/* Tell the channel we are no longer going to be in a bridge */
case SWITCH_STATUS_RESAMPLE:
if (!session->read_resampler) {
switch_mutex_lock(session->resample_mutex);
+
status = switch_resample_create(&session->read_resampler,
read_frame->codec->implementation->actual_samples_per_second,
session->read_impl.actual_samples_per_second,
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Unable to allocate resampler\n");
status = SWITCH_STATUS_FALSE;
goto done;
+ } else {
+ switch_core_session_message_t msg = { 0 };
+ msg.numeric_arg = 1;
+ msg.message_id = SWITCH_MESSAGE_RESAMPLE_EVENT;
+ switch_core_session_receive_message(session, &msg);
+
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Activating read resampler\n");
}
}
case SWITCH_STATUS_SUCCESS:
switch_resample_destroy(&session->read_resampler);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Deactivating read resampler\n");
switch_mutex_unlock(session->resample_mutex);
+
+ {
+ switch_core_session_message_t msg = { 0 };
+ msg.numeric_arg = 0;
+ msg.message_id = SWITCH_MESSAGE_RESAMPLE_EVENT;
+ switch_core_session_receive_message(session, &msg);
+ }
+
}
status = SWITCH_STATUS_SUCCESS;
switch_mutex_unlock(session->resample_mutex);
if (status != SWITCH_STATUS_SUCCESS) {
goto done;
+ } else {
+ switch_core_session_message_t msg = { 0 };
+ msg.numeric_arg = 1;
+ msg.message_id = SWITCH_MESSAGE_RESAMPLE_EVENT;
+ switch_core_session_receive_message(session, &msg);
+
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Activating write resampler\n");
}
}
break;
switch_resample_destroy(&session->write_resampler);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Deactivating write resampler\n");
switch_mutex_unlock(session->resample_mutex);
+
+ {
+ switch_core_session_message_t msg = { 0 };
+ msg.numeric_arg = 0;
+ msg.message_id = SWITCH_MESSAGE_RESAMPLE_EVENT;
+ switch_core_session_receive_message(session, &msg);
+ }
+
}
write_frame = frame;
status = SWITCH_STATUS_SUCCESS;
if (status != SWITCH_STATUS_SUCCESS) {
goto done;
+ } else {
+ switch_core_session_message_t msg = { 0 };
+ msg.numeric_arg = 1;
+ msg.message_id = SWITCH_MESSAGE_RESAMPLE_EVENT;
+ switch_core_session_receive_message(session, &msg);
+
+
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Activating write resampler\n");
}
}
break;
break;
case SWITCH_STATUS_NOOP:
if (session->write_resampler) {
+ switch_core_session_message_t msg = { 0 };
+ int ok = 0;
+
switch_mutex_lock(session->resample_mutex);
- if (session->write_resampler) {
+ if (session->write_resampler) {
switch_resample_destroy(&session->write_resampler);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Deactivating write resampler\n");
+ ok = 1;
}
switch_mutex_unlock(session->resample_mutex);
+
+ if (ok) {
+ msg.numeric_arg = 0;
+ msg.message_id = SWITCH_MESSAGE_RESAMPLE_EVENT;
+ switch_core_session_receive_message(session, &msg);
+ }
+
}
enc_frame->codec = session->write_codec;
enc_frame->samples = enc_frame->datalen / sizeof(int16_t);
switch (msg->message_id) {
+ case SWITCH_MESSAGE_RESAMPLE_EVENT:
+ {
+ if (switch_channel_test_flag(session->channel, CF_CONFERENCE)) {
+ switch_channel_set_flag(session->channel, CF_CONFERENCE_RESET_MEDIA);
+ }
+ }
+ break;
+
case SWITCH_MESSAGE_INDICATE_VIDEO_REFRESH_REQ:
{
if (v_engine->rtp_session) {
"ANSWER_EVENT",
"PROGRESS_EVENT",
"RING_EVENT",
+ "RESAMPLE_EVENT",
"INVALID"
};