mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-07-06 07:29:30 +00:00
add a way to tell mod_conference when the rate of the channel has changed due to a codec change so it can reset the resampler and codecs internally
This commit is contained in:
parent
a491df05f1
commit
bd4a0d8cbc
@ -1013,6 +1013,7 @@ typedef enum {
|
|||||||
SWITCH_MESSAGE_ANSWER_EVENT,
|
SWITCH_MESSAGE_ANSWER_EVENT,
|
||||||
SWITCH_MESSAGE_PROGRESS_EVENT,
|
SWITCH_MESSAGE_PROGRESS_EVENT,
|
||||||
SWITCH_MESSAGE_RING_EVENT,
|
SWITCH_MESSAGE_RING_EVENT,
|
||||||
|
SWITCH_MESSAGE_RESAMPLE_EVENT,
|
||||||
SWITCH_MESSAGE_INVALID
|
SWITCH_MESSAGE_INVALID
|
||||||
} switch_core_session_message_types_t;
|
} switch_core_session_message_types_t;
|
||||||
|
|
||||||
@ -1407,6 +1408,7 @@ typedef enum {
|
|||||||
CF_VIDEO_PAUSE,
|
CF_VIDEO_PAUSE,
|
||||||
CF_BYPASS_MEDIA_AFTER_HOLD,
|
CF_BYPASS_MEDIA_AFTER_HOLD,
|
||||||
CF_HANGUP_HELD,
|
CF_HANGUP_HELD,
|
||||||
|
CF_CONFERENCE_RESET_MEDIA,
|
||||||
/* WARNING: DO NOT ADD ANY FLAGS BELOW THIS LINE */
|
/* 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() */
|
/* 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
|
CF_FLAG_MAX
|
||||||
|
@ -485,6 +485,7 @@ struct conference_member {
|
|||||||
switch_thread_t *input_thread;
|
switch_thread_t *input_thread;
|
||||||
cJSON *json;
|
cJSON *json;
|
||||||
cJSON *status_field;
|
cJSON *status_field;
|
||||||
|
uint8_t loop_loop;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@ -3659,7 +3660,7 @@ static void *SWITCH_THREAD_FUNC conference_loop_input(switch_thread_t *thread, v
|
|||||||
switch_frame_t *read_frame = NULL;
|
switch_frame_t *read_frame = NULL;
|
||||||
uint32_t hangover = 40, hangunder = 5, hangover_hits = 0, hangunder_hits = 0, diff_level = 400;
|
uint32_t hangover = 40, hangunder = 5, hangover_hits = 0, hangunder_hits = 0, diff_level = 400;
|
||||||
switch_core_session_t *session = member->session;
|
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) {
|
if (switch_core_session_read_lock(session) != SWITCH_STATUS_SUCCESS) {
|
||||||
goto end;
|
goto end;
|
||||||
@ -3922,6 +3923,18 @@ static void *SWITCH_THREAD_FUNC conference_loop_input(switch_thread_t *thread, v
|
|||||||
member->last_score = member->score;
|
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 */
|
/* 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))
|
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_test_flag(member, MFLAG_CAN_SPEAK) && !switch_test_flag(member->conference, CFLAG_WAIT_MOD)
|
||||||
@ -4072,7 +4085,7 @@ static void launch_conference_loop_input(conference_member_t *member, switch_mem
|
|||||||
{
|
{
|
||||||
switch_threadattr_t *thd_attr = NULL;
|
switch_threadattr_t *thd_attr = NULL;
|
||||||
|
|
||||||
if (member == NULL)
|
if (member == NULL || member->input_thread)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
switch_threadattr_create(&thd_attr, pool);
|
switch_threadattr_create(&thd_attr, pool);
|
||||||
@ -4116,7 +4129,7 @@ static void conference_loop_output(conference_member_t *member)
|
|||||||
call_list = NULL;
|
call_list = NULL;
|
||||||
cp = NULL;
|
cp = NULL;
|
||||||
|
|
||||||
|
member->loop_loop = 0;
|
||||||
|
|
||||||
switch_assert(member->conference != NULL);
|
switch_assert(member->conference != NULL);
|
||||||
|
|
||||||
@ -4229,7 +4242,7 @@ static void conference_loop_output(conference_member_t *member)
|
|||||||
|
|
||||||
/* Fair WARNING, If you expect the caller to hear anything or for digit handling to be processed, */
|
/* 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! */
|
/* 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_channel_ready(channel)) {
|
||||||
switch_event_t *event;
|
switch_event_t *event;
|
||||||
int use_timer = 0;
|
int use_timer = 0;
|
||||||
@ -4429,15 +4442,21 @@ static void conference_loop_output(conference_member_t *member)
|
|||||||
|
|
||||||
end:
|
end:
|
||||||
|
|
||||||
|
if (!member->loop_loop) {
|
||||||
switch_clear_flag_locked(member, MFLAG_RUNNING);
|
switch_clear_flag_locked(member, MFLAG_RUNNING);
|
||||||
|
|
||||||
/* Wait for the input thread to end */
|
/* Wait for the input thread to end */
|
||||||
if (member->input_thread) {
|
if (member->input_thread) {
|
||||||
switch_thread_join(&st, member->input_thread);
|
switch_thread_join(&st, member->input_thread);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch_core_timer_destroy(&timer);
|
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_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_channel_cause2str(switch_channel_get_cause(channel)));
|
||||||
|
|
||||||
@ -8006,10 +8025,14 @@ static int setup_media(conference_member_t *member, conference_obj_t *conference
|
|||||||
switch_codec_implementation_t read_impl = { 0 };
|
switch_codec_implementation_t read_impl = { 0 };
|
||||||
switch_core_session_get_read_impl(member->session, &read_impl);
|
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)) {
|
if (switch_core_codec_ready(&member->read_codec)) {
|
||||||
switch_core_codec_destroy(&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) {
|
if (member->read_resampler) {
|
||||||
@ -8640,7 +8663,10 @@ SWITCH_STANDARD_APP(conference_function)
|
|||||||
switch_core_session_receive_message(session, &msg);
|
switch_core_session_receive_message(session, &msg);
|
||||||
|
|
||||||
/* Run the conference loop */
|
/* Run the conference loop */
|
||||||
|
do {
|
||||||
conference_loop_output(&member);
|
conference_loop_output(&member);
|
||||||
|
} while (member.loop_loop);
|
||||||
|
|
||||||
switch_channel_set_private(channel, "_conference_autocall_list_", NULL);
|
switch_channel_set_private(channel, "_conference_autocall_list_", NULL);
|
||||||
|
|
||||||
/* Tell the channel we are no longer going to be in a bridge */
|
/* Tell the channel we are no longer going to be in a bridge */
|
||||||
|
@ -599,6 +599,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi
|
|||||||
case SWITCH_STATUS_RESAMPLE:
|
case SWITCH_STATUS_RESAMPLE:
|
||||||
if (!session->read_resampler) {
|
if (!session->read_resampler) {
|
||||||
switch_mutex_lock(session->resample_mutex);
|
switch_mutex_lock(session->resample_mutex);
|
||||||
|
|
||||||
status = switch_resample_create(&session->read_resampler,
|
status = switch_resample_create(&session->read_resampler,
|
||||||
read_frame->codec->implementation->actual_samples_per_second,
|
read_frame->codec->implementation->actual_samples_per_second,
|
||||||
session->read_impl.actual_samples_per_second,
|
session->read_impl.actual_samples_per_second,
|
||||||
@ -610,6 +611,13 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi
|
|||||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Unable to allocate resampler\n");
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Unable to allocate resampler\n");
|
||||||
status = SWITCH_STATUS_FALSE;
|
status = SWITCH_STATUS_FALSE;
|
||||||
goto done;
|
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:
|
case SWITCH_STATUS_SUCCESS:
|
||||||
@ -636,6 +644,14 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi
|
|||||||
switch_resample_destroy(&session->read_resampler);
|
switch_resample_destroy(&session->read_resampler);
|
||||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Deactivating read resampler\n");
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Deactivating read resampler\n");
|
||||||
switch_mutex_unlock(session->resample_mutex);
|
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;
|
status = SWITCH_STATUS_SUCCESS;
|
||||||
@ -1199,6 +1215,13 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess
|
|||||||
switch_mutex_unlock(session->resample_mutex);
|
switch_mutex_unlock(session->resample_mutex);
|
||||||
if (status != SWITCH_STATUS_SUCCESS) {
|
if (status != SWITCH_STATUS_SUCCESS) {
|
||||||
goto done;
|
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;
|
||||||
@ -1226,6 +1249,14 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess
|
|||||||
switch_resample_destroy(&session->write_resampler);
|
switch_resample_destroy(&session->write_resampler);
|
||||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Deactivating write resampler\n");
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Deactivating write resampler\n");
|
||||||
switch_mutex_unlock(session->resample_mutex);
|
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;
|
write_frame = frame;
|
||||||
status = SWITCH_STATUS_SUCCESS;
|
status = SWITCH_STATUS_SUCCESS;
|
||||||
@ -1497,6 +1528,14 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess
|
|||||||
|
|
||||||
if (status != SWITCH_STATUS_SUCCESS) {
|
if (status != SWITCH_STATUS_SUCCESS) {
|
||||||
goto done;
|
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;
|
||||||
@ -1511,12 +1550,23 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess
|
|||||||
break;
|
break;
|
||||||
case SWITCH_STATUS_NOOP:
|
case SWITCH_STATUS_NOOP:
|
||||||
if (session->write_resampler) {
|
if (session->write_resampler) {
|
||||||
|
switch_core_session_message_t msg = { 0 };
|
||||||
|
int ok = 0;
|
||||||
|
|
||||||
switch_mutex_lock(session->resample_mutex);
|
switch_mutex_lock(session->resample_mutex);
|
||||||
if (session->write_resampler) {
|
if (session->write_resampler) {
|
||||||
switch_resample_destroy(&session->write_resampler);
|
switch_resample_destroy(&session->write_resampler);
|
||||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Deactivating write resampler\n");
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Deactivating write resampler\n");
|
||||||
|
ok = 1;
|
||||||
}
|
}
|
||||||
switch_mutex_unlock(session->resample_mutex);
|
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->codec = session->write_codec;
|
||||||
enc_frame->samples = enc_frame->datalen / sizeof(int16_t);
|
enc_frame->samples = enc_frame->datalen / sizeof(int16_t);
|
||||||
|
@ -7479,6 +7479,14 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_receive_message(switch_core_se
|
|||||||
|
|
||||||
switch (msg->message_id) {
|
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:
|
case SWITCH_MESSAGE_INDICATE_VIDEO_REFRESH_REQ:
|
||||||
{
|
{
|
||||||
if (v_engine->rtp_session) {
|
if (v_engine->rtp_session) {
|
||||||
|
@ -754,6 +754,7 @@ static const char *message_names[] = {
|
|||||||
"ANSWER_EVENT",
|
"ANSWER_EVENT",
|
||||||
"PROGRESS_EVENT",
|
"PROGRESS_EVENT",
|
||||||
"RING_EVENT",
|
"RING_EVENT",
|
||||||
|
"RESAMPLE_EVENT",
|
||||||
"INVALID"
|
"INVALID"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user