From 6dd3edd0f7a68dc9e08dccf13b666788487a310d Mon Sep 17 00:00:00 2001 From: =?utf8?q?Sebastian=20Dr=C3=B6ge?= Date: Thu, 22 Apr 2010 13:56:58 +0200 Subject: [PATCH] videomixer: Add support for YUY2, YVYU, UYVY --- gst/videomixer/blend.c | 132 ++++++++++++++++++++++++++++++++++++++++++++ gst/videomixer/blend.h | 9 +++ gst/videomixer/videomixer.c | 26 ++++++++- 3 files changed, 165 insertions(+), 2 deletions(-) diff --git a/gst/videomixer/blend.c b/gst/videomixer/blend.c index ac70a2c..a5c95af 100644 --- a/gst/videomixer/blend.c +++ b/gst/videomixer/blend.c @@ -595,6 +595,121 @@ RGB_FILL_COLOR (rgbx_c, 4, _memset_rgbx_c); MEMSET_RGB_C (bgrx, 4, 2, 1, 0); RGB_FILL_COLOR (bgrx_c, 4, _memset_bgrx_c); +/* YUY2, YVYU, UYVY */ + +#define PACKED_422_BLEND(name, MEMCPY, BLENDLOOP) \ +static void \ +blend_##name (const guint8 * src, gint xpos, gint ypos, \ + gint src_width, gint src_height, gdouble src_alpha, \ + guint8 * dest, gint dest_width, gint dest_height) \ +{ \ + gint b_alpha; \ + gint i; \ + gint src_stride, dest_stride; \ + \ + src_stride = GST_ROUND_UP_4 (src_width * 2); \ + dest_stride = GST_ROUND_UP_4 (dest_width * 2); \ + \ + b_alpha = CLAMP ((gint) (src_alpha * 256), 0, 256); \ + \ + xpos = GST_ROUND_UP_2 (xpos); \ + \ + /* adjust src pointers for negative sizes */ \ + if (xpos < 0) { \ + src += -xpos * 2; \ + src_width -= -xpos; \ + xpos = 0; \ + } \ + if (ypos < 0) { \ + src += -ypos * src_stride; \ + src_height -= -ypos; \ + ypos = 0; \ + } \ + \ + /* adjust width/height if the src is bigger than dest */ \ + if (xpos + src_width > dest_width) { \ + src_width = dest_width - xpos; \ + } \ + if (ypos + src_height > dest_height) { \ + src_height = dest_height - ypos; \ + } \ + \ + dest = dest + 2 * xpos + (ypos * dest_stride); \ + /* If it's completely transparent... we just return */ \ + if (G_UNLIKELY (src_alpha == 0.0)) { \ + GST_INFO ("Fast copy (alpha == 0.0)"); \ + return; \ + } \ + \ + /* If it's completely opaque, we do a fast copy */ \ + if (G_UNLIKELY (src_alpha == 1.0)) { \ + GST_INFO ("Fast copy (alpha == 1.0)"); \ + for (i = 0; i < src_height; i++) { \ + MEMCPY (dest, src, 2 * src_width); \ + src += src_stride; \ + dest += dest_stride; \ + } \ + return; \ + } \ + \ + BLENDLOOP(dest, src, src_stride, dest_stride, 2 * src_width, src_height, 2 * dest_width, b_alpha); \ +} + +#define PACKED_422_FILL_CHECKER_C(name, Y1, U, Y2, V) \ +static void \ +fill_checker_##name##_c (guint8 * dest, gint width, gint height) \ +{ \ + gint i, j; \ + static const int tab[] = { 80, 160, 80, 160 }; \ + gint dest_add; \ + \ + width = GST_ROUND_UP_2 (width); \ + dest_add = GST_ROUND_UP_4 (width * 2) - width * 2; \ + width /= 2; \ + \ + for (i = 0; i < height; i++) { \ + for (j = 0; j < width; j++) { \ + dest[Y1] = tab[((i & 0x8) >> 3) + ((j & 0x8) >> 3)]; \ + dest[Y2] = tab[((i & 0x8) >> 3) + ((j & 0x8) >> 3)]; \ + dest[U] = 128; \ + dest[V] = 128; \ + dest += 4; \ + } \ + dest += dest_add; \ + } \ +} + +#define PACKED_422_FILL_COLOR(name, Y1, U, Y2, V) \ +static void \ +fill_color_##name (guint8 * dest, gint width, gint height, \ + gint colY, gint colU, gint colV) \ +{ \ + gint i, j; \ + gint dest_add; \ + \ + width = GST_ROUND_UP_2 (width); \ + dest_add = GST_ROUND_UP_4 (width * 2) - width * 2; \ + width /= 2; \ + \ + for (i = 0; i < height; i++) { \ + for (j = 0; j < width; j++) { \ + dest[Y1] = colY; \ + dest[Y2] = colY; \ + dest[U] = colU; \ + dest[V] = colV; \ + dest += 4; \ + } \ + dest += dest_add; \ + } \ +} + +PACKED_422_BLEND (yuy2_c, memcpy, _blend_u8_c); +PACKED_422_FILL_CHECKER_C (yuy2, 0, 1, 2, 3); +PACKED_422_FILL_CHECKER_C (uyvy, 1, 0, 3, 2); +PACKED_422_FILL_COLOR (yuy2_c, 0, 1, 2, 3); +PACKED_422_FILL_COLOR (yvyu_c, 0, 3, 2, 1); +PACKED_422_FILL_COLOR (uyvy_c, 1, 0, 3, 2); + /* MMX Implementations */ #ifdef BUILD_X86_ASM @@ -674,6 +789,8 @@ RGB_FILL_COLOR (rgbx_mmx, 4, _memset_rgbx_mmx); MEMSET_xRGB_MMX (bgrx, 8, 16, 24); RGB_FILL_COLOR (bgrx_mmx, 4, _memset_bgrx_mmx); + +PACKED_422_BLEND (yuy2_mmx, _memcpy_u8_mmx, _blend_u8_mmx); #endif /* Init function */ @@ -689,6 +806,8 @@ BlendFunction gst_video_mixer_blend_rgb; /* BGR is equal to RGB */ BlendFunction gst_video_mixer_blend_rgbx; /* BGRx, xRGB, xBGR are equal to RGBx */ +BlendFunction gst_video_mixer_blend_yuy2; +/* YVYU and UYVY are equal to YUY2 */ FillCheckerFunction gst_video_mixer_fill_checker_argb; FillCheckerFunction gst_video_mixer_fill_checker_bgra; @@ -703,6 +822,9 @@ FillCheckerFunction gst_video_mixer_fill_checker_rgb; /* BGR is equal to RGB */ FillCheckerFunction gst_video_mixer_fill_checker_xrgb; /* BGRx, xRGB, xBGR are equal to RGBx */ +FillCheckerFunction gst_video_mixer_fill_checker_yuy2; +/* YVYU is equal to YUY2 */ +FillCheckerFunction gst_video_mixer_fill_checker_uyvy; FillColorFunction gst_video_mixer_fill_color_argb; FillColorFunction gst_video_mixer_fill_color_bgra; @@ -720,6 +842,9 @@ FillColorFunction gst_video_mixer_fill_color_xrgb; FillColorFunction gst_video_mixer_fill_color_xbgr; FillColorFunction gst_video_mixer_fill_color_rgbx; FillColorFunction gst_video_mixer_fill_color_bgrx; +FillColorFunction gst_video_mixer_fill_color_yuy2; +FillColorFunction gst_video_mixer_fill_color_yvyu; +FillColorFunction gst_video_mixer_fill_color_uyvy; void gst_video_mixer_init_blend (void) @@ -737,6 +862,7 @@ gst_video_mixer_init_blend (void) gst_video_mixer_blend_y41b = blend_y41b_c; gst_video_mixer_blend_rgb = blend_rgb_c; gst_video_mixer_blend_xrgb = blend_xrgb_c; + gst_video_mixer_blend_yuy2 = blend_yuy2_c; gst_video_mixer_fill_checker_argb = fill_checker_argb_c; gst_video_mixer_fill_checker_bgra = fill_checker_bgra_c; @@ -747,6 +873,8 @@ gst_video_mixer_init_blend (void) gst_video_mixer_fill_checker_y41b = fill_checker_y41b_c; gst_video_mixer_fill_checker_rgb = fill_checker_rgb_c; gst_video_mixer_fill_checker_xrgb = fill_checker_xrgb_c; + gst_video_mixer_fill_checker_yuy2 = fill_checker_yuy2_c; + gst_video_mixer_fill_checker_uyvy = fill_checker_uyvy_c; gst_video_mixer_fill_color_argb = fill_color_argb_c; gst_video_mixer_fill_color_bgra = fill_color_bgra_c; @@ -764,6 +892,9 @@ gst_video_mixer_init_blend (void) gst_video_mixer_fill_color_xbgr = fill_color_xbgr_c; gst_video_mixer_fill_color_rgbx = fill_color_rgbx_c; gst_video_mixer_fill_color_bgrx = fill_color_bgrx_c; + gst_video_mixer_fill_color_yuy2 = fill_color_yuy2_c; + gst_video_mixer_fill_color_yvyu = fill_color_yvyu_c; + gst_video_mixer_fill_color_uyvy = fill_color_uyvy_c; #ifdef BUILD_X86_ASM if (cpu_flags & OIL_IMPL_FLAG_MMX) { @@ -775,6 +906,7 @@ gst_video_mixer_init_blend (void) gst_video_mixer_blend_y41b = blend_y41b_mmx; gst_video_mixer_blend_rgb = blend_rgb_mmx; gst_video_mixer_blend_xrgb = blend_xrgb_mmx; + gst_video_mixer_blend_yuy2 = blend_yuy2_mmx; gst_video_mixer_fill_checker_i420 = fill_checker_i420_mmx; gst_video_mixer_fill_checker_y444 = fill_checker_y444_mmx; diff --git a/gst/videomixer/blend.h b/gst/videomixer/blend.h index 3c0a2d8..4f770cb 100644 --- a/gst/videomixer/blend.h +++ b/gst/videomixer/blend.h @@ -42,6 +42,9 @@ extern BlendFunction gst_video_mixer_blend_rgbx; #define gst_video_mixer_blend_bgrx gst_video_mixer_blend_rgbx #define gst_video_mixer_blend_xrgb gst_video_mixer_blend_rgbx #define gst_video_mixer_blend_xbgr gst_video_mixer_blend_rgbx +extern BlendFunction gst_video_mixer_blend_yuy2; +#define gst_video_mixer_blend_uyvy gst_video_mixer_blend_yuy2; +#define gst_video_mixer_blend_yvyu gst_video_mixer_blend_yuy2; extern FillCheckerFunction gst_video_mixer_fill_checker_argb; #define gst_video_mixer_fill_checker_abgr gst_video_mixer_fill_checker_argb @@ -59,6 +62,9 @@ extern FillCheckerFunction gst_video_mixer_fill_checker_rgbx; #define gst_video_mixer_fill_checker_bgrx gst_video_mixer_fill_checker_rgbx #define gst_video_mixer_fill_checker_xrgb gst_video_mixer_fill_checker_rgbx #define gst_video_mixer_fill_checker_xbgr gst_video_mixer_fill_checker_rgbx +extern FillCheckerFunction gst_video_mixer_fill_checker_yuy2; +#define gst_video_mixer_fill_checker_yvyu gst_video_mixer_fill_checker_yuy2; +extern FillCheckerFunction gst_video_mixer_fill_checker_uyvy; extern FillColorFunction gst_video_mixer_fill_color_argb; extern FillColorFunction gst_video_mixer_fill_color_abgr; @@ -76,6 +82,9 @@ extern FillColorFunction gst_video_mixer_fill_color_xrgb; extern FillColorFunction gst_video_mixer_fill_color_xbgr; extern FillColorFunction gst_video_mixer_fill_color_rgbx; extern FillColorFunction gst_video_mixer_fill_color_bgrx; +extern FillColorFunction gst_video_mixer_fill_color_yuy2; +extern FillColorFunction gst_video_mixer_fill_color_yvyu; +extern FillColorFunction gst_video_mixer_fill_color_uyvy; void gst_video_mixer_init_blend (void); diff --git a/gst/videomixer/videomixer.c b/gst/videomixer/videomixer.c index c4448a6..c77604e 100644 --- a/gst/videomixer/videomixer.c +++ b/gst/videomixer/videomixer.c @@ -472,7 +472,9 @@ static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src", GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("AYUV") ";" GST_VIDEO_CAPS_BGRA ";" GST_VIDEO_CAPS_ARGB ";" GST_VIDEO_CAPS_RGBA ";" GST_VIDEO_CAPS_ABGR ";" GST_VIDEO_CAPS_YUV ("Y444") ";" GST_VIDEO_CAPS_YUV ("Y42B") ";" - GST_VIDEO_CAPS_YUV ("{ I420, YV12 }") ";" + GST_VIDEO_CAPS_YUV ("YUY2") ";" GST_VIDEO_CAPS_YUV ("UYVY") ";" + GST_VIDEO_CAPS_YUV ("YVYU") ";" + GST_VIDEO_CAPS_YUV ("I420") ";" GST_VIDEO_CAPS_YUV ("YV12") ";" GST_VIDEO_CAPS_YUV ("Y41B") ";" GST_VIDEO_CAPS_RGB ";" GST_VIDEO_CAPS_BGR ";" GST_VIDEO_CAPS_xRGB ";" GST_VIDEO_CAPS_xBGR ";" GST_VIDEO_CAPS_RGBx ";" GST_VIDEO_CAPS_BGRx) @@ -484,7 +486,9 @@ static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink_%d", GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("AYUV") ";" GST_VIDEO_CAPS_BGRA ";" GST_VIDEO_CAPS_ARGB ";" GST_VIDEO_CAPS_RGBA ";" GST_VIDEO_CAPS_ABGR ";" GST_VIDEO_CAPS_YUV ("Y444") ";" GST_VIDEO_CAPS_YUV ("Y42B") ";" - GST_VIDEO_CAPS_YUV ("{ I420, YV12 }") ";" + GST_VIDEO_CAPS_YUV ("YUY2") ";" GST_VIDEO_CAPS_YUV ("UYVY") ";" + GST_VIDEO_CAPS_YUV ("YVYU") ";" + GST_VIDEO_CAPS_YUV ("I420") ";" GST_VIDEO_CAPS_YUV ("YV12") ";" GST_VIDEO_CAPS_YUV ("Y41B") ";" GST_VIDEO_CAPS_RGB ";" GST_VIDEO_CAPS_BGR ";" GST_VIDEO_CAPS_xRGB ";" GST_VIDEO_CAPS_xBGR ";" GST_VIDEO_CAPS_RGBx ";" GST_VIDEO_CAPS_BGRx) @@ -991,6 +995,24 @@ gst_videomixer_setcaps (GstPad * pad, GstCaps * caps) mixer->fill_color = gst_video_mixer_fill_color_y42b; ret = TRUE; break; + case GST_VIDEO_FORMAT_YUY2: + mixer->blend = gst_video_mixer_blend_yuy2; + mixer->fill_checker = gst_video_mixer_fill_checker_yuy2; + mixer->fill_color = gst_video_mixer_fill_color_yuy2; + ret = TRUE; + break; + case GST_VIDEO_FORMAT_UYVY: + mixer->blend = gst_video_mixer_blend_uyvy; + mixer->fill_checker = gst_video_mixer_fill_checker_uyvy; + mixer->fill_color = gst_video_mixer_fill_color_uyvy; + ret = TRUE; + break; + case GST_VIDEO_FORMAT_YVYU: + mixer->blend = gst_video_mixer_blend_yvyu; + mixer->fill_checker = gst_video_mixer_fill_checker_yvyu; + mixer->fill_color = gst_video_mixer_fill_color_yvyu; + ret = TRUE; + break; case GST_VIDEO_FORMAT_I420: mixer->blend = gst_video_mixer_blend_i420; mixer->fill_checker = gst_video_mixer_fill_checker_i420; -- 2.7.4