From 0294e1e48ae933839a4af9f04752fdfcaf5ec896 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Sebastian=20Dr=C3=B6ge?= Date: Wed, 21 Apr 2010 17:41:43 +0200 Subject: [PATCH] alpha: Refactor processing and add support for other planar YUV formats This reduces the generated code size by a factor of 2.5. --- gst/alpha/gstalpha.c | 2264 ++++++++++++++++++++++---------------------------- 1 file changed, 995 insertions(+), 1269 deletions(-) diff --git a/gst/alpha/gstalpha.c b/gst/alpha/gstalpha.c index a288acd..956c215 100644 --- a/gst/alpha/gstalpha.c +++ b/gst/alpha/gstalpha.c @@ -137,10 +137,12 @@ static GstStaticPadTemplate gst_alpha_sink_template = GST_PAD_ALWAYS, GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("AYUV") ";" GST_VIDEO_CAPS_ARGB ";" GST_VIDEO_CAPS_BGRA ";" GST_VIDEO_CAPS_ABGR - ";" GST_VIDEO_CAPS_RGBA + ";" GST_VIDEO_CAPS_RGBA ";" GST_VIDEO_CAPS_YUV ("Y444") ";" GST_VIDEO_CAPS_xRGB ";" GST_VIDEO_CAPS_BGRx ";" GST_VIDEO_CAPS_xBGR ";" GST_VIDEO_CAPS_RGBx ";" GST_VIDEO_CAPS_RGB ";" GST_VIDEO_CAPS_BGR - ";" ";" GST_VIDEO_CAPS_YUV ("I420") ";" GST_VIDEO_CAPS_YUV ("YV12") + ";" GST_VIDEO_CAPS_YUV ("Y42B") ";" + ";" GST_VIDEO_CAPS_YUV ("I420") ";" GST_VIDEO_CAPS_YUV ("YV12") + ";" GST_VIDEO_CAPS_YUV ("Y41B") ) ); @@ -468,7 +470,7 @@ gst_alpha_set_caps (GstBaseTransform * btrans, /* based on http://www.cs.utah.edu/~michael/chroma/ */ static inline gint -chroma_keying_yuv (gint a, gint * y, guint ny, gint * u, +chroma_keying_yuv (gint a, gint * y, gint * u, gint * v, gint cr, gint cb, gint smin, gint smax, guint8 accept_angle_tg, guint8 accept_angle_ctg, guint8 one_over_kc, guint8 kfgy_scale, gint8 kg, guint noise_level2) @@ -478,11 +480,9 @@ chroma_keying_yuv (gint a, gint * y, guint ny, gint * u, gint x, z; gint b_alpha; - for (tmp = 0; tmp < ny; tmp++) { - /* too dark or too bright, keep alpha */ - if (y[tmp] < smin || y[tmp] > smax) - return a; - } + /* too dark or too bright, keep alpha */ + if (*y < smin || *y > smax) + return a; /* Convert foreground to XZ coords where X direction is defined by the key color */ @@ -522,8 +522,7 @@ chroma_keying_yuv (gint a, gint * y, guint ny, gint * u, tmp = (tmp1 * kfgy_scale) >> 4; tmp1 = MIN (tmp, 255); - for (tmp = 0; tmp < ny; tmp++) - y[tmp] = (y[tmp] < tmp1) ? 0 : y[tmp] - tmp1; + *y = (*y < tmp1) ? 0 : *y - tmp1; /* Convert suppressed foreground back to CbCr */ tmp = (x1 * cb - y1 * cr) >> 7; @@ -547,290 +546,363 @@ chroma_keying_yuv (gint a, gint * y, guint ny, gint * u, #define APPLY_MATRIX(m,o,v1,v2,v3) ((m[o*4] * v1 + m[o*4+1] * v2 + m[o*4+2] * v3 + m[o*4+3]) >> 8) -#define CREATE_ARGB_AYUV_FUNCTIONS(name, A, R, G, B) \ -static void \ -gst_alpha_set_##name##_ayuv (const guint8 * src, guint8 * dest, gint width, \ - gint height, GstAlpha * alpha) \ -{ \ - gint s_alpha = CLAMP ((gint) (alpha->alpha * 256), 0, 256); \ - gint i, j; \ - gint matrix[12]; \ - gint y, u, v; \ - \ - memcpy (matrix, \ - alpha->out_sdtv ? cog_rgb_to_ycbcr_matrix_8bit_sdtv : \ - cog_rgb_to_ycbcr_matrix_8bit_hdtv, 12 * sizeof (gint)); \ - \ - for (i = 0; i < height; i++) { \ - for (j = 0; j < width; j++) { \ - dest[0] = (src[A] * s_alpha) >> 8; \ - \ - y = APPLY_MATRIX (matrix, 0, src[R], src[G], src[B]); \ - u = APPLY_MATRIX (matrix, 1, src[R], src[G], src[B]); \ - v = APPLY_MATRIX (matrix, 2, src[R], src[G], src[B]); \ - \ - dest[1] = y; \ - dest[2] = u; \ - dest[3] = v; \ - \ - dest += 4; \ - src += 4; \ - } \ - } \ -} \ -\ -static void \ -gst_alpha_chroma_key_##name##_ayuv (const guint8 * src, guint8 * dest, gint width, \ - gint height, GstAlpha * alpha) \ -{ \ - gint i, j; \ - gint a, y, u, v; \ - gint r, g, b; \ - gint smin, smax; \ - gint pa = CLAMP ((gint) (alpha->alpha * 256), 0, 256); \ - gint8 cb = alpha->cb, cr = alpha->cr; \ - gint8 kg = alpha->kg; \ - guint8 accept_angle_tg = alpha->accept_angle_tg; \ - guint8 accept_angle_ctg = alpha->accept_angle_ctg; \ - guint8 one_over_kc = alpha->one_over_kc; \ - guint8 kfgy_scale = alpha->kfgy_scale; \ - guint noise_level2 = alpha->noise_level2; \ - gint matrix[12]; \ - \ - smin = 128 - alpha->black_sensitivity; \ - smax = 128 + alpha->white_sensitivity; \ - \ - memcpy (matrix, \ - alpha->out_sdtv ? cog_rgb_to_ycbcr_matrix_8bit_sdtv : \ - cog_rgb_to_ycbcr_matrix_8bit_hdtv, 12 * sizeof (gint)); \ - \ - for (i = 0; i < height; i++) { \ - for (j = 0; j < width; j++) { \ - a = (src[A] * pa) >> 8; \ - r = src[R]; \ - g = src[G]; \ - b = src[B]; \ - \ - y = APPLY_MATRIX (matrix, 0, r, g, b); \ - u = APPLY_MATRIX (matrix, 1, r, g, b) - 128; \ - v = APPLY_MATRIX (matrix, 2, r, g, b) - 128; \ - \ - a = chroma_keying_yuv (a, &y, 1, &u, &v, cr, cb, \ - smin, smax, accept_angle_tg, accept_angle_ctg, \ - one_over_kc, kfgy_scale, kg, noise_level2); \ - \ - u += 128; \ - v += 128; \ - \ - dest[0] = a; \ - dest[1] = y; \ - dest[2] = u; \ - dest[3] = v; \ - \ - src += 4; \ - dest += 4; \ - } \ - } \ +static void +gst_alpha_set_argb_ayuv (const guint8 * src, guint8 * dest, gint width, + gint height, GstAlpha * alpha) +{ + gint s_alpha = CLAMP ((gint) (alpha->alpha * 256), 0, 256); + gint i, j; + gint matrix[12]; + gint y, u, v; + gint o[4]; + + o[0] = + gst_video_format_get_component_offset (alpha->in_format, 3, width, + height); + o[1] = + gst_video_format_get_component_offset (alpha->in_format, 0, width, + height); + o[2] = + gst_video_format_get_component_offset (alpha->in_format, 1, width, + height); + o[3] = + gst_video_format_get_component_offset (alpha->in_format, 2, width, + height); + + memcpy (matrix, + alpha->out_sdtv ? cog_rgb_to_ycbcr_matrix_8bit_sdtv : + cog_rgb_to_ycbcr_matrix_8bit_hdtv, 12 * sizeof (gint)); + + for (i = 0; i < height; i++) { + for (j = 0; j < width; j++) { + dest[0] = (src[o[0]] * s_alpha) >> 8; + + y = APPLY_MATRIX (matrix, 0, src[o[1]], src[o[2]], src[o[3]]); + u = APPLY_MATRIX (matrix, 1, src[o[1]], src[o[2]], src[o[3]]); + v = APPLY_MATRIX (matrix, 2, src[o[1]], src[o[2]], src[o[3]]); + + dest[1] = y; + dest[2] = u; + dest[3] = v; + + dest += 4; + src += 4; + } + } +} + +static void +gst_alpha_chroma_key_argb_ayuv (const guint8 * src, guint8 * dest, gint width, + gint height, GstAlpha * alpha) +{ + gint i, j; + gint a, y, u, v; + gint r, g, b; + gint smin, smax; + gint pa = CLAMP ((gint) (alpha->alpha * 256), 0, 256); + gint8 cb = alpha->cb, cr = alpha->cr; + gint8 kg = alpha->kg; + guint8 accept_angle_tg = alpha->accept_angle_tg; + guint8 accept_angle_ctg = alpha->accept_angle_ctg; + guint8 one_over_kc = alpha->one_over_kc; + guint8 kfgy_scale = alpha->kfgy_scale; + guint noise_level2 = alpha->noise_level2; + gint matrix[12]; + gint o[4]; + + o[0] = + gst_video_format_get_component_offset (alpha->in_format, 3, width, + height); + o[1] = + gst_video_format_get_component_offset (alpha->in_format, 0, width, + height); + o[2] = + gst_video_format_get_component_offset (alpha->in_format, 1, width, + height); + o[3] = + gst_video_format_get_component_offset (alpha->in_format, 2, width, + height); + + smin = 128 - alpha->black_sensitivity; + smax = 128 + alpha->white_sensitivity; + + memcpy (matrix, + alpha->out_sdtv ? cog_rgb_to_ycbcr_matrix_8bit_sdtv : + cog_rgb_to_ycbcr_matrix_8bit_hdtv, 12 * sizeof (gint)); + + for (i = 0; i < height; i++) { + for (j = 0; j < width; j++) { + a = (src[o[0]] * pa) >> 8; + r = src[o[1]]; + g = src[o[2]]; + b = src[o[3]]; + + y = APPLY_MATRIX (matrix, 0, r, g, b); + u = APPLY_MATRIX (matrix, 1, r, g, b) - 128; + v = APPLY_MATRIX (matrix, 2, r, g, b) - 128; + + a = chroma_keying_yuv (a, &y, &u, &v, cr, cb, + smin, smax, accept_angle_tg, accept_angle_ctg, + one_over_kc, kfgy_scale, kg, noise_level2); + + u += 128; + v += 128; + + dest[0] = a; + dest[1] = y; + dest[2] = u; + dest[3] = v; + + src += 4; + dest += 4; + } + } +} + +static void +gst_alpha_set_argb_argb (const guint8 * src, guint8 * dest, gint width, + gint height, GstAlpha * alpha) +{ + gint s_alpha = CLAMP ((gint) (alpha->alpha * 256), 0, 256); + gint i, j; + gint p[4], o[4]; + + p[0] = + gst_video_format_get_component_offset (alpha->out_format, 3, width, + height); + p[1] = + gst_video_format_get_component_offset (alpha->out_format, 0, width, + height); + p[2] = + gst_video_format_get_component_offset (alpha->out_format, 1, width, + height); + p[3] = + gst_video_format_get_component_offset (alpha->out_format, 2, width, + height); + + o[0] = + gst_video_format_get_component_offset (alpha->in_format, 3, width, + height); + o[1] = + gst_video_format_get_component_offset (alpha->in_format, 0, width, + height); + o[2] = + gst_video_format_get_component_offset (alpha->in_format, 1, width, + height); + o[3] = + gst_video_format_get_component_offset (alpha->in_format, 2, width, + height); + + for (i = 0; i < height; i++) { + for (j = 0; j < width; j++) { + dest[p[0]] = (src[o[0]] * s_alpha) >> 8; + + dest[p[1]] = src[o[1]]; + dest[p[2]] = src[o[2]]; + dest[p[3]] = src[o[3]]; + + dest += 4; + src += 4; + } + } } -CREATE_ARGB_AYUV_FUNCTIONS (argb, 0, 1, 2, 3); -CREATE_ARGB_AYUV_FUNCTIONS (abgr, 0, 3, 2, 1); -CREATE_ARGB_AYUV_FUNCTIONS (rgba, 3, 0, 1, 2); -CREATE_ARGB_AYUV_FUNCTIONS (bgra, 3, 2, 1, 0); - -#define CREATE_ARGB_ARGB_FUNCTIONS(name, name2, A, R, G, B, A2, R2, G2, B2) \ -static void \ -gst_alpha_set_##name##_##name2 (const guint8 * src, guint8 * dest, gint width, \ - gint height, GstAlpha * alpha) \ -{ \ - gint s_alpha = CLAMP ((gint) (alpha->alpha * 256), 0, 256); \ - gint i, j; \ - \ - for (i = 0; i < height; i++) { \ - for (j = 0; j < width; j++) { \ - dest[A2] = (src[A] * s_alpha) >> 8; \ - \ - dest[R2] = src[R]; \ - dest[G2] = src[G]; \ - dest[B2] = src[B]; \ - \ - dest += 4; \ - src += 4; \ - } \ - } \ -} \ -\ -static void \ -gst_alpha_chroma_key_##name##_##name2 (const guint8 * src, guint8 * dest, gint width, \ - gint height, GstAlpha * alpha) \ -{ \ - gint i, j; \ - gint a, y, u, v; \ - gint r, g, b; \ - gint smin, smax; \ - gint pa = CLAMP ((gint) (alpha->alpha * 256), 0, 256); \ - gint8 cb = alpha->cb, cr = alpha->cr; \ - gint8 kg = alpha->kg; \ - guint8 accept_angle_tg = alpha->accept_angle_tg; \ - guint8 accept_angle_ctg = alpha->accept_angle_ctg; \ - guint8 one_over_kc = alpha->one_over_kc; \ - guint8 kfgy_scale = alpha->kfgy_scale; \ - guint noise_level2 = alpha->noise_level2; \ - gint matrix[12], matrix2[12]; \ - \ - smin = 128 - alpha->black_sensitivity; \ - smax = 128 + alpha->white_sensitivity; \ - \ - memcpy (matrix, \ - cog_rgb_to_ycbcr_matrix_8bit_sdtv, \ - 12 * sizeof (gint)); \ - memcpy (matrix2, \ - cog_ycbcr_to_rgb_matrix_8bit_sdtv, \ - 12 * sizeof (gint)); \ - \ - for (i = 0; i < height; i++) { \ - for (j = 0; j < width; j++) { \ - a = (src[A] * pa) >> 8; \ - r = src[R]; \ - g = src[G]; \ - b = src[B]; \ - \ - y = APPLY_MATRIX (matrix, 0, r, g, b); \ - u = APPLY_MATRIX (matrix, 1, r, g, b) - 128; \ - v = APPLY_MATRIX (matrix, 2, r, g, b) - 128; \ - \ - a = chroma_keying_yuv (a, &y, 1, &u, &v, cr, cb, \ - smin, smax, accept_angle_tg, accept_angle_ctg, \ - one_over_kc, kfgy_scale, kg, noise_level2); \ - \ - u += 128; \ - v += 128; \ - \ - r = APPLY_MATRIX (matrix2, 0, y, u, v); \ - g = APPLY_MATRIX (matrix2, 1, y, u, v); \ - b = APPLY_MATRIX (matrix2, 2, y, u, v); \ - \ - dest[A2] = a; \ - dest[R2] = CLAMP (r, 0, 255); \ - dest[G2] = CLAMP (g, 0, 255); \ - dest[B2] = CLAMP (b, 0, 255); \ - \ - src += 4; \ - dest += 4; \ - } \ - } \ +static void +gst_alpha_chroma_key_argb_argb (const guint8 * src, guint8 * dest, gint width, + gint height, GstAlpha * alpha) +{ + gint i, j; + gint a, y, u, v; + gint r, g, b; + gint smin, smax; + gint pa = CLAMP ((gint) (alpha->alpha * 256), 0, 256); + gint8 cb = alpha->cb, cr = alpha->cr; + gint8 kg = alpha->kg; + guint8 accept_angle_tg = alpha->accept_angle_tg; + guint8 accept_angle_ctg = alpha->accept_angle_ctg; + guint8 one_over_kc = alpha->one_over_kc; + guint8 kfgy_scale = alpha->kfgy_scale; + guint noise_level2 = alpha->noise_level2; + gint matrix[12], matrix2[12]; + gint p[4], o[4]; + + p[0] = + gst_video_format_get_component_offset (alpha->out_format, 3, width, + height); + p[1] = + gst_video_format_get_component_offset (alpha->out_format, 0, width, + height); + p[2] = + gst_video_format_get_component_offset (alpha->out_format, 1, width, + height); + p[3] = + gst_video_format_get_component_offset (alpha->out_format, 2, width, + height); + + o[0] = + gst_video_format_get_component_offset (alpha->in_format, 3, width, + height); + o[1] = + gst_video_format_get_component_offset (alpha->in_format, 0, width, + height); + o[2] = + gst_video_format_get_component_offset (alpha->in_format, 1, width, + height); + o[3] = + gst_video_format_get_component_offset (alpha->in_format, 2, width, + height); + + smin = 128 - alpha->black_sensitivity; + smax = 128 + alpha->white_sensitivity; + + memcpy (matrix, cog_rgb_to_ycbcr_matrix_8bit_sdtv, 12 * sizeof (gint)); + memcpy (matrix2, cog_ycbcr_to_rgb_matrix_8bit_sdtv, 12 * sizeof (gint)); + + for (i = 0; i < height; i++) { + for (j = 0; j < width; j++) { + a = (src[o[0]] * pa) >> 8; + r = src[o[1]]; + g = src[o[2]]; + b = src[o[3]]; + + y = APPLY_MATRIX (matrix, 0, r, g, b); + u = APPLY_MATRIX (matrix, 1, r, g, b) - 128; + v = APPLY_MATRIX (matrix, 2, r, g, b) - 128; + + a = chroma_keying_yuv (a, &y, &u, &v, cr, cb, + smin, smax, accept_angle_tg, accept_angle_ctg, + one_over_kc, kfgy_scale, kg, noise_level2); + + u += 128; + v += 128; + + r = APPLY_MATRIX (matrix2, 0, y, u, v); + g = APPLY_MATRIX (matrix2, 1, y, u, v); + b = APPLY_MATRIX (matrix2, 2, y, u, v); + + dest[p[0]] = a; + dest[p[1]] = CLAMP (r, 0, 255); + dest[p[2]] = CLAMP (g, 0, 255); + dest[p[3]] = CLAMP (b, 0, 255); + + src += 4; + dest += 4; + } + } } -CREATE_ARGB_ARGB_FUNCTIONS (argb, argb, 0, 1, 2, 3, 0, 1, 2, 3); -CREATE_ARGB_ARGB_FUNCTIONS (argb, abgr, 0, 1, 2, 3, 0, 3, 2, 1); -CREATE_ARGB_ARGB_FUNCTIONS (argb, rgba, 0, 1, 2, 3, 3, 0, 1, 2); -CREATE_ARGB_ARGB_FUNCTIONS (argb, bgra, 0, 1, 2, 3, 3, 2, 1, 0); - -CREATE_ARGB_ARGB_FUNCTIONS (abgr, argb, 0, 3, 2, 1, 0, 1, 2, 3); -CREATE_ARGB_ARGB_FUNCTIONS (abgr, abgr, 0, 3, 2, 1, 0, 3, 2, 1); -CREATE_ARGB_ARGB_FUNCTIONS (abgr, rgba, 0, 3, 2, 1, 3, 0, 1, 2); -CREATE_ARGB_ARGB_FUNCTIONS (abgr, bgra, 0, 3, 2, 1, 3, 2, 1, 0); - -CREATE_ARGB_ARGB_FUNCTIONS (rgba, argb, 3, 0, 1, 2, 0, 1, 2, 3); -CREATE_ARGB_ARGB_FUNCTIONS (rgba, abgr, 3, 0, 1, 2, 0, 3, 2, 1); -CREATE_ARGB_ARGB_FUNCTIONS (rgba, rgba, 3, 0, 1, 2, 3, 0, 1, 2); -CREATE_ARGB_ARGB_FUNCTIONS (rgba, bgra, 3, 0, 1, 2, 3, 2, 1, 0); - -CREATE_ARGB_ARGB_FUNCTIONS (bgra, argb, 3, 2, 1, 0, 0, 1, 2, 3); -CREATE_ARGB_ARGB_FUNCTIONS (bgra, abgr, 3, 2, 1, 0, 0, 3, 2, 1); -CREATE_ARGB_ARGB_FUNCTIONS (bgra, rgba, 3, 2, 1, 0, 3, 0, 1, 2); -CREATE_ARGB_ARGB_FUNCTIONS (bgra, bgra, 3, 2, 1, 0, 3, 2, 1, 0); - -#define CREATE_AYUV_ARGB_FUNCTIONS(name, A, R, G, B) \ -static void \ -gst_alpha_set_ayuv_##name (const guint8 * src, guint8 * dest, gint width, \ - gint height, GstAlpha * alpha) \ -{ \ - gint s_alpha = CLAMP ((gint) (alpha->alpha * 256), 0, 256); \ - gint y, x; \ - gint matrix[12]; \ - gint r, g, b; \ - \ - memcpy (matrix, \ - alpha->in_sdtv ? cog_ycbcr_to_rgb_matrix_8bit_sdtv : \ - cog_ycbcr_to_rgb_matrix_8bit_hdtv, 12 * sizeof (gint)); \ - \ - for (y = 0; y < height; y++) { \ - for (x = 0; x < width; x++) { \ - dest[A] = (src[0] * s_alpha) >> 8; \ - \ - r = APPLY_MATRIX (matrix, 0, src[1], src[2], src[3]); \ - g = APPLY_MATRIX (matrix, 1, src[1], src[2], src[3]); \ - b = APPLY_MATRIX (matrix, 2, src[1], src[2], src[3]); \ - \ - dest[R] = CLAMP (r, 0, 255); \ - dest[G] = CLAMP (g, 0, 255); \ - dest[B] = CLAMP (b, 0, 255); \ - \ - dest += 4; \ - src += 4; \ - } \ - } \ -} \ -\ -static void \ -gst_alpha_chroma_key_ayuv_##name (const guint8 * src, guint8 * dest, gint width, \ - gint height, GstAlpha * alpha) \ -{ \ - gint i, j; \ - gint a, y, u, v; \ - gint r, g, b; \ - gint smin, smax; \ - gint pa = CLAMP ((gint) (alpha->alpha * 256), 0, 256); \ - gint8 cb = alpha->cb, cr = alpha->cr; \ - gint8 kg = alpha->kg; \ - guint8 accept_angle_tg = alpha->accept_angle_tg; \ - guint8 accept_angle_ctg = alpha->accept_angle_ctg; \ - guint8 one_over_kc = alpha->one_over_kc; \ - guint8 kfgy_scale = alpha->kfgy_scale; \ - guint noise_level2 = alpha->noise_level2; \ - gint matrix[12]; \ - \ - smin = 128 - alpha->black_sensitivity; \ - smax = 128 + alpha->white_sensitivity; \ - \ - memcpy (matrix, \ - alpha->in_sdtv ? cog_ycbcr_to_rgb_matrix_8bit_sdtv : \ - cog_ycbcr_to_rgb_matrix_8bit_hdtv, 12 * sizeof (gint)); \ - \ - for (i = 0; i < height; i++) { \ - for (j = 0; j < width; j++) { \ - a = (src[0] * pa) >> 8; \ - y = src[1]; \ - u = src[2] - 128; \ - v = src[3] - 128; \ - \ - a = chroma_keying_yuv (a, &y, 1, &u, &v, cr, cb, \ - smin, smax, accept_angle_tg, accept_angle_ctg, \ - one_over_kc, kfgy_scale, kg, noise_level2); \ - \ - u += 128; \ - v += 128; \ - \ - r = APPLY_MATRIX (matrix, 0, y, u, v); \ - g = APPLY_MATRIX (matrix, 1, y, u, v); \ - b = APPLY_MATRIX (matrix, 2, y, u, v); \ - \ - dest[A] = a; \ - dest[R] = CLAMP (r, 0, 255); \ - dest[G] = CLAMP (g, 0, 255); \ - dest[B] = CLAMP (b, 0, 255); \ - \ - src += 4; \ - dest += 4; \ - } \ - } \ +static void +gst_alpha_set_ayuv_argb (const guint8 * src, guint8 * dest, gint width, + gint height, GstAlpha * alpha) +{ + gint s_alpha = CLAMP ((gint) (alpha->alpha * 256), 0, 256); + gint y, x; + gint matrix[12]; + gint r, g, b; + gint p[4]; + + p[0] = + gst_video_format_get_component_offset (alpha->out_format, 3, width, + height); + p[1] = + gst_video_format_get_component_offset (alpha->out_format, 0, width, + height); + p[2] = + gst_video_format_get_component_offset (alpha->out_format, 1, width, + height); + p[3] = + gst_video_format_get_component_offset (alpha->out_format, 2, width, + height); + + memcpy (matrix, + alpha->in_sdtv ? cog_ycbcr_to_rgb_matrix_8bit_sdtv : + cog_ycbcr_to_rgb_matrix_8bit_hdtv, 12 * sizeof (gint)); + + for (y = 0; y < height; y++) { + for (x = 0; x < width; x++) { + dest[p[0]] = (src[0] * s_alpha) >> 8; + + r = APPLY_MATRIX (matrix, 0, src[1], src[2], src[3]); + g = APPLY_MATRIX (matrix, 1, src[1], src[2], src[3]); + b = APPLY_MATRIX (matrix, 2, src[1], src[2], src[3]); + + dest[p[1]] = CLAMP (r, 0, 255); + dest[p[2]] = CLAMP (g, 0, 255); + dest[p[3]] = CLAMP (b, 0, 255); + + dest += 4; + src += 4; + } + } } -CREATE_AYUV_ARGB_FUNCTIONS (argb, 0, 1, 2, 3); -CREATE_AYUV_ARGB_FUNCTIONS (abgr, 0, 3, 2, 1); -CREATE_AYUV_ARGB_FUNCTIONS (rgba, 3, 0, 1, 2); -CREATE_AYUV_ARGB_FUNCTIONS (bgra, 3, 2, 1, 0); +static void +gst_alpha_chroma_key_ayuv_argb (const guint8 * src, guint8 * dest, gint width, + gint height, GstAlpha * alpha) +{ + gint i, j; + gint a, y, u, v; + gint r, g, b; + gint smin, smax; + gint pa = CLAMP ((gint) (alpha->alpha * 256), 0, 256); + gint8 cb = alpha->cb, cr = alpha->cr; + gint8 kg = alpha->kg; + guint8 accept_angle_tg = alpha->accept_angle_tg; + guint8 accept_angle_ctg = alpha->accept_angle_ctg; + guint8 one_over_kc = alpha->one_over_kc; + guint8 kfgy_scale = alpha->kfgy_scale; + guint noise_level2 = alpha->noise_level2; + gint matrix[12]; + gint p[4]; + + p[0] = + gst_video_format_get_component_offset (alpha->out_format, 3, width, + height); + p[1] = + gst_video_format_get_component_offset (alpha->out_format, 0, width, + height); + p[2] = + gst_video_format_get_component_offset (alpha->out_format, 1, width, + height); + p[3] = + gst_video_format_get_component_offset (alpha->out_format, 2, width, + height); + + smin = 128 - alpha->black_sensitivity; + smax = 128 + alpha->white_sensitivity; + + memcpy (matrix, + alpha->in_sdtv ? cog_ycbcr_to_rgb_matrix_8bit_sdtv : + cog_ycbcr_to_rgb_matrix_8bit_hdtv, 12 * sizeof (gint)); + + for (i = 0; i < height; i++) { + for (j = 0; j < width; j++) { + a = (src[0] * pa) >> 8; + y = src[1]; + u = src[2] - 128; + v = src[3] - 128; + + a = chroma_keying_yuv (a, &y, &u, &v, cr, cb, + smin, smax, accept_angle_tg, accept_angle_ctg, + one_over_kc, kfgy_scale, kg, noise_level2); + + u += 128; + v += 128; + + r = APPLY_MATRIX (matrix, 0, y, u, v); + g = APPLY_MATRIX (matrix, 1, y, u, v); + b = APPLY_MATRIX (matrix, 2, y, u, v); + + dest[p[0]] = a; + dest[p[1]] = CLAMP (r, 0, 255); + dest[p[2]] = CLAMP (g, 0, 255); + dest[p[3]] = CLAMP (b, 0, 255); + + src += 4; + dest += 4; + } + } +} static void gst_alpha_set_ayuv_ayuv (const guint8 * src, guint8 * dest, gint width, @@ -899,7 +971,7 @@ gst_alpha_chroma_key_ayuv_ayuv (const guint8 * src, guint8 * dest, u = src[2] - 128; v = src[3] - 128; - a = chroma_keying_yuv (a, &y, 1, &u, &v, cr, cb, + a = chroma_keying_yuv (a, &y, &u, &v, cr, cb, smin, smax, accept_angle_tg, accept_angle_ctg, one_over_kc, kfgy_scale, kg, noise_level2); @@ -929,7 +1001,7 @@ gst_alpha_chroma_key_ayuv_ayuv (const guint8 * src, guint8 * dest, u = APPLY_MATRIX (matrix, 1, src[1], src[2], src[3]) - 128; v = APPLY_MATRIX (matrix, 2, src[1], src[2], src[3]) - 128; - a = chroma_keying_yuv (a, &y, 1, &u, &v, cr, cb, + a = chroma_keying_yuv (a, &y, &u, &v, cr, cb, smin, smax, accept_angle_tg, accept_angle_ctg, one_over_kc, kfgy_scale, kg, noise_level2); @@ -948,504 +1020,298 @@ gst_alpha_chroma_key_ayuv_ayuv (const guint8 * src, guint8 * dest, } } -#define CREATE_I420_ARGB_FUNCTIONS(name, A, R, G, B) \ -static void \ -gst_alpha_set_i420_##name (const guint8 * src, guint8 * dest, gint width, \ - gint height, GstAlpha * alpha) \ -{ \ - gint b_alpha = CLAMP ((gint) (alpha->alpha * 255), 0, 255); \ - const guint8 *srcY; \ - const guint8 *srcU; \ - const guint8 *srcV; \ - gint i, j; \ - gint src_wrap, src_uv_wrap; \ - gint y_stride, uv_stride; \ - gboolean odd_width; \ - gint matrix[12]; \ - gint r, g, b; \ - \ - y_stride = gst_video_format_get_row_stride (alpha->in_format, 0, width); \ - uv_stride = gst_video_format_get_row_stride (alpha->in_format, 1, width); \ - \ - src_wrap = y_stride - width; \ - src_uv_wrap = uv_stride - (width / 2); \ - \ - srcY = src; \ - srcU = src + gst_video_format_get_component_offset (alpha->in_format, \ - 1, width, height); \ - srcV = src + gst_video_format_get_component_offset (alpha->in_format, \ - 2, width, height); \ - \ - odd_width = (width % 2 != 0); \ - \ - memcpy (matrix, \ - alpha->in_sdtv ? cog_ycbcr_to_rgb_matrix_8bit_sdtv : \ - cog_ycbcr_to_rgb_matrix_8bit_hdtv, 12 * sizeof (gint)); \ - \ - for (i = 0; i < height; i++) { \ - for (j = 0; j < width / 2; j++) { \ - dest[A] = b_alpha; \ - r = APPLY_MATRIX (matrix, 0, srcY[0], srcU[0], srcV[0]); \ - g = APPLY_MATRIX (matrix, 1, srcY[0], srcU[0], srcV[0]); \ - b = APPLY_MATRIX (matrix, 2, srcY[0], srcU[0], srcV[0]); \ - dest[R] = CLAMP (r, 0, 255); \ - dest[G] = CLAMP (g, 0, 255); \ - dest[B] = CLAMP (b, 0, 255); \ - \ - dest[4 + A] = b_alpha; \ - r = APPLY_MATRIX (matrix, 0, srcY[1], srcU[0], srcV[0]); \ - g = APPLY_MATRIX (matrix, 1, srcY[1], srcU[0], srcV[0]); \ - b = APPLY_MATRIX (matrix, 2, srcY[1], srcU[0], srcV[0]); \ - dest[4 + R] = CLAMP (r, 0, 255); \ - dest[4 + G] = CLAMP (g, 0, 255); \ - dest[4 + B] = CLAMP (b, 0, 255); \ - \ - dest += 8; \ - srcY += 2; \ - srcU++; \ - srcV++; \ - } \ - /* Might have one odd column left to do */ \ - if (odd_width) { \ - dest[A] = b_alpha; \ - r = APPLY_MATRIX (matrix, 0, srcY[0], srcU[0], srcV[0]); \ - g = APPLY_MATRIX (matrix, 1, srcY[0], srcU[0], srcV[0]); \ - b = APPLY_MATRIX (matrix, 2, srcY[0], srcU[0], srcV[0]); \ - dest[R] = CLAMP (r, 0, 255); \ - dest[G] = CLAMP (g, 0, 255); \ - dest[B] = CLAMP (b, 0, 255); \ - \ - dest += 4; \ - srcY++; \ - } \ - if (i % 2 == 0) { \ - srcU -= width / 2; \ - srcV -= width / 2; \ - } else { \ - srcU += src_uv_wrap; \ - srcV += src_uv_wrap; \ - } \ - srcY += src_wrap; \ - } \ -} \ -\ -static inline void \ -gst_alpha_chromakey_row_i420_##name (GstAlpha * alpha, guint8 * dest1, \ - guint8 * dest2, const guint8 * srcY1, const guint8 * srcY2, \ - const guint8 * srcU, const guint8 * srcV, gint width) \ -{ \ - gint xpos; \ - gint a, a2, u, v; \ - gint r, g, b; \ - gint smin, smax; \ - gint8 cb = alpha->cb, cr = alpha->cr; \ - gint8 kg = alpha->kg; \ - guint8 accept_angle_tg = alpha->accept_angle_tg; \ - guint8 accept_angle_ctg = alpha->accept_angle_ctg; \ - guint8 one_over_kc = alpha->one_over_kc; \ - guint8 kfgy_scale = alpha->kfgy_scale; \ - guint noise_level2 = alpha->noise_level2; \ - gint matrix[12], y; \ - \ - a = CLAMP ((gint) (alpha->alpha * 255), 0, 255); \ - smin = 128 - alpha->black_sensitivity; \ - smax = 128 + alpha->white_sensitivity; \ - \ - memcpy (matrix, \ - alpha->in_sdtv ? cog_ycbcr_to_rgb_matrix_8bit_sdtv : \ - cog_ycbcr_to_rgb_matrix_8bit_hdtv, 12 * sizeof (gint)); \ - \ - for (xpos = 0; xpos < width / 2; xpos++) { \ - y = srcY1[0]; \ - u = srcU[0] - 128; \ - v = srcV[0] - 128; \ - \ - a2 = chroma_keying_yuv (a, &y, 1, &u, &v, cr, cb, smin, \ - smax, accept_angle_tg, accept_angle_ctg, \ - one_over_kc, kfgy_scale, kg, noise_level2); \ - \ - u += 128; \ - v += 128; \ - \ - r = APPLY_MATRIX (matrix, 0, y, u, v); \ - g = APPLY_MATRIX (matrix, 1, y, u, v); \ - b = APPLY_MATRIX (matrix, 2, y, u, v); \ - \ - dest1[A] = a2; \ - dest1[R] = CLAMP (r, 0, 255); \ - dest1[G] = CLAMP (g, 0, 255); \ - dest1[B] = CLAMP (b, 0, 255); \ - \ - y = srcY1[1]; \ - u = srcU[0] - 128; \ - v = srcV[0] - 128; \ - \ - a2 = chroma_keying_yuv (a, &y, 1, &u, &v, cr, cb, smin, \ - smax, accept_angle_tg, accept_angle_ctg, \ - one_over_kc, kfgy_scale, kg, noise_level2); \ - \ - u += 128; \ - v += 128; \ - \ - r = APPLY_MATRIX (matrix, 0, y, u, v); \ - g = APPLY_MATRIX (matrix, 1, y, u, v); \ - b = APPLY_MATRIX (matrix, 2, y, u, v); \ - \ - dest1[4 + A] = a2; \ - dest1[4 + R] = CLAMP (r, 0, 255); \ - dest1[4 + G] = CLAMP (g, 0, 255); \ - dest1[4 + B] = CLAMP (b, 0, 255); \ - \ - y = srcY2[0]; \ - u = srcU[0] - 128; \ - v = srcV[0] - 128; \ - \ - a2 = chroma_keying_yuv (a, &y, 1, &u, &v, cr, cb, smin, \ - smax, accept_angle_tg, accept_angle_ctg, \ - one_over_kc, kfgy_scale, kg, noise_level2); \ - \ - u += 128; \ - v += 128; \ - \ - r = APPLY_MATRIX (matrix, 0, y, u, v); \ - g = APPLY_MATRIX (matrix, 1, y, u, v); \ - b = APPLY_MATRIX (matrix, 2, y, u, v); \ - \ - dest2[A] = a2; \ - dest2[R] = CLAMP (r, 0, 255); \ - dest2[G] = CLAMP (g, 0, 255); \ - dest2[B] = CLAMP (b, 0, 255); \ - \ - y = srcY2[1]; \ - u = srcU[0] - 128; \ - v = srcV[0] - 128; \ - \ - a2 = chroma_keying_yuv (a, &y, 1, &u, &v, cr, cb, smin, \ - smax, accept_angle_tg, accept_angle_ctg, \ - one_over_kc, kfgy_scale, kg, noise_level2); \ - \ - u += 128; \ - v += 128; \ - \ - r = APPLY_MATRIX (matrix, 0, y, u, v); \ - g = APPLY_MATRIX (matrix, 1, y, u, v); \ - b = APPLY_MATRIX (matrix, 2, y, u, v); \ - \ - dest2[4 + A] = a2; \ - dest2[4 + R] = CLAMP (r, 0, 255); \ - dest2[4 + G] = CLAMP (g, 0, 255); \ - dest2[4 + B] = CLAMP (b, 0, 255); \ - \ - srcY1 += 2; \ - srcY2 += 2; \ - srcU++; \ - srcV++; \ - dest1 += 8; \ - dest2 += 8; \ - } \ -} \ -\ -static void \ -gst_alpha_chroma_key_i420_##name (const guint8 * src, guint8 * dest, \ - gint width, gint height, GstAlpha * alpha) \ -{ \ - const guint8 *srcY1, *srcY2, *srcU, *srcV; \ - guint8 *dest1, *dest2; \ - gint ypos; \ - gint dest_stride, src_y_stride, src_uv_stride; \ - \ - dest_stride = \ - gst_video_format_get_row_stride (GST_VIDEO_FORMAT_AYUV, 0, width); \ - src_y_stride = \ - gst_video_format_get_row_stride (alpha->in_format, 0, width); \ - src_uv_stride = \ - gst_video_format_get_row_stride (alpha->in_format, 1, width); \ - \ - srcY1 = src; \ - srcY2 = src + src_y_stride; \ - \ - srcU = src + gst_video_format_get_component_offset (alpha->in_format, \ - 1, width, height); \ - srcV = src + gst_video_format_get_component_offset (alpha->in_format, \ - 2, width, height); \ - \ - dest1 = dest; \ - dest2 = dest + dest_stride; \ - \ - /* Redefine Y strides to skip 2 lines at a time ... */ \ - dest_stride *= 2; \ - src_y_stride *= 2; \ - \ - for (ypos = 0; ypos < height / 2; ypos++) { \ - gst_alpha_chromakey_row_i420_##name (alpha, dest1, dest2, \ - srcY1, srcY2, srcU, srcV, width); \ - \ - dest1 += dest_stride; \ - dest2 += dest_stride; \ - srcY1 += src_y_stride; \ - srcY2 += src_y_stride; \ - srcU += src_uv_stride; \ - srcV += src_uv_stride; \ - } \ +static void +gst_alpha_set_rgb_ayuv (const guint8 * src, guint8 * dest, gint width, + gint height, GstAlpha * alpha) +{ + gint s_alpha = CLAMP ((gint) (alpha->alpha * 255), 0, 255); + gint i, j; + gint matrix[12]; + gint y, u, v; + gint o[3]; + gint bpp; + + bpp = gst_video_format_get_pixel_stride (alpha->in_format, 0); + + o[0] = + gst_video_format_get_component_offset (alpha->in_format, 0, width, + height); + o[1] = + gst_video_format_get_component_offset (alpha->in_format, 1, width, + height); + o[2] = + gst_video_format_get_component_offset (alpha->in_format, 2, width, + height); + + memcpy (matrix, + alpha->out_sdtv ? cog_rgb_to_ycbcr_matrix_8bit_sdtv : + cog_rgb_to_ycbcr_matrix_8bit_hdtv, 12 * sizeof (gint)); + + for (i = 0; i < height; i++) { + for (j = 0; j < width; j++) { + dest[0] = s_alpha; + + y = APPLY_MATRIX (matrix, 0, src[o[0]], src[o[1]], src[o[2]]); + u = APPLY_MATRIX (matrix, 1, src[o[0]], src[o[1]], src[o[2]]); + v = APPLY_MATRIX (matrix, 2, src[o[0]], src[o[1]], src[o[2]]); + + dest[1] = y; + dest[2] = u; + dest[3] = v; + + dest += 4; + src += bpp; + } + } } -CREATE_I420_ARGB_FUNCTIONS (argb, 0, 1, 2, 3); -CREATE_I420_ARGB_FUNCTIONS (abgr, 0, 3, 2, 1); -CREATE_I420_ARGB_FUNCTIONS (rgba, 3, 0, 1, 2); -CREATE_I420_ARGB_FUNCTIONS (bgra, 3, 2, 1, 0); - -#define CREATE_RGB_AYUV_FUNCTIONS(name, R, G, B, bpp) \ -static void \ -gst_alpha_set_##name##_ayuv (const guint8 * src, guint8 * dest, gint width, \ - gint height, GstAlpha * alpha) \ -{ \ - gint s_alpha = CLAMP ((gint) (alpha->alpha * 255), 0, 255); \ - gint i, j; \ - gint matrix[12]; \ - gint y, u, v; \ - \ - memcpy (matrix, \ - alpha->out_sdtv ? cog_rgb_to_ycbcr_matrix_8bit_sdtv : \ - cog_rgb_to_ycbcr_matrix_8bit_hdtv, 12 * sizeof (gint)); \ - \ - for (i = 0; i < height; i++) { \ - for (j = 0; j < width; j++) { \ - dest[0] = s_alpha; \ - \ - y = APPLY_MATRIX (matrix, 0, src[R], src[G], src[B]); \ - u = APPLY_MATRIX (matrix, 1, src[R], src[G], src[B]); \ - v = APPLY_MATRIX (matrix, 2, src[R], src[G], src[B]); \ - \ - dest[1] = y; \ - dest[2] = u; \ - dest[3] = v; \ - \ - dest += 4; \ - src += bpp; \ - } \ - } \ -} \ -\ -static void \ -gst_alpha_chroma_key_##name##_ayuv (const guint8 * src, guint8 * dest, gint width, \ - gint height, GstAlpha * alpha) \ -{ \ - gint i, j; \ - gint a, y, u, v; \ - gint r, g, b; \ - gint smin, smax; \ - gint pa = CLAMP ((gint) (alpha->alpha * 255), 0, 255); \ - gint8 cb = alpha->cb, cr = alpha->cr; \ - gint8 kg = alpha->kg; \ - guint8 accept_angle_tg = alpha->accept_angle_tg; \ - guint8 accept_angle_ctg = alpha->accept_angle_ctg; \ - guint8 one_over_kc = alpha->one_over_kc; \ - guint8 kfgy_scale = alpha->kfgy_scale; \ - guint noise_level2 = alpha->noise_level2; \ - gint matrix[12]; \ - \ - smin = 128 - alpha->black_sensitivity; \ - smax = 128 + alpha->white_sensitivity; \ - \ - memcpy (matrix, \ - alpha->out_sdtv ? cog_rgb_to_ycbcr_matrix_8bit_sdtv : \ - cog_rgb_to_ycbcr_matrix_8bit_hdtv, 12 * sizeof (gint)); \ - \ - for (i = 0; i < height; i++) { \ - for (j = 0; j < width; j++) { \ - a = pa; \ - r = src[R]; \ - g = src[G]; \ - b = src[B]; \ - \ - y = APPLY_MATRIX (matrix, 0, r, g, b); \ - u = APPLY_MATRIX (matrix, 1, r, g, b) - 128; \ - v = APPLY_MATRIX (matrix, 2, r, g, b) - 128; \ - \ - a = chroma_keying_yuv (a, &y, 1, &u, &v, cr, cb, \ - smin, smax, accept_angle_tg, accept_angle_ctg, \ - one_over_kc, kfgy_scale, kg, noise_level2); \ - \ - u += 128; \ - v += 128; \ - \ - dest[0] = a; \ - dest[1] = y; \ - dest[2] = u; \ - dest[3] = v; \ - \ - src += bpp; \ - dest += 4; \ - } \ - } \ +static void +gst_alpha_chroma_key_rgb_ayuv (const guint8 * src, guint8 * dest, gint width, + gint height, GstAlpha * alpha) +{ + gint i, j; + gint a, y, u, v; + gint r, g, b; + gint smin, smax; + gint pa = CLAMP ((gint) (alpha->alpha * 255), 0, 255); + gint8 cb = alpha->cb, cr = alpha->cr; + gint8 kg = alpha->kg; + guint8 accept_angle_tg = alpha->accept_angle_tg; + guint8 accept_angle_ctg = alpha->accept_angle_ctg; + guint8 one_over_kc = alpha->one_over_kc; + guint8 kfgy_scale = alpha->kfgy_scale; + guint noise_level2 = alpha->noise_level2; + gint matrix[12]; + gint o[3]; + gint bpp; + + bpp = gst_video_format_get_pixel_stride (alpha->in_format, 0); + + o[0] = + gst_video_format_get_component_offset (alpha->in_format, 0, width, + height); + o[1] = + gst_video_format_get_component_offset (alpha->in_format, 1, width, + height); + o[2] = + gst_video_format_get_component_offset (alpha->in_format, 2, width, + height); + + smin = 128 - alpha->black_sensitivity; + smax = 128 + alpha->white_sensitivity; + + memcpy (matrix, + alpha->out_sdtv ? cog_rgb_to_ycbcr_matrix_8bit_sdtv : + cog_rgb_to_ycbcr_matrix_8bit_hdtv, 12 * sizeof (gint)); + + for (i = 0; i < height; i++) { + for (j = 0; j < width; j++) { + a = pa; + r = src[o[0]]; + g = src[o[1]]; + b = src[o[2]]; + + y = APPLY_MATRIX (matrix, 0, r, g, b); + u = APPLY_MATRIX (matrix, 1, r, g, b) - 128; + v = APPLY_MATRIX (matrix, 2, r, g, b) - 128; + + a = chroma_keying_yuv (a, &y, &u, &v, cr, cb, + smin, smax, accept_angle_tg, accept_angle_ctg, + one_over_kc, kfgy_scale, kg, noise_level2); + + u += 128; + v += 128; + + dest[0] = a; + dest[1] = y; + dest[2] = u; + dest[3] = v; + + src += bpp; + dest += 4; + } + } } -CREATE_RGB_AYUV_FUNCTIONS (xrgb, 1, 2, 3, 4); -CREATE_RGB_AYUV_FUNCTIONS (xbgr, 3, 2, 1, 4); -CREATE_RGB_AYUV_FUNCTIONS (rgbx, 0, 1, 2, 4); -CREATE_RGB_AYUV_FUNCTIONS (bgrx, 2, 1, 0, 4); -CREATE_RGB_AYUV_FUNCTIONS (rgb, 0, 1, 2, 3); -CREATE_RGB_AYUV_FUNCTIONS (bgr, 2, 1, 0, 3); - -#define CREATE_RGB_ARGB_FUNCTIONS(name, name2, R, G, B, A2, R2, G2, B2, bpp) \ -static void \ -gst_alpha_set_##name##_##name2 (const guint8 * src, guint8 * dest, gint width, \ - gint height, GstAlpha * alpha) \ -{ \ - gint s_alpha = CLAMP ((gint) (alpha->alpha * 255), 0, 255); \ - gint i, j; \ - \ - for (i = 0; i < height; i++) { \ - for (j = 0; j < width; j++) { \ - dest[A2] = s_alpha; \ - \ - dest[R2] = src[R]; \ - dest[G2] = src[G]; \ - dest[B2] = src[B]; \ - \ - dest += 4; \ - src += bpp; \ - } \ - } \ -} \ -\ -static void \ -gst_alpha_chroma_key_##name##_##name2 (const guint8 * src, guint8 * dest, gint width, \ - gint height, GstAlpha * alpha) \ -{ \ - gint i, j; \ - gint a, y, u, v; \ - gint r, g, b; \ - gint smin, smax; \ - gint pa = CLAMP ((gint) (alpha->alpha * 255), 0, 255); \ - gint8 cb = alpha->cb, cr = alpha->cr; \ - gint8 kg = alpha->kg; \ - guint8 accept_angle_tg = alpha->accept_angle_tg; \ - guint8 accept_angle_ctg = alpha->accept_angle_ctg; \ - guint8 one_over_kc = alpha->one_over_kc; \ - guint8 kfgy_scale = alpha->kfgy_scale; \ - guint noise_level2 = alpha->noise_level2; \ - gint matrix[12], matrix2[12]; \ - \ - smin = 128 - alpha->black_sensitivity; \ - smax = 128 + alpha->white_sensitivity; \ - \ - memcpy (matrix, \ - cog_rgb_to_ycbcr_matrix_8bit_sdtv, \ - 12 * sizeof (gint)); \ - memcpy (matrix2, \ - cog_ycbcr_to_rgb_matrix_8bit_sdtv, \ - 12 * sizeof (gint)); \ - \ - for (i = 0; i < height; i++) { \ - for (j = 0; j < width; j++) { \ - a = pa; \ - r = src[R]; \ - g = src[G]; \ - b = src[B]; \ - \ - y = APPLY_MATRIX (matrix, 0, r, g, b); \ - u = APPLY_MATRIX (matrix, 1, r, g, b) - 128; \ - v = APPLY_MATRIX (matrix, 2, r, g, b) - 128; \ - \ - a = chroma_keying_yuv (a, &y, 1, &u, &v, cr, cb, \ - smin, smax, accept_angle_tg, accept_angle_ctg, \ - one_over_kc, kfgy_scale, kg, noise_level2); \ - \ - u += 128; \ - v += 128; \ - \ - r = APPLY_MATRIX (matrix2, 0, y, u, v); \ - g = APPLY_MATRIX (matrix2, 1, y, u, v); \ - b = APPLY_MATRIX (matrix2, 2, y, u, v); \ - \ - dest[A2] = a; \ - dest[R2] = CLAMP (r, 0, 255); \ - dest[G2] = CLAMP (g, 0, 255); \ - dest[B2] = CLAMP (b, 0, 255); \ - \ - src += bpp; \ - dest += 4; \ - } \ - } \ +static void +gst_alpha_set_rgb_argb (const guint8 * src, guint8 * dest, gint width, + gint height, GstAlpha * alpha) +{ + gint s_alpha = CLAMP ((gint) (alpha->alpha * 255), 0, 255); + gint i, j; + gint p[4], o[3]; + gint bpp; + + bpp = gst_video_format_get_pixel_stride (alpha->in_format, 0); + + o[0] = + gst_video_format_get_component_offset (alpha->in_format, 0, width, + height); + o[1] = + gst_video_format_get_component_offset (alpha->in_format, 1, width, + height); + o[2] = + gst_video_format_get_component_offset (alpha->in_format, 2, width, + height); + + p[0] = + gst_video_format_get_component_offset (alpha->out_format, 3, width, + height); + p[1] = + gst_video_format_get_component_offset (alpha->out_format, 0, width, + height); + p[2] = + gst_video_format_get_component_offset (alpha->out_format, 1, width, + height); + p[3] = + gst_video_format_get_component_offset (alpha->out_format, 2, width, + height); + + for (i = 0; i < height; i++) { + for (j = 0; j < width; j++) { + dest[p[0]] = s_alpha; + + dest[p[1]] = src[o[0]]; + dest[p[2]] = src[o[1]]; + dest[p[3]] = src[o[2]]; + + dest += 4; + src += bpp; + } + } } -CREATE_RGB_ARGB_FUNCTIONS (xrgb, argb, 1, 2, 3, 0, 1, 2, 3, 4); -CREATE_RGB_ARGB_FUNCTIONS (xrgb, abgr, 1, 2, 3, 0, 3, 2, 1, 4); -CREATE_RGB_ARGB_FUNCTIONS (xrgb, rgba, 1, 2, 3, 3, 0, 1, 2, 4); -CREATE_RGB_ARGB_FUNCTIONS (xrgb, bgra, 1, 2, 3, 3, 2, 1, 0, 4); +static void +gst_alpha_chroma_key_rgb_argb (const guint8 * src, guint8 * dest, gint width, + gint height, GstAlpha * alpha) +{ + gint i, j; + gint a, y, u, v; + gint r, g, b; + gint smin, smax; + gint pa = CLAMP ((gint) (alpha->alpha * 255), 0, 255); + gint8 cb = alpha->cb, cr = alpha->cr; + gint8 kg = alpha->kg; + guint8 accept_angle_tg = alpha->accept_angle_tg; + guint8 accept_angle_ctg = alpha->accept_angle_ctg; + guint8 one_over_kc = alpha->one_over_kc; + guint8 kfgy_scale = alpha->kfgy_scale; + guint noise_level2 = alpha->noise_level2; + gint matrix[12], matrix2[12]; + gint p[4], o[3]; + gint bpp; + + bpp = gst_video_format_get_pixel_stride (alpha->in_format, 0); + + o[0] = + gst_video_format_get_component_offset (alpha->in_format, 0, width, + height); + o[1] = + gst_video_format_get_component_offset (alpha->in_format, 1, width, + height); + o[2] = + gst_video_format_get_component_offset (alpha->in_format, 2, width, + height); + + p[0] = + gst_video_format_get_component_offset (alpha->out_format, 3, width, + height); + p[1] = + gst_video_format_get_component_offset (alpha->out_format, 0, width, + height); + p[2] = + gst_video_format_get_component_offset (alpha->out_format, 1, width, + height); + p[3] = + gst_video_format_get_component_offset (alpha->out_format, 2, width, + height); + + smin = 128 - alpha->black_sensitivity; + smax = 128 + alpha->white_sensitivity; + + memcpy (matrix, cog_rgb_to_ycbcr_matrix_8bit_sdtv, 12 * sizeof (gint)); + memcpy (matrix2, cog_ycbcr_to_rgb_matrix_8bit_sdtv, 12 * sizeof (gint)); + + for (i = 0; i < height; i++) { + for (j = 0; j < width; j++) { + a = pa; + r = src[o[0]]; + g = src[o[1]]; + b = src[o[2]]; -CREATE_RGB_ARGB_FUNCTIONS (xbgr, argb, 3, 2, 1, 0, 1, 2, 3, 4); -CREATE_RGB_ARGB_FUNCTIONS (xbgr, abgr, 3, 2, 1, 0, 3, 2, 1, 4); -CREATE_RGB_ARGB_FUNCTIONS (xbgr, rgba, 3, 2, 1, 3, 0, 1, 2, 4); -CREATE_RGB_ARGB_FUNCTIONS (xbgr, bgra, 3, 2, 1, 3, 2, 1, 0, 4); + y = APPLY_MATRIX (matrix, 0, r, g, b); + u = APPLY_MATRIX (matrix, 1, r, g, b) - 128; + v = APPLY_MATRIX (matrix, 2, r, g, b) - 128; + + a = chroma_keying_yuv (a, &y, &u, &v, cr, cb, + smin, smax, accept_angle_tg, accept_angle_ctg, + one_over_kc, kfgy_scale, kg, noise_level2); -CREATE_RGB_ARGB_FUNCTIONS (rgbx, argb, 0, 1, 2, 0, 1, 2, 3, 4); -CREATE_RGB_ARGB_FUNCTIONS (rgbx, abgr, 0, 1, 2, 0, 3, 2, 1, 4); -CREATE_RGB_ARGB_FUNCTIONS (rgbx, rgba, 0, 1, 2, 3, 0, 1, 2, 4); -CREATE_RGB_ARGB_FUNCTIONS (rgbx, bgra, 0, 1, 2, 3, 2, 1, 0, 4); + u += 128; + v += 128; -CREATE_RGB_ARGB_FUNCTIONS (bgrx, argb, 2, 1, 0, 0, 1, 2, 3, 4); -CREATE_RGB_ARGB_FUNCTIONS (bgrx, abgr, 2, 1, 0, 0, 3, 2, 1, 4); -CREATE_RGB_ARGB_FUNCTIONS (bgrx, rgba, 2, 1, 0, 3, 0, 1, 2, 4); -CREATE_RGB_ARGB_FUNCTIONS (bgrx, bgra, 2, 1, 0, 3, 2, 1, 0, 4); + r = APPLY_MATRIX (matrix2, 0, y, u, v); + g = APPLY_MATRIX (matrix2, 1, y, u, v); + b = APPLY_MATRIX (matrix2, 2, y, u, v); -CREATE_RGB_ARGB_FUNCTIONS (rgb, argb, 0, 1, 2, 0, 1, 2, 3, 3); -CREATE_RGB_ARGB_FUNCTIONS (rgb, abgr, 0, 1, 2, 0, 3, 2, 1, 3); -CREATE_RGB_ARGB_FUNCTIONS (rgb, rgba, 0, 1, 2, 3, 0, 1, 2, 3); -CREATE_RGB_ARGB_FUNCTIONS (rgb, bgra, 0, 1, 2, 3, 2, 1, 0, 3); + dest[p[0]] = a; + dest[p[1]] = CLAMP (r, 0, 255); + dest[p[2]] = CLAMP (g, 0, 255); + dest[p[3]] = CLAMP (b, 0, 255); -CREATE_RGB_ARGB_FUNCTIONS (bgr, argb, 2, 1, 0, 0, 1, 2, 3, 3); -CREATE_RGB_ARGB_FUNCTIONS (bgr, abgr, 2, 1, 0, 0, 3, 2, 1, 3); -CREATE_RGB_ARGB_FUNCTIONS (bgr, rgba, 2, 1, 0, 3, 0, 1, 2, 3); -CREATE_RGB_ARGB_FUNCTIONS (bgr, bgra, 2, 1, 0, 3, 2, 1, 0, 3); + src += bpp; + dest += 4; + } + } +} static void -gst_alpha_set_i420_ayuv (const guint8 * src, guint8 * dest, gint width, +gst_alpha_set_planar_yuv_ayuv (const guint8 * src, guint8 * dest, gint width, gint height, GstAlpha * alpha) { gint b_alpha = CLAMP ((gint) (alpha->alpha * 255), 0, 255); - const guint8 *srcY; - const guint8 *srcU; - const guint8 *srcV; + const guint8 *srcY, *srcY_tmp; + const guint8 *srcU, *srcU_tmp; + const guint8 *srcV, *srcV_tmp; gint i, j; - gint src_wrap, src_uv_wrap; gint y_stride, uv_stride; - gboolean odd_width; + gint v_subs, h_subs; y_stride = gst_video_format_get_row_stride (alpha->in_format, 0, width); uv_stride = gst_video_format_get_row_stride (alpha->in_format, 1, width); - src_wrap = y_stride - width; - src_uv_wrap = uv_stride - (width / 2); - - srcY = src; - srcU = src + gst_video_format_get_component_offset (alpha->in_format, - 1, width, height); - srcV = src + gst_video_format_get_component_offset (alpha->in_format, - 2, width, height); - - odd_width = (width % 2 != 0); + srcY_tmp = srcY = src; + srcU_tmp = srcU = + src + gst_video_format_get_component_offset (alpha->in_format, 1, width, + height); + srcV_tmp = srcV = + src + gst_video_format_get_component_offset (alpha->in_format, 2, width, + height); + + switch (alpha->in_format) { + case GST_VIDEO_FORMAT_I420: + case GST_VIDEO_FORMAT_YV12: + v_subs = h_subs = 2; + break; + case GST_VIDEO_FORMAT_Y444: + v_subs = h_subs = 1; + break; + case GST_VIDEO_FORMAT_Y42B: + v_subs = 1; + h_subs = 2; + break; + case GST_VIDEO_FORMAT_Y41B: + v_subs = 1; + h_subs = 4; + break; + default: + g_assert_not_reached (); + break; + } if (alpha->in_sdtv == alpha->out_sdtv) { for (i = 0; i < height; i++) { - for (j = 0; j < width / 2; j++) { - dest[0] = b_alpha; - dest[1] = srcY[0]; - dest[2] = srcU[0]; - dest[3] = srcV[0]; - dest[4] = b_alpha; - dest[5] = srcY[1]; - dest[6] = srcU[0]; - dest[7] = srcV[0]; - - dest += 8; - srcY += 2; - srcU++; - srcV++; - } - /* Might have one odd column left to do */ - if (odd_width) { + for (j = 0; j < width; j++) { dest[0] = b_alpha; dest[1] = srcY[0]; dest[2] = srcU[0]; @@ -1453,69 +1319,75 @@ gst_alpha_set_i420_ayuv (const guint8 * src, guint8 * dest, gint width, dest += 4; srcY++; + if ((j + 1) % h_subs == 0) { + srcU++; + srcV++; + } } - if (i % 2 == 0) { - srcU -= width / 2; - srcV -= width / 2; + + srcY_tmp = srcY = srcY_tmp + y_stride; + if ((i + 1) % v_subs == 0) { + srcU_tmp = srcU = srcU_tmp + uv_stride; + srcV_tmp = srcV = srcV_tmp + uv_stride; } else { - srcU += src_uv_wrap; - srcV += src_uv_wrap; + srcU = srcU_tmp; + srcV = srcV_tmp; } - srcY += src_wrap; } } else { gint matrix[12]; + gint a, y, u, v; memcpy (matrix, alpha->out_sdtv ? cog_ycbcr_hdtv_to_ycbcr_sdtv_matrix_8bit : cog_ycbcr_sdtv_to_ycbcr_hdtv_matrix_8bit, 12 * sizeof (gint)); for (i = 0; i < height; i++) { - for (j = 0; j < width / 2; j++) { - dest[0] = b_alpha; - dest[1] = APPLY_MATRIX (matrix, 0, srcY[0], srcU[0], srcV[0]); - dest[2] = APPLY_MATRIX (matrix, 1, srcY[0], srcU[0], srcV[0]); - dest[3] = APPLY_MATRIX (matrix, 2, srcY[0], srcU[0], srcV[0]); - dest[4] = b_alpha; - dest[5] = APPLY_MATRIX (matrix, 0, srcY[1], srcU[0], srcV[0]); - dest[6] = APPLY_MATRIX (matrix, 1, srcY[1], srcU[0], srcV[0]); - dest[7] = APPLY_MATRIX (matrix, 2, srcY[1], srcU[0], srcV[0]); - - dest += 8; - srcY += 2; - srcU++; - srcV++; - } - /* Might have one odd column left to do */ - if (odd_width) { - dest[0] = b_alpha; - dest[1] = APPLY_MATRIX (matrix, 0, srcY[0], srcU[0], srcV[0]); - dest[2] = APPLY_MATRIX (matrix, 1, srcY[0], srcU[0], srcV[0]); - dest[3] = APPLY_MATRIX (matrix, 2, srcY[0], srcU[0], srcV[0]); + for (j = 0; j < width; j++) { + a = b_alpha; + y = srcY[0]; + u = srcU[0]; + v = srcV[0]; + + dest[0] = a; + dest[1] = APPLY_MATRIX (matrix, 0, y, u, v); + dest[2] = APPLY_MATRIX (matrix, 1, y, u, v); + dest[3] = APPLY_MATRIX (matrix, 2, y, u, v); dest += 4; srcY++; + if ((j + 1) % h_subs == 0) { + srcU++; + srcV++; + } } - if (i % 2 == 0) { - srcU -= width / 2; - srcV -= width / 2; + + srcY_tmp = srcY = srcY_tmp + y_stride; + if ((i + 1) % v_subs == 0) { + srcU_tmp = srcU = srcU_tmp + uv_stride; + srcV_tmp = srcV = srcV_tmp + uv_stride; } else { - srcU += src_uv_wrap; - srcV += src_uv_wrap; + srcU = srcU_tmp; + srcV = srcV_tmp; } - srcY += src_wrap; } } } -static inline void -gst_alpha_chromakey_row_i420_ayuv (GstAlpha * alpha, guint8 * dest1, - guint8 * dest2, const guint8 * srcY1, const guint8 * srcY2, - const guint8 * srcU, const guint8 * srcV, gint width) +static void +gst_alpha_chroma_key_planar_yuv_ayuv (const guint8 * src, guint8 * dest, + gint width, gint height, GstAlpha * alpha) { - gint xpos; - gint a, a2, u, v; - gint smin, smax; + gint b_alpha = CLAMP ((gint) (alpha->alpha * 255), 0, 255); + const guint8 *srcY, *srcY_tmp; + const guint8 *srcU, *srcU_tmp; + const guint8 *srcV, *srcV_tmp; + gint i, j; + gint a, y, u, v; + gint y_stride, uv_stride; + gint v_subs, h_subs; + gint smin = 128 - alpha->black_sensitivity; + gint smax = 128 + alpha->white_sensitivity; gint8 cb = alpha->cb, cr = alpha->cr; gint8 kg = alpha->kg; guint8 accept_angle_tg = alpha->accept_angle_tg; @@ -1524,177 +1396,334 @@ gst_alpha_chromakey_row_i420_ayuv (GstAlpha * alpha, guint8 * dest1, guint8 kfgy_scale = alpha->kfgy_scale; guint noise_level2 = alpha->noise_level2; - a = CLAMP ((gint) (alpha->alpha * 255), 0, 255); - smin = 128 - alpha->black_sensitivity; - smax = 128 + alpha->white_sensitivity; + y_stride = gst_video_format_get_row_stride (alpha->in_format, 0, width); + uv_stride = gst_video_format_get_row_stride (alpha->in_format, 1, width); + + srcY_tmp = srcY = src; + srcU_tmp = srcU = + src + gst_video_format_get_component_offset (alpha->in_format, 1, width, + height); + srcV_tmp = srcV = + src + gst_video_format_get_component_offset (alpha->in_format, 2, width, + height); + + switch (alpha->in_format) { + case GST_VIDEO_FORMAT_I420: + case GST_VIDEO_FORMAT_YV12: + v_subs = h_subs = 2; + break; + case GST_VIDEO_FORMAT_Y444: + v_subs = h_subs = 1; + break; + case GST_VIDEO_FORMAT_Y42B: + v_subs = 1; + h_subs = 2; + break; + case GST_VIDEO_FORMAT_Y41B: + v_subs = 1; + h_subs = 4; + break; + default: + g_assert_not_reached (); + break; + } if (alpha->in_sdtv == alpha->out_sdtv) { - gint y[4]; + for (i = 0; i < height; i++) { + for (j = 0; j < width; j++) { + a = b_alpha; + y = srcY[0]; + u = srcU[0] - 128; + v = srcV[0] - 128; - for (xpos = 0; xpos < width / 2; xpos++) { - y[0] = srcY1[0]; - y[1] = srcY1[1]; - y[2] = srcY2[0]; - y[3] = srcY2[1]; - u = srcU[0] - 128; - v = srcV[0] - 128; + a = chroma_keying_yuv (a, &y, &u, &v, cr, cb, smin, + smax, accept_angle_tg, accept_angle_ctg, + one_over_kc, kfgy_scale, kg, noise_level2); - a2 = chroma_keying_yuv (a, y, 4, &u, &v, cr, cb, smin, - smax, accept_angle_tg, accept_angle_ctg, - one_over_kc, kfgy_scale, kg, noise_level2); + u += 128; + v += 128; - u += 128; - v += 128; + dest[0] = a; + dest[1] = y; + dest[2] = u; + dest[3] = v; - dest1[0] = a2; - dest1[1] = y[0]; - dest1[2] = u; - dest1[3] = v; - dest1[4] = a2; - dest1[5] = y[1]; - dest1[6] = u; - dest1[7] = v; - - dest2[0] = a2; - dest2[1] = y[2]; - dest2[2] = u; - dest2[3] = v; - dest2[4] = a2; - dest2[5] = y[3]; - dest2[6] = u; - dest2[7] = v; - - srcY1 += 2; - srcY2 += 2; - srcU++; - srcV++; - dest1 += 8; - dest2 += 8; + dest += 4; + srcY++; + if ((j + 1) % h_subs == 0) { + srcU++; + srcV++; + } + } + + srcY_tmp = srcY = srcY_tmp + y_stride; + if ((i + 1) % v_subs == 0) { + srcU_tmp = srcU = srcU_tmp + uv_stride; + srcV_tmp = srcV = srcV_tmp + uv_stride; + } else { + srcU = srcU_tmp; + srcV = srcV_tmp; + } } } else { - gint matrix[12], y; + gint matrix[12]; memcpy (matrix, alpha->out_sdtv ? cog_ycbcr_hdtv_to_ycbcr_sdtv_matrix_8bit : cog_ycbcr_sdtv_to_ycbcr_hdtv_matrix_8bit, 12 * sizeof (gint)); - for (xpos = 0; xpos < width / 2; xpos++) { - y = APPLY_MATRIX (matrix, 0, srcY1[0], srcU[0], srcV[0]); - u = APPLY_MATRIX (matrix, 1, srcY1[0], srcU[0], srcV[0]) - 128; - v = APPLY_MATRIX (matrix, 2, srcY1[0], srcU[0], srcV[0]) - 128; - - a2 = chroma_keying_yuv (a, &y, 1, &u, &v, cr, cb, smin, - smax, accept_angle_tg, accept_angle_ctg, - one_over_kc, kfgy_scale, kg, noise_level2); + for (i = 0; i < height; i++) { + for (j = 0; j < width; j++) { + a = b_alpha; + y = APPLY_MATRIX (matrix, 0, srcY[0], srcU[0], srcV[0]); + u = APPLY_MATRIX (matrix, 1, srcY[0], srcU[0], srcV[0]) - 128; + v = APPLY_MATRIX (matrix, 2, srcY[0], srcU[0], srcV[0]) - 128; - u += 128; - v += 128; + a = chroma_keying_yuv (a, &y, &u, &v, cr, cb, smin, + smax, accept_angle_tg, accept_angle_ctg, + one_over_kc, kfgy_scale, kg, noise_level2); - dest1[0] = a2; - dest1[1] = y; - dest1[2] = u; - dest1[3] = v; + dest[0] = a; + dest[1] = y; + dest[2] = u + 128; + dest[3] = v + 128; - y = APPLY_MATRIX (matrix, 0, srcY1[1], srcU[0], srcV[0]); - u = APPLY_MATRIX (matrix, 1, srcY1[1], srcU[0], srcV[0]) - 128; - v = APPLY_MATRIX (matrix, 2, srcY1[1], srcU[0], srcV[0]) - 128; + dest += 4; + srcY++; + if ((j + 1) % h_subs == 0) { + srcU++; + srcV++; + } + } - a2 = chroma_keying_yuv (a, &y, 1, &u, &v, cr, cb, smin, - smax, accept_angle_tg, accept_angle_ctg, - one_over_kc, kfgy_scale, kg, noise_level2); + srcY_tmp = srcY = srcY_tmp + y_stride; + if ((i + 1) % v_subs == 0) { + srcU_tmp = srcU = srcU_tmp + uv_stride; + srcV_tmp = srcV = srcV_tmp + uv_stride; + } else { + srcU = srcU_tmp; + srcV = srcV_tmp; + } + } + } +} - u += 128; - v += 128; +static void +gst_alpha_set_planar_yuv_argb (const guint8 * src, guint8 * dest, gint width, + gint height, GstAlpha * alpha) +{ + gint b_alpha = CLAMP ((gint) (alpha->alpha * 255), 0, 255); + const guint8 *srcY; + const guint8 *srcU, *srcU_tmp; + const guint8 *srcV, *srcV_tmp; + gint i, j; + gint src_wrap, src_uv_wrap; + gint y_stride, uv_stride; + gint v_subs, h_subs; + gint matrix[12]; + gint a, y, u, v; + gint p[4]; + + p[0] = + gst_video_format_get_component_offset (alpha->out_format, 3, width, + height); + p[1] = + gst_video_format_get_component_offset (alpha->out_format, 0, width, + height); + p[2] = + gst_video_format_get_component_offset (alpha->out_format, 1, width, + height); + p[3] = + gst_video_format_get_component_offset (alpha->out_format, 2, width, + height); - dest1[4] = a2; - dest1[5] = y; - dest1[6] = u; - dest1[7] = v; + y_stride = gst_video_format_get_row_stride (alpha->in_format, 0, width); + uv_stride = gst_video_format_get_row_stride (alpha->in_format, 1, width); - y = APPLY_MATRIX (matrix, 0, srcY2[0], srcU[0], srcV[0]); - u = APPLY_MATRIX (matrix, 1, srcY2[0], srcU[0], srcV[0]) - 128; - v = APPLY_MATRIX (matrix, 2, srcY2[0], srcU[0], srcV[0]) - 128; + src_wrap = y_stride - width; + src_uv_wrap = uv_stride - (width / 2); - a2 = chroma_keying_yuv (a, &y, 1, &u, &v, cr, cb, smin, - smax, accept_angle_tg, accept_angle_ctg, - one_over_kc, kfgy_scale, kg, noise_level2); + srcY = src; + srcU_tmp = srcU = + src + gst_video_format_get_component_offset (alpha->in_format, 1, width, + height); + srcV_tmp = srcV = + src + gst_video_format_get_component_offset (alpha->in_format, 2, width, + height); + + switch (alpha->in_format) { + case GST_VIDEO_FORMAT_I420: + case GST_VIDEO_FORMAT_YV12: + v_subs = h_subs = 2; + break; + case GST_VIDEO_FORMAT_Y444: + v_subs = h_subs = 1; + break; + case GST_VIDEO_FORMAT_Y42B: + v_subs = 1; + h_subs = 2; + break; + case GST_VIDEO_FORMAT_Y41B: + v_subs = 1; + h_subs = 4; + break; + default: + g_assert_not_reached (); + break; + } - u += 128; - v += 128; + memcpy (matrix, + alpha->in_sdtv ? cog_ycbcr_to_rgb_matrix_8bit_sdtv : + cog_ycbcr_to_rgb_matrix_8bit_hdtv, 12 * sizeof (gint)); + + for (i = 0; i < height; i++) { + for (j = 0; j < width; j++) { + a = b_alpha; + y = srcY[0]; + u = srcU[0]; + v = srcV[0]; + + dest[p[0]] = a; + dest[p[1]] = APPLY_MATRIX (matrix, 0, y, u, v); + dest[p[2]] = APPLY_MATRIX (matrix, 1, y, u, v); + dest[p[3]] = APPLY_MATRIX (matrix, 2, y, u, v); + + dest += 4; + srcY++; + if ((j + 1) % h_subs == 0) { + srcU++; + srcV++; + } + } + + srcY += src_wrap; + if ((i + 1) % v_subs == 0) { + srcU_tmp = srcU += src_uv_wrap; + srcV_tmp = srcV += src_uv_wrap; + } else { + srcU = srcU_tmp; + srcV = srcV_tmp; + } + } +} + +static void +gst_alpha_chroma_key_planar_yuv_argb (const guint8 * src, guint8 * dest, + gint width, gint height, GstAlpha * alpha) +{ + gint b_alpha = CLAMP ((gint) (alpha->alpha * 255), 0, 255); + const guint8 *srcY; + const guint8 *srcU, *srcU_tmp; + const guint8 *srcV, *srcV_tmp; + gint i, j; + gint a, y, u, v; + gint src_wrap, src_uv_wrap; + gint y_stride, uv_stride; + gint v_subs, h_subs; + gint smin = 128 - alpha->black_sensitivity; + gint smax = 128 + alpha->white_sensitivity; + gint8 cb = alpha->cb, cr = alpha->cr; + gint8 kg = alpha->kg; + guint8 accept_angle_tg = alpha->accept_angle_tg; + guint8 accept_angle_ctg = alpha->accept_angle_ctg; + guint8 one_over_kc = alpha->one_over_kc; + guint8 kfgy_scale = alpha->kfgy_scale; + guint noise_level2 = alpha->noise_level2; + gint matrix[12]; + gint p[4]; + + p[0] = + gst_video_format_get_component_offset (alpha->out_format, 3, width, + height); + p[1] = + gst_video_format_get_component_offset (alpha->out_format, 0, width, + height); + p[2] = + gst_video_format_get_component_offset (alpha->out_format, 1, width, + height); + p[3] = + gst_video_format_get_component_offset (alpha->out_format, 2, width, + height); + + y_stride = gst_video_format_get_row_stride (alpha->in_format, 0, width); + uv_stride = gst_video_format_get_row_stride (alpha->in_format, 1, width); + + src_wrap = y_stride - width; + src_uv_wrap = uv_stride - (width / 2); + + srcY = src; + srcU_tmp = srcU = + src + gst_video_format_get_component_offset (alpha->in_format, 1, width, + height); + srcV_tmp = srcV = + src + gst_video_format_get_component_offset (alpha->in_format, 2, width, + height); + + switch (alpha->in_format) { + case GST_VIDEO_FORMAT_I420: + case GST_VIDEO_FORMAT_YV12: + v_subs = h_subs = 2; + break; + case GST_VIDEO_FORMAT_Y444: + v_subs = h_subs = 1; + break; + case GST_VIDEO_FORMAT_Y42B: + v_subs = 1; + h_subs = 2; + break; + case GST_VIDEO_FORMAT_Y41B: + v_subs = 1; + h_subs = 4; + break; + default: + g_assert_not_reached (); + break; + } - dest2[0] = a2; - dest2[1] = y; - dest2[2] = u; - dest2[3] = v; + memcpy (matrix, + alpha->in_sdtv ? cog_ycbcr_to_rgb_matrix_8bit_sdtv : + cog_ycbcr_to_rgb_matrix_8bit_hdtv, 12 * sizeof (gint)); - y = APPLY_MATRIX (matrix, 0, srcY2[1], srcU[0], srcV[0]); - u = APPLY_MATRIX (matrix, 1, srcY2[1], srcU[0], srcV[0]) - 128; - v = APPLY_MATRIX (matrix, 2, srcY2[1], srcU[0], srcV[0]) - 128; + for (i = 0; i < height; i++) { + for (j = 0; j < width; j++) { + a = b_alpha; + y = srcY[0]; + u = srcU[0] - 128; + v = srcV[0] - 128; - a2 = chroma_keying_yuv (a, &y, 1, &u, &v, cr, cb, smin, + a = chroma_keying_yuv (a, &y, &u, &v, cr, cb, smin, smax, accept_angle_tg, accept_angle_ctg, one_over_kc, kfgy_scale, kg, noise_level2); u += 128; v += 128; - dest2[4] = a2; - dest2[5] = y; - dest2[6] = u; - dest2[7] = v; - - srcY1 += 2; - srcY2 += 2; - srcU++; - srcV++; - dest1 += 8; - dest2 += 8; + dest[0] = a; + dest[1] = APPLY_MATRIX (matrix, 0, y, u, v); + dest[2] = APPLY_MATRIX (matrix, 1, y, u, v); + dest[3] = APPLY_MATRIX (matrix, 2, y, u, v); + + dest += 4; + srcY++; + if ((j + 1) % h_subs == 0) { + srcU++; + srcV++; + } } - } -} -static void -gst_alpha_chroma_key_i420_ayuv (const guint8 * src, guint8 * dest, - gint width, gint height, GstAlpha * alpha) -{ - const guint8 *srcY1, *srcY2, *srcU, *srcV; - guint8 *dest1, *dest2; - gint ypos; - gint dest_stride, src_y_stride, src_uv_stride; - - dest_stride = - gst_video_format_get_row_stride (GST_VIDEO_FORMAT_AYUV, 0, width); - src_y_stride = gst_video_format_get_row_stride (alpha->in_format, 0, width); - src_uv_stride = gst_video_format_get_row_stride (alpha->in_format, 1, width); - - srcY1 = src; - srcY2 = src + src_y_stride; - - srcU = src + gst_video_format_get_component_offset (alpha->in_format, - 1, width, height); - srcV = src + gst_video_format_get_component_offset (alpha->in_format, - 2, width, height); - - dest1 = dest; - dest2 = dest + dest_stride; - - /* Redefine Y strides to skip 2 lines at a time ... */ - dest_stride *= 2; - src_y_stride *= 2; - - for (ypos = 0; ypos < height / 2; ypos++) { - gst_alpha_chromakey_row_i420_ayuv (alpha, dest1, dest2, - srcY1, srcY2, srcU, srcV, width); - - dest1 += dest_stride; - dest2 += dest_stride; - srcY1 += src_y_stride; - srcY2 += src_y_stride; - srcU += src_uv_stride; - srcV += src_uv_stride; + srcY += src_wrap; + if ((i + 1) % v_subs == 0) { + srcU_tmp = srcU += src_uv_wrap; + srcV_tmp = srcV += src_uv_wrap; + } else { + srcU = srcU_tmp; + srcV = srcV_tmp; + } } } + + static void gst_alpha_init_params (GstAlpha * alpha) { @@ -1775,217 +1804,65 @@ gst_alpha_set_process_function (GstAlpha * alpha) case GST_VIDEO_FORMAT_AYUV: alpha->process = gst_alpha_set_ayuv_ayuv; break; + case GST_VIDEO_FORMAT_Y444: + case GST_VIDEO_FORMAT_Y42B: case GST_VIDEO_FORMAT_I420: case GST_VIDEO_FORMAT_YV12: - alpha->process = gst_alpha_set_i420_ayuv; + case GST_VIDEO_FORMAT_Y41B: + alpha->process = gst_alpha_set_planar_yuv_ayuv; break; case GST_VIDEO_FORMAT_ARGB: - alpha->process = gst_alpha_set_argb_ayuv; - break; case GST_VIDEO_FORMAT_ABGR: - alpha->process = gst_alpha_set_abgr_ayuv; - break; case GST_VIDEO_FORMAT_RGBA: - alpha->process = gst_alpha_set_rgba_ayuv; - break; case GST_VIDEO_FORMAT_BGRA: - alpha->process = gst_alpha_set_bgra_ayuv; + alpha->process = gst_alpha_set_argb_ayuv; break; case GST_VIDEO_FORMAT_xRGB: - alpha->process = gst_alpha_set_xrgb_ayuv; - break; case GST_VIDEO_FORMAT_xBGR: - alpha->process = gst_alpha_set_xbgr_ayuv; - break; case GST_VIDEO_FORMAT_RGBx: - alpha->process = gst_alpha_set_rgbx_ayuv; - break; case GST_VIDEO_FORMAT_BGRx: - alpha->process = gst_alpha_set_bgrx_ayuv; - break; case GST_VIDEO_FORMAT_RGB: - alpha->process = gst_alpha_set_rgb_ayuv; - break; case GST_VIDEO_FORMAT_BGR: - alpha->process = gst_alpha_set_bgr_ayuv; + alpha->process = gst_alpha_set_rgb_ayuv; break; - default: break; } break; case GST_VIDEO_FORMAT_ARGB: - switch (alpha->in_format) { - case GST_VIDEO_FORMAT_AYUV: - alpha->process = gst_alpha_set_ayuv_argb; - break; - case GST_VIDEO_FORMAT_I420: - case GST_VIDEO_FORMAT_YV12: - alpha->process = gst_alpha_set_i420_argb; - break; - case GST_VIDEO_FORMAT_ARGB: - alpha->process = gst_alpha_set_argb_argb; - break; - case GST_VIDEO_FORMAT_ABGR: - alpha->process = gst_alpha_set_abgr_argb; - break; - case GST_VIDEO_FORMAT_RGBA: - alpha->process = gst_alpha_set_rgba_argb; - break; - case GST_VIDEO_FORMAT_BGRA: - alpha->process = gst_alpha_set_bgra_argb; - break; - case GST_VIDEO_FORMAT_xRGB: - alpha->process = gst_alpha_set_xrgb_argb; - break; - case GST_VIDEO_FORMAT_xBGR: - alpha->process = gst_alpha_set_xbgr_argb; - break; - case GST_VIDEO_FORMAT_RGBx: - alpha->process = gst_alpha_set_rgbx_argb; - break; - case GST_VIDEO_FORMAT_BGRx: - alpha->process = gst_alpha_set_bgrx_argb; - break; - case GST_VIDEO_FORMAT_RGB: - alpha->process = gst_alpha_set_rgb_argb; - break; - case GST_VIDEO_FORMAT_BGR: - alpha->process = gst_alpha_set_bgr_argb; - break; - default: - break; - } - break; case GST_VIDEO_FORMAT_ABGR: - switch (alpha->in_format) { - case GST_VIDEO_FORMAT_AYUV: - alpha->process = gst_alpha_set_ayuv_abgr; - break; - case GST_VIDEO_FORMAT_I420: - case GST_VIDEO_FORMAT_YV12: - alpha->process = gst_alpha_set_i420_abgr; - break; - case GST_VIDEO_FORMAT_ARGB: - alpha->process = gst_alpha_set_argb_abgr; - break; - case GST_VIDEO_FORMAT_ABGR: - alpha->process = gst_alpha_set_abgr_abgr; - break; - case GST_VIDEO_FORMAT_RGBA: - alpha->process = gst_alpha_set_rgba_abgr; - break; - case GST_VIDEO_FORMAT_BGRA: - alpha->process = gst_alpha_set_bgra_abgr; - break; - case GST_VIDEO_FORMAT_xRGB: - alpha->process = gst_alpha_set_xrgb_abgr; - break; - case GST_VIDEO_FORMAT_xBGR: - alpha->process = gst_alpha_set_xbgr_abgr; - break; - case GST_VIDEO_FORMAT_RGBx: - alpha->process = gst_alpha_set_rgbx_abgr; - break; - case GST_VIDEO_FORMAT_BGRx: - alpha->process = gst_alpha_set_bgrx_abgr; - break; - case GST_VIDEO_FORMAT_RGB: - alpha->process = gst_alpha_set_rgb_abgr; - break; - case GST_VIDEO_FORMAT_BGR: - alpha->process = gst_alpha_set_bgr_abgr; - break; - default: - break; - } - break; case GST_VIDEO_FORMAT_RGBA: - switch (alpha->in_format) { - case GST_VIDEO_FORMAT_AYUV: - alpha->process = gst_alpha_set_ayuv_rgba; - break; - case GST_VIDEO_FORMAT_I420: - case GST_VIDEO_FORMAT_YV12: - alpha->process = gst_alpha_set_i420_rgba; - break; - case GST_VIDEO_FORMAT_ARGB: - alpha->process = gst_alpha_set_argb_rgba; - break; - case GST_VIDEO_FORMAT_ABGR: - alpha->process = gst_alpha_set_abgr_rgba; - break; - case GST_VIDEO_FORMAT_RGBA: - alpha->process = gst_alpha_set_rgba_rgba; - break; - case GST_VIDEO_FORMAT_BGRA: - alpha->process = gst_alpha_set_bgra_rgba; - break; - case GST_VIDEO_FORMAT_xRGB: - alpha->process = gst_alpha_set_xrgb_rgba; - break; - case GST_VIDEO_FORMAT_xBGR: - alpha->process = gst_alpha_set_xbgr_rgba; - break; - case GST_VIDEO_FORMAT_RGBx: - alpha->process = gst_alpha_set_rgbx_rgba; - break; - case GST_VIDEO_FORMAT_BGRx: - alpha->process = gst_alpha_set_bgrx_rgba; - break; - case GST_VIDEO_FORMAT_RGB: - alpha->process = gst_alpha_set_rgb_rgba; - break; - case GST_VIDEO_FORMAT_BGR: - alpha->process = gst_alpha_set_bgr_rgba; - break; - default: - break; - } - break; case GST_VIDEO_FORMAT_BGRA: switch (alpha->in_format) { case GST_VIDEO_FORMAT_AYUV: - alpha->process = gst_alpha_set_ayuv_bgra; + alpha->process = gst_alpha_set_ayuv_argb; break; + case GST_VIDEO_FORMAT_Y444: + case GST_VIDEO_FORMAT_Y42B: case GST_VIDEO_FORMAT_I420: case GST_VIDEO_FORMAT_YV12: - alpha->process = gst_alpha_set_i420_bgra; + case GST_VIDEO_FORMAT_Y41B: + alpha->process = gst_alpha_set_planar_yuv_argb; break; case GST_VIDEO_FORMAT_ARGB: - alpha->process = gst_alpha_set_argb_bgra; - break; case GST_VIDEO_FORMAT_ABGR: - alpha->process = gst_alpha_set_abgr_bgra; - break; case GST_VIDEO_FORMAT_RGBA: - alpha->process = gst_alpha_set_rgba_bgra; - break; case GST_VIDEO_FORMAT_BGRA: - alpha->process = gst_alpha_set_bgra_bgra; + alpha->process = gst_alpha_set_argb_argb; break; case GST_VIDEO_FORMAT_xRGB: - alpha->process = gst_alpha_set_xrgb_bgra; - break; case GST_VIDEO_FORMAT_xBGR: - alpha->process = gst_alpha_set_xbgr_bgra; - break; case GST_VIDEO_FORMAT_RGBx: - alpha->process = gst_alpha_set_rgbx_bgra; - break; case GST_VIDEO_FORMAT_BGRx: - alpha->process = gst_alpha_set_bgrx_bgra; - break; case GST_VIDEO_FORMAT_RGB: - alpha->process = gst_alpha_set_rgb_bgra; - break; case GST_VIDEO_FORMAT_BGR: - alpha->process = gst_alpha_set_bgr_bgra; + alpha->process = gst_alpha_set_rgb_argb; break; default: break; } break; + break; default: break; } @@ -1999,216 +1876,65 @@ gst_alpha_set_process_function (GstAlpha * alpha) case GST_VIDEO_FORMAT_AYUV: alpha->process = gst_alpha_chroma_key_ayuv_ayuv; break; + case GST_VIDEO_FORMAT_Y444: + case GST_VIDEO_FORMAT_Y42B: case GST_VIDEO_FORMAT_I420: case GST_VIDEO_FORMAT_YV12: - alpha->process = gst_alpha_chroma_key_i420_ayuv; + case GST_VIDEO_FORMAT_Y41B: + alpha->process = gst_alpha_chroma_key_planar_yuv_ayuv; break; case GST_VIDEO_FORMAT_ARGB: - alpha->process = gst_alpha_chroma_key_argb_ayuv; - break; case GST_VIDEO_FORMAT_ABGR: - alpha->process = gst_alpha_chroma_key_abgr_ayuv; - break; case GST_VIDEO_FORMAT_RGBA: - alpha->process = gst_alpha_chroma_key_rgba_ayuv; - break; case GST_VIDEO_FORMAT_BGRA: - alpha->process = gst_alpha_chroma_key_bgra_ayuv; + alpha->process = gst_alpha_chroma_key_argb_ayuv; break; case GST_VIDEO_FORMAT_xRGB: - alpha->process = gst_alpha_chroma_key_xrgb_ayuv; - break; case GST_VIDEO_FORMAT_xBGR: - alpha->process = gst_alpha_chroma_key_xbgr_ayuv; - break; case GST_VIDEO_FORMAT_RGBx: - alpha->process = gst_alpha_chroma_key_rgbx_ayuv; - break; case GST_VIDEO_FORMAT_BGRx: - alpha->process = gst_alpha_chroma_key_bgrx_ayuv; - break; case GST_VIDEO_FORMAT_RGB: - alpha->process = gst_alpha_chroma_key_rgb_ayuv; - break; case GST_VIDEO_FORMAT_BGR: - alpha->process = gst_alpha_chroma_key_bgr_ayuv; + alpha->process = gst_alpha_chroma_key_rgb_ayuv; break; default: break; } break; case GST_VIDEO_FORMAT_ARGB: - switch (alpha->in_format) { - case GST_VIDEO_FORMAT_AYUV: - alpha->process = gst_alpha_chroma_key_ayuv_argb; - break; - case GST_VIDEO_FORMAT_I420: - case GST_VIDEO_FORMAT_YV12: - alpha->process = gst_alpha_chroma_key_i420_argb; - break; - case GST_VIDEO_FORMAT_ARGB: - alpha->process = gst_alpha_chroma_key_argb_argb; - break; - case GST_VIDEO_FORMAT_ABGR: - alpha->process = gst_alpha_chroma_key_abgr_argb; - break; - case GST_VIDEO_FORMAT_RGBA: - alpha->process = gst_alpha_chroma_key_rgba_argb; - break; - case GST_VIDEO_FORMAT_BGRA: - alpha->process = gst_alpha_chroma_key_bgra_argb; - break; - case GST_VIDEO_FORMAT_xRGB: - alpha->process = gst_alpha_chroma_key_xrgb_argb; - break; - case GST_VIDEO_FORMAT_xBGR: - alpha->process = gst_alpha_chroma_key_xbgr_argb; - break; - case GST_VIDEO_FORMAT_RGBx: - alpha->process = gst_alpha_chroma_key_rgbx_argb; - break; - case GST_VIDEO_FORMAT_BGRx: - alpha->process = gst_alpha_chroma_key_bgrx_argb; - break; - case GST_VIDEO_FORMAT_RGB: - alpha->process = gst_alpha_chroma_key_rgb_argb; - break; - case GST_VIDEO_FORMAT_BGR: - alpha->process = gst_alpha_chroma_key_bgr_argb; - break; - default: - break; - } - break; case GST_VIDEO_FORMAT_ABGR: - switch (alpha->in_format) { - case GST_VIDEO_FORMAT_AYUV: - alpha->process = gst_alpha_chroma_key_ayuv_abgr; - break; - case GST_VIDEO_FORMAT_I420: - case GST_VIDEO_FORMAT_YV12: - alpha->process = gst_alpha_chroma_key_i420_abgr; - break; - case GST_VIDEO_FORMAT_ARGB: - alpha->process = gst_alpha_chroma_key_argb_abgr; - break; - case GST_VIDEO_FORMAT_ABGR: - alpha->process = gst_alpha_chroma_key_abgr_abgr; - break; - case GST_VIDEO_FORMAT_RGBA: - alpha->process = gst_alpha_chroma_key_rgba_abgr; - break; - case GST_VIDEO_FORMAT_BGRA: - alpha->process = gst_alpha_chroma_key_bgra_abgr; - break; - case GST_VIDEO_FORMAT_xRGB: - alpha->process = gst_alpha_chroma_key_xrgb_abgr; - break; - case GST_VIDEO_FORMAT_xBGR: - alpha->process = gst_alpha_chroma_key_xbgr_abgr; - break; - case GST_VIDEO_FORMAT_RGBx: - alpha->process = gst_alpha_chroma_key_rgbx_abgr; - break; - case GST_VIDEO_FORMAT_BGRx: - alpha->process = gst_alpha_chroma_key_bgrx_abgr; - break; - case GST_VIDEO_FORMAT_RGB: - alpha->process = gst_alpha_chroma_key_rgb_abgr; - break; - case GST_VIDEO_FORMAT_BGR: - alpha->process = gst_alpha_chroma_key_bgr_abgr; - break; - default: - break; - } - break; case GST_VIDEO_FORMAT_RGBA: - switch (alpha->in_format) { - case GST_VIDEO_FORMAT_AYUV: - alpha->process = gst_alpha_chroma_key_ayuv_rgba; - break; - case GST_VIDEO_FORMAT_I420: - case GST_VIDEO_FORMAT_YV12: - alpha->process = gst_alpha_chroma_key_i420_rgba; - break; - case GST_VIDEO_FORMAT_ARGB: - alpha->process = gst_alpha_chroma_key_argb_rgba; - break; - case GST_VIDEO_FORMAT_ABGR: - alpha->process = gst_alpha_chroma_key_abgr_rgba; - break; - case GST_VIDEO_FORMAT_RGBA: - alpha->process = gst_alpha_chroma_key_rgba_rgba; - break; - case GST_VIDEO_FORMAT_BGRA: - alpha->process = gst_alpha_chroma_key_bgra_rgba; - break; - case GST_VIDEO_FORMAT_xRGB: - alpha->process = gst_alpha_chroma_key_xrgb_rgba; - break; - case GST_VIDEO_FORMAT_xBGR: - alpha->process = gst_alpha_chroma_key_xbgr_rgba; - break; - case GST_VIDEO_FORMAT_RGBx: - alpha->process = gst_alpha_chroma_key_rgbx_rgba; - break; - case GST_VIDEO_FORMAT_BGRx: - alpha->process = gst_alpha_chroma_key_bgrx_rgba; - break; - case GST_VIDEO_FORMAT_RGB: - alpha->process = gst_alpha_chroma_key_rgb_rgba; - break; - case GST_VIDEO_FORMAT_BGR: - alpha->process = gst_alpha_chroma_key_bgr_rgba; - break; - default: - break; - } - break; case GST_VIDEO_FORMAT_BGRA: switch (alpha->in_format) { case GST_VIDEO_FORMAT_AYUV: - alpha->process = gst_alpha_chroma_key_ayuv_bgra; + alpha->process = gst_alpha_chroma_key_ayuv_argb; break; + case GST_VIDEO_FORMAT_Y444: + case GST_VIDEO_FORMAT_Y42B: case GST_VIDEO_FORMAT_I420: case GST_VIDEO_FORMAT_YV12: - alpha->process = gst_alpha_chroma_key_i420_bgra; + case GST_VIDEO_FORMAT_Y41B: + alpha->process = gst_alpha_chroma_key_planar_yuv_argb; break; case GST_VIDEO_FORMAT_ARGB: - alpha->process = gst_alpha_chroma_key_argb_bgra; - break; case GST_VIDEO_FORMAT_ABGR: - alpha->process = gst_alpha_chroma_key_abgr_bgra; - break; case GST_VIDEO_FORMAT_RGBA: - alpha->process = gst_alpha_chroma_key_rgba_bgra; - break; case GST_VIDEO_FORMAT_BGRA: - alpha->process = gst_alpha_chroma_key_bgra_bgra; + alpha->process = gst_alpha_chroma_key_argb_argb; break; case GST_VIDEO_FORMAT_xRGB: - alpha->process = gst_alpha_chroma_key_xrgb_bgra; - break; case GST_VIDEO_FORMAT_xBGR: - alpha->process = gst_alpha_chroma_key_xbgr_bgra; - break; case GST_VIDEO_FORMAT_RGBx: - alpha->process = gst_alpha_chroma_key_rgbx_bgra; - break; case GST_VIDEO_FORMAT_BGRx: - alpha->process = gst_alpha_chroma_key_bgrx_bgra; - break; case GST_VIDEO_FORMAT_RGB: - alpha->process = gst_alpha_chroma_key_rgb_bgra; - break; case GST_VIDEO_FORMAT_BGR: - alpha->process = gst_alpha_chroma_key_bgr_bgra; + alpha->process = gst_alpha_chroma_key_rgb_argb; break; default: break; } break; + break; default: break; } -- 2.7.4