mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-03-13 20:50:41 +00:00
FS-11206: [mod_conference] add conference hold feature
This commit is contained in:
parent
868e92649e
commit
7f3878dfcb
@ -78,7 +78,9 @@ void conference_al_gen_arc(conference_obj_t *conference, switch_stream_handle_t
|
||||
|
||||
switch_mutex_lock(conference->member_mutex);
|
||||
for (member = conference->members; member; member = member->next) {
|
||||
if (member->channel && conference_utils_member_test_flag(member, MFLAG_CAN_SPEAK) && !conference_utils_member_test_flag(member, MFLAG_NO_POSITIONAL)) {
|
||||
if (member->channel && conference_utils_member_test_flag(member, MFLAG_CAN_SPEAK) &&
|
||||
!conference_utils_member_test_flag(member, MFLAG_HOLD) &&
|
||||
!conference_utils_member_test_flag(member, MFLAG_NO_POSITIONAL)) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
@ -112,7 +114,9 @@ void conference_al_gen_arc(conference_obj_t *conference, switch_stream_handle_t
|
||||
|
||||
for (member = conference->members; member; member = member->next) {
|
||||
|
||||
if (!member->channel || conference_utils_member_test_flag(member, MFLAG_NO_POSITIONAL) || !conference_utils_member_test_flag(member, MFLAG_CAN_SPEAK)) {
|
||||
if (!member->channel || conference_utils_member_test_flag(member, MFLAG_NO_POSITIONAL) ||
|
||||
conference_utils_member_test_flag(member, MFLAG_HOLD) ||
|
||||
!conference_utils_member_test_flag(member, MFLAG_CAN_SPEAK)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -72,6 +72,8 @@ api_command_t conference_api_sub_commands[] = {
|
||||
{"vid-flip", (void_fn_t) & conference_api_sub_vid_flip, CONF_API_SUB_MEMBER_TARGET, "vid-flip", "<[member_id|all|last|non_moderator]>"},
|
||||
{"vid-border", (void_fn_t) & conference_api_sub_vid_border, CONF_API_SUB_MEMBER_TARGET, "vid-border", "<[member_id|all|last|non_moderator]>"},
|
||||
{"hup", (void_fn_t) & conference_api_sub_hup, CONF_API_SUB_MEMBER_TARGET, "hup", "<[member_id|all|last|non_moderator]>"},
|
||||
{"hold", (void_fn_t) & conference_api_sub_hold, CONF_API_SUB_MEMBER_TARGET, "hold", "<[member_id|all]|last|non_moderator> [file]"},
|
||||
{"unhold", (void_fn_t) & conference_api_sub_unhold, CONF_API_SUB_MEMBER_TARGET, "unhold", "<[member_id|all]|last|non_moderator>"},
|
||||
{"mute", (void_fn_t) & conference_api_sub_mute, CONF_API_SUB_MEMBER_TARGET, "mute", "<[member_id|all]|last|non_moderator> [<quiet>]"},
|
||||
{"tmute", (void_fn_t) & conference_api_sub_tmute, CONF_API_SUB_MEMBER_TARGET, "tmute", "<[member_id|all]|last|non_moderator> [<quiet>]"},
|
||||
{"unmute", (void_fn_t) & conference_api_sub_unmute, CONF_API_SUB_MEMBER_TARGET, "unmute", "<[member_id|all]|last|non_moderator> [<quiet>]"},
|
||||
@ -313,6 +315,11 @@ switch_status_t conference_api_sub_mute(conference_member_t *member, switch_stre
|
||||
if (member == NULL)
|
||||
return SWITCH_STATUS_GENERR;
|
||||
|
||||
if (conference_utils_member_test_flag(member, MFLAG_HOLD)) {
|
||||
if (stream) stream->write_function(stream, "-ERR mute %u\n", member->id);
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
conference_utils_member_clear_flag_locked(member, MFLAG_CAN_SPEAK);
|
||||
conference_utils_member_clear_flag_locked(member, MFLAG_TALKING);
|
||||
|
||||
@ -345,6 +352,107 @@ switch_status_t conference_api_sub_mute(conference_member_t *member, switch_stre
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
switch_status_t conference_api_sub_unhold(conference_member_t *member, switch_stream_handle_t *stream, void *data)
|
||||
{
|
||||
mcu_layer_t *layer = NULL;
|
||||
switch_event_t *event;
|
||||
|
||||
if (member == NULL)
|
||||
return SWITCH_STATUS_GENERR;
|
||||
|
||||
conference_utils_member_clear_flag_locked(member, MFLAG_HOLD);
|
||||
|
||||
if (member->session && !conference_utils_member_test_flag(member, MFLAG_MUTE_DETECT)) {
|
||||
switch_core_media_hard_mute(member->session, SWITCH_FALSE);
|
||||
}
|
||||
|
||||
conference_member_stop_file(member, FILE_STOP_ALL);
|
||||
|
||||
if (switch_core_session_media_flow(member->session, SWITCH_MEDIA_TYPE_VIDEO) != SWITCH_MEDIA_FLOW_SENDONLY) {
|
||||
if ((layer = conference_video_get_layer_locked(member))) {
|
||||
layer->clear = 1;
|
||||
conference_video_release_layer(&layer);
|
||||
}
|
||||
|
||||
conference_video_reset_video_bitrate_counters(member);
|
||||
|
||||
if (member->channel) {
|
||||
switch_channel_clear_flag(member->channel, CF_VIDEO_PAUSE_READ);
|
||||
switch_channel_video_sync(member->channel);
|
||||
}
|
||||
}
|
||||
|
||||
if (stream != NULL) {
|
||||
stream->write_function(stream, "+OK unhold %u\n", member->id);
|
||||
}
|
||||
|
||||
if (test_eflag(member->conference, EFLAG_HOLD_MEMBER) &&
|
||||
switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) {
|
||||
conference_member_add_event_data(member, event);
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "unhold-member");
|
||||
switch_event_fire(&event);
|
||||
}
|
||||
|
||||
if (conference_utils_test_flag(member->conference, CFLAG_POSITIONAL)) {
|
||||
conference_al_gen_arc(member->conference, NULL);
|
||||
}
|
||||
|
||||
conference_member_update_status_field(member);
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
switch_status_t conference_api_sub_hold(conference_member_t *member, switch_stream_handle_t *stream, void *data)
|
||||
{
|
||||
switch_event_t *event;
|
||||
|
||||
if (member == NULL)
|
||||
return SWITCH_STATUS_GENERR;
|
||||
|
||||
conference_utils_member_clear_flag_locked(member, MFLAG_TALKING);
|
||||
|
||||
if (switch_core_session_media_flow(member->session, SWITCH_MEDIA_TYPE_VIDEO) != SWITCH_MEDIA_FLOW_SENDONLY) {
|
||||
conference_video_reset_video_bitrate_counters(member);
|
||||
|
||||
if (member->channel) {
|
||||
switch_channel_set_flag(member->channel, CF_VIDEO_PAUSE_READ);
|
||||
switch_core_session_request_video_refresh(member->session);
|
||||
switch_channel_video_sync(member->channel);
|
||||
}
|
||||
}
|
||||
|
||||
if (member->session) {
|
||||
switch_core_media_hard_mute(member->session, SWITCH_TRUE);
|
||||
}
|
||||
|
||||
conference_utils_member_set_flag(member, MFLAG_HOLD);
|
||||
|
||||
conference_member_set_score_iir(member, 0);
|
||||
|
||||
if (!zstr(data)) {
|
||||
conference_member_play_file(member, data, 0, SWITCH_FALSE);
|
||||
}
|
||||
|
||||
if (stream != NULL) {
|
||||
stream->write_function(stream, "+OK hold %u\n", member->id);
|
||||
}
|
||||
|
||||
if (test_eflag(member->conference, EFLAG_HOLD_MEMBER) &&
|
||||
switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) {
|
||||
conference_member_add_event_data(member, event);
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "hold-member");
|
||||
switch_event_fire(&event);
|
||||
}
|
||||
|
||||
if (conference_utils_test_flag(member->conference, CFLAG_POSITIONAL)) {
|
||||
conference_al_gen_arc(member->conference, NULL);
|
||||
}
|
||||
|
||||
conference_member_update_status_field(member);
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
switch_status_t conference_api_sub_tmute(conference_member_t *member, switch_stream_handle_t *stream, void *data)
|
||||
{
|
||||
@ -352,6 +460,11 @@ switch_status_t conference_api_sub_tmute(conference_member_t *member, switch_str
|
||||
if (member == NULL)
|
||||
return SWITCH_STATUS_GENERR;
|
||||
|
||||
if (conference_utils_member_test_flag(member, MFLAG_HOLD)) {
|
||||
if (stream) stream->write_function(stream, "-ERR mute %u\n", member->id);
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (conference_utils_member_test_flag(member, MFLAG_CAN_SPEAK)) {
|
||||
return conference_api_sub_mute(member, stream, data);
|
||||
}
|
||||
@ -367,6 +480,11 @@ switch_status_t conference_api_sub_unmute(conference_member_t *member, switch_st
|
||||
if (member == NULL)
|
||||
return SWITCH_STATUS_GENERR;
|
||||
|
||||
if (conference_utils_member_test_flag(member, MFLAG_HOLD)) {
|
||||
if (stream) stream->write_function(stream, "-ERR unmute %u\n", member->id);
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
conference_utils_member_set_flag_locked(member, MFLAG_CAN_SPEAK);
|
||||
|
||||
if (member->session && !conference_utils_member_test_flag(member, MFLAG_MUTE_DETECT)) {
|
||||
@ -413,6 +531,11 @@ switch_status_t conference_api_sub_conference_video_vmute_snap(conference_member
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (conference_utils_member_test_flag(member, MFLAG_HOLD)) {
|
||||
if (stream) stream->write_function(stream, "-ERR member %u is on hold\n", member->id);
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (stream != NULL) {
|
||||
stream->write_function(stream, "+OK vmute image snapped %u\n", member->id);
|
||||
}
|
||||
@ -437,6 +560,11 @@ switch_status_t conference_api_sub_vmute(conference_member_t *member, switch_str
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (conference_utils_member_test_flag(member, MFLAG_HOLD)) {
|
||||
if (stream) stream->write_function(stream, "-ERR member %u is on hold\n", member->id);
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
conference_utils_member_clear_flag_locked(member, MFLAG_CAN_BE_SEEN);
|
||||
conference_video_reset_video_bitrate_counters(member);
|
||||
|
||||
@ -473,6 +601,11 @@ switch_status_t conference_api_sub_tvmute(conference_member_t *member, switch_st
|
||||
if (member == NULL)
|
||||
return SWITCH_STATUS_GENERR;
|
||||
|
||||
if (conference_utils_member_test_flag(member, MFLAG_HOLD)) {
|
||||
if (stream) stream->write_function(stream, "-ERR member %u is on hold\n", member->id);
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (conference_utils_member_test_flag(member, MFLAG_CAN_BE_SEEN)) {
|
||||
return conference_api_sub_vmute(member, stream, data);
|
||||
}
|
||||
@ -493,6 +626,11 @@ switch_status_t conference_api_sub_unvmute(conference_member_t *member, switch_s
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (conference_utils_member_test_flag(member, MFLAG_HOLD)) {
|
||||
if (stream) stream->write_function(stream, "-ERR member %u is on hold\n", member->id);
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if ((layer = conference_video_get_layer_locked(member))) {
|
||||
layer->clear = 1;
|
||||
conference_video_release_layer(&layer);
|
||||
@ -534,6 +672,11 @@ switch_status_t conference_api_sub_vblind(conference_member_t *member, switch_st
|
||||
if (member == NULL)
|
||||
return SWITCH_STATUS_GENERR;
|
||||
|
||||
if (conference_utils_member_test_flag(member, MFLAG_HOLD)) {
|
||||
if (stream) stream->write_function(stream, "-ERR member %u is on hold\n", member->id);
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
switch_core_session_write_blank_video(member->session, 50);
|
||||
conference_utils_member_clear_flag_locked(member, MFLAG_CAN_SEE);
|
||||
conference_video_reset_video_bitrate_counters(member);
|
||||
@ -565,6 +708,11 @@ switch_status_t conference_api_sub_tvblind(conference_member_t *member, switch_s
|
||||
if (member == NULL)
|
||||
return SWITCH_STATUS_GENERR;
|
||||
|
||||
if (conference_utils_member_test_flag(member, MFLAG_HOLD)) {
|
||||
if (stream) stream->write_function(stream, "-ERR member %u is on hold\n", member->id);
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (conference_utils_member_test_flag(member, MFLAG_CAN_SEE)) {
|
||||
return conference_api_sub_vblind(member, stream, data);
|
||||
}
|
||||
@ -580,6 +728,11 @@ switch_status_t conference_api_sub_unvblind(conference_member_t *member, switch_
|
||||
if (member == NULL)
|
||||
return SWITCH_STATUS_GENERR;
|
||||
|
||||
if (conference_utils_member_test_flag(member, MFLAG_HOLD)) {
|
||||
if (stream) stream->write_function(stream, "-ERR member %u is on hold\n", member->id);
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
conference_utils_member_set_flag_locked(member, MFLAG_CAN_SEE);
|
||||
conference_video_reset_video_bitrate_counters(member);
|
||||
|
||||
@ -613,6 +766,11 @@ switch_status_t conference_api_sub_deaf(conference_member_t *member, switch_stre
|
||||
if (member == NULL)
|
||||
return SWITCH_STATUS_GENERR;
|
||||
|
||||
if (conference_utils_member_test_flag(member, MFLAG_HOLD)) {
|
||||
if (stream) stream->write_function(stream, "-ERR member %u is on hold\n", member->id);
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
conference_utils_member_clear_flag_locked(member, MFLAG_CAN_HEAR);
|
||||
|
||||
if (!(data) || !strstr((char *) data, "quiet")) {
|
||||
@ -655,6 +813,11 @@ switch_status_t conference_api_sub_undeaf(conference_member_t *member, switch_st
|
||||
if (member == NULL)
|
||||
return SWITCH_STATUS_GENERR;
|
||||
|
||||
if (conference_utils_member_test_flag(member, MFLAG_HOLD)) {
|
||||
if (stream) stream->write_function(stream, "-ERR member %u is on hold\n", member->id);
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
conference_utils_member_set_flag_locked(member, MFLAG_CAN_HEAR);
|
||||
|
||||
if (!(data) || !strstr((char *) data, "quiet")) {
|
||||
|
@ -132,6 +132,8 @@ void conference_loop_mute_toggle(conference_member_t *member, caller_control_act
|
||||
if (member == NULL)
|
||||
return;
|
||||
|
||||
if (conference_utils_member_test_flag(member, MFLAG_HOLD)) return;
|
||||
|
||||
if (conference_utils_member_test_flag(member, MFLAG_CAN_SPEAK)) {
|
||||
conference_api_sub_mute(member, NULL, NULL);
|
||||
} else {
|
||||
@ -144,6 +146,8 @@ void conference_loop_mute_toggle(conference_member_t *member, caller_control_act
|
||||
|
||||
void conference_loop_mute_on(conference_member_t *member, caller_control_action_t *action)
|
||||
{
|
||||
if (conference_utils_member_test_flag(member, MFLAG_HOLD)) return;
|
||||
|
||||
if (conference_utils_member_test_flag(member, MFLAG_CAN_SPEAK)) {
|
||||
conference_api_sub_mute(member, NULL, NULL);
|
||||
}
|
||||
@ -151,6 +155,8 @@ void conference_loop_mute_on(conference_member_t *member, caller_control_action_
|
||||
|
||||
void conference_loop_mute_off(conference_member_t *member, caller_control_action_t *action)
|
||||
{
|
||||
if (conference_utils_member_test_flag(member, MFLAG_HOLD)) return;
|
||||
|
||||
if (!conference_utils_member_test_flag(member, MFLAG_CAN_SPEAK)) {
|
||||
conference_api_sub_unmute(member, NULL, NULL);
|
||||
if (!conference_utils_member_test_flag(member, MFLAG_CAN_HEAR)) {
|
||||
@ -280,6 +286,8 @@ void conference_loop_deafmute_toggle(conference_member_t *member, caller_control
|
||||
if (member == NULL)
|
||||
return;
|
||||
|
||||
if (conference_utils_member_test_flag(member, MFLAG_HOLD)) return;
|
||||
|
||||
if (conference_utils_member_test_flag(member, MFLAG_CAN_SPEAK)) {
|
||||
conference_api_sub_mute(member, NULL, NULL);
|
||||
if (conference_utils_member_test_flag(member, MFLAG_CAN_HEAR)) {
|
||||
@ -933,7 +941,8 @@ void *SWITCH_THREAD_FUNC conference_loop_input(switch_thread_t *thread, void *ob
|
||||
|
||||
/* if the member can speak, compute the audio energy level and */
|
||||
/* generate events when the level crosses the threshold */
|
||||
if ((conference_utils_member_test_flag(member, MFLAG_CAN_SPEAK) || conference_utils_member_test_flag(member, MFLAG_MUTE_DETECT))) {
|
||||
if (((conference_utils_member_test_flag(member, MFLAG_CAN_SPEAK) && !conference_utils_member_test_flag(member, MFLAG_HOLD)) ||
|
||||
conference_utils_member_test_flag(member, MFLAG_MUTE_DETECT))) {
|
||||
uint32_t energy = 0, i = 0, samples = 0, j = 0;
|
||||
int16_t *data;
|
||||
int gate_check = 0;
|
||||
@ -990,7 +999,7 @@ void *SWITCH_THREAD_FUNC conference_loop_input(switch_thread_t *thread, void *ob
|
||||
|
||||
gate_check = conference_member_noise_gate_check(member);
|
||||
|
||||
if (conference_utils_member_test_flag(member, MFLAG_CAN_SPEAK)) {
|
||||
if (conference_utils_member_test_flag(member, MFLAG_CAN_SPEAK) && !conference_utils_member_test_flag(member, MFLAG_HOLD)) {
|
||||
if (member->max_energy_level) {
|
||||
if (member->score > member->max_energy_level && ++member->max_energy_hits > member->max_energy_hit_trigger) {
|
||||
member->mute_counter = member->burst_mute_count;
|
||||
@ -1131,6 +1140,7 @@ void *SWITCH_THREAD_FUNC conference_loop_input(switch_thread_t *thread, void *ob
|
||||
member->talking_count = 0;
|
||||
|
||||
if (test_eflag(member->conference, EFLAG_START_TALKING) && conference_utils_member_test_flag(member, MFLAG_CAN_SPEAK) &&
|
||||
!conference_utils_member_test_flag(member, MFLAG_HOLD) &&
|
||||
switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) {
|
||||
conference_member_add_event_data(member, event);
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "start-talking");
|
||||
@ -1157,7 +1167,8 @@ void *SWITCH_THREAD_FUNC conference_loop_input(switch_thread_t *thread, void *ob
|
||||
hangunder_hits--;
|
||||
}
|
||||
|
||||
if (conference_utils_member_test_flag(member, MFLAG_TALKING) && conference_utils_member_test_flag(member, MFLAG_CAN_SPEAK)) {
|
||||
if (conference_utils_member_test_flag(member, MFLAG_TALKING) && conference_utils_member_test_flag(member, MFLAG_CAN_SPEAK) &&
|
||||
!conference_utils_member_test_flag(member, MFLAG_HOLD)) {
|
||||
if (++hangover_hits >= hangover) {
|
||||
hangover_hits = hangunder_hits = 0;
|
||||
|
||||
@ -1188,7 +1199,8 @@ void *SWITCH_THREAD_FUNC conference_loop_input(switch_thread_t *thread, void *ob
|
||||
|
||||
/* skip frames that are not actual media or when we are muted or silent */
|
||||
if ((conference_utils_member_test_flag(member, MFLAG_TALKING) || member->energy_level == 0 || conference_utils_test_flag(member->conference, CFLAG_AUDIO_ALWAYS))
|
||||
&& conference_utils_member_test_flag(member, MFLAG_CAN_SPEAK) && !conference_utils_test_flag(member->conference, CFLAG_WAIT_MOD)
|
||||
&& conference_utils_member_test_flag(member, MFLAG_CAN_SPEAK) && !conference_utils_test_flag(member->conference, CFLAG_WAIT_MOD)
|
||||
&& !conference_utils_member_test_flag(member, MFLAG_HOLD)
|
||||
&& (member->conference->count > 1 || (member->conference->record_count && member->conference->count >= member->conference->min_recording_participants))) {
|
||||
switch_audio_resampler_t *read_resampler = member->read_resampler;
|
||||
void *data;
|
||||
|
@ -133,7 +133,9 @@ void conference_member_update_status_field(conference_member_t *member)
|
||||
|
||||
switch_live_array_lock(member->conference->la);
|
||||
|
||||
if (!conference_utils_member_test_flag(member, MFLAG_CAN_SPEAK)) {
|
||||
if (conference_utils_member_test_flag(member, MFLAG_HOLD)) {
|
||||
str = "HOLD";
|
||||
} else if (!conference_utils_member_test_flag(member, MFLAG_CAN_SPEAK)) {
|
||||
str = "MUTE";
|
||||
} else if (switch_channel_test_flag(member->channel, CF_HOLD)) {
|
||||
str = "HOLD";
|
||||
@ -258,6 +260,7 @@ switch_status_t conference_member_add_event_data(conference_member_t *member, sw
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Speak", "%s", conference_utils_member_test_flag(member, MFLAG_CAN_SPEAK) ? "true" : "false" );
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Talking", "%s", conference_utils_member_test_flag(member, MFLAG_TALKING) ? "true" : "false" );
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Mute-Detect", "%s", conference_utils_member_test_flag(member, MFLAG_MUTE_DETECT) ? "true" : "false" );
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Hold", "%s", conference_utils_member_test_flag(member, MFLAG_HOLD) ? "true" : "false" );
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Member-ID", "%u", member->id);
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Member-Type", "%s", conference_utils_member_test_flag(member, MFLAG_MOD) ? "moderator" : "member");
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Member-Ghost", "%s", conference_utils_member_test_flag(member, MFLAG_GHOST) ? "true" : "false");
|
||||
|
@ -237,9 +237,7 @@ void conference_utils_clear_eflags(char *events, uint32_t *f)
|
||||
*next++ = '\0';
|
||||
}
|
||||
|
||||
if (!strcmp(event, "add-member")) {
|
||||
*f &= ~EFLAG_ADD_MEMBER;
|
||||
} else if (!strcmp(event, "del-member")) {
|
||||
if (!strcmp(event, "del-member")) {
|
||||
*f &= ~EFLAG_DEL_MEMBER;
|
||||
} else if (!strcmp(event, "energy-level")) {
|
||||
*f &= ~EFLAG_ENERGY_LEVEL;
|
||||
@ -257,6 +255,8 @@ void conference_utils_clear_eflags(char *events, uint32_t *f)
|
||||
*f &= ~EFLAG_MUTE_DETECT;
|
||||
} else if (!strcmp(event, "mute-member")) {
|
||||
*f &= ~EFLAG_MUTE_MEMBER;
|
||||
} else if (!strcmp(event, "hold-member")) {
|
||||
*f &= ~EFLAG_HOLD_MEMBER;
|
||||
} else if (!strcmp(event, "kick-member")) {
|
||||
*f &= ~EFLAG_KICK_MEMBER;
|
||||
} else if (!strcmp(event, "dtmf-member")) {
|
||||
|
@ -1414,6 +1414,10 @@ switch_status_t conference_video_attach_video_layer(conference_member_t *member,
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
if (conference_utils_member_test_flag(member, MFLAG_HOLD)) {
|
||||
conference_utils_member_clear_flag(member, MFLAG_DED_VID_LAYER);
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
if (!switch_channel_test_flag(channel, CF_VIDEO_READY) && !member->avatar_png_img) {
|
||||
conference_utils_member_clear_flag(member, MFLAG_DED_VID_LAYER);
|
||||
@ -1425,6 +1429,8 @@ switch_status_t conference_video_attach_video_layer(conference_member_t *member,
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
switch_mutex_lock(canvas->mutex);
|
||||
|
||||
layer = &canvas->layers[idx];
|
||||
@ -2606,6 +2612,10 @@ switch_status_t conference_video_find_layer(conference_obj_t *conference, mcu_ca
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
if (conference_utils_member_test_flag(member, MFLAG_HOLD)) {
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
switch_mutex_lock(canvas->mutex);
|
||||
|
||||
for (i = 0; i < canvas->total_layers; i++) {
|
||||
@ -2730,7 +2740,7 @@ void conference_video_pop_next_image(conference_member_t *member, switch_image_t
|
||||
size = switch_queue_size(member->video_queue);
|
||||
} while(size > 1);
|
||||
|
||||
if (conference_utils_member_test_flag(member, MFLAG_CAN_BE_SEEN) &&
|
||||
if (conference_utils_member_test_flag(member, MFLAG_CAN_BE_SEEN) && !conference_utils_member_test_flag(member, MFLAG_HOLD) &&
|
||||
member->video_layer_id > -1 &&
|
||||
switch_core_session_media_flow(member->session, SWITCH_MEDIA_TYPE_VIDEO) != SWITCH_MEDIA_FLOW_SENDONLY &&
|
||||
switch_core_session_media_flow(member->session, SWITCH_MEDIA_TYPE_VIDEO) != SWITCH_MEDIA_FLOW_INACTIVE
|
||||
@ -2961,7 +2971,7 @@ void conference_video_check_auto_bitrate(conference_member_t *member, mcu_layer_
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "%s setting bitrate to %dkps because it was forced.\n",
|
||||
switch_channel_get_name(member->channel), kps);
|
||||
} else {
|
||||
if (layer && conference_utils_member_test_flag(member, MFLAG_CAN_BE_SEEN)) {
|
||||
if (layer && conference_utils_member_test_flag(member, MFLAG_CAN_BE_SEEN) && !conference_utils_member_test_flag(member, MFLAG_HOLD)) {
|
||||
if (layer->screen_w != screen_w) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "%s auto-setting bitrate to %dkps (max res %dx%d) to accommodate %dx%d resolution\n",
|
||||
switch_channel_get_name(member->channel), kps, screen_w, screen_h, layer->screen_w, layer->screen_h);
|
||||
@ -3177,6 +3187,7 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr
|
||||
int no_muted = conference_utils_test_flag(imember->conference, CFLAG_VIDEO_MUTE_EXIT_CANVAS);
|
||||
int no_av = conference_utils_test_flag(imember->conference, CFLAG_VIDEO_REQUIRED_FOR_CANVAS);
|
||||
int seen = conference_utils_member_test_flag(imember, MFLAG_CAN_BE_SEEN);
|
||||
int hold = conference_utils_member_test_flag(imember, MFLAG_HOLD);
|
||||
|
||||
if (imember->channel && switch_channel_ready(imember->channel) && switch_channel_test_flag(imember->channel, CF_VIDEO_READY) &&
|
||||
imember->watching_canvas_id == canvas->canvas_id) {
|
||||
@ -3184,7 +3195,7 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr
|
||||
}
|
||||
|
||||
if (imember->channel && switch_channel_ready(imember->channel) && switch_channel_test_flag(imember->channel, CF_VIDEO_READY) &&
|
||||
!conference_utils_member_test_flag(imember, MFLAG_SECOND_SCREEN) &&
|
||||
!conference_utils_member_test_flag(imember, MFLAG_SECOND_SCREEN) && !hold &&
|
||||
conference_utils_member_test_flag(imember, MFLAG_RUNNING) && (!no_muted || seen) && (!no_av || (no_av && !imember->avatar_png_img))
|
||||
&& imember->canvas_id == canvas->canvas_id && imember->video_media_flow != SWITCH_MEDIA_FLOW_SENDONLY && imember->video_media_flow != SWITCH_MEDIA_FLOW_INACTIVE) {
|
||||
video_count++;
|
||||
@ -3403,8 +3414,9 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr
|
||||
continue;
|
||||
}
|
||||
|
||||
if (conference_utils_test_flag(imember->conference, CFLAG_VIDEO_MUTE_EXIT_CANVAS) &&
|
||||
!conference_utils_member_test_flag(imember, MFLAG_CAN_BE_SEEN) && imember->video_layer_id > -1) {
|
||||
if ((conference_utils_member_test_flag(imember, MFLAG_HOLD) ||
|
||||
(conference_utils_test_flag(imember->conference, CFLAG_VIDEO_MUTE_EXIT_CANVAS) &&
|
||||
!conference_utils_member_test_flag(imember, MFLAG_CAN_BE_SEEN))) && imember->video_layer_id > -1) {
|
||||
conference_video_detach_video_layer(imember);
|
||||
switch_img_free(&imember->video_mute_img);
|
||||
|
||||
@ -3518,7 +3530,7 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr
|
||||
// switch_img_free(&layer->cur_img);
|
||||
//}
|
||||
|
||||
if (conference_utils_member_test_flag(imember, MFLAG_CAN_BE_SEEN) || switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_SENDONLY || switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_INACTIVE || conference_utils_test_flag(imember->conference, CFLAG_VIDEO_MUTE_EXIT_CANVAS)) {
|
||||
if ((conference_utils_member_test_flag(imember, MFLAG_CAN_BE_SEEN) && !conference_utils_member_test_flag(imember, MFLAG_HOLD)) || switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_SENDONLY || switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_INACTIVE || conference_utils_test_flag(imember->conference, CFLAG_VIDEO_MUTE_EXIT_CANVAS)) {
|
||||
layer->mute_patched = 0;
|
||||
} else {
|
||||
|
||||
@ -3637,7 +3649,7 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr
|
||||
|
||||
if (total > 0 &&
|
||||
(!conference_utils_test_flag(imember->conference, CFLAG_VIDEO_MUTE_EXIT_CANVAS) ||
|
||||
conference_utils_member_test_flag(imember, MFLAG_CAN_BE_SEEN)) &&
|
||||
(conference_utils_member_test_flag(imember, MFLAG_CAN_BE_SEEN) && !conference_utils_member_test_flag(imember, MFLAG_HOLD))) &&
|
||||
imember->session && switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) != SWITCH_MEDIA_FLOW_SENDONLY &&
|
||||
imember->session && switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) != SWITCH_MEDIA_FLOW_INACTIVE) {
|
||||
|
||||
@ -3804,7 +3816,7 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr
|
||||
}
|
||||
|
||||
if (layer) {
|
||||
if (conference_utils_member_test_flag(omember, MFLAG_CAN_BE_SEEN)) {
|
||||
if (conference_utils_member_test_flag(omember, MFLAG_CAN_BE_SEEN) && !conference_utils_member_test_flag(imember, MFLAG_HOLD)) {
|
||||
layer->mute_patched = 0;
|
||||
} else if (!conference_utils_test_flag(omember->conference, CFLAG_VIDEO_MUTE_EXIT_CANVAS)) {
|
||||
if (!layer->mute_patched) {
|
||||
@ -4954,6 +4966,7 @@ switch_status_t conference_video_thread_callback(switch_core_session_t *session,
|
||||
|
||||
if (frame->img && (((member->video_layer_id > -1) && canvas_id > -1) || member->canvas) &&
|
||||
conference_utils_member_test_flag(member, MFLAG_CAN_BE_SEEN) &&
|
||||
!conference_utils_member_test_flag(member, MFLAG_HOLD) &&
|
||||
switch_queue_size(member->video_queue) < member->conference->video_fps.fps &&
|
||||
!member->conference->canvases[canvas_id]->playing_video_file) {
|
||||
|
||||
|
@ -84,6 +84,7 @@ void conference_list(conference_obj_t *conference, switch_stream_handle_t *strea
|
||||
char *uuid;
|
||||
char *name;
|
||||
uint32_t count = 0;
|
||||
switch_bool_t hold = conference_utils_member_test_flag(member, MFLAG_HOLD);
|
||||
|
||||
if (conference_utils_member_test_flag(member, MFLAG_NOCHANNEL)) {
|
||||
continue;
|
||||
@ -97,21 +98,26 @@ void conference_list(conference_obj_t *conference, switch_stream_handle_t *strea
|
||||
stream->write_function(stream, "%u%s%s%s%s%s%s%s%s%s",
|
||||
member->id, delim, name, delim, uuid, delim, profile->caller_id_name, delim, profile->caller_id_number, delim);
|
||||
|
||||
if (conference_utils_member_test_flag(member, MFLAG_CAN_HEAR)) {
|
||||
if (!hold && conference_utils_member_test_flag(member, MFLAG_CAN_HEAR)) {
|
||||
stream->write_function(stream, "hear");
|
||||
count++;
|
||||
}
|
||||
|
||||
if (conference_utils_member_test_flag(member, MFLAG_CAN_SPEAK)) {
|
||||
if (!hold && conference_utils_member_test_flag(member, MFLAG_CAN_SPEAK)) {
|
||||
stream->write_function(stream, "%s%s", count ? "|" : "", "speak");
|
||||
count++;
|
||||
}
|
||||
|
||||
if (conference_utils_member_test_flag(member, MFLAG_TALKING)) {
|
||||
if (!hold && conference_utils_member_test_flag(member, MFLAG_TALKING)) {
|
||||
stream->write_function(stream, "%s%s", count ? "|" : "", "talking");
|
||||
count++;
|
||||
}
|
||||
|
||||
if (hold) {
|
||||
stream->write_function(stream, "%s%s", count ? "|" : "", "hold");
|
||||
count++;
|
||||
}
|
||||
|
||||
if (switch_channel_test_flag(switch_core_session_get_channel(member->session), CF_VIDEO)) {
|
||||
stream->write_function(stream, "%s%s", count ? "|" : "", "video");
|
||||
count++;
|
||||
@ -331,6 +337,7 @@ void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, void *ob
|
||||
switch_channel_test_flag(channel, CF_VIDEO_READY) &&
|
||||
imember->video_media_flow != SWITCH_MEDIA_FLOW_SENDONLY &&
|
||||
!conference_utils_member_test_flag(imember, MFLAG_SECOND_SCREEN) &&
|
||||
!conference_utils_member_test_flag(imember, MFLAG_HOLD) &&
|
||||
(!conference_utils_test_flag(conference, CFLAG_VIDEO_MUTE_EXIT_CANVAS) ||
|
||||
conference_utils_member_test_flag(imember, MFLAG_CAN_BE_SEEN))) {
|
||||
members_with_video++;
|
||||
@ -1225,7 +1232,8 @@ void conference_xlist(conference_obj_t *conference, switch_xml_t x_conference, i
|
||||
switch_xml_t x_tag;
|
||||
int toff = 0;
|
||||
char tmp[50] = "";
|
||||
|
||||
switch_bool_t hold = conference_utils_member_test_flag(member, MFLAG_HOLD);
|
||||
|
||||
if (conference_utils_member_test_flag(member, MFLAG_NOCHANNEL)) {
|
||||
if (member->rec_path) {
|
||||
x_member = switch_xml_add_child_d(x_members, "member", moff++);
|
||||
@ -1286,19 +1294,22 @@ void conference_xlist(conference_obj_t *conference, switch_xml_t x_conference, i
|
||||
switch_assert(x_flags);
|
||||
|
||||
x_tag = switch_xml_add_child_d(x_flags, "can_hear", count++);
|
||||
switch_xml_set_txt_d(x_tag, conference_utils_member_test_flag(member, MFLAG_CAN_HEAR) ? "true" : "false");
|
||||
switch_xml_set_txt_d(x_tag, (!hold && conference_utils_member_test_flag(member, MFLAG_CAN_HEAR)) ? "true" : "false");
|
||||
|
||||
x_tag = switch_xml_add_child_d(x_flags, "can_see", count++);
|
||||
switch_xml_set_txt_d(x_tag, conference_utils_member_test_flag(member, MFLAG_CAN_SEE) ? "true" : "false");
|
||||
switch_xml_set_txt_d(x_tag, (!hold && conference_utils_member_test_flag(member, MFLAG_CAN_SEE)) ? "true" : "false");
|
||||
|
||||
x_tag = switch_xml_add_child_d(x_flags, "can_speak", count++);
|
||||
switch_xml_set_txt_d(x_tag, conference_utils_member_test_flag(member, MFLAG_CAN_SPEAK) ? "true" : "false");
|
||||
switch_xml_set_txt_d(x_tag, (!hold && conference_utils_member_test_flag(member, MFLAG_CAN_SPEAK)) ? "true" : "false");
|
||||
|
||||
x_tag = switch_xml_add_child_d(x_flags, "mute_detect", count++);
|
||||
switch_xml_set_txt_d(x_tag, conference_utils_member_test_flag(member, MFLAG_MUTE_DETECT) ? "true" : "false");
|
||||
|
||||
x_tag = switch_xml_add_child_d(x_flags, "talking", count++);
|
||||
switch_xml_set_txt_d(x_tag, conference_utils_member_test_flag(member, MFLAG_TALKING) ? "true" : "false");
|
||||
switch_xml_set_txt_d(x_tag, (!hold && conference_utils_member_test_flag(member, MFLAG_TALKING)) ? "true" : "false");
|
||||
|
||||
x_tag = switch_xml_add_child_d(x_flags, "hold", count++);
|
||||
switch_xml_set_txt_d(x_tag, hold ? "true" : "false");
|
||||
|
||||
x_tag = switch_xml_add_child_d(x_flags, "has_video", count++);
|
||||
switch_xml_set_txt_d(x_tag, switch_channel_test_flag(switch_core_session_get_channel(member->session), CF_VIDEO) ? "true" : "false");
|
||||
@ -1374,6 +1385,8 @@ void conference_jlist(conference_obj_t *conference, cJSON *json_conferences)
|
||||
switch_channel_t *channel;
|
||||
switch_caller_profile_t *profile;
|
||||
char *uuid;
|
||||
switch_bool_t hold = conference_utils_member_test_flag(member, MFLAG_HOLD);
|
||||
|
||||
cJSON_AddItemToObject(json_conference_members, "member", json_conference_member = cJSON_CreateObject());
|
||||
|
||||
if (conference_utils_member_test_flag(member, MFLAG_NOCHANNEL)) {
|
||||
@ -1405,9 +1418,10 @@ void conference_jlist(conference_obj_t *conference, cJSON *json_conferences)
|
||||
cJSON_AddNumberToObject(json_conference_member, "volume_out", member->volume_out_level);
|
||||
cJSON_AddNumberToObject(json_conference_member, "output-volume", member->volume_out_level);
|
||||
cJSON_AddNumberToObject(json_conference_member, "input-volume", member->volume_in_level);
|
||||
ADDBOOL(json_conference_member_flags, "can_hear", conference_utils_member_test_flag(member, MFLAG_CAN_HEAR));
|
||||
ADDBOOL(json_conference_member_flags, "can_see", conference_utils_member_test_flag(member, MFLAG_CAN_SEE));
|
||||
ADDBOOL(json_conference_member_flags, "can_speak", conference_utils_member_test_flag(member, MFLAG_CAN_SPEAK));
|
||||
ADDBOOL(json_conference_member_flags, "can_hear", !hold && conference_utils_member_test_flag(member, MFLAG_CAN_HEAR));
|
||||
ADDBOOL(json_conference_member_flags, "can_see", !hold && conference_utils_member_test_flag(member, MFLAG_CAN_SEE));
|
||||
ADDBOOL(json_conference_member_flags, "can_speak", !hold && conference_utils_member_test_flag(member, MFLAG_CAN_SPEAK));
|
||||
ADDBOOL(json_conference_member_flags, "hold", hold);
|
||||
ADDBOOL(json_conference_member_flags, "mute_detect", conference_utils_member_test_flag(member, MFLAG_MUTE_DETECT));
|
||||
ADDBOOL(json_conference_member_flags, "talking", conference_utils_member_test_flag(member, MFLAG_TALKING));
|
||||
ADDBOOL(json_conference_member_flags, "has_video", switch_channel_test_flag(switch_core_session_get_channel(member->session), CF_VIDEO));
|
||||
|
@ -220,6 +220,7 @@ typedef enum {
|
||||
MFLAG_NO_VIDEO_BLANKS,
|
||||
MFLAG_VIDEO_JOIN,
|
||||
MFLAG_DED_VID_LAYER,
|
||||
MFLAG_HOLD,
|
||||
///////////////////////////
|
||||
MFLAG_MAX
|
||||
} member_flag_t;
|
||||
@ -322,7 +323,7 @@ typedef enum {
|
||||
} node_flag_t;
|
||||
|
||||
typedef enum {
|
||||
EFLAG_ADD_MEMBER = (1 << 0),
|
||||
EFLAG_HOLD_MEMBER = (1 << 0),
|
||||
EFLAG_DEL_MEMBER = (1 << 1),
|
||||
EFLAG_ENERGY_LEVEL = (1 << 2),
|
||||
EFLAG_VOLUME_LEVEL = (1 << 3),
|
||||
@ -1210,6 +1211,8 @@ switch_status_t conference_api_sub_file_seek(conference_obj_t *conference, switc
|
||||
switch_status_t conference_api_sub_cam(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv);
|
||||
switch_status_t conference_api_sub_stop(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv);
|
||||
switch_status_t conference_api_sub_hup(conference_member_t *member, switch_stream_handle_t *stream, void *data);
|
||||
switch_status_t conference_api_sub_hold(conference_member_t *member, switch_stream_handle_t *stream, void *data);
|
||||
switch_status_t conference_api_sub_unhold(conference_member_t *member, switch_stream_handle_t *stream, void *data);
|
||||
switch_status_t conference_api_sub_pauserec(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv);
|
||||
switch_status_t conference_api_sub_volume_out(conference_member_t *member, switch_stream_handle_t *stream, void *data);
|
||||
switch_status_t conference_api_sub_lock(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv);
|
||||
|
Loading…
x
Reference in New Issue
Block a user