提交 b733e8d9 authored 作者: Anthony Minessale's avatar Anthony Minessale

FS-10050: [core] chromakey

上级 05632bb0
...@@ -44,6 +44,16 @@ ...@@ -44,6 +44,16 @@
SWITCH_BEGIN_EXTERN_C SWITCH_BEGIN_EXTERN_C
#define CHROMAKEY_MAX_MASK 25
typedef enum {
SWITCH_SHADE_NONE = 0,
SWITCH_SHADE_RED,
SWITCH_SHADE_GREEN,
SWITCH_SHADE_BLUE,
SWITCH_SHADE_AUTO
} switch_shade_t;
typedef enum { typedef enum {
POS_LEFT_TOP = 0, POS_LEFT_TOP = 0,
POS_LEFT_MID, POS_LEFT_MID,
...@@ -420,8 +430,16 @@ SWITCH_DECLARE(switch_status_t) switch_I420_copy2(uint8_t *src_planes[], int src ...@@ -420,8 +430,16 @@ SWITCH_DECLARE(switch_status_t) switch_I420_copy2(uint8_t *src_planes[], int src
/*!\brief chromakey an img, img must be RGBA and return modified img */ /*!\brief chromakey an img, img must be RGBA and return modified img */
SWITCH_DECLARE(void) switch_img_chromakey(switch_image_t *img, switch_rgb_color_t *mask, int threshold); SWITCH_DECLARE(void) switch_img_chromakey(switch_image_t *img, switch_rgb_color_t *mask, int threshold);
SWITCH_DECLARE(void) switch_img_chromakey_multi(switch_image_t *img, switch_image_t *cache_img, switch_rgb_color_t *mask, int *thresholds, int count); SWITCH_DECLARE(switch_status_t) switch_chromakey_clear_colors(switch_chromakey_t *ck);
SWITCH_DECLARE(switch_status_t) switch_chromakey_autocolor(switch_chromakey_t *ck, switch_shade_t autocolor, uint32_t threshold);
SWITCH_DECLARE(switch_status_t) switch_chromakey_add_color(switch_chromakey_t *ck, switch_rgb_color_t *color, uint32_t threshold);
SWITCH_DECLARE(switch_status_t) switch_chromakey_destroy(switch_chromakey_t **ckP);
SWITCH_DECLARE(switch_status_t) switch_chromakey_create(switch_chromakey_t **ckP);
SWITCH_DECLARE(void) switch_chromakey_set_default_threshold(switch_chromakey_t *ck, uint32_t threshold);
SWITCH_DECLARE(void) switch_chromakey_process(switch_chromakey_t *ck, switch_image_t *img);
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_END_EXTERN_C SWITCH_END_EXTERN_C
#endif #endif
......
...@@ -2666,6 +2666,9 @@ struct switch_rtp_text_factory_s; ...@@ -2666,6 +2666,9 @@ struct switch_rtp_text_factory_s;
typedef struct switch_rtp_text_factory_s switch_rtp_text_factory_t; typedef struct switch_rtp_text_factory_s switch_rtp_text_factory_t;
typedef struct switch_agc_s switch_agc_t; typedef struct switch_agc_s switch_agc_t;
struct switch_chromakey_s;
typedef struct switch_chromakey_s switch_chromakey_t;
SWITCH_END_EXTERN_C SWITCH_END_EXTERN_C
#endif #endif
/* For Emacs: /* For Emacs:
......
...@@ -38,13 +38,11 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_video_filter_load); ...@@ -38,13 +38,11 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_video_filter_load);
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_video_filter_shutdown); SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_video_filter_shutdown);
SWITCH_MODULE_DEFINITION(mod_video_filter, mod_video_filter_load, mod_video_filter_shutdown, NULL); SWITCH_MODULE_DEFINITION(mod_video_filter, mod_video_filter_load, mod_video_filter_shutdown, NULL);
#define MAX_MASK 25
typedef struct chromakey_context_s { typedef struct chromakey_context_s {
int threshold; int threshold;
switch_image_t *bgimg; switch_image_t *bgimg;
switch_image_t *bgimg_scaled; switch_image_t *bgimg_scaled;
switch_image_t *last_img;
switch_image_t *imgfg; switch_image_t *imgfg;
switch_image_t *imgbg; switch_image_t *imgbg;
void *data; void *data;
...@@ -53,13 +51,11 @@ typedef struct chromakey_context_s { ...@@ -53,13 +51,11 @@ typedef struct chromakey_context_s {
switch_size_t patch_datalen; switch_size_t patch_datalen;
switch_file_handle_t vfh; switch_file_handle_t vfh;
switch_rgb_color_t bgcolor; switch_rgb_color_t bgcolor;
switch_rgb_color_t mask[MAX_MASK];
int thresholds[MAX_MASK];
int mask_len;
switch_core_session_t *session; switch_core_session_t *session;
switch_mutex_t *command_mutex; switch_mutex_t *command_mutex;
int patch; int patch;
int mod; int mod;
switch_chromakey_t *ck;
} chromakey_context_t; } chromakey_context_t;
static void init_context(chromakey_context_t *context) static void init_context(chromakey_context_t *context)
...@@ -67,6 +63,7 @@ static void init_context(chromakey_context_t *context) ...@@ -67,6 +63,7 @@ static void init_context(chromakey_context_t *context)
switch_color_set_rgb(&context->bgcolor, "#000000"); switch_color_set_rgb(&context->bgcolor, "#000000");
context->threshold = 300; context->threshold = 300;
switch_mutex_init(&context->command_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(context->session)); switch_mutex_init(&context->command_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(context->session));
switch_chromakey_create(&context->ck);
} }
static void uninit_context(chromakey_context_t *context) static void uninit_context(chromakey_context_t *context)
...@@ -80,9 +77,9 @@ static void uninit_context(chromakey_context_t *context) ...@@ -80,9 +77,9 @@ static void uninit_context(chromakey_context_t *context)
memset(&context->vfh, 0, sizeof(context->vfh)); memset(&context->vfh, 0, sizeof(context->vfh));
} }
switch_img_free(&context->last_img);
switch_safe_free(context->data); switch_safe_free(context->data);
switch_safe_free(context->patch_data); switch_safe_free(context->patch_data);
switch_chromakey_destroy(&context->ck);
} }
static void parse_params(chromakey_context_t *context, int start, int argc, char **argv, const char **function, switch_media_bug_flag_t *flags) static void parse_params(chromakey_context_t *context, int start, int argc, char **argv, const char **function, switch_media_bug_flag_t *flags)
...@@ -96,29 +93,30 @@ static void parse_params(chromakey_context_t *context, int start, int argc, char ...@@ -96,29 +93,30 @@ static void parse_params(chromakey_context_t *context, int start, int argc, char
if (n > 0 && argv[i]) { // color if (n > 0 && argv[i]) { // color
int j = 0; int j = 0;
char *list[MAX_MASK]; char *list[CHROMAKEY_MAX_MASK];
int list_argc; int list_argc;
list_argc = switch_split(argv[i], ':', list); list_argc = switch_split(argv[i], ':', list);
context->mask_len = 0; switch_chromakey_clear_colors(context->ck);
memset(context->thresholds, 0, sizeof(context->thresholds[0]) * MAX_MASK);
for (j = 0; j < list_argc; j++) { for (j = 0; j < list_argc; j++) {
char *p; char *p;
int thresh = 0; int thresh = 0;
switch_rgb_color_t color = { 0 };
if ((p = strchr(list[j], '+'))) { if ((p = strchr(list[j], '+'))) {
*p++ = '\0'; *p++ = '\0';
thresh = atoi(p); thresh = atoi(p);
if (thresh < 0) thresh = 0; if (thresh < 0) thresh = 0;
} }
switch_color_set_rgb(&context->mask[j], list[j]); if (*list[j] == '#') {
if (thresh) { switch_color_set_rgb(&color, list[j]);
context->thresholds[j] = thresh*thresh; switch_chromakey_add_color(context->ck, &color, thresh);
} else {
switch_chromakey_autocolor(context->ck, switch_chromakey_str2shade(context->ck, list[j]), thresh);
} }
context->mask_len++;
} }
} }
...@@ -126,14 +124,9 @@ static void parse_params(chromakey_context_t *context, int start, int argc, char ...@@ -126,14 +124,9 @@ static void parse_params(chromakey_context_t *context, int start, int argc, char
if (n > 1 && argv[i]) { // thresh if (n > 1 && argv[i]) { // thresh
int thresh = atoi(argv[i]); int thresh = atoi(argv[i]);
int j;
if (thresh > 0) { if (thresh > 0) {
context->threshold = thresh * thresh; switch_chromakey_set_default_threshold(context->ck, thresh);
for (j = 0; j < context->mask_len; j++) {
if (!context->thresholds[j]) context->thresholds[j] = context->threshold;
}
} }
} }
...@@ -237,7 +230,12 @@ static switch_status_t video_thread_callback(switch_core_session_t *session, swi ...@@ -237,7 +230,12 @@ static switch_status_t video_thread_callback(switch_core_session_t *session, swi
context->mod = 0; context->mod = 0;
if (switch_mutex_trylock(context->command_mutex) != SWITCH_STATUS_SUCCESS) { if (switch_mutex_trylock(context->command_mutex) != SWITCH_STATUS_SUCCESS) {
switch_img_patch(frame->img, context->last_img, 0, 0); switch_image_t *last_img = switch_chromakey_cache_image(context->ck);
if (last_img) {
switch_img_patch(frame->img, last_img, 0, 0);
}
return SWITCH_STATUS_SUCCESS; return SWITCH_STATUS_SUCCESS;
} }
...@@ -256,10 +254,7 @@ static switch_status_t video_thread_callback(switch_core_session_t *session, swi ...@@ -256,10 +254,7 @@ static switch_status_t video_thread_callback(switch_core_session_t *session, swi
img = switch_img_wrap(NULL, SWITCH_IMG_FMT_ARGB, frame->img->d_w, frame->img->d_h, 1, context->data); img = switch_img_wrap(NULL, SWITCH_IMG_FMT_ARGB, frame->img->d_w, frame->img->d_h, 1, context->data);
switch_assert(img); switch_assert(img);
switch_img_chromakey_multi(img, context->last_img, context->mask, context->thresholds, context->mask_len); switch_chromakey_process(context->ck, img);
switch_img_free(&context->last_img);
switch_img_copy(img, &context->last_img);
if (context->bgimg) { if (context->bgimg) {
switch_image_t *tmp = NULL; switch_image_t *tmp = NULL;
......
差异被折叠。
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论