From 8670e5f801b5fd3717e88854fef28041350ceca1 Mon Sep 17 00:00:00 2001
From: Anthony Minessale <anthm@freeswitch.org>
Date: Mon, 14 Dec 2015 16:05:51 -0600
Subject: [PATCH 1/2] FS-8642 addtl patch

---
 src/mod/applications/mod_conference/conference_video.c | 3 ++-
 src/switch_channel.c                                   | 2 +-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/src/mod/applications/mod_conference/conference_video.c b/src/mod/applications/mod_conference/conference_video.c
index 45ca7c41c7..e4301fc279 100644
--- a/src/mod/applications/mod_conference/conference_video.c
+++ b/src/mod/applications/mod_conference/conference_video.c
@@ -649,6 +649,7 @@ void conference_video_detach_video_layer(conference_member_t *member)
 	member->avatar_patched = 0;
 	conference_video_check_used_layers(canvas);
 	canvas->send_keyframe = 1;
+	member->managed_kps = 0;
 
 	if (conference_utils_test_flag(member->conference, CFLAG_JSON_STATUS)) {
 		conference_member_update_status_field(member);
@@ -876,7 +877,6 @@ void conference_video_layer_set_banner(conference_member_t *member, mcu_layer_t
 
 void conference_video_reset_video_bitrate_counters(conference_member_t *member)
 {
-	member->managed_kps = 0;
 	member->blackouts = 0;
 	member->good_img = 0;
 	member->blanks = 0;
@@ -972,6 +972,7 @@ switch_status_t conference_video_attach_video_layer(conference_member_t *member,
 
 	switch_img_fill(canvas->img, layer->x_pos, layer->y_pos, layer->screen_w, layer->screen_h, &canvas->letterbox_bgcolor);
 	conference_video_reset_video_bitrate_counters(member);
+	member->managed_kps = 0;
 
 	if (conference_utils_test_flag(member->conference, CFLAG_JSON_STATUS)) {
 		conference_member_update_status_field(member);
diff --git a/src/switch_channel.c b/src/switch_channel.c
index a62a39a388..1b8f1e894e 100644
--- a/src/switch_channel.c
+++ b/src/switch_channel.c
@@ -1858,7 +1858,7 @@ SWITCH_DECLARE(void) switch_channel_set_flag_value(switch_channel_t *channel, sw
 		switch_core_session_start_video_thread(channel->session);
 	}
 	
-	if (flag == CF_VIDEO_DECODED_READ) {
+	if (flag == CF_VIDEO_DECODED_READ && channel->flags[CF_VIDEO]) {
 		switch_core_session_request_video_refresh(channel->session);
 		if (!switch_core_session_in_video_thread(channel->session)) {
 			switch_channel_wait_for_flag(channel, CF_VIDEO_READY, SWITCH_TRUE, 10000, NULL);

From 881197e661c93c5a09d3d789fc0f92fb60a74737 Mon Sep 17 00:00:00 2001
From: Anthony Minessale II <anthony.minessale@gmail.com>
Date: Mon, 14 Dec 2015 14:23:31 -0600
Subject: [PATCH 2/2] FS-8629 #resolve [Add new param video-mute-exit-canvas to
 conference cflags]

---
 .../mod_conference/conference_utils.c         |  2 +
 .../mod_conference/conference_video.c         | 37 ++++++++++++++++---
 .../mod_conference/mod_conference.c           |  2 +-
 .../mod_conference/mod_conference.h           |  1 +
 4 files changed, 36 insertions(+), 6 deletions(-)

diff --git a/src/mod/applications/mod_conference/conference_utils.c b/src/mod/applications/mod_conference/conference_utils.c
index b28fedf6d3..274b499e44 100644
--- a/src/mod/applications/mod_conference/conference_utils.c
+++ b/src/mod/applications/mod_conference/conference_utils.c
@@ -193,6 +193,8 @@ void conference_utils_set_cflags(const char *flags, conference_flag_t *f)
 				f[CFLAG_VIDEO_BRIDGE_FIRST_TWO] = 1;
 			} else if (!strcasecmp(argv[i], "video-required-for-canvas")) {
 				f[CFLAG_VIDEO_REQUIRED_FOR_CANVAS] = 1;
+			} else if (!strcasecmp(argv[i], "video-mute-exit-canvas")) {
+				f[CFLAG_VIDEO_MUTE_EXIT_CANVAS] = 1;
 			} else if (!strcasecmp(argv[i], "manage-inbound-video-bitrate")) {
 				f[CFLAG_MANAGE_INBOUND_VIDEO_BITRATE] = 1;
 			} else if (!strcasecmp(argv[i], "video-muxing-personal-canvas")) {
diff --git a/src/mod/applications/mod_conference/conference_video.c b/src/mod/applications/mod_conference/conference_video.c
index e4301fc279..db57c03bb6 100644
--- a/src/mod/applications/mod_conference/conference_video.c
+++ b/src/mod/applications/mod_conference/conference_video.c
@@ -893,6 +893,11 @@ switch_status_t conference_video_attach_video_layer(conference_member_t *member,
 
 	channel = switch_core_session_get_channel(member->session);
 
+	if (conference_utils_test_flag(member->conference, CFLAG_VIDEO_MUTE_EXIT_CANVAS) &&
+		!conference_utils_member_test_flag(member, MFLAG_CAN_BE_SEEN)) {
+		return SWITCH_STATUS_FALSE;
+	}
+
 
 	if (!switch_channel_test_flag(channel, CF_VIDEO_READY) && !member->avatar_png_img) {
 		return SWITCH_STATUS_FALSE;
@@ -1725,6 +1730,11 @@ switch_status_t conference_video_find_layer(conference_obj_t *conference, mcu_ca
 	mcu_layer_t *layer = NULL;
 	int i;
 
+	if (conference_utils_test_flag(conference, CFLAG_VIDEO_MUTE_EXIT_CANVAS) &&
+		!conference_utils_member_test_flag(member, MFLAG_CAN_BE_SEEN)) {
+		return SWITCH_STATUS_FALSE;
+	}
+
 	switch_mutex_lock(canvas->mutex);
 
 	for (i = 0; i < canvas->total_layers; i++) {
@@ -2097,11 +2107,15 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr
 			layout_group_t *lg = NULL;
 			video_layout_t *vlayout = NULL;
 			int canvas_count = 0;
-
+			
 			switch_mutex_lock(conference->member_mutex);
 			for (imember = conference->members; imember; imember = imember->next) {
+				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);
+
 				if (imember->channel && switch_channel_ready(imember->channel) && switch_channel_test_flag(imember->channel, CF_VIDEO_READY) && 
-					conference_utils_member_test_flag(imember, MFLAG_RUNNING) 
+					conference_utils_member_test_flag(imember, MFLAG_RUNNING) && (!no_muted || seen) && (!no_av || imember->avatar_png_img)
 					&& imember->canvas_id == canvas->canvas_id && imember->video_media_flow != SWITCH_MEDIA_FLOW_SENDONLY) {
 					canvas_count++;
 				}
@@ -2234,6 +2248,21 @@ 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) {
+				conference_video_detach_video_layer(imember);
+				switch_img_free(&imember->video_mute_img);
+				
+				if (imember->id == imember->conference->video_floor_holder) {
+					conference_video_set_floor_holder(conference, NULL, SWITCH_FALSE);
+				} else if (imember->id == imember->conference->last_video_floor_holder) {
+					conference->last_video_floor_holder = 0;
+				}
+				
+				switch_core_session_rwunlock(imember->session);
+				continue;
+			}
+
 			//VIDFLOOR
 			if (canvas->layout_floor_id > -1 && imember->id == conference->video_floor_holder &&
 				imember->video_layer_id != canvas->layout_floor_id) {
@@ -2250,8 +2279,6 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr
 				continue;
 			}
 
-
-
 			switch_mutex_lock(canvas->mutex);
 
 			//printf("MEMBER %d layer_id %d canvas: %d/%d\n", imember->id, imember->video_layer_id,
@@ -2300,7 +2327,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)) {
+				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 || conference_utils_test_flag(imember->conference, CFLAG_VIDEO_MUTE_EXIT_CANVAS)) {
 					layer->mute_patched = 0;
 				} else {
 					switch_image_t *tmp;
diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c
index 4ba5a23f51..ff5e57b348 100644
--- a/src/mod/applications/mod_conference/mod_conference.c
+++ b/src/mod/applications/mod_conference/mod_conference.c
@@ -279,7 +279,7 @@ void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, void *ob
 					}
 				}
 
-				if (switch_channel_ready(channel) && switch_channel_test_flag(channel, CF_VIDEO) && imember->video_media_flow != SWITCH_MEDIA_FLOW_SENDONLY) {
+				if (switch_channel_ready(channel) && switch_channel_test_flag(channel, CF_VIDEO_READY) && imember->video_media_flow != SWITCH_MEDIA_FLOW_SENDONLY && (!conference_utils_test_flag(conference, CFLAG_VIDEO_MUTE_EXIT_CANVAS) || conference_utils_member_test_flag(imember, MFLAG_CAN_BE_SEEN))) {
 					members_with_video++;
 				}
 
diff --git a/src/mod/applications/mod_conference/mod_conference.h b/src/mod/applications/mod_conference/mod_conference.h
index 7c9793686b..83f7860307 100644
--- a/src/mod/applications/mod_conference/mod_conference.h
+++ b/src/mod/applications/mod_conference/mod_conference.h
@@ -246,6 +246,7 @@ typedef enum {
 	CFLAG_VIDEO_REQUIRED_FOR_CANVAS,
 	CFLAG_PERSONAL_CANVAS,
 	CFLAG_REFRESH_LAYOUT,
+	CFLAG_VIDEO_MUTE_EXIT_CANVAS,
 	/////////////////////////////////
 	CFLAG_MAX
 } conference_flag_t;