diff --git a/src/include/switch_core_video.h b/src/include/switch_core_video.h index e7f98a8a7b..198d5f1720 100644 --- a/src/include/switch_core_video.h +++ b/src/include/switch_core_video.h @@ -387,7 +387,11 @@ SWITCH_DECLARE(switch_status_t) switch_I420_copy(const uint8_t* src_y, int src_s SWITCH_DECLARE(switch_status_t) switch_I420_copy2(uint8_t *src_planes[], int src_stride[], uint8_t *dst_planes[], int dst_stride[], int width, int height); -/** @} */ + +/*!\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_END_EXTERN_C #endif diff --git a/src/switch_core_video.c b/src/switch_core_video.c index 7b227884a3..9994af9134 100644 --- a/src/switch_core_video.c +++ b/src/switch_core_video.c @@ -73,6 +73,13 @@ static inline void switch_color_rgb2yuv(switch_rgb_color_t *rgb, switch_yuv_colo static inline void switch_color_yuv2rgb(switch_yuv_color_t *yuv, switch_rgb_color_t *rgb); #endif +/*!\brief compute distance between two colors +* +* \param[in] c1 RGB color1 +* \param[in] c2 RGB color2 +*/ +static inline int switch_color_distance(switch_rgb_color_t *c1, switch_rgb_color_t *c2); + /*!\brief Draw a pixel on an image * * \param[in] img Image descriptor @@ -527,6 +534,27 @@ SWITCH_DECLARE(switch_image_t *) switch_img_copy_rect(switch_image_t *img, uint3 #endif } +SWITCH_DECLARE(void) switch_img_chromakey(switch_image_t *img, switch_rgb_color_t *mask, int threshold) +{ + uint8_t *pixel; + switch_assert(img); + + if (img->fmt != SWITCH_IMG_FMT_ARGB) return; + + pixel = img->planes[SWITCH_PLANE_PACKED]; + + for (; pixel < (img->planes[SWITCH_PLANE_PACKED] + img->d_w * img->d_h * 4); pixel += 4) { + switch_rgb_color_t *color = (switch_rgb_color_t *)pixel; + int distance = switch_color_distance(color, mask); + + if (distance <= threshold) { + *pixel = 0; + } + } + + return; +} + static inline void switch_img_draw_pixel(switch_image_t *img, int x, int y, switch_rgb_color_t *color) { #ifdef SWITCH_HAVE_YUV @@ -767,6 +795,16 @@ static inline void switch_color_rgb2yuv(switch_rgb_color_t *rgb, switch_yuv_colo } #endif +static inline int switch_color_distance(switch_rgb_color_t *c1, switch_rgb_color_t *c2) +{ + int rmean = ( c1->r + c2->r ) / 2; + int r = c1->r - c2->r; + int g = c1->g - c2->g; + int b = c1->b - c2->b; + + return sqrt((((512+rmean)*r*r)>>8) + 4*g*g + (((767-rmean)*b*b)>>8)); +} + #define CLAMP(val) MAX(0, MIN(val, 255)) #ifdef SWITCH_HAVE_YUV @@ -2008,7 +2046,7 @@ static inline uint32_t switch_img_fmt2fourcc(switch_img_fmt_t fmt) case SWITCH_IMG_FMT_YVYU: fourcc = (uint32_t)FOURCC_ANY ; break; case SWITCH_IMG_FMT_BGR24: fourcc = (uint32_t)FOURCC_RAW ; break; case SWITCH_IMG_FMT_RGB32_LE: fourcc = (uint32_t)FOURCC_ANY ; break; - case SWITCH_IMG_FMT_ARGB: fourcc = (uint32_t)FOURCC_ANY ; break; + case SWITCH_IMG_FMT_ARGB: fourcc = (uint32_t)FOURCC_BGRA; break; case SWITCH_IMG_FMT_ARGB_LE: fourcc = (uint32_t)FOURCC_ANY ; break; case SWITCH_IMG_FMT_RGB565_LE: fourcc = (uint32_t)FOURCC_ANY ; break; case SWITCH_IMG_FMT_RGB555_LE: fourcc = (uint32_t)FOURCC_ANY ; break;