]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
FS-10050 add chromakey
authorSeven Du <dujinfang@gmail.com>
Thu, 16 Feb 2017 17:06:56 +0000 (01:06 +0800)
committerSeven Du <dujinfang@gmail.com>
Thu, 16 Feb 2017 17:19:57 +0000 (01:19 +0800)
src/include/switch_core_video.h
src/switch_core_video.c

index e7f98a8a7bb60f8504edf3a2dc08f45dabb148e4..198d5f17207b5e0bd2953bf8528b6c623a278acf 100644 (file)
@@ -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
index 7b227884a382e05890c5f94211d66aad105fb0dd..9994af91341fe9d5bcc9fe4dee8dc45215b4a016 100644 (file)
@@ -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;