}
-void conference_video_parse_filter_string(conference_file_filter_t *filters, const char *filter_str)
-{
- *filters = 0;
-
- if (!filter_str) return;
-
- if (switch_stristr("fg-gray", filter_str)) {
- *filters |= FILTER_GRAY_FG;
- }
-
- if (switch_stristr("bg-gray", filter_str)) {
- *filters |= FILTER_GRAY_BG;
- }
-
- if (switch_stristr("fg-sepia", filter_str)) {
- *filters |= FILTER_SEPIA_FG;
- }
-
- if (switch_stristr("bg-sepia", filter_str)) {
- *filters |= FILTER_SEPIA_BG;
- }
-}
-
void conference_video_scale_and_patch(mcu_layer_t *layer, switch_image_t *ximg, switch_bool_t freeze)
{
switch_image_t *IMG, *img;
if (layer->overlay_img) {
switch_img_fit(&layer->overlay_img, layer->img->d_w, layer->img->d_h, SWITCH_FIT_SCALE);
- if (layer->overlay_filters & FILTER_GRAY_FG) {
+ if (layer->overlay_filters & SCV_FILTER_GRAY_FG) {
switch_img_gray(layer->img, 0, 0, layer->img->d_w, layer->img->d_h);
}
- if (layer->overlay_filters & FILTER_SEPIA_FG) {
+ if (layer->overlay_filters & SCV_FILTER_SEPIA_FG) {
switch_img_sepia(layer->img, 0, 0, layer->img->d_w, layer->img->d_h);
}
- if (layer->overlay_filters & FILTER_GRAY_BG) {
+ if (layer->overlay_filters & SCV_FILTER_GRAY_BG) {
switch_img_gray(layer->overlay_img, 0, 0, layer->overlay_img->d_w, layer->overlay_img->d_h);
}
- if (layer->overlay_filters & FILTER_SEPIA_BG) {
+ if (layer->overlay_filters & SCV_FILTER_SEPIA_BG) {
switch_img_sepia(layer->overlay_img, 0, 0, layer->overlay_img->d_w, layer->overlay_img->d_h);
}
}
if (img) {
- if (member->video_filters & FILTER_GRAY_FG) {
+ if (member->video_filters & SCV_FILTER_GRAY_FG) {
switch_img_gray(img, 0, 0, img->d_w, img->d_h);
}
- if (member->video_filters & FILTER_SEPIA_FG) {
+ if (member->video_filters & SCV_FILTER_SEPIA_FG) {
switch_img_sepia(img, 0, 0, img->d_w, img->d_h);
}
}
switch_image_t *overlay_img = NULL;
switch_img_copy(canvas->img, &overlay_img);
- if (conference->fnode->filters & FILTER_GRAY_BG) {
+ if (conference->fnode->filters & SCV_FILTER_GRAY_BG) {
switch_img_gray(overlay_img, 0, 0, overlay_img->d_w, overlay_img->d_h);
}
- if (conference->fnode->filters & FILTER_SEPIA_BG) {
+ if (conference->fnode->filters & SCV_FILTER_SEPIA_BG) {
switch_img_sepia(overlay_img, 0, 0, overlay_img->d_w, overlay_img->d_h);
}
- if (conference->fnode->filters & FILTER_GRAY_FG) {
+ if (conference->fnode->filters & SCV_FILTER_GRAY_FG) {
switch_img_gray(file_img, 0, 0, file_img->d_w, file_img->d_h);
}
- if (conference->fnode->filters & FILTER_SEPIA_FG) {
+ if (conference->fnode->filters & SCV_FILTER_SEPIA_FG) {
switch_img_sepia(file_img, 0, 0, file_img->d_w, file_img->d_h);
}
#endif
struct conference_obj;
-typedef enum {
- FILTER_GRAY_FG = (1 << 0),
- FILTER_GRAY_BG = (1 << 1),
- FILTER_SEPIA_FG = (1 << 2),
- FILTER_SEPIA_BG = (1 << 3)
-} conference_file_filter_t;
-
typedef struct conference_file_node {
switch_file_handle_t fh;
switch_speech_handle_t *sh;
int loops;
int new_fnode;
int layer_lock;
- conference_file_filter_t filters;
+ switch_core_video_filter_t filters;
} conference_file_node_t;
typedef enum {
switch_frame_geometry_t manual_geometry;
mcu_layer_cam_opts_t cam_opts;
switch_mutex_t *overlay_mutex;
- conference_file_filter_t overlay_filters;
+ switch_core_video_filter_t overlay_filters;
} mcu_layer_t;
typedef struct video_layout_s {
uint32_t text_framesize;
mcu_layer_cam_opts_t cam_opts;
- conference_file_filter_t video_filters;
+ switch_core_video_filter_t video_filters;
};
typedef enum {
void conference_video_check_flush(conference_member_t *member, switch_bool_t force);
void conference_video_set_canvas_letterbox_bgcolor(mcu_canvas_t *canvas, char *color);
void conference_video_set_canvas_bgcolor(mcu_canvas_t *canvas, char *color);
-void conference_video_parse_filter_string(conference_file_filter_t *filters, const char *filter_str);
void conference_video_scale_and_patch(mcu_layer_t *layer, switch_image_t *ximg, switch_bool_t freeze);
void conference_video_reset_layer(mcu_layer_t *layer);
void conference_video_reset_layer_cam(mcu_layer_t *layer);
typedef struct chromakey_context_s {
int threshold;
switch_image_t *bgimg;
+ switch_image_t *bgimg_orig;
switch_image_t *bgimg_scaled;
+ switch_image_t *fgimg_scaled;
switch_image_t *imgfg;
switch_image_t *imgbg;
void *data;
switch_size_t datalen;
switch_size_t patch_datalen;
switch_file_handle_t vfh;
+ switch_file_handle_t fg_vfh;
switch_rgb_color_t bgcolor;
switch_core_session_t *session;
switch_mutex_t *command_mutex;
int patch;
int mod;
switch_chromakey_t *ck;
+ switch_core_video_filter_t video_filters;
} chromakey_context_t;
static void init_context(chromakey_context_t *context)
static void uninit_context(chromakey_context_t *context)
{
switch_img_free(&context->bgimg);
+ switch_img_free(&context->bgimg_orig);
switch_img_free(&context->bgimg_scaled);
+ switch_img_free(&context->fgimg_scaled);
switch_img_free(&context->imgbg);
switch_img_free(&context->imgfg);
+
if (switch_test_flag(&context->vfh, SWITCH_FILE_OPEN)) {
switch_core_file_close(&context->vfh);
memset(&context->vfh, 0, sizeof(context->vfh));
}
+ if (switch_test_flag(&context->fg_vfh, SWITCH_FILE_OPEN)) {
+ switch_core_file_close(&context->fg_vfh);
+ memset(&context->vfh, 0, sizeof(context->fg_vfh));
+ }
+
switch_safe_free(context->data);
switch_safe_free(context->patch_data);
switch_chromakey_destroy(&context->ck);
memset(&context->vfh, 0, sizeof(context->vfh));
}
+ if (context->bgimg_orig) {
+ switch_img_free(&context->bgimg_orig);
+ }
+
if (context->bgimg) {
switch_img_free(&context->bgimg);
}
switch_img_free(&context->bgimg_scaled);
}
+ if (context->fgimg_scaled) {
+ switch_img_free(&context->fgimg_scaled);
+ }
+
if (argv[i][0] == '#') { // bgcolor
switch_color_set_rgb(&context->bgcolor, argv[i]);
} else if (switch_stristr(".png", argv[i])) {
- if (!(context->bgimg = switch_img_read_png(argv[i], SWITCH_IMG_FMT_ARGB))) {
+ if (!(context->bgimg_orig = switch_img_read_png(argv[i], SWITCH_IMG_FMT_ARGB))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error opening png\n");
}
} else {
while (n > 3 && argv[i]) {
+
+ if (!strncasecmp(argv[i], "filter:", 7)) {
+ char *filter = argv[i] + 7;
+ switch_core_video_parse_filter_string(&context->video_filters, filter);
+
+ if (context->bgimg_orig && context->video_filters) {
+ switch_img_free(&context->bgimg);
+ switch_img_copy(context->bgimg_orig, &context->bgimg);
+
+ if (context->video_filters & SCV_FILTER_SEPIA_BG) {
+ switch_img_sepia(context->bgimg, 0, 0, context->bgimg->d_w, context->bgimg->d_h);
+ }
+
+ if (context->video_filters & SCV_FILTER_GRAY_BG) {
+ switch_img_sepia(context->bgimg, 0, 0, context->bgimg->d_w, context->bgimg->d_h);
+ }
+ }
+ }
+
+
+ if (!strncasecmp(argv[i], "fgvid:", 6)) {
+ char *file = argv[i] + 6;
+
+ if (switch_test_flag(&context->fg_vfh, SWITCH_FILE_OPEN)) {
+ switch_core_file_close(&context->fg_vfh);
+ memset(&context->fg_vfh, 0, sizeof(context->fg_vfh));
+ }
+
+ if (!zstr(file)) {
+ if (switch_core_file_open(&context->fg_vfh, file, 1, 8000,
+ SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT | SWITCH_FILE_FLAG_VIDEO,
+ switch_core_session_get_pool(context->session)) != SWITCH_STATUS_SUCCESS) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error opening video file\n");
+ } else {
+ switch_vid_params_t vp = { 0 };
+
+ switch_core_media_get_vid_params(context->session, &vp);
+ context->fg_vfh.mm.scale_w = vp.width;
+ context->fg_vfh.mm.scale_h = vp.height;
+ context->fg_vfh.mm.fps = vp.fps;
+ }
+ }
+ }
+
if (!strncasecmp(argv[i], "fg:", 3)) {
switch_img_free(&context->imgfg);
if (!zstr(argv[i]+3)) {
i++;
}
+ if (context->bgimg_orig && !context->bgimg) {
+ switch_img_copy(context->bgimg_orig, &context->bgimg);
+ }
+
switch_core_session_request_video_refresh(context->session);
context->mod++;
switch_assert(img);
switch_chromakey_process(context->ck, img);
+ if (context->video_filters & SCV_FILTER_GRAY_FG) {
+ switch_img_gray(img, 0, 0, img->d_w, img->d_h);
+ }
+
+ if (context->video_filters & SCV_FILTER_SEPIA_FG) {
+ switch_img_sepia(img, 0, 0, img->d_w, img->d_h);
+ }
+
if (context->bgimg) {
switch_image_t *tmp = NULL;
if (file_frame.img) {
switch_img_free(&context->bgimg_scaled);
use_img = context->bgimg_scaled = file_frame.img;
+
+ if (context->video_filters & SCV_FILTER_SEPIA_BG) {
+ switch_img_sepia(use_img, 0, 0, use_img->d_w, use_img->d_h);
+ }
+
+ if (context->video_filters & SCV_FILTER_GRAY_BG) {
+ switch_img_sepia(use_img, 0, 0, use_img->d_w, use_img->d_h);
+ }
+
} else {
use_img = context->bgimg_scaled;
}
switch_img_patch(img, context->imgfg, x, y);
}
+ if (switch_test_flag(&context->fg_vfh, SWITCH_FILE_OPEN)) {
+ switch_frame_t file_frame = { 0 };
+ switch_status_t status;
+ switch_image_t *use_img = NULL;
+
+ context->fg_vfh.mm.scale_w = frame->img->d_w;
+ context->fg_vfh.mm.scale_h = frame->img->d_h;
+
+ status = switch_core_file_read_video(&context->fg_vfh, &file_frame, SVR_FLUSH);
+ switch_core_file_command(&context->fg_vfh, SCFC_FLUSH_AUDIO);
+
+
+ if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_BREAK) {
+ int close = 1;
+
+ if (context->fg_vfh.params) {
+ const char *loopstr = switch_event_get_header(context->fg_vfh.params, "loop");
+ if (switch_true(loopstr)) {
+ uint32_t pos = 0;
+ switch_core_file_seek(&context->fg_vfh, &pos, 0, SEEK_SET);
+ close = 0;
+ }
+ }
+
+ if (close) {
+ switch_core_file_close(&context->fg_vfh);
+ }
+ }
+
+ if (file_frame.img) {
+ switch_img_free(&context->fgimg_scaled);
+ use_img = context->fgimg_scaled = file_frame.img;
+ } else {
+ use_img = context->fgimg_scaled;
+ }
+
+ if (use_img) {
+ switch_img_patch(img, use_img, 0, 0);
+ }
+
+ }
+
+
switch_img_from_raw(frame->img, patch_data, SWITCH_IMG_FMT_ARGB, frame->img->d_w, frame->img->d_h);
switch_img_free(&img);