FS-11034: [mod_conference] Add border control to video #resolve
This commit is contained in:
parent
b272c5e521
commit
2a82d401a6
|
@ -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>"},
|
{"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>]"},
|
{"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-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]>"},
|
{"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>]"},
|
{"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>]"},
|
{"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;
|
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)
|
switch_status_t conference_api_sub_vid_flip(conference_member_t *member, switch_stream_handle_t *stream, void *data)
|
||||||
{
|
{
|
||||||
|
|
|
@ -46,6 +46,7 @@ struct _mapping control_mappings[] = {
|
||||||
{"mute on", conference_loop_mute_on},
|
{"mute on", conference_loop_mute_on},
|
||||||
{"mute off", conference_loop_mute_off},
|
{"mute off", conference_loop_mute_off},
|
||||||
{"moh toggle", conference_loop_moh_toggle},
|
{"moh toggle", conference_loop_moh_toggle},
|
||||||
|
{"border", conference_loop_border},
|
||||||
{"vmute", conference_loop_vmute_toggle},
|
{"vmute", conference_loop_vmute_toggle},
|
||||||
{"vmute on", conference_loop_vmute_on},
|
{"vmute on", conference_loop_vmute_on},
|
||||||
{"vmute off", conference_loop_vmute_off},
|
{"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");
|
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)
|
void conference_loop_vmute_toggle(conference_member_t *member, caller_control_action_t *action)
|
||||||
{
|
{
|
||||||
if (member == NULL)
|
if (member == NULL)
|
||||||
|
|
|
@ -415,6 +415,7 @@ void conference_video_reset_layer(mcu_layer_t *layer)
|
||||||
layer->banner_patched = 0;
|
layer->banner_patched = 0;
|
||||||
layer->is_avatar = 0;
|
layer->is_avatar = 0;
|
||||||
layer->need_patch = 0;
|
layer->need_patch = 0;
|
||||||
|
layer->manual_border = 0;
|
||||||
|
|
||||||
conference_video_reset_layer_cam(layer);
|
conference_video_reset_layer_cam(layer);
|
||||||
|
|
||||||
|
@ -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)
|
void conference_video_scale_and_patch(mcu_layer_t *layer, switch_image_t *ximg, switch_bool_t freeze)
|
||||||
{
|
{
|
||||||
switch_image_t *IMG, *img;
|
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);
|
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;
|
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->img) {
|
||||||
if (layer->banner_img) {
|
if (layer->banner_img) {
|
||||||
want_h = img_h - layer->banner_img->d_h;
|
want_h = img_h - layer->banner_img->d_h;
|
||||||
|
@ -824,7 +831,8 @@ void conference_video_scale_and_patch(mcu_layer_t *layer, switch_image_t *ximg,
|
||||||
want_h = img_h;
|
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) {
|
if (layer->img->d_w != img_w || layer->img->d_h != img_h) {
|
||||||
switch_img_free(&layer->img);
|
switch_img_free(&layer->img);
|
||||||
|
@ -840,28 +848,28 @@ void conference_video_scale_and_patch(mcu_layer_t *layer, switch_image_t *ximg,
|
||||||
|
|
||||||
switch_assert(layer->img);
|
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);
|
switch_img_fill(IMG, x_pos, y_pos, img_w, img_h, &layer->canvas->border_color);
|
||||||
}
|
}
|
||||||
|
|
||||||
img_w -= (layer->geometry.border * 2);
|
//img_w -= (border * 2);
|
||||||
img_h -= (layer->geometry.border * 2);
|
//img_h -= (border * 2);
|
||||||
|
|
||||||
//printf("SCALE %d,%d %dx%d\n", x_pos, y_pos, img_w, img_h);
|
//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);
|
switch_img_scale(img, &layer->img, img_w, img_h);
|
||||||
|
|
||||||
if (layer->logo_img) {
|
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->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, eh = layer->img->d_h;
|
int ew = layer->img->d_w - (border * 2), eh = layer->img->d_h - (border * 2);
|
||||||
int ex = 0, ey = 0;
|
int ex = 0, ey = 0;
|
||||||
|
|
||||||
switch_img_fit(&layer->logo_img, ew, eh, layer->logo_fit);
|
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_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(layer->img, layer->logo_img, ex + border, ey + border);
|
||||||
//switch_img_patch(IMG, layer->logo_img, layer->x_pos + ex + layer->geometry.border, layer->y_pos + ey + layer->geometry.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_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_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,
|
switch_img_patch(IMG, layer->banner_img, layer->x_pos + border,
|
||||||
layer->y_pos + (layer->screen_h - layer->banner_img->d_h) + layer->geometry.border);
|
layer->y_pos + (layer->screen_h - layer->banner_img->d_h) + border);
|
||||||
layer->banner_patched = 1;
|
layer->banner_patched = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -906,7 +914,7 @@ void conference_video_scale_and_patch(mcu_layer_t *layer, switch_image_t *ximg,
|
||||||
}
|
}
|
||||||
switch_mutex_unlock(layer->overlay_mutex);
|
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;
|
member->layer_timeout = DEFAULT_LAYER_TIMEOUT;
|
||||||
conference_utils_member_set_flag_locked(member, MFLAG_VIDEO_JOIN);
|
conference_utils_member_set_flag_locked(member, MFLAG_VIDEO_JOIN);
|
||||||
switch_channel_set_flag(member->channel, CF_VIDEO_REFRESH_REQ);
|
switch_channel_set_flag(member->channel, CF_VIDEO_REFRESH_REQ);
|
||||||
|
layer->manual_border = member->video_manual_border;
|
||||||
canvas->send_keyframe = 30;
|
canvas->send_keyframe = 30;
|
||||||
|
|
||||||
//member->watching_canvas_id = canvas->canvas_id;
|
//member->watching_canvas_id = canvas->canvas_id;
|
||||||
|
|
|
@ -3196,7 +3196,7 @@ conference_obj_t *conference_new(char *name, conference_xml_cfg_t cfg, switch_co
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!video_border_color) {
|
if (!video_border_color) {
|
||||||
video_border_color = "#000000";
|
video_border_color = "#00ff00";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!video_super_canvas_bgcolor) {
|
if (!video_super_canvas_bgcolor) {
|
||||||
|
|
|
@ -505,6 +505,7 @@ typedef struct mcu_layer_s {
|
||||||
mcu_layer_cam_opts_t cam_opts;
|
mcu_layer_cam_opts_t cam_opts;
|
||||||
switch_mutex_t *overlay_mutex;
|
switch_mutex_t *overlay_mutex;
|
||||||
switch_core_video_filter_t overlay_filters;
|
switch_core_video_filter_t overlay_filters;
|
||||||
|
int manual_border;
|
||||||
} mcu_layer_t;
|
} mcu_layer_t;
|
||||||
|
|
||||||
typedef struct video_layout_s {
|
typedef struct video_layout_s {
|
||||||
|
@ -904,6 +905,7 @@ struct conference_member {
|
||||||
|
|
||||||
mcu_layer_cam_opts_t cam_opts;
|
mcu_layer_cam_opts_t cam_opts;
|
||||||
switch_core_video_filter_t video_filters;
|
switch_core_video_filter_t video_filters;
|
||||||
|
int video_manual_border;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum {
|
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_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_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_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_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_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);
|
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_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_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_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_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_hangup(conference_member_t *member, caller_control_action_t *action);
|
||||||
void conference_loop_transfer(conference_member_t *member, caller_control_action_t *action);
|
void conference_loop_transfer(conference_member_t *member, caller_control_action_t *action);
|
||||||
|
|
Loading…
Reference in New Issue