diff --git a/src/mod/applications/mod_conference/conference_video.c b/src/mod/applications/mod_conference/conference_video.c index c5ba30369f..2ea8032968 100644 --- a/src/mod/applications/mod_conference/conference_video.c +++ b/src/mod/applications/mod_conference/conference_video.c @@ -110,7 +110,7 @@ void conference_video_parse_layouts(conference_obj_t *conference, int WIDTH, int if ((x_layouts = switch_xml_child(x_layout_settings, "layouts"))) { for (x_layout = switch_xml_child(x_layouts, "layout"); x_layout; x_layout = x_layout->next) { video_layout_t *vlayout; - const char *val = NULL, *name = NULL, *bgimg = NULL; + const char *val = NULL, *name = NULL, *bgimg = NULL, *fgimg = NULL; switch_bool_t auto_3d = SWITCH_FALSE; int border = 0; @@ -126,6 +126,7 @@ void conference_video_parse_layouts(conference_obj_t *conference, int WIDTH, int auto_3d = switch_true(switch_xml_attr(x_layout, "auto-3d-position")); bgimg = switch_xml_attr(x_layout, "bgimg"); + fgimg = switch_xml_attr(x_layout, "fgimg"); if ((val = switch_xml_attr(x_layout, "border"))) { border = atoi(val); @@ -140,6 +141,10 @@ void conference_video_parse_layouts(conference_obj_t *conference, int WIDTH, int vlayout->bgimg = switch_core_strdup(conference->pool, bgimg); } + if (fgimg) { + vlayout->fgimg = switch_core_strdup(conference->pool, fgimg); + } + for (x_image = switch_xml_child(x_layout, "image"); x_image; x_image = x_image->next) { const char *res_id = NULL, *audio_position = NULL; int x = -1, y = -1, scale = -1, hscale = -1, floor = 0, flooronly = 0, fileonly = 0, overlap = 0, zoom = 0; @@ -1174,6 +1179,12 @@ void conference_video_init_canvas_layers(conference_obj_t *conference, mcu_canva switch_img_free(&canvas->bgimg); } + if (vlayout->fgimg) { + conference_video_set_canvas_fgimg(canvas, vlayout->fgimg); + } else if (canvas->fgimg) { + switch_img_free(&canvas->fgimg); + } + if (conference->video_canvas_bgimg && !vlayout->bgimg) { conference_video_set_canvas_bgimg(canvas, conference->video_canvas_bgimg); } @@ -1212,6 +1223,33 @@ switch_status_t conference_video_set_canvas_bgimg(mcu_canvas_t *canvas, const ch } +switch_status_t conference_video_set_canvas_fgimg(mcu_canvas_t *canvas, const char *img_path) +{ + + int x = 0, y = 0, scaled = 0; + + if (img_path) { + switch_img_free(&canvas->fgimg); + canvas->fgimg = switch_img_read_png(img_path, SWITCH_IMG_FMT_ARGB); + } else { + scaled = 1; + } + + if (!canvas->fgimg) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot open image for fgimg\n"); + return SWITCH_STATUS_FALSE; + } + + if (!scaled) { + switch_img_fit(&canvas->fgimg, canvas->img->d_w, canvas->img->d_h, SWITCH_FIT_SIZE); + } + switch_img_find_position(POS_CENTER_MID, canvas->img->d_w, canvas->img->d_h, canvas->fgimg->d_w, canvas->fgimg->d_h, &x, &y); + switch_img_patch(canvas->img, canvas->fgimg, x, y); + + return SWITCH_STATUS_SUCCESS; +} + + switch_status_t conference_video_attach_canvas(conference_obj_t *conference, mcu_canvas_t *canvas, int super) { if (conference->canvas_count >= MAX_CANVASES + 1) { @@ -1295,6 +1333,7 @@ void conference_video_destroy_canvas(mcu_canvas_t **canvasP) { switch_img_free(&canvas->img); switch_img_free(&canvas->bgimg); + switch_img_free(&canvas->fgimg); conference_video_flush_queue(canvas->video_queue, 0); for (i = 0; i < MCU_MAX_LAYERS; i++) { @@ -3242,6 +3281,10 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr conference_video_check_recording(conference, canvas, &write_frame); } + if (canvas->fgimg) { + conference_video_set_canvas_fgimg(canvas, NULL); + } + if (conference->canvas_count > 1) { switch_image_t *img_copy = NULL; @@ -3296,6 +3339,11 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr switch_core_media_gen_key_frame(imember->session); } + + if (canvas->fgimg) { + conference_video_set_canvas_fgimg(canvas, NULL); + } + switch_set_flag(&write_frame, SFF_RAW_RTP); write_frame.img = write_img; write_frame.packet = packet; diff --git a/src/mod/applications/mod_conference/mod_conference.h b/src/mod/applications/mod_conference/mod_conference.h index aa20997488..d7335e5228 100644 --- a/src/mod/applications/mod_conference/mod_conference.h +++ b/src/mod/applications/mod_conference/mod_conference.h @@ -469,6 +469,7 @@ typedef struct video_layout_s { char *name; char *audio_position; char *bgimg; + char *fgimg; mcu_layer_geometry_t images[MCU_MAX_LAYERS]; int layers; } video_layout_t; @@ -511,6 +512,7 @@ typedef struct mcu_canvas_s { int32_t video_write_bandwidth; int recording; switch_image_t *bgimg; + switch_image_t *fgimg; switch_thread_rwlock_t *video_rwlock; } mcu_canvas_t; @@ -986,6 +988,7 @@ void conference_video_find_floor(conference_member_t *member, switch_bool_t ente void conference_video_destroy_canvas(mcu_canvas_t **canvasP); void conference_video_fnode_check(conference_file_node_t *fnode, int canvas_id); switch_status_t conference_video_set_canvas_bgimg(mcu_canvas_t *canvas, const char *img_path); +switch_status_t conference_video_set_canvas_fgimg(mcu_canvas_t *canvas, const char *img_path); switch_status_t conference_al_parse_position(al_handle_t *al, const char *data); switch_status_t conference_video_thread_callback(switch_core_session_t *session, switch_frame_t *frame, void *user_data); switch_status_t conference_text_thread_callback(switch_core_session_t *session, switch_frame_t *frame, void *user_data);