diff --git a/src/mod/applications/mod_conference/conference_api.c b/src/mod/applications/mod_conference/conference_api.c index 2ea16ae9ef..b94e8ee104 100644 --- a/src/mod/applications/mod_conference/conference_api.c +++ b/src/mod/applications/mod_conference/conference_api.c @@ -70,6 +70,7 @@ api_command_t conference_api_sub_commands[] = { {"dtmf", (void_fn_t) & conference_api_sub_dtmf, CONF_API_SUB_MEMBER_TARGET, "dtmf", "<[member_id|all|last|non_moderator]> "}, {"kick", (void_fn_t) & conference_api_sub_kick, CONF_API_SUB_MEMBER_TARGET, "kick", "<[member_id|all|last|non_moderator]> []"}, {"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]>"}, {"mute", (void_fn_t) & conference_api_sub_mute, CONF_API_SUB_MEMBER_TARGET, "mute", "<[member_id|all]|last|non_moderator> []"}, {"tmute", (void_fn_t) & conference_api_sub_tmute, CONF_API_SUB_MEMBER_TARGET, "tmute", "<[member_id|all]|last|non_moderator> []"}, @@ -738,6 +739,62 @@ switch_status_t conference_api_sub_kick(conference_member_t *member, switch_stre return SWITCH_STATUS_SUCCESS; } +switch_status_t conference_api_sub_vid_border(conference_member_t *member, switch_stream_handle_t *stream, void *data) +{ + char *arg = (char *) data; + mcu_layer_t *layer = NULL; + int len = 5; + + if (member == NULL) { + return SWITCH_STATUS_GENERR; + } + + if (zstr(arg)) { + if (stream) { + stream->write_function(stream, "-ERR No text supplied\n", switch_channel_get_name(member->channel)); + } + goto end; + } + + layer = conference_video_get_layer_locked(member); + + if (!layer) { + if (stream) { + stream->write_function(stream, "-ERR Channel %s is not in a video layer\n", switch_channel_get_name(member->channel)); + } + goto end; + } + + if (!strcasecmp(arg, "toggle")) { + if (member->video_manual_border) { + len = 0; + } else { + len = 5; + } + } else { + len = atoi(arg); + } + + if (len < 0 || len > 20) { + len = 0; + } + + member->video_manual_border = len; + layer->manual_border = len; + + if (stream) { + stream->write_function(stream, "+OK\n"); + } + + end: + + if (layer) { + conference_video_release_layer(&layer); + } + + return SWITCH_STATUS_SUCCESS; +} + switch_status_t conference_api_sub_vid_flip(conference_member_t *member, switch_stream_handle_t *stream, void *data) { diff --git a/src/mod/applications/mod_conference/conference_loop.c b/src/mod/applications/mod_conference/conference_loop.c index ef39461ff7..5bfc2738f9 100644 --- a/src/mod/applications/mod_conference/conference_loop.c +++ b/src/mod/applications/mod_conference/conference_loop.c @@ -46,6 +46,7 @@ struct _mapping control_mappings[] = { {"mute on", conference_loop_mute_on}, {"mute off", conference_loop_mute_off}, {"moh toggle", conference_loop_moh_toggle}, + {"border", conference_loop_border}, {"vmute", conference_loop_vmute_toggle}, {"vmute on", conference_loop_vmute_on}, {"vmute off", conference_loop_vmute_off}, @@ -173,6 +174,11 @@ void conference_loop_moh_toggle(conference_member_t *member, caller_control_acti conference_api_set_moh(member->conference, "toggle"); } +void conference_loop_border(conference_member_t *member, caller_control_action_t *action) +{ + conference_api_sub_vid_border(member, NULL, action->expanded_data); +} + void conference_loop_vmute_toggle(conference_member_t *member, caller_control_action_t *action) { if (member == NULL) diff --git a/src/mod/applications/mod_conference/conference_video.c b/src/mod/applications/mod_conference/conference_video.c index 337ca82db9..1c94c6350a 100644 --- a/src/mod/applications/mod_conference/conference_video.c +++ b/src/mod/applications/mod_conference/conference_video.c @@ -415,7 +415,8 @@ void conference_video_reset_layer(mcu_layer_t *layer) layer->banner_patched = 0; layer->is_avatar = 0; layer->need_patch = 0; - + layer->manual_border = 0; + conference_video_reset_layer_cam(layer); if (layer->geometry.overlap) { @@ -504,7 +505,7 @@ static void set_bounds(int *x, int *y, int img_w, int img_h, int crop_w, int cro void conference_video_scale_and_patch(mcu_layer_t *layer, switch_image_t *ximg, switch_bool_t freeze) { switch_image_t *IMG, *img; - int img_changed = 0, want_w = 0, want_h = 0; + int img_changed = 0, want_w = 0, want_h = 0, border = 0; switch_mutex_lock(layer->canvas->mutex); @@ -817,6 +818,12 @@ void conference_video_scale_and_patch(mcu_layer_t *layer, switch_image_t *ximg, y_pos += (layer->screen_h - img_h) / 2; } + if (layer->manual_border) { + border = layer->manual_border; + } if (layer->geometry.border) { + border = layer->geometry.border; + } + if (layer->img) { if (layer->banner_img) { want_h = img_h - layer->banner_img->d_h; @@ -824,8 +831,9 @@ void conference_video_scale_and_patch(mcu_layer_t *layer, switch_image_t *ximg, want_h = img_h; } - want_w = img_w; - + want_w = img_w - (border * 2); + want_h -= (border * 2); + if (layer->img->d_w != img_w || layer->img->d_h != img_h) { switch_img_free(&layer->img); conference_video_clear_layer(layer); @@ -840,28 +848,28 @@ void conference_video_scale_and_patch(mcu_layer_t *layer, switch_image_t *ximg, switch_assert(layer->img); - if (layer->geometry.border) { + if (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); + //img_w -= (border * 2); + //img_h -= (border * 2); //printf("SCALE %d,%d %dx%d\n", x_pos, y_pos, img_w, img_h); switch_img_scale(img, &layer->img, img_w, img_h); if (layer->logo_img) { - //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 ew = layer->img->d_w, eh = layer->img->d_h; + //int ew = layer->screen_w - (border * 2), eh = layer->screen_h - (layer->banner_img ? layer->banner_img->d_h : 0) - (border * 2); + int ew = layer->img->d_w - (border * 2), eh = layer->img->d_h - (border * 2); int ex = 0, ey = 0; switch_img_fit(&layer->logo_img, ew, eh, layer->logo_fit); switch_img_find_position(layer->logo_pos, ew, eh, layer->logo_img->d_w, layer->logo_img->d_h, &ex, &ey); - switch_img_patch(layer->img, layer->logo_img, ex, ey); - //switch_img_patch(IMG, layer->logo_img, layer->x_pos + ex + layer->geometry.border, layer->y_pos + ey + layer->geometry.border); + switch_img_patch(layer->img, layer->logo_img, ex + border, ey + border); + //switch_img_patch(IMG, layer->logo_img, layer->x_pos + ex + border, layer->y_pos + ey + border); } @@ -871,8 +879,8 @@ void conference_video_scale_and_patch(mcu_layer_t *layer, switch_image_t *ximg, switch_img_fit(&layer->banner_img, layer->screen_w, layer->screen_h, SWITCH_FIT_SIZE); switch_img_find_position(POS_LEFT_BOT, ew, eh, layer->banner_img->d_w, layer->banner_img->d_h, &ex, &ey); - 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); + switch_img_patch(IMG, layer->banner_img, layer->x_pos + border, + layer->y_pos + (layer->screen_h - layer->banner_img->d_h) + border); layer->banner_patched = 1; } @@ -905,8 +913,8 @@ void conference_video_scale_and_patch(mcu_layer_t *layer, switch_image_t *ximg, } switch_mutex_unlock(layer->overlay_mutex); - - switch_img_patch_rect(IMG, x_pos + layer->geometry.border, y_pos + layer->geometry.border, layer->img, 0, 0, want_w, want_h); + + switch_img_patch_rect(IMG, x_pos + border, y_pos + border, layer->img, 0, 0, want_w, want_h); } @@ -1477,7 +1485,7 @@ switch_status_t conference_video_attach_video_layer(conference_member_t *member, member->layer_timeout = DEFAULT_LAYER_TIMEOUT; conference_utils_member_set_flag_locked(member, MFLAG_VIDEO_JOIN); switch_channel_set_flag(member->channel, CF_VIDEO_REFRESH_REQ); - + layer->manual_border = member->video_manual_border; canvas->send_keyframe = 30; //member->watching_canvas_id = canvas->canvas_id; diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index eed989dbc5..995f1ef307 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -3196,7 +3196,7 @@ conference_obj_t *conference_new(char *name, conference_xml_cfg_t cfg, switch_co } if (!video_border_color) { - video_border_color = "#000000"; + video_border_color = "#00ff00"; } if (!video_super_canvas_bgcolor) { diff --git a/src/mod/applications/mod_conference/mod_conference.h b/src/mod/applications/mod_conference/mod_conference.h index a80f47a9a4..c87c7adaef 100644 --- a/src/mod/applications/mod_conference/mod_conference.h +++ b/src/mod/applications/mod_conference/mod_conference.h @@ -505,6 +505,7 @@ typedef struct mcu_layer_s { mcu_layer_cam_opts_t cam_opts; switch_mutex_t *overlay_mutex; switch_core_video_filter_t overlay_filters; + int manual_border; } mcu_layer_t; typedef struct video_layout_s { @@ -904,6 +905,7 @@ struct conference_member { mcu_layer_cam_opts_t cam_opts; switch_core_video_filter_t video_filters; + int video_manual_border; }; typedef enum { @@ -1245,6 +1247,7 @@ switch_status_t conference_api_sub_canvas(conference_member_t *member, switch_st switch_status_t conference_api_sub_layer(conference_member_t *member, switch_stream_handle_t *stream, void *data); switch_status_t conference_api_sub_kick(conference_member_t *member, switch_stream_handle_t *stream, void *data); switch_status_t conference_api_sub_vid_flip(conference_member_t *member, switch_stream_handle_t *stream, void *data); +switch_status_t conference_api_sub_vid_border(conference_member_t *member, switch_stream_handle_t *stream, void *data); switch_status_t conference_api_sub_transfer(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv); switch_status_t conference_api_sub_record(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv); switch_status_t conference_api_sub_norecord(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv); @@ -1278,6 +1281,7 @@ void conference_loop_conference_video_vmute_snapoff(conference_member_t *member, void conference_loop_vmute_toggle(conference_member_t *member, caller_control_action_t *action); void conference_loop_vmute_on(conference_member_t *member, caller_control_action_t *action); void conference_loop_moh_toggle(conference_member_t *member, caller_control_action_t *action); +void conference_loop_border(conference_member_t *member, caller_control_action_t *action); void conference_loop_deafmute_toggle(conference_member_t *member, caller_control_action_t *action); void conference_loop_hangup(conference_member_t *member, caller_control_action_t *action); void conference_loop_transfer(conference_member_t *member, caller_control_action_t *action);