FS-7513: improve reservation id and layout switching with overlap
This commit is contained in:
parent
93b3a946ec
commit
270aba6849
|
@ -366,6 +366,7 @@ typedef struct mcu_layer_geometry_s {
|
||||||
int y;
|
int y;
|
||||||
int scale;
|
int scale;
|
||||||
int floor;
|
int floor;
|
||||||
|
int overlap;
|
||||||
char *res_id;
|
char *res_id;
|
||||||
char *audio_position;
|
char *audio_position;
|
||||||
} mcu_layer_geometry_t;
|
} mcu_layer_geometry_t;
|
||||||
|
@ -627,6 +628,7 @@ struct conference_member {
|
||||||
char *video_banner_text;
|
char *video_banner_text;
|
||||||
char *video_logo;
|
char *video_logo;
|
||||||
char *video_mute_png;
|
char *video_mute_png;
|
||||||
|
char *video_reservation_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
@ -763,6 +765,7 @@ static void conference_parse_layouts(conference_obj_t *conference)
|
||||||
{
|
{
|
||||||
switch_event_t *params;
|
switch_event_t *params;
|
||||||
switch_xml_t cxml = NULL, cfg = NULL, x_layouts, x_layout, x_layout_settings, x_group, x_groups, x_image;
|
switch_xml_t cxml = NULL, cfg = NULL, x_layouts, x_layout, x_layout_settings, x_group, x_groups, x_image;
|
||||||
|
char cmd_str[256] = "";
|
||||||
|
|
||||||
if (!conference->layout_hash) {
|
if (!conference->layout_hash) {
|
||||||
switch_core_hash_init(&conference->layout_hash);
|
switch_core_hash_init(&conference->layout_hash);
|
||||||
|
@ -801,7 +804,7 @@ static void conference_parse_layouts(conference_obj_t *conference)
|
||||||
|
|
||||||
for (x_image = switch_xml_child(x_layout, "image"); x_image; x_image = x_image->next) {
|
for (x_image = switch_xml_child(x_layout, "image"); x_image; x_image = x_image->next) {
|
||||||
const char *res_id = NULL, *audio_position = NULL;
|
const char *res_id = NULL, *audio_position = NULL;
|
||||||
int x = -1, y = -1, scale = -1, floor = 0;
|
int x = -1, y = -1, scale = -1, floor = 0, overlap = 0;
|
||||||
|
|
||||||
if ((val = switch_xml_attr(x_image, "x"))) {
|
if ((val = switch_xml_attr(x_image, "x"))) {
|
||||||
x = atoi(val);
|
x = atoi(val);
|
||||||
|
@ -818,6 +821,10 @@ static void conference_parse_layouts(conference_obj_t *conference)
|
||||||
if ((val = switch_xml_attr(x_image, "floor"))) {
|
if ((val = switch_xml_attr(x_image, "floor"))) {
|
||||||
floor = switch_true(val);
|
floor = switch_true(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((val = switch_xml_attr(x_image, "overlap"))) {
|
||||||
|
overlap = switch_true(val);
|
||||||
|
}
|
||||||
|
|
||||||
if ((val = switch_xml_attr(x_image, "reservation_id"))) {
|
if ((val = switch_xml_attr(x_image, "reservation_id"))) {
|
||||||
res_id = val;
|
res_id = val;
|
||||||
|
@ -838,6 +845,7 @@ static void conference_parse_layouts(conference_obj_t *conference)
|
||||||
vlayout->images[vlayout->layers].y = y;
|
vlayout->images[vlayout->layers].y = y;
|
||||||
vlayout->images[vlayout->layers].scale = scale;
|
vlayout->images[vlayout->layers].scale = scale;
|
||||||
vlayout->images[vlayout->layers].floor = floor;
|
vlayout->images[vlayout->layers].floor = floor;
|
||||||
|
vlayout->images[vlayout->layers].overlap = overlap;
|
||||||
|
|
||||||
if (res_id) {
|
if (res_id) {
|
||||||
vlayout->images[vlayout->layers].res_id = switch_core_strdup(conference->pool, res_id);
|
vlayout->images[vlayout->layers].res_id = switch_core_strdup(conference->pool, res_id);
|
||||||
|
@ -851,6 +859,8 @@ static void conference_parse_layouts(conference_obj_t *conference)
|
||||||
}
|
}
|
||||||
|
|
||||||
switch_core_hash_insert(conference->layout_hash, name, vlayout);
|
switch_core_hash_insert(conference->layout_hash, name, vlayout);
|
||||||
|
switch_snprintf(cmd_str, sizeof(cmd_str), "add conference ::conference::list_conferences vid-layout %s", name);
|
||||||
|
switch_console_set_complete(cmd_str);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1248,7 +1258,6 @@ static switch_status_t attach_video_layer(conference_member_t *member, int idx)
|
||||||
{
|
{
|
||||||
mcu_layer_t *layer = NULL;
|
mcu_layer_t *layer = NULL;
|
||||||
switch_channel_t *channel = NULL;
|
switch_channel_t *channel = NULL;
|
||||||
const char *res_id = NULL;
|
|
||||||
switch_status_t status = SWITCH_STATUS_SUCCESS;
|
switch_status_t status = SWITCH_STATUS_SUCCESS;
|
||||||
const char *var = NULL;
|
const char *var = NULL;
|
||||||
switch_rgb_color_t color;
|
switch_rgb_color_t color;
|
||||||
|
@ -1257,6 +1266,7 @@ static switch_status_t attach_video_layer(conference_member_t *member, int idx)
|
||||||
|
|
||||||
channel = switch_core_session_get_channel(member->session);
|
channel = switch_core_session_get_channel(member->session);
|
||||||
|
|
||||||
|
|
||||||
if (!switch_channel_test_flag(channel, CF_VIDEO)) {
|
if (!switch_channel_test_flag(channel, CF_VIDEO)) {
|
||||||
return SWITCH_STATUS_FALSE;
|
return SWITCH_STATUS_FALSE;
|
||||||
}
|
}
|
||||||
|
@ -1264,12 +1274,24 @@ static switch_status_t attach_video_layer(conference_member_t *member, int idx)
|
||||||
switch_mutex_lock(member->conference->canvas->mutex);
|
switch_mutex_lock(member->conference->canvas->mutex);
|
||||||
|
|
||||||
layer = &member->conference->canvas->layers[idx];
|
layer = &member->conference->canvas->layers[idx];
|
||||||
|
|
||||||
layer->tagged = 0;
|
layer->tagged = 0;
|
||||||
|
if (layer->geometry.res_id) {
|
||||||
|
if (!member->video_reservation_id || strcmp(layer->geometry.res_id, member->video_reservation_id)) {
|
||||||
|
switch_goto_status(SWITCH_STATUS_FALSE, end);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (layer->member_id && layer->member_id == member->id) {
|
if (layer->member_id && layer->member_id == member->id) {
|
||||||
member->video_layer_id = idx;
|
member->video_layer_id = idx;
|
||||||
switch_goto_status(SWITCH_STATUS_BREAK, end);
|
switch_goto_status(SWITCH_STATUS_BREAK, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (layer->geometry.res_id || member->video_reservation_id) {
|
||||||
|
if (!layer->geometry.res_id || !member->video_reservation_id || strcmp(layer->geometry.res_id, member->video_reservation_id)) {
|
||||||
|
switch_goto_status(SWITCH_STATUS_FALSE, end);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (member->video_layer_id > -1) {
|
if (member->video_layer_id > -1) {
|
||||||
detach_video_layer(member);
|
detach_video_layer(member);
|
||||||
|
@ -1277,14 +1299,6 @@ static switch_status_t attach_video_layer(conference_member_t *member, int idx)
|
||||||
|
|
||||||
reset_layer(member->conference->canvas, layer);
|
reset_layer(member->conference->canvas, layer);
|
||||||
switch_img_free(&layer->mute_img);
|
switch_img_free(&layer->mute_img);
|
||||||
|
|
||||||
res_id = switch_channel_get_variable_dup(channel, "video_reservation_id", SWITCH_FALSE, -1);
|
|
||||||
|
|
||||||
if (layer->geometry.res_id || res_id) {
|
|
||||||
if (!layer->geometry.res_id || !res_id || strcmp(layer->geometry.res_id, res_id)) {
|
|
||||||
switch_goto_status(SWITCH_STATUS_FALSE, end);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var = NULL;
|
var = NULL;
|
||||||
if (member->video_banner_text || (var = switch_channel_get_variable_dup(channel, "video_banner_text", SWITCH_FALSE, -1))) {
|
if (member->video_banner_text || (var = switch_channel_get_variable_dup(channel, "video_banner_text", SWITCH_FALSE, -1))) {
|
||||||
|
@ -1331,6 +1345,7 @@ static void init_canvas_layers(conference_obj_t *conference, video_layout_t *vla
|
||||||
layer->geometry.y = vlayout->images[i].y;
|
layer->geometry.y = vlayout->images[i].y;
|
||||||
layer->geometry.scale = vlayout->images[i].scale;
|
layer->geometry.scale = vlayout->images[i].scale;
|
||||||
layer->geometry.floor = vlayout->images[i].floor;
|
layer->geometry.floor = vlayout->images[i].floor;
|
||||||
|
layer->geometry.overlap = vlayout->images[i].overlap;
|
||||||
layer->idx = i;
|
layer->idx = i;
|
||||||
|
|
||||||
|
|
||||||
|
@ -1651,7 +1666,7 @@ static void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread
|
||||||
switch_mutex_lock(conference->canvas->mutex);
|
switch_mutex_lock(conference->canvas->mutex);
|
||||||
//printf("MEMBER %d layer_id %d canvas: %d/%d\n", imember->id, imember->video_layer_id,
|
//printf("MEMBER %d layer_id %d canvas: %d/%d\n", imember->id, imember->video_layer_id,
|
||||||
// conference->canvas->layers_used, conference->canvas->total_layers);
|
// conference->canvas->layers_used, conference->canvas->total_layers);
|
||||||
|
|
||||||
if (imember->video_layer_id > -1) {
|
if (imember->video_layer_id > -1) {
|
||||||
layer = &conference->canvas->layers[imember->video_layer_id];
|
layer = &conference->canvas->layers[imember->video_layer_id];
|
||||||
if (layer->member_id != imember->id) {
|
if (layer->member_id != imember->id) {
|
||||||
|
@ -1663,10 +1678,21 @@ static void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread
|
||||||
if (!layer && conference->canvas->layers_used < conference->canvas->total_layers) {
|
if (!layer && conference->canvas->layers_used < conference->canvas->total_layers) {
|
||||||
/* find an empty layer */
|
/* find an empty layer */
|
||||||
for (i = 0; i < conference->canvas->total_layers; i++) {
|
for (i = 0; i < conference->canvas->total_layers; i++) {
|
||||||
layer = &conference->canvas->layers[i];
|
mcu_layer_t *xlayer = &conference->canvas->layers[i];
|
||||||
if (!layer->member_id) {
|
|
||||||
switch_status_t lstatus = attach_video_layer(imember, i);
|
if (xlayer->geometry.res_id) {
|
||||||
|
if (imember->video_reservation_id && !strcmp(xlayer->geometry.res_id, imember->video_reservation_id)) {
|
||||||
|
layer = xlayer;
|
||||||
|
attach_video_layer(imember, i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (!xlayer->member_id) {
|
||||||
|
switch_status_t lstatus;
|
||||||
|
|
||||||
|
lstatus = attach_video_layer(imember, i);
|
||||||
|
|
||||||
if (lstatus == SWITCH_STATUS_SUCCESS || lstatus == SWITCH_STATUS_BREAK) {
|
if (lstatus == SWITCH_STATUS_SUCCESS || lstatus == SWITCH_STATUS_BREAK) {
|
||||||
|
layer = xlayer;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1716,7 +1742,7 @@ static void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread
|
||||||
for (i = 0; i < conference->canvas->total_layers; i++) {
|
for (i = 0; i < conference->canvas->total_layers; i++) {
|
||||||
mcu_layer_t *layer = &conference->canvas->layers[i];
|
mcu_layer_t *layer = &conference->canvas->layers[i];
|
||||||
|
|
||||||
if (layer->member_id > -1 && layer->cur_img && layer->tagged) {
|
if (layer->member_id > -1 && layer->cur_img && (layer->tagged || layer->geometry.overlap)) {
|
||||||
scale_and_patch(conference, layer, NULL);
|
scale_and_patch(conference, layer, NULL);
|
||||||
layer->tagged = 0;
|
layer->tagged = 0;
|
||||||
}
|
}
|
||||||
|
@ -3547,6 +3573,10 @@ static switch_status_t conference_add_member(conference_obj_t *conference, confe
|
||||||
member->video_mute_png = switch_core_strdup(member->pool, var);
|
member->video_mute_png = switch_core_strdup(member->pool, var);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((var = switch_channel_get_variable_dup(member->channel, "video_reservation_id", SWITCH_FALSE, -1))) {
|
||||||
|
member->video_reservation_id = switch_core_strdup(member->pool, var);
|
||||||
|
}
|
||||||
|
|
||||||
switch_channel_set_variable_printf(channel, "conference_member_id", "%d", member->id);
|
switch_channel_set_variable_printf(channel, "conference_member_id", "%d", member->id);
|
||||||
switch_channel_set_variable_printf(channel, "conference_moderator", "%s", switch_test_flag(member, MFLAG_MOD) ? "true" : "false");
|
switch_channel_set_variable_printf(channel, "conference_moderator", "%s", switch_test_flag(member, MFLAG_MOD) ? "true" : "false");
|
||||||
switch_channel_set_variable_printf(channel, "conference_ghost", "%s", switch_test_flag(member, MFLAG_GHOST) ? "true" : "false");
|
switch_channel_set_variable_printf(channel, "conference_ghost", "%s", switch_test_flag(member, MFLAG_GHOST) ? "true" : "false");
|
||||||
|
@ -8140,6 +8170,17 @@ static switch_status_t conf_api_sub_vid_layout(conference_obj_t *conference, swi
|
||||||
return SWITCH_STATUS_SUCCESS;
|
return SWITCH_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!strcasecmp(argv[2], "list")) {
|
||||||
|
switch_hash_index_t *hi;
|
||||||
|
void *val;
|
||||||
|
const void *vvar;
|
||||||
|
for (hi = switch_core_hash_first(conference->layout_hash); hi; hi = switch_core_hash_next(&hi)) {
|
||||||
|
switch_core_hash_this(hi, &vvar, NULL, &val);
|
||||||
|
stream->write_function(stream, "%s\n", (char *)vvar);
|
||||||
|
}
|
||||||
|
return SWITCH_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
if (!strcasecmp(argv[2], "group")) {
|
if (!strcasecmp(argv[2], "group")) {
|
||||||
layout_group_t *lg = NULL;
|
layout_group_t *lg = NULL;
|
||||||
|
|
||||||
|
@ -8425,15 +8466,15 @@ static switch_status_t conf_api_sub_vid_logo_img(conference_member_t *member, sw
|
||||||
return SWITCH_STATUS_FALSE;
|
return SWITCH_STATUS_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch_mutex_lock(member->conference->canvas->mutex);
|
|
||||||
|
|
||||||
if (member->video_layer_id == -1 || !member->conference->canvas) {
|
if (member->video_layer_id == -1 || !member->conference->canvas) {
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch_mutex_lock(member->conference->canvas->mutex);
|
||||||
|
|
||||||
layer = &member->conference->canvas->layers[member->video_layer_id];
|
layer = &member->conference->canvas->layers[member->video_layer_id];
|
||||||
|
|
||||||
if (!strcasecmp(text, "clear")) {
|
if (strcasecmp(text, "clear")) {
|
||||||
member->video_logo = switch_core_strdup(member->pool, text);
|
member->video_logo = switch_core_strdup(member->pool, text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8449,6 +8490,43 @@ static switch_status_t conf_api_sub_vid_logo_img(conference_member_t *member, sw
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static switch_status_t conf_api_sub_vid_res_id(conference_member_t *member, switch_stream_handle_t *stream, void *data)
|
||||||
|
{
|
||||||
|
char *text = (char *) data;
|
||||||
|
//mcu_layer_t *layer = NULL;
|
||||||
|
|
||||||
|
if (member == NULL)
|
||||||
|
return SWITCH_STATUS_GENERR;
|
||||||
|
|
||||||
|
if (!switch_channel_test_flag(member->channel, CF_VIDEO)) {
|
||||||
|
return SWITCH_STATUS_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!member->conference->canvas) {
|
||||||
|
stream->write_function(stream, "-ERR conference is not in mixing mode\n");
|
||||||
|
return SWITCH_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch_mutex_lock(member->conference->canvas->mutex);
|
||||||
|
|
||||||
|
//layer = &member->conference->canvas->layers[member->video_layer_id];
|
||||||
|
|
||||||
|
if (!strcasecmp(text, "clear")) {
|
||||||
|
member->video_reservation_id = NULL;
|
||||||
|
stream->write_function(stream, "+OK reservation_id cleared\n");
|
||||||
|
} else {
|
||||||
|
member->video_reservation_id = switch_core_strdup(member->pool, text);
|
||||||
|
stream->write_function(stream, "+OK reservation_id %s\n", text);
|
||||||
|
}
|
||||||
|
|
||||||
|
detach_video_layer(member);
|
||||||
|
|
||||||
|
switch_mutex_unlock(member->conference->canvas->mutex);
|
||||||
|
|
||||||
|
return SWITCH_STATUS_SUCCESS;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
static switch_status_t conf_api_sub_vid_banner(conference_member_t *member, switch_stream_handle_t *stream, void *data)
|
static switch_status_t conf_api_sub_vid_banner(conference_member_t *member, switch_stream_handle_t *stream, void *data)
|
||||||
{
|
{
|
||||||
mcu_layer_t *layer = NULL;
|
mcu_layer_t *layer = NULL;
|
||||||
|
@ -9919,6 +9997,7 @@ static api_command_t conf_api_sub_commands[] = {
|
||||||
{"vid-banner", (void_fn_t) & conf_api_sub_vid_banner, CONF_API_SUB_MEMBER_TARGET, "vid-banner", "<member_id|last> <text>"},
|
{"vid-banner", (void_fn_t) & conf_api_sub_vid_banner, CONF_API_SUB_MEMBER_TARGET, "vid-banner", "<member_id|last> <text>"},
|
||||||
{"vid-mute-img", (void_fn_t) & conf_api_sub_vid_mute_img, CONF_API_SUB_MEMBER_TARGET, "vid-mute-img", "<member_id|last> [<path>|clear]"},
|
{"vid-mute-img", (void_fn_t) & conf_api_sub_vid_mute_img, CONF_API_SUB_MEMBER_TARGET, "vid-mute-img", "<member_id|last> [<path>|clear]"},
|
||||||
{"vid-logo-img", (void_fn_t) & conf_api_sub_vid_logo_img, CONF_API_SUB_MEMBER_TARGET, "vid-logo-img", "<member_id|last> [<path>|clear]"},
|
{"vid-logo-img", (void_fn_t) & conf_api_sub_vid_logo_img, CONF_API_SUB_MEMBER_TARGET, "vid-logo-img", "<member_id|last> [<path>|clear]"},
|
||||||
|
{"vid-res-id", (void_fn_t) & conf_api_sub_vid_res_id, CONF_API_SUB_MEMBER_TARGET, "vid-res-id", "<member_id|last> <val>|clear"},
|
||||||
{"clear-vid-floor", (void_fn_t) & conf_api_sub_clear_vid_floor, CONF_API_SUB_ARGS_AS_ONE, "clear-vid-floor", ""},
|
{"clear-vid-floor", (void_fn_t) & conf_api_sub_clear_vid_floor, CONF_API_SUB_ARGS_AS_ONE, "clear-vid-floor", ""},
|
||||||
{"vid-layout", (void_fn_t) & conf_api_sub_vid_layout, CONF_API_SUB_ARGS_SPLIT, "vid-layout", "<layout name>"},
|
{"vid-layout", (void_fn_t) & conf_api_sub_vid_layout, CONF_API_SUB_ARGS_SPLIT, "vid-layout", "<layout name>"},
|
||||||
{"vid-write-png", (void_fn_t) & conf_api_sub_write_png, CONF_API_SUB_ARGS_SPLIT, "vid-write-png", "<path>"},
|
{"vid-write-png", (void_fn_t) & conf_api_sub_write_png, CONF_API_SUB_ARGS_SPLIT, "vid-write-png", "<path>"},
|
||||||
|
|
Loading…
Reference in New Issue