From 545b21c9bd2c01c1307cc81ce94b03a9096cd7a4 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Sebastian=20Dr=C3=B6ge?= Date: Thu, 22 Apr 2010 15:20:24 +0200 Subject: [PATCH] alpha: Add support for YUY2, YVYU and UYVY --- gst/alpha/gstalpha.c | 504 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 503 insertions(+), 1 deletion(-) diff --git a/gst/alpha/gstalpha.c b/gst/alpha/gstalpha.c index 956c215..5265f81 100644 --- a/gst/alpha/gstalpha.c +++ b/gst/alpha/gstalpha.c @@ -140,7 +140,8 @@ static GstStaticPadTemplate gst_alpha_sink_template = ";" 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 ("Y42B") ";" + ";" GST_VIDEO_CAPS_YUV ("Y42B") ";" GST_VIDEO_CAPS_YUV ("YUY2") + ";" GST_VIDEO_CAPS_YUV ("YVYU") ";" GST_VIDEO_CAPS_YUV ("UYVY") ";" GST_VIDEO_CAPS_YUV ("I420") ";" GST_VIDEO_CAPS_YUV ("YV12") ";" GST_VIDEO_CAPS_YUV ("Y41B") ) @@ -1722,7 +1723,488 @@ gst_alpha_chroma_key_planar_yuv_argb (const guint8 * src, guint8 * dest, } } +static void +gst_alpha_set_packed_422_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 y, u, v; + gint p[4]; /* Y U Y V */ + gint src_stride; + const guint8 *src_tmp; + + src_stride = gst_video_format_get_row_stride (alpha->in_format, 0, width); + + p[0] = + gst_video_format_get_component_offset (alpha->in_format, 0, width, + height); + p[2] = p[0] + 2; + p[1] = + gst_video_format_get_component_offset (alpha->in_format, 1, width, + height); + p[3] = + gst_video_format_get_component_offset (alpha->in_format, 2, width, + height); + + if (alpha->in_sdtv != alpha->out_sdtv) { + gint matrix[12]; + + memcpy (matrix, + alpha->in_sdtv ? cog_ycbcr_sdtv_to_ycbcr_hdtv_matrix_8bit : + cog_ycbcr_hdtv_to_ycbcr_sdtv_matrix_8bit, 12 * sizeof (gint)); + + for (i = 0; i < height; i++) { + src_tmp = src; + + for (j = 0; j < width - 1; j += 2) { + dest[0] = s_alpha; + dest[4] = s_alpha; + + y = APPLY_MATRIX (matrix, 0, src[p[0]], src[p[1]], src[p[3]]); + u = APPLY_MATRIX (matrix, 1, src[p[0]], src[p[1]], src[p[3]]); + v = APPLY_MATRIX (matrix, 2, src[p[0]], src[p[1]], src[p[3]]); + + dest[1] = y; + dest[2] = u; + dest[3] = v; + + y = APPLY_MATRIX (matrix, 0, src[p[2]], src[p[1]], src[p[3]]); + u = APPLY_MATRIX (matrix, 1, src[p[2]], src[p[1]], src[p[3]]); + v = APPLY_MATRIX (matrix, 2, src[p[2]], src[p[1]], src[p[3]]); + + dest[5] = y; + dest[6] = u; + dest[7] = v; + + dest += 8; + src += 4; + } + + if (j == width - 1) { + dest[0] = s_alpha; + + y = APPLY_MATRIX (matrix, 0, src[p[0]], src[p[1]], src[p[3]]); + u = APPLY_MATRIX (matrix, 1, src[p[0]], src[p[1]], src[p[3]]); + v = APPLY_MATRIX (matrix, 2, src[p[0]], src[p[1]], src[p[3]]); + + dest[1] = y; + dest[2] = u; + dest[3] = v; + + dest += 4; + } + + src = src_tmp + src_stride; + } + } else { + for (i = 0; i < height; i++) { + src_tmp = src; + + for (j = 0; j < width - 1; j += 2) { + dest[0] = s_alpha; + dest[4] = s_alpha; + + y = src[p[0]]; + u = src[p[1]]; + v = src[p[3]];; + + dest[1] = y; + dest[2] = u; + dest[3] = v; + + y = src[p[2]]; + + dest[5] = y; + dest[6] = u; + dest[7] = v; + + dest += 8; + src += 4; + } + + if (j == width - 1) { + dest[0] = s_alpha; + + y = src[p[0]]; + u = src[p[1]]; + v = src[p[3]];; + + dest[1] = y; + dest[2] = u; + dest[3] = v; + + dest += 4; + } + + src = src_tmp + src_stride; + } + } +} + +static void +gst_alpha_chroma_key_packed_422_ayuv (const guint8 * src, guint8 * dest, + gint width, gint height, GstAlpha * alpha) +{ + gint i, j; + gint a, y, u, v; + 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 p[4]; /* Y U Y V */ + gint src_stride; + const guint8 *src_tmp; + + src_stride = gst_video_format_get_row_stride (alpha->in_format, 0, width); + + p[0] = + gst_video_format_get_component_offset (alpha->in_format, 0, width, + height); + p[2] = p[0] + 2; + p[1] = + gst_video_format_get_component_offset (alpha->in_format, 1, width, + height); + p[3] = + gst_video_format_get_component_offset (alpha->in_format, 2, width, + height); + + smin = 128 - alpha->black_sensitivity; + smax = 128 + alpha->white_sensitivity; + + if (alpha->in_sdtv != alpha->out_sdtv) { + gint matrix[12]; + + memcpy (matrix, + alpha->in_sdtv ? cog_ycbcr_sdtv_to_ycbcr_hdtv_matrix_8bit : + cog_ycbcr_hdtv_to_ycbcr_sdtv_matrix_8bit, 12 * sizeof (gint)); + + for (i = 0; i < height; i++) { + src_tmp = src; + + for (j = 0; j < width - 1; j += 2) { + y = APPLY_MATRIX (matrix, 0, src[p[0]], src[p[1]], src[p[3]]); + u = APPLY_MATRIX (matrix, 1, src[p[0]], src[p[1]], src[p[3]]) - 128; + v = APPLY_MATRIX (matrix, 2, src[p[0]], src[p[1]], src[p[3]]) - 128; + + a = chroma_keying_yuv (pa, &y, &u, &v, cr, cb, + smin, smax, accept_angle_tg, accept_angle_ctg, + one_over_kc, kfgy_scale, kg, noise_level2); + + dest[0] = a; + dest[1] = y; + dest[2] = u + 128; + dest[3] = v + 128; + + y = APPLY_MATRIX (matrix, 0, src[p[2]], src[p[1]], src[p[3]]); + u = APPLY_MATRIX (matrix, 1, src[p[2]], src[p[1]], src[p[3]]) - 128; + v = APPLY_MATRIX (matrix, 2, src[p[2]], src[p[1]], src[p[3]]) - 128; + + a = chroma_keying_yuv (pa, &y, &u, &v, cr, cb, + smin, smax, accept_angle_tg, accept_angle_ctg, + one_over_kc, kfgy_scale, kg, noise_level2); + + dest[4] = a; + dest[5] = y; + dest[6] = u + 128; + dest[7] = v + 128; + + dest += 8; + src += 4; + } + + if (j == width - 1) { + y = APPLY_MATRIX (matrix, 0, src[p[0]], src[p[1]], src[p[3]]); + u = APPLY_MATRIX (matrix, 1, src[p[0]], src[p[1]], src[p[3]]) - 128; + v = APPLY_MATRIX (matrix, 2, src[p[0]], src[p[1]], src[p[3]]) - 128; + + a = chroma_keying_yuv (pa, &y, &u, &v, cr, cb, + smin, smax, accept_angle_tg, accept_angle_ctg, + one_over_kc, kfgy_scale, kg, noise_level2); + + dest[0] = a; + dest[1] = y; + dest[2] = u + 128; + dest[3] = v + 128; + + dest += 4; + } + + src = src_tmp + src_stride; + } + } else { + for (i = 0; i < height; i++) { + src_tmp = src; + + for (j = 0; j < width - 1; j += 2) { + y = src[p[0]]; + u = src[p[1]] - 128; + v = src[p[3]] - 128; + + a = chroma_keying_yuv (pa, &y, &u, &v, cr, cb, + smin, smax, accept_angle_tg, accept_angle_ctg, + one_over_kc, kfgy_scale, kg, noise_level2); + + dest[0] = a; + dest[1] = y; + dest[2] = u + 128; + dest[3] = v + 128; + + y = src[p[2]]; + u = src[p[1]] - 128; + v = src[p[3]] - 128; + + a = chroma_keying_yuv (pa, &y, &u, &v, cr, cb, + smin, smax, accept_angle_tg, accept_angle_ctg, + one_over_kc, kfgy_scale, kg, noise_level2); + + dest[4] = a; + dest[5] = y; + dest[6] = u + 128; + dest[7] = v + 128; + + dest += 8; + src += 4; + } + + if (j == width - 1) { + y = src[p[0]]; + u = src[p[1]] - 128; + v = src[p[3]] - 128; + + a = chroma_keying_yuv (pa, &y, &u, &v, cr, cb, + smin, smax, accept_angle_tg, accept_angle_ctg, + one_over_kc, kfgy_scale, kg, noise_level2); + + dest[0] = a; + dest[1] = y; + dest[2] = u + 128; + dest[3] = v + 128; + + dest += 4; + } + + src = src_tmp + src_stride; + } + } +} + +static void +gst_alpha_set_packed_422_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[4]; + gint src_stride; + const guint8 *src_tmp; + gint matrix[12]; + gint r, g, b; + + src_stride = gst_video_format_get_row_stride (alpha->in_format, 0, width); + + o[0] = + gst_video_format_get_component_offset (alpha->in_format, 0, width, + height); + o[2] = o[0] + 2; + o[1] = + 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); + + 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 (i = 0; i < height; i++) { + src_tmp = src; + + for (j = 0; j < width - 1; j += 2) { + r = APPLY_MATRIX (matrix, 0, src[o[0]], src[o[1]], src[o[3]]); + g = APPLY_MATRIX (matrix, 1, src[o[0]], src[o[1]], src[o[3]]); + b = APPLY_MATRIX (matrix, 2, src[o[0]], src[o[1]], src[o[3]]); + + dest[p[0]] = s_alpha; + dest[p[1]] = r; + dest[p[2]] = g; + dest[p[3]] = b; + + r = APPLY_MATRIX (matrix, 0, src[o[2]], src[o[1]], src[o[3]]); + g = APPLY_MATRIX (matrix, 1, src[o[2]], src[o[1]], src[o[3]]); + b = APPLY_MATRIX (matrix, 2, src[o[2]], src[o[1]], src[o[3]]); + dest[4 + p[0]] = s_alpha; + dest[4 + p[1]] = r; + dest[4 + p[2]] = g; + dest[4 + p[3]] = b; + + dest += 8; + src += 4; + } + + if (j == width - 1) { + r = APPLY_MATRIX (matrix, 0, src[o[0]], src[o[1]], src[o[3]]); + g = APPLY_MATRIX (matrix, 1, src[o[0]], src[o[1]], src[o[3]]); + b = APPLY_MATRIX (matrix, 2, src[o[0]], src[o[1]], src[o[3]]); + + dest[p[0]] = s_alpha; + dest[p[1]] = r; + dest[p[2]] = g; + dest[p[3]] = b; + + dest += 4; + } + + src = src_tmp + src_stride; + } +} + +static void +gst_alpha_chroma_key_packed_422_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 p[4], o[4]; + gint src_stride; + const guint8 *src_tmp; + gint matrix[12]; + + src_stride = gst_video_format_get_row_stride (alpha->in_format, 0, width); + + o[0] = + gst_video_format_get_component_offset (alpha->in_format, 0, width, + height); + o[2] = o[0] + 2; + o[1] = + 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); + + 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)); + + smin = 128 - alpha->black_sensitivity; + smax = 128 + alpha->white_sensitivity; + + for (i = 0; i < height; i++) { + src_tmp = src; + + for (j = 0; j < width - 1; j += 2) { + y = src[o[0]]; + u = src[o[1]] - 128; + v = src[o[3]] - 128; + + a = chroma_keying_yuv (pa, &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]] = r; + dest[p[2]] = g; + dest[p[3]] = b; + + y = src[o[2]]; + u = src[o[1]] - 128; + v = src[o[3]] - 128; + + a = chroma_keying_yuv (pa, &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[4 + p[0]] = a; + dest[4 + p[1]] = r; + dest[4 + p[2]] = g; + dest[4 + p[3]] = b; + + dest += 8; + src += 4; + } + + if (j == width - 1) { + y = src[o[0]]; + u = src[o[1]] - 128; + v = src[o[3]] - 128; + + a = chroma_keying_yuv (pa, &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]] = r; + dest[p[2]] = g; + dest[p[3]] = b; + + dest += 4; + } + + src = src_tmp + src_stride; + } +} static void gst_alpha_init_params (GstAlpha * alpha) @@ -1811,6 +2293,11 @@ gst_alpha_set_process_function (GstAlpha * alpha) case GST_VIDEO_FORMAT_Y41B: alpha->process = gst_alpha_set_planar_yuv_ayuv; break; + case GST_VIDEO_FORMAT_YUY2: + case GST_VIDEO_FORMAT_YVYU: + case GST_VIDEO_FORMAT_UYVY: + alpha->process = gst_alpha_set_packed_422_ayuv; + break; case GST_VIDEO_FORMAT_ARGB: case GST_VIDEO_FORMAT_ABGR: case GST_VIDEO_FORMAT_RGBA: @@ -1844,6 +2331,11 @@ gst_alpha_set_process_function (GstAlpha * alpha) case GST_VIDEO_FORMAT_Y41B: alpha->process = gst_alpha_set_planar_yuv_argb; break; + case GST_VIDEO_FORMAT_YUY2: + case GST_VIDEO_FORMAT_YVYU: + case GST_VIDEO_FORMAT_UYVY: + alpha->process = gst_alpha_set_packed_422_argb; + break; case GST_VIDEO_FORMAT_ARGB: case GST_VIDEO_FORMAT_ABGR: case GST_VIDEO_FORMAT_RGBA: @@ -1883,6 +2375,11 @@ gst_alpha_set_process_function (GstAlpha * alpha) case GST_VIDEO_FORMAT_Y41B: alpha->process = gst_alpha_chroma_key_planar_yuv_ayuv; break; + case GST_VIDEO_FORMAT_YUY2: + case GST_VIDEO_FORMAT_YVYU: + case GST_VIDEO_FORMAT_UYVY: + alpha->process = gst_alpha_chroma_key_packed_422_ayuv; + break; case GST_VIDEO_FORMAT_ARGB: case GST_VIDEO_FORMAT_ABGR: case GST_VIDEO_FORMAT_RGBA: @@ -1916,6 +2413,11 @@ gst_alpha_set_process_function (GstAlpha * alpha) case GST_VIDEO_FORMAT_Y41B: alpha->process = gst_alpha_chroma_key_planar_yuv_argb; break; + case GST_VIDEO_FORMAT_YUY2: + case GST_VIDEO_FORMAT_YVYU: + case GST_VIDEO_FORMAT_UYVY: + alpha->process = gst_alpha_chroma_key_packed_422_argb; + break; case GST_VIDEO_FORMAT_ARGB: case GST_VIDEO_FORMAT_ABGR: case GST_VIDEO_FORMAT_RGBA: -- 2.7.4