diff --git a/src/mod/applications/mod_conference/conference_api.c b/src/mod/applications/mod_conference/conference_api.c index 1f8d586e64..d0d8b5ebc6 100644 --- a/src/mod/applications/mod_conference/conference_api.c +++ b/src/mod/applications/mod_conference/conference_api.c @@ -2046,6 +2046,14 @@ switch_status_t conference_api_sub_floor(conference_member_t *member, switch_str if (member == NULL) return SWITCH_STATUS_GENERR; + if (conference_utils_member_test_flag(member, MFLAG_DED_VID_LAYER)) { + if (stream != NULL) { + stream->write_function(stream, "-ERR cannot set floor on a member in an active video role\n"); + } + + return SWITCH_STATUS_SUCCESS; + } + if (member->conference->floor_holder == member->id) { conference_member_set_floor_holder(member->conference, NULL, 0); if (stream != NULL) { @@ -2358,6 +2366,14 @@ switch_status_t conference_api_sub_vid_floor(conference_member_t *member, switch return SWITCH_STATUS_FALSE; } + if (conference_utils_member_test_flag(member, MFLAG_DED_VID_LAYER)) { + if (stream != NULL) { + stream->write_function(stream, "-ERR cannot set floor on a member in an active video role\n"); + } + + return SWITCH_STATUS_SUCCESS; + } + if (data && switch_stristr("force", (char *) data)) { force = 1; } diff --git a/src/mod/applications/mod_conference/conference_member.c b/src/mod/applications/mod_conference/conference_member.c index e55b068416..5121ee3168 100644 --- a/src/mod/applications/mod_conference/conference_member.c +++ b/src/mod/applications/mod_conference/conference_member.c @@ -1064,8 +1064,17 @@ void conference_member_set_floor_holder(conference_obj_t *conference, conference uint32_t old_id = 0; conference_member_t *lmember = NULL; - conference->floor_holder_score_iir = 0; + if (!member && id) { + member = lmember = conference_member_get(conference, id); + } + + if (member && conference_utils_member_test_flag(member, MFLAG_DED_VID_LAYER)) { + return; + } + + conference->floor_holder_score_iir = 0; + if (conference->floor_holder) { if ((member && conference->floor_holder == member->id) || (id && conference->floor_holder == id)) { goto end; @@ -1074,10 +1083,6 @@ void conference_member_set_floor_holder(conference_obj_t *conference, conference switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Dropping floor %d\n", old_member); } } - - if (!member && id) { - member = lmember = conference_member_get(conference, id); - } if (member) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Adding floor %s\n", diff --git a/src/mod/applications/mod_conference/conference_video.c b/src/mod/applications/mod_conference/conference_video.c index 1f3eaed838..b4a9c8d42c 100644 --- a/src/mod/applications/mod_conference/conference_video.c +++ b/src/mod/applications/mod_conference/conference_video.c @@ -1080,6 +1080,8 @@ void conference_video_detach_video_layer(conference_member_t *member) conference_video_set_canvas_bgimg(canvas, NULL); } + conference_utils_member_clear_flag(member, MFLAG_DED_VID_LAYER); + end: switch_mutex_unlock(canvas->mutex); @@ -1336,18 +1338,27 @@ switch_status_t conference_video_attach_video_layer(conference_member_t *member, if (conference_utils_test_flag(member->conference, CFLAG_VIDEO_MUTE_EXIT_CANVAS) && !conference_utils_member_test_flag(member, MFLAG_CAN_BE_SEEN)) { + 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); return SWITCH_STATUS_FALSE; } if ((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) && !member->avatar_png_img) { + conference_utils_member_clear_flag(member, MFLAG_DED_VID_LAYER); return SWITCH_STATUS_FALSE; } + if (conference_utils_member_test_flag(member, MFLAG_DED_VID_LAYER)) { + if (member->id == member->conference->floor_holder) { + conference_member_set_floor_holder(member->conference, NULL, 0); + } + } + switch_mutex_lock(canvas->mutex); layer = &canvas->layers[idx]; @@ -2540,6 +2551,7 @@ switch_status_t conference_video_find_layer(conference_obj_t *conference, mcu_ca if (xlayer->geometry.res_id) { if (member->video_reservation_id && !strcmp(xlayer->geometry.res_id, member->video_reservation_id)) { layer = xlayer; + conference_utils_member_set_flag(member, MFLAG_DED_VID_LAYER); conference_video_attach_video_layer(member, canvas, i); break; } @@ -2571,7 +2583,7 @@ switch_status_t conference_video_find_layer(conference_obj_t *conference, mcu_ca !xlayer->fnode && !xlayer->geometry.fileonly && !xlayer->geometry.res_id && !xlayer->geometry.flooronly) { switch_status_t lstatus = conference_video_attach_video_layer(member, canvas, i); - if (lstatus == SWITCH_STATUS_SUCCESS || lstatus == SWITCH_STATUS_BREAK) { + if (lstatus == SWITCH_STATUS_SUCCESS || lstatus == SWITCH_STATUS_BREAK) { layer = xlayer; break; } @@ -3322,6 +3334,7 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr mcu_layer_t *xlayer = &canvas->layers[i]; if (!zstr(imember->video_role_id) && !zstr(xlayer->geometry.role_id) && !strcmp(xlayer->geometry.role_id, imember->video_role_id)) { + conference_utils_member_set_flag(imember, MFLAG_DED_VID_LAYER); conference_video_attach_video_layer(imember, canvas, i); } } @@ -4468,6 +4481,10 @@ void conference_video_find_floor(conference_member_t *member, switch_bool_t ente switch_mutex_lock(conference->member_mutex); for (imember = conference->members; imember; imember = imember->next) { + if (conference_utils_member_test_flag(imember, MFLAG_DED_VID_LAYER)) { + continue; + } + if (!(imember->session)) { continue; } @@ -4528,12 +4545,10 @@ void conference_video_set_floor_holder(conference_obj_t *conference, conference_ return; } - if (member && member->video_reservation_id) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Setting floor not allowed on a member with a res id\n"); - /* no video floor when a reservation id is set */ - return; + if (member && conference_utils_member_test_flag(member, MFLAG_DED_VID_LAYER)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Setting floor not allowed on a member in a dedicated layer\n"); } - + if ((!force && conference_utils_test_flag(conference, CFLAG_VID_FLOOR_LOCK))) { return; } diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index eadf6c22a9..7ca2215e62 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -305,8 +305,11 @@ void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, void *ob if ((!floor_holder || (imember->id != conference->floor_holder && imember->score_iir > SCORE_IIR_SPEAKING_MAX && (conference->floor_holder_score_iir < SCORE_IIR_SPEAKING_MIN)))) {// && //(!conference_utils_test_flag(conference, CFLAG_VID_FLOOR) || switch_channel_test_flag(channel, CF_VIDEO))) { - conference_member_set_floor_holder(conference, imember, 0); - floor_holder = conference->floor_holder; + + if (!conference_utils_member_test_flag(imember, MFLAG_DED_VID_LAYER)) { + conference_member_set_floor_holder(conference, imember, 0); + floor_holder = conference->floor_holder; + } } video_media_flow = switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO); diff --git a/src/mod/applications/mod_conference/mod_conference.h b/src/mod/applications/mod_conference/mod_conference.h index 5f83db4db2..45c09d52dc 100644 --- a/src/mod/applications/mod_conference/mod_conference.h +++ b/src/mod/applications/mod_conference/mod_conference.h @@ -218,6 +218,7 @@ typedef enum { MFLAG_TALK_DATA_EVENTS, MFLAG_NO_VIDEO_BLANKS, MFLAG_VIDEO_JOIN, + MFLAG_DED_VID_LAYER, /////////////////////////// MFLAG_MAX } member_flag_t;