From 8734c9070db99be60ac251dab65a6d6440af2719 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 29 Jun 2017 18:11:16 -0500 Subject: [PATCH] FS-10448: [mod_conference] Add Video Blind #resolve --- src/include/switch_core_media.h | 1 + .../mod_conference/conference_api.c | 90 +++++++++++++++++++ .../mod_conference/conference_loop.c | 14 +++ .../mod_conference/conference_video.c | 3 + .../mod_conference/mod_conference.c | 20 ++++- .../mod_conference/mod_conference.h | 11 ++- 6 files changed, 137 insertions(+), 2 deletions(-) diff --git a/src/include/switch_core_media.h b/src/include/switch_core_media.h index 65dab34232..cf9b321655 100644 --- a/src/include/switch_core_media.h +++ b/src/include/switch_core_media.h @@ -351,6 +351,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_read_lock_unlock(switch_core_s SWITCH_DECLARE(void) switch_core_session_stop_media(switch_core_session_t *session); SWITCH_DECLARE(switch_media_flow_t) switch_core_session_media_flow(switch_core_session_t *session, switch_media_type_t type); SWITCH_DECLARE(switch_status_t) switch_core_media_get_vid_params(switch_core_session_t *session, switch_vid_params_t *vid_params); +SWITCH_DECLARE(void) switch_core_session_write_blank_video(switch_core_session_t *session, uint32_t ms); SWITCH_DECLARE(switch_status_t) switch_core_media_lock_video_file(switch_core_session_t *session, switch_rw_t rw); SWITCH_DECLARE(switch_status_t) switch_core_media_unlock_video_file(switch_core_session_t *session, switch_rw_t rw); SWITCH_DECLARE(switch_status_t) switch_core_media_set_video_file(switch_core_session_t *session, switch_file_handle_t *fh, switch_rw_t rw); diff --git a/src/mod/applications/mod_conference/conference_api.c b/src/mod/applications/mod_conference/conference_api.c index 24f4d09b95..178fe561b6 100644 --- a/src/mod/applications/mod_conference/conference_api.c +++ b/src/mod/applications/mod_conference/conference_api.c @@ -77,6 +77,9 @@ api_command_t conference_api_sub_commands[] = { {"tvmute", (void_fn_t) & conference_api_sub_tvmute, CONF_API_SUB_MEMBER_TARGET, "tvmute", "<[member_id|all]|last|non_moderator> []"}, {"vmute-snap", (void_fn_t) & conference_api_sub_conference_video_vmute_snap, CONF_API_SUB_MEMBER_TARGET, "vmute-snap", "<[member_id|all]|last|non_moderator>"}, {"unvmute", (void_fn_t) & conference_api_sub_unvmute, CONF_API_SUB_MEMBER_TARGET, "unvmute", "<[member_id|all]|last|non_moderator> []"}, + {"vblind", (void_fn_t) & conference_api_sub_vblind, CONF_API_SUB_MEMBER_TARGET, "vblind", "<[member_id|all]|last|non_moderator> []"}, + {"tvblind", (void_fn_t) & conference_api_sub_tvblind, CONF_API_SUB_MEMBER_TARGET, "tvblind", "<[member_id|all]|last|non_moderator> []"}, + {"unvblind", (void_fn_t) & conference_api_sub_unvblind, CONF_API_SUB_MEMBER_TARGET, "unvblind", "<[member_id|all]|last|non_moderator> []"}, {"deaf", (void_fn_t) & conference_api_sub_deaf, CONF_API_SUB_MEMBER_TARGET, "deaf", "<[member_id|all]|last|non_moderator>"}, {"undeaf", (void_fn_t) & conference_api_sub_undeaf, CONF_API_SUB_MEMBER_TARGET, "undeaf", "<[member_id|all]|last|non_moderator>"}, {"vid-filter", (void_fn_t) & conference_api_sub_video_filter, CONF_API_SUB_MEMBER_TARGET, "vid-filter", "<[member_id|all]|last|non_moderator> "}, @@ -522,6 +525,93 @@ switch_status_t conference_api_sub_unvmute(conference_member_t *member, switch_s return SWITCH_STATUS_SUCCESS; } +switch_status_t conference_api_sub_vblind(conference_member_t *member, switch_stream_handle_t *stream, void *data) +{ + switch_event_t *event; + + if (member == NULL) + return SWITCH_STATUS_GENERR; + + if (switch_core_session_media_flow(member->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_SENDONLY) { + 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); + + if (!(data) || !strstr((char *) data, "quiet")) { + conference_utils_member_set_flag(member, MFLAG_INDICATE_BLIND); + } + + if (stream != NULL) { + stream->write_function(stream, "OK vblind %u\n", member->id); + } + + if (test_eflag(member->conference, EFLAG_BLIND_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", "vblind-member"); + switch_event_fire(&event); + } + + conference_member_update_status_field(member); + + return SWITCH_STATUS_SUCCESS; +} + + +switch_status_t conference_api_sub_tvblind(conference_member_t *member, switch_stream_handle_t *stream, void *data) +{ + + if (member == NULL) + return SWITCH_STATUS_GENERR; + + if (conference_utils_member_test_flag(member, MFLAG_CAN_SEE)) { + return conference_api_sub_vblind(member, stream, data); + } + + return conference_api_sub_unvblind(member, stream, data); +} + + +switch_status_t conference_api_sub_unvblind(conference_member_t *member, switch_stream_handle_t *stream, void *data) +{ + switch_event_t *event; + + if (member == NULL) + return SWITCH_STATUS_GENERR; + + if (switch_core_session_media_flow(member->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_SENDONLY) { + return SWITCH_STATUS_SUCCESS; + } + + conference_utils_member_set_flag_locked(member, MFLAG_CAN_SEE); + conference_video_reset_video_bitrate_counters(member); + + switch_channel_set_flag(member->channel, CF_VIDEO_REFRESH_REQ); + + if (!(data) || !strstr((char *) data, "quiet")) { + conference_utils_member_set_flag(member, MFLAG_INDICATE_UNBLIND); + } + + if (stream != NULL) { + stream->write_function(stream, "OK unvblind %u\n", member->id); + } + + if (test_eflag(member->conference, EFLAG_BLIND_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", "unvblind-member"); + switch_event_fire(&event); + } + + + conference_member_update_status_field(member); + + return SWITCH_STATUS_SUCCESS; +} + switch_status_t conference_api_sub_deaf(conference_member_t *member, switch_stream_handle_t *stream, void *data) { switch_event_t *event; diff --git a/src/mod/applications/mod_conference/conference_loop.c b/src/mod/applications/mod_conference/conference_loop.c index 9067f7a44e..f23491af85 100644 --- a/src/mod/applications/mod_conference/conference_loop.c +++ b/src/mod/applications/mod_conference/conference_loop.c @@ -1582,6 +1582,20 @@ void conference_loop_output(conference_member_t *member) conference_utils_member_clear_flag(member, MFLAG_INDICATE_UNDEAF); } + if (conference_utils_member_test_flag(member, MFLAG_INDICATE_BLIND)) { + if (!zstr(member->conference->deaf_sound)) { + conference_member_play_file(member, member->conference->deaf_sound, 0, SWITCH_TRUE); + } + conference_utils_member_clear_flag(member, MFLAG_INDICATE_BLIND); + } + + if (conference_utils_member_test_flag(member, MFLAG_INDICATE_UNBLIND)) { + if (!zstr(member->conference->undeaf_sound)) { + conference_member_play_file(member, member->conference->undeaf_sound, 0, SWITCH_TRUE); + } + conference_utils_member_clear_flag(member, MFLAG_INDICATE_UNBLIND); + } + if (switch_core_session_private_event_count(member->session)) { switch_channel_set_app_flag(channel, CF_APP_TAGGED); switch_ivr_parse_all_events(member->session); diff --git a/src/mod/applications/mod_conference/conference_video.c b/src/mod/applications/mod_conference/conference_video.c index cc63d63d04..70d3cfbe65 100644 --- a/src/mod/applications/mod_conference/conference_video.c +++ b/src/mod/applications/mod_conference/conference_video.c @@ -1800,6 +1800,7 @@ void conference_video_write_canvas_image_to_codec_group(conference_obj_t *confer } if (switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_RECVONLY || + !conference_utils_member_test_flag(imember, MFLAG_CAN_SEE) || switch_channel_test_flag(imember->channel, CF_VIDEO_WRITING) || switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_INACTIVE) { switch_core_session_rwunlock(imember->session); @@ -3921,6 +3922,7 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr if (switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_RECVONLY || switch_channel_test_flag(imember->channel, CF_VIDEO_WRITING) || + !conference_utils_member_test_flag(imember, MFLAG_CAN_SEE) || switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_INACTIVE) { switch_core_session_rwunlock(imember->session); continue; @@ -4303,6 +4305,7 @@ void *SWITCH_THREAD_FUNC conference_video_super_muxing_thread_run(switch_thread_ if (switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_RECVONLY || switch_channel_test_flag(imember->channel, CF_VIDEO_WRITING) || + !conference_utils_member_test_flag(imember, MFLAG_CAN_SEE) || switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_INACTIVE) { switch_core_session_rwunlock(imember->session); continue; diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index 8a3c59a2bd..3920c766ce 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -1250,6 +1250,9 @@ void conference_xlist(conference_obj_t *conference, switch_xml_t x_conference, i 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"); + 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"); + 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"); @@ -1365,6 +1368,7 @@ void conference_jlist(conference_obj_t *conference, cJSON *json_conferences) 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, "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)); @@ -2605,6 +2609,8 @@ conference_obj_t *conference_new(char *name, conference_xml_cfg_t cfg, switch_co char *kicked_sound = NULL; char *deaf_sound = NULL; char *undeaf_sound = NULL; + char *blind_sound = NULL; + char *unblind_sound = NULL; char *pin = NULL; char *mpin = NULL; char *pin_sound = NULL; @@ -2862,6 +2868,10 @@ conference_obj_t *conference_new(char *name, conference_xml_cfg_t cfg, switch_co deaf_sound = val; } else if (!strcasecmp(var, "undeaf-sound") && !zstr(val)) { undeaf_sound = val; + } else if (!strcasecmp(var, "blind-sound") && !zstr(val)) { + blind_sound = val; + } else if (!strcasecmp(var, "unblind-sound") && !zstr(val)) { + unblind_sound = val; } else if (!strcasecmp(var, "member-flags") && !zstr(val)) { member_flags = val; } else if (!strcasecmp(var, "conference-flags") && !zstr(val)) { @@ -3271,7 +3281,7 @@ conference_obj_t *conference_new(char *name, conference_xml_cfg_t cfg, switch_co conference->perpetual_sound = switch_core_strdup(conference->pool, perpetual_sound); } - conference->mflags[MFLAG_CAN_SPEAK] = conference->mflags[MFLAG_CAN_HEAR] = conference->mflags[MFLAG_CAN_BE_SEEN] = 1; + conference->mflags[MFLAG_CAN_SPEAK] = conference->mflags[MFLAG_CAN_HEAR] = conference->mflags[MFLAG_CAN_BE_SEEN] = conference->mflags[MFLAG_CAN_SEE] = 1; if (!zstr(moh_sound) && switch_is_moh(moh_sound)) { conference->moh_sound = switch_core_strdup(conference->pool, moh_sound); @@ -3344,6 +3354,14 @@ conference_obj_t *conference_new(char *name, conference_xml_cfg_t cfg, switch_co conference->undeaf_sound = switch_core_strdup(conference->pool, undeaf_sound); } + if (!zstr(blind_sound)) { + conference->blind_sound = switch_core_strdup(conference->pool, blind_sound); + } + + if (!zstr(unblind_sound)) { + conference->unblind_sound = switch_core_strdup(conference->pool, unblind_sound); + } + if (!zstr(pin)) { conference->pin = switch_core_strdup(conference->pool, pin); } diff --git a/src/mod/applications/mod_conference/mod_conference.h b/src/mod/applications/mod_conference/mod_conference.h index e5eefd451e..8bbfae2b12 100644 --- a/src/mod/applications/mod_conference/mod_conference.h +++ b/src/mod/applications/mod_conference/mod_conference.h @@ -194,6 +194,8 @@ typedef enum { MFLAG_MOD, MFLAG_INDICATE_MUTE, MFLAG_INDICATE_UNMUTE, + MFLAG_INDICATE_BLIND, + MFLAG_INDICATE_UNBLIND, MFLAG_NOMOH, MFLAG_VIDEO_BRIDGE, MFLAG_INDICATE_MUTE_DETECT, @@ -205,6 +207,7 @@ typedef enum { MFLAG_NO_POSITIONAL, MFLAG_JOIN_VID_FLOOR, MFLAG_RECEIVING_VIDEO, + MFLAG_CAN_SEE, MFLAG_CAN_BE_SEEN, MFLAG_SECOND_SCREEN, MFLAG_SILENT, @@ -346,7 +349,8 @@ typedef enum { EFLAG_RECORD = (1 << 27), EFLAG_HUP_MEMBER = (1 << 28), EFLAG_PLAY_FILE_DONE = (1 << 29), - EFLAG_SET_POSITION_MEMBER = (1 << 30) + EFLAG_SET_POSITION_MEMBER = (1 << 30), + EFLAG_BLIND_MEMBER = (1 << 31) } event_type_t; #ifdef OPENAL_POSITIONING @@ -611,6 +615,8 @@ typedef struct conference_obj { char *unmuted_sound; char *deaf_sound; char *undeaf_sound; + char *blind_sound; + char *unblind_sound; char *locked_sound; char *is_locked_sound; char *is_unlocked_sound; @@ -1168,6 +1174,9 @@ switch_status_t conference_api_sub_unmute(conference_member_t *member, switch_st switch_status_t conference_api_sub_vmute(conference_member_t *member, switch_stream_handle_t *stream, void *data); switch_status_t conference_api_sub_tvmute(conference_member_t *member, switch_stream_handle_t *stream, void *data); switch_status_t conference_api_sub_unvmute(conference_member_t *member, switch_stream_handle_t *stream, void *data); +switch_status_t conference_api_sub_vblind(conference_member_t *member, switch_stream_handle_t *stream, void *data); +switch_status_t conference_api_sub_tvblind(conference_member_t *member, switch_stream_handle_t *stream, void *data); +switch_status_t conference_api_sub_unvblind(conference_member_t *member, switch_stream_handle_t *stream, void *data); switch_status_t conference_api_sub_deaf(conference_member_t *member, switch_stream_handle_t *stream, void *data); switch_status_t conference_api_sub_undeaf(conference_member_t *member, switch_stream_handle_t *stream, void *data); switch_status_t conference_api_sub_video_filter(conference_member_t *member, switch_stream_handle_t *stream, void *data);