FS-7513: play files in layers

This commit is contained in:
Anthony Minessale 2015-04-06 13:11:29 -05:00 committed by Michael Jerris
parent c128d0c850
commit 07b9600130
1 changed files with 112 additions and 7 deletions

View File

@ -344,6 +344,7 @@ typedef struct conference_file_node {
switch_bool_t mux; switch_bool_t mux;
uint32_t member_id; uint32_t member_id;
al_handle_t *al; al_handle_t *al;
int layer_id;
} conference_file_node_t; } conference_file_node_t;
typedef enum { typedef enum {
@ -371,6 +372,7 @@ typedef struct mcu_layer_geometry_s {
int scale; int scale;
int floor; int floor;
int flooronly; int flooronly;
int fileonly;
int overlap; int overlap;
char *res_id; char *res_id;
char *audio_position; char *audio_position;
@ -400,6 +402,7 @@ typedef struct mcu_layer_s {
switch_image_t *logo_img; switch_image_t *logo_img;
switch_image_t *mute_img; switch_image_t *mute_img;
switch_img_txt_handle_t *txthandle; switch_img_txt_handle_t *txthandle;
conference_file_node_t *fnode;
} mcu_layer_t; } mcu_layer_t;
typedef struct video_layout_s { typedef struct video_layout_s {
@ -708,6 +711,8 @@ static conference_obj_t *conference_find(char *name, char *domain);
static void member_bind_controls(conference_member_t *member, const char *controls); static void member_bind_controls(conference_member_t *member, const char *controls);
static void conference_send_presence(conference_obj_t *conference); static void conference_send_presence(conference_obj_t *conference);
static void conference_set_video_floor_holder(conference_obj_t *conference, conference_member_t *member, switch_bool_t force); static void conference_set_video_floor_holder(conference_obj_t *conference, conference_member_t *member, switch_bool_t force);
static void canvas_del_fnode_layer(conference_obj_t *conference, conference_file_node_t *fnode);
static void canvas_set_fnode_layer(conference_obj_t *conference, conference_file_node_t *fnode, int idx);
SWITCH_STANDARD_API(conf_api_main); SWITCH_STANDARD_API(conf_api_main);
@ -826,7 +831,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, flooronly = 0, overlap = 0; int x = -1, y = -1, scale = -1, floor = 0, flooronly = 0, fileonly = 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);
@ -848,6 +853,10 @@ static void conference_parse_layouts(conference_obj_t *conference)
flooronly = floor = switch_true(val); flooronly = floor = switch_true(val);
} }
if ((val = switch_xml_attr(x_image, "file-only"))) {
fileonly = floor = switch_true(val);
}
if ((val = switch_xml_attr(x_image, "overlap"))) { if ((val = switch_xml_attr(x_image, "overlap"))) {
overlap = switch_true(val); overlap = switch_true(val);
} }
@ -872,6 +881,7 @@ static void conference_parse_layouts(conference_obj_t *conference)
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].flooronly = flooronly; vlayout->images[vlayout->layers].flooronly = flooronly;
vlayout->images[vlayout->layers].fileonly = fileonly;
vlayout->images[vlayout->layers].overlap = overlap; vlayout->images[vlayout->layers].overlap = overlap;
if (res_id) { if (res_id) {
@ -1328,6 +1338,10 @@ static switch_status_t attach_video_layer(conference_member_t *member, int idx)
layer->tagged = 0; layer->tagged = 0;
if (layer->fnode || layer->geometry.fileonly) {
switch_goto_status(SWITCH_STATUS_FALSE, end);
}
if (layer->geometry.flooronly && member->id != member->conference->video_floor_holder) { if (layer->geometry.flooronly && member->id != member->conference->video_floor_holder) {
switch_goto_status(SWITCH_STATUS_FALSE, end); switch_goto_status(SWITCH_STATUS_FALSE, end);
} }
@ -1867,13 +1881,13 @@ static void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread
attach_video_layer(imember, i); attach_video_layer(imember, i);
break; break;
} }
} else if (xlayer->geometry.flooronly) { } else if (xlayer->geometry.flooronly && !xlayer->fnode) {
if (imember->id == conference->video_floor_holder) { if (imember->id == conference->video_floor_holder) {
layer = xlayer; layer = xlayer;
attach_video_layer(imember, i); attach_video_layer(imember, i);
break; break;
} }
} else if (!xlayer->member_id) { } else if (!xlayer->member_id && !xlayer->fnode && !xlayer->geometry.fileonly) {
switch_status_t lstatus; switch_status_t lstatus;
lstatus = attach_video_layer(imember, i); lstatus = attach_video_layer(imember, i);
@ -1927,12 +1941,23 @@ static void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread
} }
switch_mutex_unlock(conference->member_mutex); switch_mutex_unlock(conference->member_mutex);
if (conference->fnode &&
conference->fnode->layer_id > -1) {
mcu_layer_t *layer = &conference->canvas->layers[conference->fnode->layer_id];
if (switch_core_file_read_video(&conference->fnode->fh, &write_frame, SVR_FLUSH) == SWITCH_STATUS_SUCCESS) {
switch_img_free(&layer->cur_img);
layer->cur_img = write_frame.img;
layer->tagged = 1;
}
}
if (!conference->playing_video_file) { if (!conference->playing_video_file) {
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 || layer->geometry.overlap)) { if ((layer->member_id > -1 || layer->fnode) && layer->cur_img && (layer->tagged || layer->geometry.overlap)) {
if (conference->canvas->refresh) { if (conference->canvas->refresh) {
layer->refresh = 1; layer->refresh = 1;
conference->canvas->refresh++; conference->canvas->refresh++;
@ -5025,6 +5050,10 @@ static void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, v
conference_file_node_t *fnode; conference_file_node_t *fnode;
switch_memory_pool_t *pool; switch_memory_pool_t *pool;
if (conference->canvas && conference->fnode->layer_id > -1 ) {
canvas_del_fnode_layer(conference, conference->fnode);
}
if (conference->fnode->type != NODE_TYPE_SPEECH) { if (conference->fnode->type != NODE_TYPE_SPEECH) {
conference_file_close(conference, conference->fnode); conference_file_close(conference, conference->fnode);
} }
@ -7027,6 +7056,66 @@ static void conference_send_all_dtmf(conference_member_t *member, conference_obj
switch_mutex_unlock(conference->mutex); switch_mutex_unlock(conference->mutex);
} }
static void canvas_del_fnode_layer(conference_obj_t *conference, conference_file_node_t *fnode)
{
switch_mutex_lock(conference->canvas->mutex);
if (fnode->layer_id > -1) {
mcu_layer_t *xlayer = &conference->canvas->layers[fnode->layer_id];
fnode->layer_id = -1;
xlayer->fnode = NULL;
reset_layer(conference->canvas, xlayer);
}
switch_mutex_unlock(conference->canvas->mutex);
}
static void canvas_set_fnode_layer(conference_obj_t *conference, conference_file_node_t *fnode, int idx)
{
mcu_layer_t *layer = NULL;
switch_mutex_lock(conference->canvas->mutex);
if (idx == -1) {
int i;
if (conference->canvas->layout_floor_id > -1) {
idx = conference->canvas->layout_floor_id;
} else {
for (i = 0; i < conference->canvas->total_layers; i++) {
mcu_layer_t *xlayer = &conference->canvas->layers[i];
if (xlayer->geometry.res_id || xlayer->member_id) {
continue;
}
idx = i;
break;
}
}
}
if (idx < 0) return;
layer = &conference->canvas->layers[idx];
layer->fnode = fnode;
fnode->layer_id = idx;
if (layer->member_id > -1) {
conference_member_t *member;
if ((member = conference_member_get(conference, layer->member_id))) {
detach_video_layer(member);
switch_thread_rwlock_unlock(member->rwlock);
}
}
switch_mutex_unlock(conference->canvas->mutex);
}
/* Play a file in the conference room */ /* Play a file in the conference room */
static switch_status_t conference_play_file(conference_obj_t *conference, char *file, uint32_t leadin, switch_channel_t *channel, uint8_t async) static switch_status_t conference_play_file(conference_obj_t *conference, char *file, uint32_t leadin, switch_channel_t *channel, uint8_t async)
{ {
@ -7112,6 +7201,7 @@ static switch_status_t conference_play_file(conference_obj_t *conference, char *
goto done; goto done;
} }
fnode->layer_id = -1;
fnode->type = NODE_TYPE_FILE; fnode->type = NODE_TYPE_FILE;
fnode->leadin = leadin; fnode->leadin = leadin;
@ -7180,8 +7270,18 @@ static switch_status_t conference_play_file(conference_obj_t *conference, char *
fnode->file = switch_core_strdup(fnode->pool, file); fnode->file = switch_core_strdup(fnode->pool, file);
if (switch_core_file_has_video(&fnode->fh)) { if (switch_core_file_has_video(&fnode->fh)) {
conference->canvas->play_file = 1; int full_screen = 0;
conference->playing_video_file = 1;
if (fnode->fh.params) {
full_screen = switch_true(switch_event_get_header(fnode->fh.params, "full-screen"));
}
if (full_screen) {
conference->canvas->play_file = 1;
conference->playing_video_file = 1;
} else {
canvas_set_fnode_layer(conference, fnode, -1);
}
} }
/* Queue the node */ /* Queue the node */
@ -7268,6 +7368,8 @@ static switch_status_t conference_member_play_file(conference_member_t *member,
status = SWITCH_STATUS_MEMERR; status = SWITCH_STATUS_MEMERR;
goto done; goto done;
} }
fnode->layer_id = -1;
fnode->type = NODE_TYPE_FILE; fnode->type = NODE_TYPE_FILE;
fnode->leadin = leadin; fnode->leadin = leadin;
fnode->mux = mux; fnode->mux = mux;
@ -7363,6 +7465,8 @@ static switch_status_t conference_member_say(conference_member_t *member, char *
return SWITCH_STATUS_MEMERR; return SWITCH_STATUS_MEMERR;
} }
fnode->layer_id = -1;
if (*text == '{') { if (*text == '{') {
char *new_fp; char *new_fp;
@ -7503,6 +7607,7 @@ static switch_status_t conference_say(conference_obj_t *conference, const char *
return SWITCH_STATUS_MEMERR; return SWITCH_STATUS_MEMERR;
} }
fnode->layer_id = -1;
if (*text == '{') { if (*text == '{') {
char *new_fp; char *new_fp;