FS-11034: [mod_conference] Add border control to video #resolve

This commit is contained in:
Anthony Minessale 2018-03-14 18:30:49 -05:00 committed by Muteesa Fred
parent b272c5e521
commit 2a82d401a6
5 changed files with 92 additions and 17 deletions

View File

@ -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]> <digits>"},
{"kick", (void_fn_t) & conference_api_sub_kick, CONF_API_SUB_MEMBER_TARGET, "kick", "<[member_id|all|last|non_moderator]> [<optional sound file>]"},
{"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> [<quiet>]"},
{"tmute", (void_fn_t) & conference_api_sub_tmute, CONF_API_SUB_MEMBER_TARGET, "tmute", "<[member_id|all]|last|non_moderator> [<quiet>]"},
@ -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)
{

View File

@ -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)

View File

@ -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;

View File

@ -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) {

View File

@ -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);