mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-03-30 12:49:40 +00:00
videomixer: Add support for YUY2, YVYU, UYVY
This commit is contained in:
parent
bd0b307a74
commit
6dd3edd0f7
3 changed files with 165 additions and 2 deletions
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue