mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-18 22:36:33 +00:00
videoflip: Add support for YUY2, UVYV and YVYU colorspaces
https://bugzilla.gnome.org/show_bug.cgi?id=644773
This commit is contained in:
parent
3e1c707495
commit
a3ed3d9374
1 changed files with 212 additions and 2 deletions
|
@ -2,6 +2,7 @@
|
||||||
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
|
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
|
||||||
* Copyright (C) <2003> David Schleef <ds@schleef.org>
|
* Copyright (C) <2003> David Schleef <ds@schleef.org>
|
||||||
* Copyright (C) <2010> Sebastian Dröge <sebastian.droege@collabora.co.uk>
|
* Copyright (C) <2010> Sebastian Dröge <sebastian.droege@collabora.co.uk>
|
||||||
|
* Copyright (C) <2011> Youness Alaoui <youness.alaoui@collabora.co.uk>
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Library General Public
|
* modify it under the terms of the GNU Library General Public
|
||||||
|
@ -75,7 +76,10 @@ static GstStaticPadTemplate gst_video_flip_src_template =
|
||||||
GST_VIDEO_CAPS_xBGR ";" GST_VIDEO_CAPS_BGRx ";"
|
GST_VIDEO_CAPS_xBGR ";" GST_VIDEO_CAPS_BGRx ";"
|
||||||
GST_VIDEO_CAPS_RGB ";" GST_VIDEO_CAPS_BGR ";"
|
GST_VIDEO_CAPS_RGB ";" GST_VIDEO_CAPS_BGR ";"
|
||||||
GST_VIDEO_CAPS_YUV ("I420") ";"
|
GST_VIDEO_CAPS_YUV ("I420") ";"
|
||||||
GST_VIDEO_CAPS_YUV ("YV12") ";" GST_VIDEO_CAPS_YUV ("IYUV")
|
GST_VIDEO_CAPS_YUV ("YV12") ";" GST_VIDEO_CAPS_YUV ("IYUV") ";"
|
||||||
|
GST_VIDEO_CAPS_YUV ("YUY2") ";" GST_VIDEO_CAPS_YUV ("UYVY") ";"
|
||||||
|
GST_VIDEO_CAPS_YUV ("YVYU")
|
||||||
|
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -91,7 +95,9 @@ static GstStaticPadTemplate gst_video_flip_sink_template =
|
||||||
GST_VIDEO_CAPS_xBGR ";" GST_VIDEO_CAPS_BGRx ";"
|
GST_VIDEO_CAPS_xBGR ";" GST_VIDEO_CAPS_BGRx ";"
|
||||||
GST_VIDEO_CAPS_RGB ";" GST_VIDEO_CAPS_BGR ";"
|
GST_VIDEO_CAPS_RGB ";" GST_VIDEO_CAPS_BGR ";"
|
||||||
GST_VIDEO_CAPS_YUV ("I420") ";"
|
GST_VIDEO_CAPS_YUV ("I420") ";"
|
||||||
GST_VIDEO_CAPS_YUV ("YV12") ";" GST_VIDEO_CAPS_YUV ("IYUV")
|
GST_VIDEO_CAPS_YUV ("YV12") ";" GST_VIDEO_CAPS_YUV ("IYUV") ";"
|
||||||
|
GST_VIDEO_CAPS_YUV ("YUY2") ";" GST_VIDEO_CAPS_YUV ("UYVY") ";"
|
||||||
|
GST_VIDEO_CAPS_YUV ("YVYU")
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -563,6 +569,205 @@ gst_video_flip_packed_simple (GstVideoFlip * videoflip, guint8 * dest,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_video_flip_y422 (GstVideoFlip * videoflip, guint8 * dest,
|
||||||
|
const guint8 * src)
|
||||||
|
{
|
||||||
|
gint x, y;
|
||||||
|
guint8 const *s = src;
|
||||||
|
guint8 *d = dest;
|
||||||
|
GstVideoFormat format = videoflip->format;
|
||||||
|
gint sw = videoflip->from_width;
|
||||||
|
gint sh = videoflip->from_height;
|
||||||
|
gint dw = videoflip->to_width;
|
||||||
|
gint dh = videoflip->to_height;
|
||||||
|
gint src_stride, dest_stride;
|
||||||
|
gint bpp;
|
||||||
|
gint y_offset;
|
||||||
|
gint u_offset;
|
||||||
|
gint v_offset;
|
||||||
|
gint y_stride;
|
||||||
|
gint u_stride;
|
||||||
|
gint v_stride;
|
||||||
|
|
||||||
|
src_stride = gst_video_format_get_row_stride (format, 0, sw);
|
||||||
|
dest_stride = gst_video_format_get_row_stride (format, 0, dw);
|
||||||
|
|
||||||
|
y_offset = gst_video_format_get_component_offset (format, 0, sw, sh);
|
||||||
|
u_offset = gst_video_format_get_component_offset (format, 1, sw, sh);
|
||||||
|
v_offset = gst_video_format_get_component_offset (format, 2, sw, sh);
|
||||||
|
y_stride = gst_video_format_get_pixel_stride (format, 0);
|
||||||
|
u_stride = gst_video_format_get_pixel_stride (format, 1);
|
||||||
|
v_stride = gst_video_format_get_pixel_stride (format, 2);
|
||||||
|
bpp = y_stride;
|
||||||
|
|
||||||
|
switch (videoflip->method) {
|
||||||
|
case GST_VIDEO_FLIP_METHOD_90R:
|
||||||
|
for (y = 0; y < dh; y++) {
|
||||||
|
for (x = 0; x < dw; x += 2) {
|
||||||
|
guint8 u;
|
||||||
|
guint8 v;
|
||||||
|
/* u/v must be calculated using the offset of the even column */
|
||||||
|
gint even_y = (y & ~1);
|
||||||
|
|
||||||
|
u = (s[(sh - 1 - x) * src_stride + even_y * bpp + u_offset] +
|
||||||
|
s[(sh - 1 - (x + 1)) * src_stride + even_y * bpp + u_offset]) / 2;
|
||||||
|
v = (s[(sh - 1 - x) * src_stride + even_y * bpp + v_offset] +
|
||||||
|
s[(sh - 1 - (x + 1)) * src_stride + even_y * bpp + v_offset]) / 2;
|
||||||
|
d[y * dest_stride + x * bpp + u_offset] = u;
|
||||||
|
d[y * dest_stride + x * bpp + v_offset] = v;
|
||||||
|
d[y * dest_stride + x * bpp + y_offset] =
|
||||||
|
s[(sh - 1 - x) * src_stride + y * bpp + y_offset];
|
||||||
|
d[y * dest_stride + (x + 1) * bpp + y_offset] =
|
||||||
|
s[(sh - 1 - (x + 1)) * src_stride + y * bpp + y_offset];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case GST_VIDEO_FLIP_METHOD_90L:
|
||||||
|
for (y = 0; y < dh; y++) {
|
||||||
|
for (x = 0; x < dw; x += 2) {
|
||||||
|
guint8 u;
|
||||||
|
guint8 v;
|
||||||
|
/* u/v must be calculated using the offset of the even column */
|
||||||
|
gint even_y = ((sw - 1 - y) & ~1);
|
||||||
|
|
||||||
|
u = (s[x * src_stride + even_y * bpp + u_offset] +
|
||||||
|
s[(x + 1) * src_stride + even_y * bpp + u_offset]) / 2;
|
||||||
|
v = (s[x * src_stride + even_y * bpp + v_offset] +
|
||||||
|
s[(x + 1) * src_stride + even_y * bpp + v_offset]) / 2;
|
||||||
|
|
||||||
|
d[y * dest_stride + x * bpp + u_offset] = u;
|
||||||
|
d[y * dest_stride + x * bpp + v_offset] = v;
|
||||||
|
d[y * dest_stride + x * bpp + y_offset] =
|
||||||
|
s[x * src_stride + (sw - 1 - y) * bpp + y_offset];
|
||||||
|
d[y * dest_stride + (x + 1) * bpp + y_offset] =
|
||||||
|
s[(x + 1) * src_stride + (sw - 1 - y) * bpp + y_offset];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case GST_VIDEO_FLIP_METHOD_180:
|
||||||
|
for (y = 0; y < dh; y++) {
|
||||||
|
for (x = 0; x < dw; x += 2) {
|
||||||
|
guint8 u;
|
||||||
|
guint8 v;
|
||||||
|
/* u/v must be calculated using the offset of the even column */
|
||||||
|
gint even_x = ((sw - 1 - x) & ~1);
|
||||||
|
|
||||||
|
u = (s[(sh - 1 - y) * src_stride + even_x * bpp + u_offset] +
|
||||||
|
s[(sh - 1 - y) * src_stride + even_x * bpp + u_offset]) / 2;
|
||||||
|
v = (s[(sh - 1 - y) * src_stride + even_x * bpp + v_offset] +
|
||||||
|
s[(sh - 1 - y) * src_stride + even_x * bpp + v_offset]) / 2;
|
||||||
|
|
||||||
|
d[y * dest_stride + x * bpp + u_offset] = u;
|
||||||
|
d[y * dest_stride + x * bpp + v_offset] = v;
|
||||||
|
d[y * dest_stride + x * bpp + y_offset] =
|
||||||
|
s[(sh - 1 - y) * src_stride + (sw - 1 - x) * bpp + y_offset];
|
||||||
|
d[y * dest_stride + (x + 1) * bpp + y_offset] =
|
||||||
|
s[(sh - 1 - y) * src_stride + (sw - 1 - (x + 1)) * bpp +
|
||||||
|
y_offset];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case GST_VIDEO_FLIP_METHOD_HORIZ:
|
||||||
|
for (y = 0; y < dh; y++) {
|
||||||
|
for (x = 0; x < dw; x += 2) {
|
||||||
|
guint8 u;
|
||||||
|
guint8 v;
|
||||||
|
/* u/v must be calculated using the offset of the even column */
|
||||||
|
gint even_x = ((sw - 1 - x) & ~1);
|
||||||
|
|
||||||
|
u = (s[y * src_stride + even_x * bpp + u_offset] +
|
||||||
|
s[y * src_stride + even_x * bpp + u_offset]) / 2;
|
||||||
|
v = (s[y * src_stride + even_x * bpp + v_offset] +
|
||||||
|
s[y * src_stride + even_x * bpp + v_offset]) / 2;
|
||||||
|
|
||||||
|
d[y * dest_stride + x * bpp + u_offset] = u;
|
||||||
|
d[y * dest_stride + x * bpp + v_offset] = v;
|
||||||
|
d[y * dest_stride + x * bpp + y_offset] =
|
||||||
|
s[y * src_stride + (sw - 1 - x) * bpp + y_offset];
|
||||||
|
d[y * dest_stride + (x + 1) * bpp + y_offset] =
|
||||||
|
s[y * src_stride + (sw - 1 - (x + 1)) * bpp + y_offset];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case GST_VIDEO_FLIP_METHOD_VERT:
|
||||||
|
for (y = 0; y < dh; y++) {
|
||||||
|
for (x = 0; x < dw; x += 2) {
|
||||||
|
guint8 u;
|
||||||
|
guint8 v;
|
||||||
|
/* u/v must be calculated using the offset of the even column */
|
||||||
|
gint even_x = (x & ~1);
|
||||||
|
|
||||||
|
u = (s[(sh - 1 - y) * src_stride + even_x * bpp + u_offset] +
|
||||||
|
s[(sh - 1 - y) * src_stride + even_x * bpp + u_offset]) / 2;
|
||||||
|
v = (s[(sh - 1 - y) * src_stride + even_x * bpp + v_offset] +
|
||||||
|
s[(sh - 1 - y) * src_stride + even_x * bpp + v_offset]) / 2;
|
||||||
|
|
||||||
|
d[y * dest_stride + x * bpp + u_offset] = u;
|
||||||
|
d[y * dest_stride + x * bpp + v_offset] = v;
|
||||||
|
d[y * dest_stride + x * bpp + y_offset] =
|
||||||
|
s[(sh - 1 - y) * src_stride + x * bpp + y_offset];
|
||||||
|
d[y * dest_stride + (x + 1) * bpp + y_offset] =
|
||||||
|
s[(sh - 1 - y) * src_stride + (x + 1) * bpp + y_offset];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case GST_VIDEO_FLIP_METHOD_TRANS:
|
||||||
|
for (y = 0; y < dh; y++) {
|
||||||
|
for (x = 0; x < dw; x += 2) {
|
||||||
|
guint8 u;
|
||||||
|
guint8 v;
|
||||||
|
/* u/v must be calculated using the offset of the even column */
|
||||||
|
gint even_y = (y & ~1);
|
||||||
|
|
||||||
|
u = (s[x * src_stride + even_y * bpp + u_offset] +
|
||||||
|
s[(x + 1) * src_stride + even_y * bpp + u_offset]) / 2;
|
||||||
|
v = (s[x * src_stride + even_y * bpp + v_offset] +
|
||||||
|
s[(x + 1) * src_stride + even_y * bpp + v_offset]) / 2;
|
||||||
|
|
||||||
|
d[y * dest_stride + x * bpp + u_offset] = u;
|
||||||
|
d[y * dest_stride + x * bpp + v_offset] = v;
|
||||||
|
d[y * dest_stride + x * bpp + y_offset] =
|
||||||
|
s[x * src_stride + y * bpp + y_offset];
|
||||||
|
d[y * dest_stride + (x + 1) * bpp + y_offset] =
|
||||||
|
s[(x + 1) * src_stride + y * bpp + y_offset];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case GST_VIDEO_FLIP_METHOD_OTHER:
|
||||||
|
for (y = 0; y < dh; y++) {
|
||||||
|
for (x = 0; x < dw; x += 2) {
|
||||||
|
guint8 u;
|
||||||
|
guint8 v;
|
||||||
|
/* u/v must be calculated using the offset of the even column */
|
||||||
|
gint even_y = ((sw - 1 - y) & ~1);
|
||||||
|
|
||||||
|
u = (s[(sh - 1 - x) * src_stride + even_y * bpp + u_offset] +
|
||||||
|
s[(sh - 1 - (x + 1)) * src_stride + even_y * bpp + u_offset]) / 2;
|
||||||
|
v = (s[(sh - 1 - x) * src_stride + even_y * bpp + v_offset] +
|
||||||
|
s[(sh - 1 - (x + 1)) * src_stride + even_y * bpp + v_offset]) / 2;
|
||||||
|
|
||||||
|
d[y * dest_stride + x * bpp + u_offset] = u;
|
||||||
|
d[y * dest_stride + x * bpp + v_offset] = v;
|
||||||
|
d[y * dest_stride + x * bpp + y_offset] =
|
||||||
|
s[(sh - 1 - x) * src_stride + (sw - 1 - y) * bpp + y_offset];
|
||||||
|
d[y * dest_stride + (x + 1) * bpp + y_offset] =
|
||||||
|
s[(sh - 1 - (x + 1)) * src_stride + (sw - 1 - y) * bpp +
|
||||||
|
y_offset];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case GST_VIDEO_FLIP_METHOD_IDENTITY:
|
||||||
|
g_assert_not_reached ();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
g_assert_not_reached ();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_video_flip_set_caps (GstBaseTransform * btrans, GstCaps * incaps,
|
gst_video_flip_set_caps (GstBaseTransform * btrans, GstCaps * incaps,
|
||||||
GstCaps * outcaps)
|
GstCaps * outcaps)
|
||||||
|
@ -624,6 +829,11 @@ gst_video_flip_set_caps (GstBaseTransform * btrans, GstCaps * incaps,
|
||||||
case GST_VIDEO_FORMAT_Y444:
|
case GST_VIDEO_FORMAT_Y444:
|
||||||
vf->process = gst_video_flip_planar_yuv;
|
vf->process = gst_video_flip_planar_yuv;
|
||||||
break;
|
break;
|
||||||
|
case GST_VIDEO_FORMAT_YUY2:
|
||||||
|
case GST_VIDEO_FORMAT_UYVY:
|
||||||
|
case GST_VIDEO_FORMAT_YVYU:
|
||||||
|
vf->process = gst_video_flip_y422;
|
||||||
|
break;
|
||||||
case GST_VIDEO_FORMAT_AYUV:
|
case GST_VIDEO_FORMAT_AYUV:
|
||||||
case GST_VIDEO_FORMAT_ARGB:
|
case GST_VIDEO_FORMAT_ARGB:
|
||||||
case GST_VIDEO_FORMAT_ABGR:
|
case GST_VIDEO_FORMAT_ABGR:
|
||||||
|
|
Loading…
Reference in a new issue