From 3148b1ad744fffe120d026dc1670dec6c60cc84c Mon Sep 17 00:00:00 2001
From: Anthony Minessale <anthm@freeswitch.org>
Date: Fri, 17 Jul 2015 20:18:26 -0500
Subject: [PATCH] FS-7847 fix logo ratios and add borders too

---
 .../mod_conference/conference_video.c         | 51 +++++++++++++++----
 .../mod_conference/mod_conference.c           | 19 ++++++-
 .../mod_conference/mod_conference.h           |  4 ++
 3 files changed, 64 insertions(+), 10 deletions(-)

diff --git a/src/mod/applications/mod_conference/conference_video.c b/src/mod/applications/mod_conference/conference_video.c
index 4af0dcebe1..106b7fdc3b 100644
--- a/src/mod/applications/mod_conference/conference_video.c
+++ b/src/mod/applications/mod_conference/conference_video.c
@@ -112,7 +112,8 @@ void conference_video_parse_layouts(conference_obj_t *conference, int WIDTH, int
 				video_layout_t *vlayout;
 				const char *val = NULL, *name = NULL;
 				switch_bool_t auto_3d = SWITCH_FALSE;
-
+				int border = 0;
+				
 				if ((val = switch_xml_attr(x_layout, "name"))) {
 					name = val;
 				}
@@ -124,6 +125,12 @@ void conference_video_parse_layouts(conference_obj_t *conference, int WIDTH, int
 
 				auto_3d = switch_true(switch_xml_attr(x_layout, "auto-3d-position"));
 
+				if ((val = switch_xml_attr(x_layout, "border"))) {
+					border = atoi(val);
+					if (border < 0) border = 0;
+					if (border > 50) border = 50;
+				}
+
 				vlayout = switch_core_alloc(conference->pool, sizeof(*vlayout));
 				vlayout->name = switch_core_strdup(conference->pool, name);
 
@@ -174,7 +181,13 @@ void conference_video_parse_layouts(conference_obj_t *conference, int WIDTH, int
 					if ((val = switch_xml_attr(x_image, "audio-position"))) {
 						audio_position = val;
 					}
+					
+					if ((val = switch_xml_attr(x_image, "border"))) {
+						border = atoi(val);
 
+						if (border < 0) border = 0;
+						if (border > 50) border = 50;
+					}
 
 					if (x < 0 || y < 0 || scale < 0 || !name) {
 						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "invalid image\n");
@@ -184,7 +197,10 @@ void conference_video_parse_layouts(conference_obj_t *conference, int WIDTH, int
 					if (hscale == -1) {
 						hscale = scale;
 					}
-
+					
+					if (!border) border = conference->video_border_size;
+					
+					vlayout->images[vlayout->layers].border = border;
 					vlayout->images[vlayout->layers].x = x;
 					vlayout->images[vlayout->layers].y = y;
 					vlayout->images[vlayout->layers].scale = scale;
@@ -415,10 +431,10 @@ void conference_video_scale_and_patch(mcu_layer_t *layer, switch_image_t *ximg,
 		if (!layer->img) {
 			layer->img = switch_img_alloc(NULL, SWITCH_IMG_FMT_I420, img_w, img_h, 1);
 		}
-
+		
 		if (layer->banner_img && !layer->banner_patched) {
-			switch_img_fill(layer->canvas->img, layer->x_pos, layer->y_pos, layer->screen_w, layer->screen_h, &layer->canvas->letterbox_bgcolor);
-			switch_img_patch(IMG, layer->banner_img, layer->x_pos, layer->y_pos + (layer->screen_h - layer->banner_img->d_h));
+			switch_img_fill(layer->canvas->img, layer->x_pos + layer->geometry.border, layer->y_pos + layer->geometry.border, layer->screen_w, layer->screen_h, &layer->canvas->letterbox_bgcolor);
+			switch_img_patch(IMG, layer->banner_img, layer->x_pos + layer->geometry.border, layer->y_pos + (layer->screen_h - layer->banner_img->d_h) + layer->geometry.border);
 
 			if (!freeze) {
 				switch_img_set_rect(layer->img, 0, 0, layer->img->d_w, layer->img->d_h - layer->banner_img->d_h);
@@ -429,6 +445,13 @@ void conference_video_scale_and_patch(mcu_layer_t *layer, switch_image_t *ximg,
 
 		switch_assert(layer->img);
 
+		if (layer->geometry.border) {
+			switch_img_fill(IMG, x_pos, y_pos, img_w, img_h, &layer->canvas->border_color);
+		}
+		
+		img_w -= (layer->geometry.border * 2);
+		img_h -= (layer->geometry.border * 2);
+
 		if (switch_img_scale(img, &layer->img, img_w, img_h) == SWITCH_STATUS_SUCCESS) {
 			if (layer->bugged && layer->member_id > -1) {
 				conference_member_t *member;
@@ -440,21 +463,23 @@ void conference_video_scale_and_patch(mcu_layer_t *layer, switch_image_t *ximg,
 				}
 			}
 
-			switch_img_patch(IMG, layer->img, x_pos, y_pos);
+			switch_img_patch(IMG, layer->img, x_pos + layer->geometry.border, y_pos + layer->geometry.border);
 		}
 
 		if (layer->logo_img) {
-			int ew = layer->screen_w, eh = layer->screen_h - (layer->banner_img ? layer->banner_img->d_h : 0);
+			int ew = layer->screen_w - (layer->geometry.border * 2), eh = layer->screen_h - (layer->banner_img ? layer->banner_img->d_h : 0) - (layer->geometry.border * 2);
 			int ex = 0, ey = 0;
 
 			switch_img_fit(&layer->logo_img, ew, eh);
 			switch_img_find_position(layer->logo_pos, ew, eh, layer->logo_img->d_w, layer->logo_img->d_h, &ex, &ey);
-			switch_img_patch(IMG, layer->logo_img, layer->x_pos + ex, layer->y_pos + ey);
+			switch_img_patch(IMG, layer->logo_img, layer->x_pos + ex + layer->geometry.border, layer->y_pos + ey + layer->geometry.border);
 			if (layer->logo_text_img) {
 				int tx = 0, ty = 0;
+
+				switch_img_fit(&layer->logo_text_img, (ew / 2) + 1, (eh / 2) + 1);
 				switch_img_find_position(POS_LEFT_BOT,
 										 layer->logo_img->d_w, layer->logo_img->d_h, layer->logo_text_img->d_w, layer->logo_text_img->d_h, &tx, &ty);
-				switch_img_patch(IMG, layer->logo_text_img, layer->x_pos + ex + tx, layer->y_pos + ey + ty);
+				switch_img_patch(IMG, layer->logo_text_img, layer->x_pos + ex + tx + layer->geometry.border, layer->y_pos + ey + ty + layer->geometry.border);
 			}
 
 		}
@@ -477,6 +502,11 @@ void conference_video_set_canvas_letterbox_bgcolor(mcu_canvas_t *canvas, char *c
 	switch_color_set_rgb(&canvas->letterbox_bgcolor, color);
 }
 
+void conference_video_set_canvas_border_color(mcu_canvas_t *canvas, char *color)
+{
+	switch_color_set_rgb(&canvas->border_color, color);
+}
+
 void conference_video_check_used_layers(mcu_canvas_t *canvas)
 {
 	int i;
@@ -878,11 +908,13 @@ void conference_video_init_canvas_layers(conference_obj_t *conference, mcu_canva
 		}
 		layer->geometry.scale = vlayout->images[i].scale;
 		layer->geometry.zoom = vlayout->images[i].zoom;
+		layer->geometry.border = vlayout->images[i].border;
 		layer->geometry.floor = vlayout->images[i].floor;
 		layer->geometry.overlap = vlayout->images[i].overlap;
 		layer->idx = i;
 		layer->refresh = 1;
 
+																		
 		layer->screen_w = canvas->img->d_w * layer->geometry.scale / VIDEO_LAYOUT_SCALE;
 		layer->screen_h = canvas->img->d_h * layer->geometry.hscale / VIDEO_LAYOUT_SCALE;
 
@@ -975,6 +1007,7 @@ switch_status_t conference_video_init_canvas(conference_obj_t *conference, video
 	switch_mutex_lock(canvas->mutex);
 	conference_video_set_canvas_bgcolor(canvas, conference->video_canvas_bgcolor);
 	conference_video_set_canvas_letterbox_bgcolor(canvas, conference->video_letterbox_bgcolor);
+	conference_video_set_canvas_border_color(canvas, conference->video_border_color);
 	conference_video_init_canvas_layers(conference, canvas, vlayout);
 	switch_mutex_unlock(canvas->mutex);
 
diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c
index fc2c38c162..869eb74a65 100644
--- a/src/mod/applications/mod_conference/mod_conference.c
+++ b/src/mod/applications/mod_conference/mod_conference.c
@@ -2380,6 +2380,8 @@ conference_obj_t *conference_new(char *name, conference_xml_cfg_t cfg, switch_co
 	char *video_layout_group = NULL;
 	char *video_canvas_size = NULL;
 	char *video_canvas_bgcolor = NULL;
+	char *video_border_color = NULL;
+	int video_border_size = 0;
 	char *video_super_canvas_bgcolor = NULL;
 	char *video_letterbox_bgcolor = NULL;
 	char *video_codec_bandwidth = NULL;
@@ -2545,7 +2547,11 @@ conference_obj_t *conference_new(char *name, conference_xml_cfg_t cfg, switch_co
 			} else if (!strcasecmp(var, "video-super-canvas-show-all-layers") && !zstr(val)) {
 				video_super_canvas_show_all_layers = atoi(val);
 			} else if (!strcasecmp(var, "video-canvas-bgcolor") && !zstr(val)) {
-				video_canvas_bgcolor= val;
+				video_canvas_bgcolor = val;
+			} else if (!strcasecmp(var, "video-border-color") && !zstr(val)) {
+				video_border_color = val;
+			} else if (!strcasecmp(var, "video-border-size") && !zstr(val)) {
+				video_border_size = atoi(val);
 			} else if (!strcasecmp(var, "video-super-canvas-bgcolor") && !zstr(val)) {
 				video_super_canvas_bgcolor= val;
 			} else if (!strcasecmp(var, "video-letterbox-bgcolor") && !zstr(val)) {
@@ -2783,6 +2789,11 @@ conference_obj_t *conference_new(char *name, conference_xml_cfg_t cfg, switch_co
 			canvas_h = CONFERENCE_CANVAS_DEFAULT_HIGHT;
 		}
 
+		if (video_border_size) {
+			if (video_border_size < 0) video_border_size = 0;
+			if (video_border_size > 50) video_border_size = 50;
+		}
+		conference->video_border_size = video_border_size;
 
 		conference_video_parse_layouts(conference, canvas_w, canvas_h);
 
@@ -2790,6 +2801,10 @@ conference_obj_t *conference_new(char *name, conference_xml_cfg_t cfg, switch_co
 			video_canvas_bgcolor = "#333333";
 		}
 
+		if (!video_border_color) {
+			video_border_color = "#000000";
+		}
+		
 		if (!video_super_canvas_bgcolor) {
 			video_super_canvas_bgcolor = "#068df3";
 		}
@@ -2802,7 +2817,9 @@ conference_obj_t *conference_new(char *name, conference_xml_cfg_t cfg, switch_co
 			conference->no_video_avatar = switch_core_strdup(conference->pool, no_video_avatar);
 		}
 
+		
 		conference->video_canvas_bgcolor = switch_core_strdup(conference->pool, video_canvas_bgcolor);
+		conference->video_border_color = switch_core_strdup(conference->pool, video_border_color);
 		conference->video_super_canvas_bgcolor = switch_core_strdup(conference->pool, video_super_canvas_bgcolor);
 		conference->video_letterbox_bgcolor = switch_core_strdup(conference->pool, video_letterbox_bgcolor);
 
diff --git a/src/mod/applications/mod_conference/mod_conference.h b/src/mod/applications/mod_conference/mod_conference.h
index 9783dbe4c9..bbaa615159 100644
--- a/src/mod/applications/mod_conference/mod_conference.h
+++ b/src/mod/applications/mod_conference/mod_conference.h
@@ -410,6 +410,7 @@ typedef struct mcu_layer_geometry_s {
 	int fileonly;
 	int overlap;
 	int zoom;
+	int border;
 	char *res_id;
 	char *audio_position;
 } mcu_layer_geometry_t;
@@ -476,6 +477,7 @@ typedef struct mcu_canvas_s {
 	int send_keyframe;
 	int play_file;
 	switch_rgb_color_t bgcolor;
+	switch_rgb_color_t border_color;
 	switch_rgb_color_t letterbox_bgcolor;
 	switch_mutex_t *mutex;
 	switch_timer_t timer;
@@ -539,6 +541,7 @@ typedef struct conference_obj {
 	char *video_layout_name;
 	char *video_layout_group;
 	char *video_canvas_bgcolor;
+	char *video_border_color;
 	char *video_super_canvas_bgcolor;
 	char *video_letterbox_bgcolor;
 	char *no_video_avatar;
@@ -551,6 +554,7 @@ typedef struct conference_obj {
 	uint32_t terminate_on_silence;
 	uint32_t max_members;
 	uint32_t doc_version;
+	uint32_t video_border_size;
 	char *maxmember_sound;
 	uint32_t announce_count;
 	char *pin;