FS-10151: [mod_video_filter] Add filters and fg video to mod_video_filter #resolve

This commit is contained in:
Anthony Minessale 2017-03-17 15:16:13 -05:00
parent cd5182c27c
commit e61f6e227c
7 changed files with 180 additions and 47 deletions

View File

@ -46,6 +46,14 @@ SWITCH_BEGIN_EXTERN_C
#define CHROMAKEY_MAX_MASK 25
typedef enum {
SCV_FILTER_GRAY_FG = (1 << 0),
SCV_FILTER_GRAY_BG = (1 << 1),
SCV_FILTER_SEPIA_FG = (1 << 2),
SCV_FILTER_SEPIA_BG = (1 << 3)
} switch_core_video_filter_t;
typedef enum {
SWITCH_SHADE_NONE = 0,
SWITCH_SHADE_RED,
@ -476,6 +484,8 @@ SWITCH_DECLARE(void) switch_chromakey_process(switch_chromakey_t *ck, switch_ima
SWITCH_DECLARE(switch_image_t *) switch_chromakey_cache_image(switch_chromakey_t *ck);
SWITCH_DECLARE(switch_shade_t) switch_chromakey_str2shade(switch_chromakey_t *ck, const char *shade_name);
SWITCH_DECLARE(void) switch_core_video_parse_filter_string(switch_core_video_filter_t *filters, const char *filter_str);
SWITCH_END_EXTERN_C
#endif
/* For Emacs:

View File

@ -551,7 +551,7 @@ switch_status_t conference_api_sub_video_filter(conference_member_t *member, swi
{
char *filter_str = (char *) data;
conference_video_parse_filter_string(&member->video_filters, filter_str);
switch_core_video_parse_filter_string(&member->video_filters, filter_str);
stream->write_function(stream, "+OK\n");

View File

@ -294,7 +294,7 @@ switch_status_t conference_file_play(conference_obj_t *conference, char *file, u
if (!zstr(file_filters)) {
conference_video_parse_filter_string(&fnode->filters, file_filters);
switch_core_video_parse_filter_string(&fnode->filters, file_filters);
}
if (loopsstr) {

View File

@ -501,29 +501,6 @@ static void set_bounds(int *x, int *y, int img_w, int img_h, int crop_w, int cro
}
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;
@ -893,19 +870,19 @@ void conference_video_scale_and_patch(mcu_layer_t *layer, switch_image_t *ximg,
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);
}
@ -2619,11 +2596,11 @@ void conference_video_pop_next_image(conference_member_t *member, switch_image_t
}
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);
}
}
@ -3736,19 +3713,19 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr
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);
}

View File

@ -369,13 +369,6 @@ typedef struct al_handle_s {
#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;
@ -397,7 +390,7 @@ typedef struct conference_file_node {
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 {
@ -504,7 +497,7 @@ typedef struct mcu_layer_s {
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 {
@ -882,7 +875,7 @@ struct conference_member {
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 {
@ -1052,7 +1045,6 @@ void conference_video_check_used_layers(mcu_canvas_t *canvas);
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);

View File

@ -42,7 +42,9 @@ SWITCH_MODULE_DEFINITION(mod_video_filter, mod_video_filter_load, mod_video_filt
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;
@ -50,12 +52,14 @@ typedef struct chromakey_context_s {
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)
@ -69,14 +73,22 @@ 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);
@ -139,6 +151,10 @@ static void parse_params(chromakey_context_t *context, int start, int argc, char
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);
}
@ -147,11 +163,15 @@ static void parse_params(chromakey_context_t *context, int start, int argc, char
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 {
@ -174,6 +194,50 @@ static void parse_params(chromakey_context_t *context, int start, int argc, char
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)) {
@ -197,6 +261,10 @@ static void parse_params(chromakey_context_t *context, int start, int argc, char
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++;
@ -257,6 +325,14 @@ static switch_status_t video_thread_callback(switch_core_session_t *session, swi
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;
@ -304,6 +380,15 @@ static switch_status_t video_thread_callback(switch_core_session_t *session, swi
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;
}
@ -371,6 +456,49 @@ static switch_status_t video_thread_callback(switch_core_session_t *session, swi
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);

View File

@ -3301,6 +3301,32 @@ SWITCH_DECLARE(switch_status_t) switch_ARGBToARGB(const uint8_t* src_frame, int
}
SWITCH_DECLARE(void) switch_core_video_parse_filter_string(switch_core_video_filter_t *filters, const char *filter_str)
{
*filters = 0;
if (!filter_str) return;
if (switch_stristr("fg-gray", filter_str)) {
*filters |= SCV_FILTER_GRAY_FG;
}
if (switch_stristr("bg-gray", filter_str)) {
*filters |= SCV_FILTER_GRAY_BG;
}
if (switch_stristr("fg-sepia", filter_str)) {
*filters |= SCV_FILTER_SEPIA_FG;
}
if (switch_stristr("bg-sepia", filter_str)) {
*filters |= SCV_FILTER_SEPIA_BG;
}
}
/* For Emacs:
* Local Variables:
* mode:c