FS-11206: [mod_conference] add conference hold feature

This commit is contained in:
Mike Jerris 2018-06-21 05:32:22 -04:00 committed by Muteesa Fred
parent 868e92649e
commit 7f3878dfcb
8 changed files with 242 additions and 30 deletions

View File

@ -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;
}

View File

@ -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")) {

View File

@ -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;

View File

@ -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");

View File

@ -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")) {

View File

@ -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) {

View 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));

View File

@ -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);